武汉大学第二届“珞格杯”校园CTF大赛部分题目Writeup
Web ezphp 一个代码审计题。
1 2 3 4 5 6 7 if ($_GET['num' ] !== '23333' && preg_match('/^23333$/' , $_GET['num' ])){ echo '1st ok' ."<br>" ; } else { die ('会代码审计嘛23333' ); }
正则表达式。$ 匹配输入字符串的结尾位置。加一个 %0a 换行符。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 if (is_numeric($string_1)){ $md5_1 = md5($string_1); $md5_2 = md5($string_2); if ($md5_1 != $md5_2){ $a = strtr($md5_1, 'pggnb' , '12345' ); $b = strtr($md5_2, 'pggnb' , '12345' ); if ($a == $b){ echo '2nd ok' ."<br>" ; } else { die ("can u give me the right str???" ); } } else { die ("no!!!!!!!!" ); } } else { die ('is str1 numeric??????' ); }
构造一下,php 会将 0e\d 开头的纯数字字符串识别为浮点数。
1 2 3 4 5 6 7 8 9 10 11 12 13 <?php $count = 0 ; for ($i = 0 ; $i <= 30000000 ; $i++) { $md5 = strtr(md5($i), 'pggnb' , '12345' ); if (preg_match('/^0e\d+$/' , $md5)) { echo $i . " " . md5($i) . "<br>" ; $count++; } if ($count == 2 ) { break ; } } ?>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function filter ($string ) { return preg_replace('/x/' , 'yy' , $string); } $username = $_POST['username' ]; $password = "aaaaa" ; $user = array ($username, $password); $r = filter(serialize($user)); if (unserialize($r)[1 ] == "123456" ){ echo file_get_contents('flag.php' ); }
反序列化。将
放在 username 的最后,并在前面写与这串字符串一样长的 x,一个 x 变成两个 y 后我们构造的字符串就会被执行。
payload:
ezinclude 好像禁止了 get 请求?有一个发送数据后的 thankyou.php,发现有 get 参数,flag 可以在这个页面读出。
ezcmd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <?php if (isset ($_GET['ip' ])){ $ip = $_GET['ip' ]; if (preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{1f}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/" , $ip, $match)){ echo preg_match("/\&|\/|\?|\*|\<|[\x{00}-\x{20}]|\>|\'|\"|\\|\(|\)|\[|\]|\{|\}/" , $ip, $match); die ("fxck your symbol!" ); } else if (preg_match("/ /" , $ip)){ die ("no space!" ); } else if (preg_match("/.*f.*l.*a.*g.*/" , $ip)){ die ("no flag" ); } else if (preg_match("/tac|rm|echo|cat|nl|less|more|tail|head/" , $ip)){ die ("cat't read flag" ); } $a = shell_exec("ping -c 4 " .$ip); echo "<pre>" ; print_r($a); } highlight_file(__FILE__ ); ?>
构造命令行。用变量绕过 flag 的正则匹配,用 \$IFS 做空格,用grep查看文件
Misc check-in 签到题。找到 .git 中的 remote GitHub 地址,明文 flag 就在仓库里。
shellOfAwd 在第 0 个TCP流中发现服务器接受 POST 的 ”ANT“ 字段,可以从这里入手,第 3 个流中客户端发送了一段 php 代码:
由服务器在第 5 个流返回的 AES128 密钥即可解密之后通讯的所有数据,最终在第 7 个流处找到 flag。
Wechat_game 注意到 txt 文件夹里的文本都是反的,用 grep 扫一遍反的 flag 头得到答案。
佛系青年 开头是佛曰,在 这里 解密,之后看到题目里有栅栏,再用栅栏密码解密一次就可得到 flag 的 ASCII。
版权保护 观察题目结构,除正常汉字外还有大量 E2808D 和 E2E0EC。提取出 8D 和 8C 变成 0 和 1,再翻译成 ASCII,即可得到 flag。
Crypto bivibivi 先枚举方程的解,再用官方接口转换,民间也有很多算法源码。
bvtoav avtobv
RE RE1 输入 7 个数,要使这 7 个数和已知的 2 个数组成的 3*3 矩阵每行和和每列和等于 15,枚举求出(其实手算也很容易)。
1 2 3 4 5 6 7 8 9 10 for (int a = 0 ; a <= 9 ; a++) for (int b = 0 ; b <= 9 ; b++) for (int c = 0 ; c <= 9 ; c++) for (int d = 0 ; d <= 9 ; d++) for (int f = 0 ; f <= 9 ; f++) { int e = 5 , g = 4 , h = 9 , i = 2 , j = 15 ; if (a + b + c != j || d + e + f != j || a + d + g != j || b + e + h != j || c + f + i != j) continue ; printf ("%d %d %d %d %d %d\n" ,a,b,c,d,e,f); }
RE3 看到 .data 节有一串神秘字符和一串 58 个字符的密码表,直接与 base58 密码表对比翻译密文,再base58解密一次就能得到 flag。
RE4 三道题,都是 base64 编码的简单程序,分别要解一元、二元、三元方程。我的方式是先确定数在哪里,找到位置后再用sympy解方程。
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 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 ''' @Date: 2020-05-25 01:08:32 @LastEditors: QiuJhao @LastEditTime: 2020-05-26 23:56:52 ''' import base64from pwn import *import sympy as spimport ctypesdef deci (code ): content1 = base64.b64decode((code)) with open ('tmp.txt' , 'wb+' ) as f_now: f_now.write(content1) return content1 def tq (str ): a = str [1880 ] + str [1881 ] * 256 + str [1882 ] * 256 * 256 + str [1883 ] * 256 * 256 * 256 print (a) cc = 1 b = 0 for i in range (1886 ,1894 ): b = b + cc * str [i] cc = cc * 256 print (b) return repr (b/a) def todec (str ): l = list (str ) cc = 1 b = 0 flag = 1 if str [-1 ] >= 128 : flag = -1 q = 0 for i in l: l[q] = l[q] ^ 255 q = q + 1 l[0 ] = l[0 ] + 1 for i in l: b = b + cc * i cc = cc * 256 return b * flag def hextodouble (s ): cp = ctypes.pointer(ctypes.c_longlong(s)) fp = ctypes.cast(cp, ctypes.POINTER(ctypes.c_double)) return (fp.contents.value) if __name__ == '__main__' : sh = remote('218.197.154.9' , 10055 ) for i in range (1 ,11 ): sh.recvuntil('\n\n' ) code = sh.recvuntil('\n\n' ) print(code[:-2 ]) if i == 1 : answer = tq(deci(code[:-2 ])) sh.sendline(answer) if i == 2 : str = deci(code[:-2 ]) x = sp.Symbol('x' ) y = sp.Symbol('y' ) answer1 = sp.solve([todec(str [0x0778 :0x077C ]) * x + todec(str [0x0783 :0x0787 ]) * y - todec(str [0x078C :0x0794 ]), todec(str [0x07A0 :0x07A4 ]) * x + todec(str [0x07AB :0x07AF ]) * y - todec(str [0x07B4 :0x07BC ])], [x, y])[x] answer2 = sp.solve([todec(str [0x0778 :0x077C ]) * x + todec(str [0x0783 :0x0787 ]) * y - todec(str [0x078C :0x0794 ]), todec(str [0x07A0 :0x07A4 ]) * x + todec(str [0x07AB :0x07AF ]) * y - todec(str [0x07B4 :0x07BC ])], [x, y])[y] sh.send(repr (answer1)+' ' +repr (answer2)) if i == 3 : str = deci(code[:-2 ]) x, y, z = sp.symbols('x y z' , positive=True ) a1 = hextodouble(todec(str [0xAB0 :0xAB8 ])) b1 = hextodouble(todec(str [0xAB8 :0xAC0 ])) c1 = hextodouble(todec(str [0xAC0 :0xAC8 ])) e1 = hextodouble(todec(str [0xAC8 :0xAD0 ])) a2 = hextodouble(todec(str [0xAD0 :0xAD8 ])) b2 = hextodouble(todec(str [0xAD8 :0xAE0 ])) c2 = hextodouble(todec(str [0xAE0 :0xAE8 ])) e2 = hextodouble(todec(str [0xAE8 :0xAF0 ])) a3 = hextodouble(todec(str [0xAF0 :0xAF8 ])) b3 = hextodouble(todec(str [0xAF8 :0xB00 ])) c3 = hextodouble(todec(str [0xB00 :0xB08 ])) e3 = hextodouble(todec(str [0xB08 :0xB10 ])) answer1 = (sp.solve([x*a1+y*b1+z*c1-e1, x*a2+y*b2+z*c2-e2, x*a3+y*b3+z*c3-e3], [x, y, z])[x]) answer2 = (sp.solve([x*a1+y*b1+z*c1-e1, x*a2+y*b2+z*c2-e2, x*a3+y*b3+z*c3-e3], [x, y, z])[y]) answer3 = (sp.solve([x*a1+y*b1+z*c1-e1, x*a2+y*b2+z*c2-e2, x*a3+y*b3+z*c3-e3], [x, y, z])[z]) print(repr (answer1), repr (answer2), repr (answer3)) sh.send(repr (round (answer1))+' ' +repr (round (answer2))+' ' +repr (round (answer3))) sh.interactive() print(sh.recvuntil('Right!\n\n' ))
PS:IdontknowAngrorUnicorn
Decrypt 固件解密思路是用旧版本未被加密的固件提出解密程序。先下载所有该型号固件,发现有一个标有 Middleware 的版本,经过 binwalk 多次提取后得到文件系统,在 /bin 下可发现二进制文件 imgdecrypt。使用 qemu 运行这个 MIPS 程序解密 bin 即可得到key。
1 sudo chroot . ./qemu-mips-static bin/imgdecrypt DIR878A1_FW1.12B01_Encrypt.bin
区块链 智能合约? 那是啥 在 etherscan 打开题目给的合约地址,查看第一条交易,flag 就在 Input Data 中。
正解应该用 remix.ethereum.org 把程序编译后再调用开头的合约地址运行。