Introduction
ROP Emporium训练4:badchars的解析。
badchars32
Step 1
程序正常运行截图:
可以看到运行时提示badchars,结合题目说明,可能这些字符串会被程序特殊处理。
checksec:32位程序,依然只开启了DEP保护
Step 2
将程序丢到IDA Pro中去(至于为什么没用hopper,只能说这题需要理解下程序,而hopper的伪代码不够C……),先看下main函数:
main函数聚焦在pwnme函数:
首先发现memcpy函数存在栈溢出漏洞,其次出现了两个函数nstrlen和checkBadchars:
nstrlen函数是当遇到0xa(ASII码10即’\n’)时就截断。
checkBadchars函数是遇到\x62(ASII码98即’b’)、\x69(ASII码105即’i’)、\x63(ASII码99即’c’)、\x2f(ASII码47即’/‘)、\x20(ASII码32即’
还发现程序中是存在system函数的,但是没有’/bin/sh’字符串。所以我们需要将需要的字符串写入内存,这样就会遇到’/’、’b’、’s’被过滤的情况。
为了解决这个情况,根据题目的提示,需要通过XOR(异或)对输入的字符串加密后输入然后再解密。
Step 3
顺着这个思路首先解决第一个问题,字符串写到哪里。看一下各个段的权限,下面的段是有写权限的:
.bss段是空的所以可以把字符串写在.bss段。
然后是第二个问题怎么实现异或,通过ROPgadget找一下:
果然在0x08048890这里存在这样一条XOR指令可以利用。通过这条指令我们可以将XOR后的’/bin/sh’字符串传入,通过这条指令解密后再作为system函数的参数。
接着是XOR值的选择,我们可以写个简单的脚本找一下:
1 | badchars = '\x62\x69\x63\x2f\x20\x66\x6e\x73' |
运行结果为2,即当’/bin/sh\x00’和2异或的时候不会出现被过滤的字符。
当然还需要找一个指令段帮助控制ebx和cl寄存器(32位的ecx寄存器分为两个16位的cx寄存器,cx寄存器再分成8位的ch和cl寄存器)的值,也通过ROPgadget找一下:
最后就是找两个指令段,分别辅助写入和控制寄存器:
图中标记的一对指令刚好满足条件。
Step 4
思路顺利之后就是写EXP了:
1 | * from pwn import * |
注释掉的部分是在传入的XOR加密shellcode解密时候,将xor指令的传参分成两步进行,可是却无法正确getshell,希望有大佬可以解惑。
EXP运行结果:
badchars
64位程序和32位思路一样,传参的时候甚至更加简单,因为可以一次性将需要的字符串写入内存。
Tips
写入的字符串可以是’sh\x00\x00’,这样32位程序也可以实现一次性传参,前提是sh系统变量就是默认的’/bin/sh’命令。