[Pwnable.kr] ascii_easy

29. 2 月 2016 pwnable writeup 2

这应该是网上这道题第一篇公开的solution吧。首先要感谢一下韩国小哥inhack,虽然他的blog基本都是加密的,然而我在fb上联系到他之后他很热情地引导我做出了这道题,让我学到了新的东西。

 

这道题首先给出了提示”ulimit”,这里是一个可以禁用ALSR的黑科技,当设置ulimit -s unlimted时,系统的ALSR将会失效,原因在于arch/x86/mm/mmap.c中:

在第二个if会返回true,所以ALSR就不起作用了,所有的地址成为固定值。

 

然后我们再看这个题,F5反汇编得到:

可以看出vuln()中dest长度为0xA8,而strcpy的源字符串长度最大 0x18F,存在栈溢出。常规的想法是通过一个 “x”*0xA8 + oebp + ret_addr + ‘xxxx’ + ‘sh’ 的payload覆盖ret,控制eip执行system(‘/bin/sh’)拿到shell。

然后使用gdb查看system的函数地址:

_$RWYHFGK)FXO<code srcset=F9%Z7LVM” width=”415″ height=”115″>

这个函数地址是符合要求的(能通过ascii检查),再看一下system函数在libc中的地址:

][HIO$4PA8T$1SXP_QUO]T4

是0x3f250.

然后我们还需要在libc里面找一个”sh\x00″的字符串地址,我们使用ida的search -> sequence of bytes功能,搜索”73 68 00″,找到了四个结果,我们依次看看这四个结果。LE)C_$IHBQ3ROD3}FKBD9WL

假设”sh\x00″的起始地址是str_addr,那么libc加载到ascii_easy之后的地址应该是 0x555c5250 – 0x3f250 + str_addr

上面四个地址计算结果分别是(注意左边一栏并不是sh的开始地址,而是指令的开始地址):0x556E2495,0x556E2801,0x556E4A31,0x556E69C2,其中只有第三个(0x556E4A31)是可以通过ascii的检查的,所以我们使用这个做为system()的参数字符串指针地址。

所以最后的payload是:

AZPFM~%C_RB_`)H1~{NH~$2

 

这个题到这里已经结束了,但是在以前(大概是去年)这么做还不行,因为据inhack说当时的libc的system地址跟我现在看到的不一样,导致四个”sh”的字符串地址都无法使用。所以他需要用别的方法,比如:将自己的tmp目录加入环境变量,写一个只包含system(“/bin/sh”)的c程序,然后到libc中寻找可以使用的字符串,比如:

RRI%~$FBY1IZUAPIUNDUP}5

这里的library的地址计算之后恰好可以通过ascii检查,那么就让自己的可执行文件名字改成library,这样调用library可以直接执行自己写的程序。


2 thoughts on “[Pwnable.kr] ascii_easy”

  • 1
    周鹏 on 2016年7月29日 回复

    Yiz96同学,您好,我对于“让自己的可执行文件名字改成library,这样调用library可以直接执行自己写的程序”这一句话不是很了解,不知道能不能解释一下?

    • 2
      Yiz96 on 2016年8月9日 回复

      最后一张图,利用“library”这个字符串,执行环境变量里面(tmp)下我们执行的执行文件来得到shell

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据