slmail&windows缓冲区溢出案例(一)
缓冲区溢出案例与exp开发流程
- bug是怎么找到的?
- 你怎么知道x比特在y命令,可以使应用程序崩溃造成缓冲区溢出漏洞?
有三种方法:
- 如果有源代码,阅读源码是最简单的寻找bug的方式。
- 逆向工程
- fuzzing
fuzzing 是一种向应用程序发送构造的数据,然后期盼程序崩溃。
程序崩溃说明程序没有对输入做正确的过滤。
漏洞历史
下面讲一下在slmail 5.5.0 邮件服务软件上的知名缓冲区溢出漏洞。
在2005年发现,pop3 pass命令,在用户登陆的时候,有bof漏洞。攻击者无需知道
任何口令即可引发bof漏洞。
该软件未使用DEP或者ASLR编译,使得漏洞利用过程更加简单,我们不必绕过这些内部安全机制。
DEP和ASLR
这是微软的内存保护机制。
DEP是一系列硬件、软件技术,执行额外的内存检查,防止恶意代码在程序上运行。
DEP主要的好处是当发生异常时,防止代码从数据区执行。
ASLR打乱载入应用程序、动态链接库时候的基地址(base address)
与pop3协议通信
我们选择slmail作为案例的原因是,与纯文本pop3协议通信十分简单。
我们可以使用netcat与pop3服务器进行通信。
https://slmail.software.informer.com/5.5/
安装exe到windows,重启后,windows开放了pop3-110端口
写一个python脚本
这个脚本的作用很简单,和nc起到的作用一样。为什么要写这个脚本呢?因为根据这个脚本稍作修改,就可以改为fuzzer脚本,使得应用程序崩溃。
https://github.com/Whale3070/ctf-coding/blob/master/send.py
https://github.com/Whale3070/ctf-coding/blob/master/fuzzer.py
immunity debugger
左上 –指令面板
右上 –寄存器面板
左下 –内存转储面板
右下 –堆栈面板
file – attach –SLmail
挂载后,点击下图的开始按钮,运行程序
运行fuzzer.py,使程序崩溃,造成了缓冲区溢出
定位缓冲区大小
定位缓冲区大小,当输入2500个a,程序运行正常;输入2600个a时候,就会报错。
1 |
|
控制eip
控制eip寄存器是exp开发流程中关键的有,eip寄存器就像驾驭马的辔头一样,控制缰绳就让应用程序前进,
拉着缰绳就能让它改变前进方向。所以我们使用4个A在buffer(缓冲区)中覆盖了EIP,这里有两个常见的方法:
二叉树分析
将2700个A修改为,发送1350A和1350个B,如果EIP被B所覆盖,我们知道了4比特存在于buffer的第二部分。
接下来,修改1350个B为675个B和675个C,然后再一次发送buffer。
如果EIP被C覆盖,我们知道了4bit存在于2000-2700比特范围之间。
我们继续将buffer二分直到我们知道了准确的覆盖EIP的4bit。
从数学上来说,这将在7次之内找到。
发送一个特殊的字符串(使用msf)
最快的方式是发送一个特殊的字符,来确认覆盖EIP的范围,然后在buffer中查找这个字符。
patter_create.rb
是一个ruby工具,来创建和定位这样的buffer,并且可以在msf中找到它。
使用方法:
1 |
|
复制生成的字符串,修改send.py,将字符串作为pass密码发送,而不是2700个A,注意下一次程序崩溃时,ESP和EIP寄存器中的值
执行send3py
注意弹框的地址39694438
1 |
|
于是得知了offset为2606
检查buffer,准备执行shellcode
msf可以自动生成shellcode,标准的反弹shell的payload(有效载荷)需要大约350-400比特的空间。
修改buffer,string= "A"* 2606+ "B"*4 + "C"*(3500-2606-4)
查看最后的crash,我们可以看到ESP寄存器直接指向了我们缓冲区的C地址,这看起来有足够的空间让我们放置shellcode。