pwnable.kr之write up之passcode

CTF

Posted by 0xl00se on May 10, 2017

1.预备知识

GOT(Global Offset Table):用于记录在 ELF 文件中所用到的共享库中符号的绝对地址。在程序刚开始运行时,GOT 表项是空的,当符号第一次被调用时会动态解析符号的绝对地址然后转去执行,并将被解析符号的绝对地址记录在 GOT 中,第二次调用同一符号时,由于 GOT 中已经记录了其绝对地址,直接转去执行即可(不用重新解析)。

PLT(Procedure Linkage Table)的作用是将位置无关的符号转移到绝对地址。当一个外部符号被调用时,PLT 去引用 GOT 中的其符号对应的绝对地址,然后转入并执行。

其中PLT 对应.plt section ,而GOT对应 .got.plt ,主要对应函数的绝对地址。通过readelf查看可执行文件,我们发现还存在.got section,这个section主要对应动态链接库中变量的绝对地址。我们还要注意PLT section在代码链接的时候已经存在,存在于代码段中,而GOT存在于数据段中。

2.查看passcode.c源代码。

发现login()里的scanf函数的参数有些奇怪,没有&符号,变成了往里面输入地址,而不是正常的int型参数了。

3.IDA打开passcode可执行程序,发现name偏移量为-6CH,pass1偏移量为-0CH,两者相差(6C-0C)= 96个字节。

4.F4运行到断点位置,红线部分是我们的实现的目标地址。

观察passcode.c源码,发现fflush()可以利用,整个overflow思路如下:name覆盖pass1,然后 通过GOT跳转到fflush(),然后在JMP地址到system()上。

5.fflush的GOT地址可通过如下获取:

6.system地址如下:

7.开始构造payload python -c "print 96*'A'+'\x04\xa0\x04\x08'+'134514147'"|./passcode"