-
-
[原创]小白学pwn——ret2libc
-
发表于:
2020-2-2 10:22
8779
-
开了NX,看来不能像以前那样愉快的ret2shellcode了
sub_4008BF
sub_4008E4
漏洞点找到了,buf只有0x40个字节,但read却读入了0xC8个字节。
因此想让程序运行到我们想要的位置,只需填充0x40(buf大小)+0x8(rbp大小)再加入返回地址即可。
不过麻烦的是,题目只导入了puts,printf,read等函数,我们必须手动找出system和'/bin/sh'的地址
利用同版本libc里函数偏移确定的特点,我们可以先用现有的函数推测libc的版本,然后用
间接算出system跟字符串'/bin/sh'的地址
获得libc中某函数的地址一般使用GOT表泄露。
由于 libc 的延迟绑定机制,我们需要泄漏已经执行过的函数的地址,已经执行过的话就会在got表生存下来,有了真实的地址!这里,我们选用puts函数实现2次调用,让它生存下来
因为我们得到的地址只在这次运行中有效,所以,当我们打印出puts地址并且pwntools recv()以后,必须再次执行start函数实现第二次的栈溢出,从而ret到system
所以我们的流程就是
1.调用puts打印出puts的真实地址
2.计算system与bin/sh字符串的地址
3.再次栈溢出调用system('/bin/sh')
写脚本吧!
菜鸡遇到的坑1,以前32位栈溢出的时候直接把参数放栈里,结果忘了64位调用要把参数放进edi,吃了好多sigsegv才反应过来。
所以在puts前,我们要先return到pop edi;ret;来把我们栈中可控的数据(也就是GOT puts)放入edi中,这么两句的搜索可以用
0x400730就是start的地址,相当于我们在同一次运行中再次执行了一次程序
然后就是我遇到的坑2,读我们输出的地址之前,一定要先把题目的废话读进来(因为原来的程序结束是login fail!我们直接recvuntil到fail)
然后因为第二次start也会输出废话,所以要截取中间的内容,括号中的字符串也是读取的一部分,u64只能转换恰好8位的字符串,我们puts出的地址因为是字符串,前面的0会被截断,所以只有低六位的,我们手动给他补全。
关于这几个offset还有libc的版本,可以用python库LibcSearcher也可以上网站libc database search查询,根据已有函数的地址后三位,算出system的偏移。
和调用puts一样的流程。
大功告成!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
最后于 2020-2-2 17:40
被v0id_编辑
,原因: