1. echo
1、checksec
32位,只开启了NX
2、ida
3、思路
由于没有开启PIE而且程序调用了system,所以可以直接拿到printf的got表地址和system的plt地址。
先找到s相对于printf是第几个参数,然后在这个地方,按照ctfwiki上面说的大数覆盖的方法,将printf的got表改成system的地址。
或者直接用fmtstr_payload
进入下一次循环的时候,输入’/bin/sh’,再次调用printf的时候实际上是调的system,s作为了system的参数。
1 |
|
2. echo2
1、checksec
64位,开启了PIE,无法直接获得printf和system的地址
2、ida64
和echo差不太多
3、思路
要先找到程序本身的基址和libc的基址,由于要求可以不用hackme那个网站上的libc,就直接用的本地的。
首先用gdb调试一下,会发现在栈上面有
通过这两个地方可以找到程序在运行起来后的地址。
接下来就是要去找string和这两个变量是printf的第几个参数
1 |
|
emmm好像要分两次输进去,分别找。
可以得到%6$p=0x4141414141414141,41和43是对应的main+74和__libc_main_start+231的地址。于是可以计算main和 __libc_main_start的真实地址。
由于偏移量总是不变的,所以可以得到printf和system的真实地址,然后进行覆写。
1 |
|
也可以用onegadget找到libc里面text段里面直接调用execute的地址,然后覆盖exit的地址为这个
3.
1、可以在gdb里面用got看got表的地址。
2、recvutill(‘.’,drop=true),是指接受’.‘之前的数据并且不要’.‘。
3、64位的程序还要考虑寄存器的6个,但是这里本来就比6大