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"
。