在选择2时,会回送输入函数的真实地址。当输入system函数的时候,system真实地址就爆出来了。我们还需要/bin/sh的真实地址才能凑成system("/bin/sh")得到shell。首先要得到libc的基址、system在libc中的偏移、/bin/sh在libc中的偏移。 libc基址+system基址=system的真实地址 libc基址+/bin/sh的偏移=/bin/sh的真实地址 如上图,二进制文件执行时,会调用动态链接库libc.so,需要什么函数就调用什么。
使用libc.so.6获取里面的system和/bin/sh的偏移地址。为什么libc.so的函数地址不是真实地址?因为libc.so是个文件,其中的函数地址是以文件的开头作为基准的,所以libc中的system地址只是一个偏移,而内存中的才是函数真实地址。
先查看libc.so.6: libc.so.6是libc-2.27.so的软链接,需要把libc-2.27.so拷出来。 把libc-2.27.so拖到IDA中,在左侧窗口中任意单击一个函数,快捷键ctrl+f,输入system,查看其地址。 快捷键shift+f12调出字符串窗口,单击任意处按快捷键ctrl+f,输入/bin/sh,获得地址。
如图,此时,rsp指到0x10的位置。也就是将要执行leave剩下的部分:pop rbp。执行完后,rsp会指到0x18;
接着执行ret,也就是pop rdi,rsp再下降一格,ppc指令的地址弹到rip上;下一条就会执行ppc。
执行pop rax时,rsp的内容也就是system地址会被弹到rax上。rsp再往下降一格。rip指向pop rdi指令。
执行pop rdi时,/bin/sh地址会被弹到rdi上。最后调用call rax也就是system函数。
** 大功告成 **