pwnable.kr horcruxes Writeup

이번 문제는 소스가 제공되지 않습니다. 일단 현재 상황을 먼저 알아보겠습니다. Voldemort concealed his splitted soul inside 7 horcruxes. Find all horcruxes, and ROP it! author: jiwon choi ssh horcruxes@pwnable.kr -p2222 (pw:guest) ==================================================== horcruxes@pwnable:~$ cat ./readme connect to port 9032 (nc 0 9032). the 'horcruxes' binary will be executed under horcruxes_pwn privilege. rop it to read the flag. horcruxes@pwnable:~$ file ./horcruxes ./horcruxes: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-, for GNU/Linux 2.6.32, BuildID[sha1]=bed2c3c01d21a3cbb1109e76a83310dfb8a077be, not stripped horcruxes@pwnable:~$ checksec --file=./horcruxes [*] '/home/horcruxes/horcruxes' Arch: i386-32-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x809f000) asm 문제처럼 주어진 바이너리는 분석용이고 실제 익스는 nc 를 통해 해야 하네요 ...

2020-12-11 · 5 min · 980 words · Byeongmin Bae

pwnable.kr asm Writeup

이번 문제는 open, read, write, exit 시스템콜만으로 커스텀 쉘코드를 작성해서 flag 파일을 읽는것이 목표입니다. seccomp 우회라고 볼 수 있겠네요. /* Mommy! I think I know how to make shellcodes ssh asm@pwnable.kr -p2222 (pw: guest) =========================================================== asm@ubuntu:~$ checksec --file ./asm [*] '/home/asm/asm' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: PIE enabled Stripped: No */ #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; } 바이너리에 setgid 가 걸려있지 않아 readme 를 읽어봤더니 현재 asm, asm.c 는 분석용이고 권한상승 후 플래그를 얻으려면 nc 0 9026 에 페이로드를 전달해야 한다고 합니다. ...

2020-04-15 · 5 min · 1028 words · Byeongmin Bae

pwnable.kr cmd2 Writeup

이번 문제는 특이하게 커멘드를 입력받아 system 함수로 실행해줍니다. 하지만 모든 환경 변수가 지워지고 PATH 도 이상하게 바뀝니다. 게다가 입력되는 커멘드에서 환경변수와 관련된 문자열도 필터링됩니다. /* Daddy bought me a system command shell. but he put some filters to prevent me from playing with it without his permission... but I wanna play anytime I want! ssh cmd2@pwnable.kr -p2222 (pw:flag of cmd1) =========================================================== cmd2@ubuntu:~$ checksec cmd2 [*] '/home/cmd2/cmd2' Arch: amd64-64-little RELRO: Partial RELRO Stack: No canary found NX: NX enabled PIE: No PIE (0x400000) Stripped: No */ #include <stdio.h> #include <string.h> int filter(char* cmd){ int r=0; r += strstr(cmd, "=")!=0; r += strstr(cmd, "PATH")!=0; r += strstr(cmd, "export")!=0; r += strstr(cmd, "/")!=0; r += strstr(cmd, "`")!=0; r += strstr(cmd, "flag")!=0; return r; } extern char** environ; void delete_env(){ char** p; for(p=environ; *p; p++) memset(*p, 0, strlen(*p)); } int main(int argc, char* argv[], char** envp){ delete_env(); putenv("PATH=/no_command_execution_until_you_become_a_hacker"); if(filter(argv[1])) return 0; printf("%s\n", argv[1]); system( argv[1] ); return 0; } 처음엔 여러가지 명령어를 시도해봤는데 PATH 때문에 당연히 먹히지 않았습니다. ...

2020-04-14 · 2 min · 355 words · Byeongmin Bae

pwnable.kr passcode Writeup

이번 문제는 인증 절차를 무력화 시켜 플래그를 얻는 문제입니다. /* Mommy told me to make a passcode based login system. My initial C code was compiled without any error! Well, there was some compiler warning, but who cares about that? ssh passcode@pwnable.kr -p2222 (pw:guest) ========================================================= passcode@pwnable:~$ checksec ./passcode [*] '/home/passcode/passcode' Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x8048000) */ #include <stdio.h> #include <stdlib.h> void login() { int passcode1; int passcode2; printf("enter passcode1 : "); scanf("%d", passcode1); fflush(stdin); // ha! mommy told me that 32bit is vulnerable to bruteforcing :) printf("enter passcode2 : "); scanf("%d", passcode2); printf("checking...\n"); if (passcode1 == 338150 && passcode2 == 13371337) { printf("Login OK!\n"); system("/bin/cat flag"); } else { printf("Login Failed!\n"); exit(0); } } void welcome() { char name[100]; printf("enter you name : "); scanf("%100s", name); printf("Welcome %s!\n", name); } int main() { printf("Toddler's Secure Login System 1.0 beta.\n"); welcome(); login(); // something after login... printf("Now I can safely trust you that you have credential :)\n"); return 0; } 코드를 보면 scanf() 에 주소 연산자가 누락되어있어 두 passcode 변수는 입력을 받을 수 있는 상황이 아닙니다. ...

2020-04-14 · 3 min · 575 words · Byeongmin Bae

reversing.kr Easy Keygen Writeup

이번 문제는 간단한 키젠을 제작하는 문제입니다. 문제 설명을 보면 시리얼 키가 5B134977135E7D13 일때의 name 을 찾아달라고 합니다. 분석 도중 입력 받은 name 에 대해 조건에 따라 xor 연산을 반복하는 부분을 보았습니다. .text:00401000 var_130 = byte ptr -130h .text:00401000 var_12F = byte ptr -12Fh .text:00401000 var_12E = byte ptr -12Eh .text:00401038 mov [esp+140h+var_130], 10h .text:0040103D mov [esp+140h+var_12F], 20h .text:00401042 mov [esp+140h+var_12E], 30h var_130 은 0x10, 0x20, 0x30 세 값을 순환하며 name 배열의 각 바이트와 순차적으로 xor 연산을 수행합니다. ...

2020-03-04 · 1 min · 200 words · Byeongmin Bae

Bypassing ASLR/DEP via ROP for Root Privilege Escalation

저번 글에서는 ASLR이 비활성화된 환경에서 ret2libc 기법과 권한상승을 위한 ROP 개념을 다뤘었습니다. 하지만 현대적 시스템에서는 ASLR 이 기본적으로 활성화 되어있어 다음 실행 때 라이브러리의 주소를 정확히 “예측“하기는 어렵습니다. 물론 32비트에서 조건에 따라 브루트포스가 가능하긴 합니다. 그래서 이번 글에서는 동적 링킹 메커니즘을 이용해 libc leak 을 일으켜 ASLR/DEP 가 활성화 되어있는 환경에서도 exploit 을 성공시키는 방법에 대해 알아보겠습니다. 한가지 팁은 gdb 는 편리한 디버깅을 위해 ASLR 비활성화가 기본이라 실제 환경과 똑같이 만들려면 따로 커멘드를 쳐야 합니다. ...

2019-10-23 · 4 min · 796 words · Byeongmin Bae

Bypassing DEP via ret2libc and ROP for Root Privilege Escalation

저번 ret2sc 와 달리 ret2libc 는 매핑된 외부 라이브러리 함수를 이용해 쉘을 실행하기 때문에 DEP 가 걸려있어도 유효한 기법입니다. 만약 ASLR이 적용된 환경이라면 주소가 매번 변경되므로 주소 leak 과 오프셋 계산 과정이 추가적으로 들어가는데, 이 주제는 다음 글에서 다루도록 하겠습니다. 이번에는 ret2libc 기법으로 쉘을 획득하고 ROP 기법으로 권한상승까지 해보겠습니다. 저번과 똑같은 예제 코드지만 이번엔 스택 실행 권한이 없습니다. /* $ gcc -m32 -fno-stack-protector -mpreferred-stack-boundary=2 -no-pie $ cat /proc/sys/kernel/randomize_va_space # 0 Kernel: 4.4.0-142-generic x86_64 | gcc: 5.4.0 Checksec: Partial RELRO | No canary found | NX enabled | No PIE */ #include <stdio.h> #include <string.h> int main(int argc, char **argv) { char buf[32]; strcpy(buf, *(argv + 1)); printf("%s", buf); } system() 이 호출이 가능한지 확인하기 위해 ret 영역을 system() 의 주소로 덮어보겠습니다. ...

2019-07-30 · 4 min · 835 words · Byeongmin Bae

ret2sc for Root Privilege Escalation

저번 포스팅에선 쉘코드를 어떻게 만드는지에 대해 알아봤습니다. 이번엔 DEP 가 해제되어 있을 때 메모리에 쉘코드를 삽입하고 실행 흐름을 조작하는 기법인 ret2sc 에 대해 알아보겠습니다. 200n년도엔 공격자가 스택 영역에 쉘코드를 집어넣고 실행했던 일이 흔했지만 2004년부터 본격적으로 도입된 DEP 로 인해 많이 줄었습니다. 만약 DEP 가 걸려있다면, ret2libc 또는 ROP 기법을 보통 사용합니다. 이건 이후 포스팅에서 다루도록 하겠습니다. 아래 예제는 좀 극단적이지만 개발자가 실수로 보안 기능을 전부 끄고 사용자의 입력값을 검증 없이 그대로 복사한다고 가정해보겠습니다. ...

2019-07-09 · 3 min · 562 words · Byeongmin Bae

Writing Shellcode on Linux x86

이번 글에서는 pwner 의 기본기인 쉘코드 작성법에 대해 간단히 알아보겠습니다. 대회에 출제된 문제중에 이미 알려진 쉘코드를 사용해도 익스가 안될 때가 있어서 이럴땐 커스텀 쉘코드를 만드는 것이 좋습니다. 솔직히 요즘엔 다들 pwntools 의 shellcraft 를 써서 간단히 만들지만, 이번 포스팅에서는 How? 에 중점을 둬서 선조님들의 방식으로 한번 만들어보겠습니다. 쉘코드를 만들려면 먼저 c로 쉘을 실행하는 코드를 작성하고 타깃 아키텍처에 맞게 빌드해야 합니다. 그런 다음 바이너리를 분석해 어셈 코드로 재작성하고, 최종적으로 opcode를 추출하면 쉘코드가 완성됩니다. ...

2019-06-02 · 3 min · 627 words · Byeongmin Bae

LOB succubus (lv.18/20) Writeup

이번 문제는 간단한 ret2sc 문제입니다. /* The Lord of the BOF : The Fellowship of the BOF - nightmare - PLT */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dumpcode.h> main(int argc, char *argv[]) { char buffer[40]; char *addr; if(argc < 2){ printf("argv error\n"); exit(0); } // check address addr = (char *)&strcpy; if(memcmp(argv[1]+44, &addr, 4) != 0){ printf("You must fall in love with strcpy()\n"); exit(0); } // overflow! strcpy(buffer, argv[1]); printf("%s\n", buffer); // dangerous waterfall memset(buffer+40+8, 'A', 4); } 풀이에 앞서 먼저 조건을 살펴보겠습니다. ...

2019-05-26 · 2 min · 311 words · Byeongmin Bae