0x0 程序保护和流程
保护:
流程:
main()
存在一个很明显的问题,就第二次可以输入的字符串大小是根据第一次输入的数字大小确定的,所以存在一个明显的栈溢出。
0x1 利用过程
1.通过栈溢出控制程序的流程只会发生在函数结束时,但是在这个程序中只要第一次的read函数一直有效程序就不会退出,所以在对栈完成布局之后就需要关闭输入。
2.一旦关闭输入,就不能继续输入了,所以必须一次就把gadget全部布置到栈上。
3.通过提示可以在.data中找到flag字符串。
4.于是猜想需要将名字为flag的文件中的内容读取并输出就能得到flag了。而读取并输出的流程可以为open()->read()->printf()。(write函数参数较多,printf函数可以少写一点代码)
flag=open("flag",0); // O_RDONLY==0
read(fd, addr, 100);
printf(addr);
但是在这段程序中并没有open函数,不过还可以使用syscall直接调用open函数,而在libc中可以发现open()的调用号为2。
接下来只需要找到syscall的gadget就并配合其他gadget就可以实现open()了。程序中的write函数和alarm函数都是需要syscall完成调用的。
所以只需要修改got表将got表中的地址加上偏移就可以直接调用syscall。选用这两个函数的原因是都有syscall,知道got表地址,并且不在ROP链中。
5.通过以上分析和程序中的gadget可以写出payload了。
需要的gadget。
pop_rax=0x4006fc
pop_rdi=0x4008a3
pop_rsi=0x4008a1
pop_rdx=0x4006fe