pwnable.xyz
[pwnable.xyz] door write up
[pwnable.xyz] door write up
2020.08.10Analytic 이번 문제는 `main()` 함수와 `win()` 함수 2개만 있다. `main()` 함수를 보면 사용자가 입력한 값을 write 하는 것만 있다. int main(){ setup() puts("Door To Other RealmS") int32_t var_14 = 0 int32_t var_10 = 0 *door = rand():0.d while (true) print_menu() uint64_t rax_2 = zx.q(read_int32():0.d) if (rax_2:0.d != 2) if (rax_2:0.d s> 2) if (rax_2:0.d != 3) if (rax_2:0.d == 4) return 0 // rax_2 == 3 else if (*door == 0) continue e..
[pwnable.xyz] car shop write up
[pwnable.xyz] car shop write up
2020.08.09Analytic `Full RELRO` 이기 때문에 GOT overwrite를 할 수 없다. `buy()` 함수를 보면 사용자가 선택한 자동차가 메모리 공간에 저장된다. 이때의 메모리 구조를 보면 아래와 같다. `0x603260` ~ `0x6032af`: 사용자가 `buy()` 함수를 호출하면 `car`라는 구조체의 chunk가 만들어짐 `0x603260`: 자동차 이름을 저장한 주소 `0x603268`: 자동차 이름의 크기 `0x603270`: 다음 청크(`car`)의 주소 `0x603278`: 이전 청크(`car`)의 주소 `0x603290`: 자동차의 이름 gdb-peda$ x/10gx 0x603260 0x603260: 0x0000000000603290 0x0000000000000003 0x6032..
[pwnable.xyz] words write up
[pwnable.xyz] words write up
2020.08.08Analytic 아래 사진은 사용자 정의 함수 목록이다. fill_letters(), fill_numbers(), fill_handles(), fill_words() 함수들은 특별한 기능은 없고 사용자 선택에 따라 문장을 만들어 출력하는 함수 이다. 하지만 fill_handles() 함수를 제외한 나머지 함수들은 만들어진 문장으로 초기화 하여 생성하지만, fill_handles() 함수는 로직 에러로 초기화를 하지 않고 문장을 추가한다. 코드로 자세히 설명하자면, 사용자가 select1 값이 2가 아니고 select2 값이 6이상이면 문장을 초기화 하지 않는다. 이 로직 에러로 문장을 계속 추가 할 수 있게 된다. 문장이 저장되는 메모리 공간은 아래와 같다. 문장이 저장되는 시작 부분은 변수 a인 0x6..
[pwnable.xyz] notebook write up
[pwnable.xyz] notebook write up
2020.08.07바이너리 파일을 분석하여 c로 나타내면 아래와 같다. void make_note(){ printf("size: "); int size = read_int(); void* addr = malloc(0x38); *(addr + 0x30) = malloc(size); *(addr + 0x8) = size; *addr = &get_size(); printf("Title: "); readline(addr + 0xc, 0x1f, 0xa); printf("Note: ") readline(*(addr + 0x30), size, 0xa); *data_602300 = addr; } void edit_note(){ int addr = *data_602300; if(addr != 0){ addr = *(*data_602300..
[pwnable.xyz] nin write up
[pwnable.xyz] nin write up
2020.08.07이번 문제는 UAF 관련 문제이다. 해당 바이너리에는 아래와 같은 보안 장치가 설정되어 있다. 바이너리를 c코드로 변환하면 아래와 같다. void hash_gift(arg1, arg2){ int result1 = 0; int result2 = 0; int count = 0; while(true){ if(count >= int(arg2/2)) break; result1 = result1 + *(arg1 + count); count++; } for(int i = int(arg2)/2; i 0x2; eax = eax >> 0x1f; edx = edx - eax; eax = edx; eax = eax 사용자가 입력한 값 (크기: 사용자가 입력한 길이에 따라 다름) 0x603280 ==> invite_reznor..
[pwnable.xyz] note v2 write up
[pwnable.xyz] note v2 write up
2020.08.05해당 바이너리에는 아래와 같은 보안 기법이 적용되어 있다. 또한 아래 사진처럼 여러개의 사용자 정의 함수들의 존재하는 것을 볼 수 있다. 사용자 정의 함수들 중 아래 make_note() 함수를 보자. 기본적으로 0x28 만큼 공간을 할당하고, 사용자로 부터 크기를 입력받아 공간을 할당한다. 만약 *(addr + 0x20) 에 값이 들어가 있으면 공간을 할당 하지 않는다. void make_note(){ if(count
[pwnable.xyz] - dirty tultle write up
[pwnable.xyz] - dirty tultle write up
2020.04.15pwnable.xyz 34번째 문제 dirty turtle 이다. Analyze 이번 문제의 사용자 정의 함수를 보면 아래와 같다. ubuntu:~/environment/ctf/pwnable.xyz/34_Dirty turtle $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start get_val handler main setup win checksec으로 바이너리에 적용된 보안 기법을 보면 아래와 같다. ubuntu:~/environment/ctf/pwnable.xyz/34_Dirty turtle $ checksec --file=challenge RELRO STACK CANARY NX PIE RPATH RUNPATH Symbols FORT..
[pwnable.xyz] badayum write up
[pwnable.xyz] badayum write up
2020.03.10pwnable.xyz 30번째 문제이다. 해당 바이너리의 사용자 정의 함수를 보면 존재 하지 않았다... ubuntu:~/environment/ctf/pwnable.xyz/30_badayum $ func challenge nm: challenge: no symbols 그래서 gdb로 main 함수를 찾고 play(?) 함수와 win() 함수를 찾았다. 이를 c코드로 나타내면 아래와 같다. /* main: 0x555555554ead play??: 0x555555554d48 win: 0x555555554d30 */ long play(){ int tmp_1 = 0; // rbp-0x74 int tmp_2 = 0; // rbp-0x78 while(tmp_1 edx = 0x1f4e9d7e) edx = edx 0x..
[pwnable.xyz] Hero Factory write up
[pwnable.xyz] Hero Factory write up
2020.03.10pwnable.xyz 33번째 문제이다. Analyze 해당 바이너리에서 사용자 정의 함수들을 보면 아래와 같다. ubuntu:~/environment/ctf/pwnable.xyz/33_Hero Factory $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start createHero crossfit deleteHero floss getInt hadouken handler main printFnc printHero printMenu printSuperPowers setup usePower win wrestle zeroHero gdb로 바이너리를 분석하여 c코드로 나타내면 아래와 같다. (분석 환경이 gdb 밖에 없는 내 자신이 대단..) v..
[pwnable.xyz] catalog write up
[pwnable.xyz] catalog write up
2020.02.28pwnable.xyz 26번째 catalog 문제이다. Analyze 문제의 바이너리에 사용자 정의 함수를 보면 아래와 같다. ubuntu:~/environment/ctf/pwnable.xyz/26_catalog $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start edit_name handler main print_menu print_name read_int32 setup win write_name gdb로 바이너리를 분석하여 c로 나타내면 아래와 같다. /* gdb-peda$ x/50gx 0x0000000000602280 0x602280 : 0x0000000000603260 0x0000000000000000 0x602290 : 0x0..
[pwnable.xyz] message write up
[pwnable.xyz] message write up
2020.02.25pwnable.xyz 20번째 message 문제이다. keyword: buffer overflow keyword: canary leak Analyze ubuntu:~/environment/ctf/pwnable.xyz/20_message $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start get_choice handler main print_menu setup win gdb로 바이너리를 분석해서 c로 나타내면 아래와 같다. #include void print_menu(){ puts("Menu:\n1. Edit message.\n2. Print message.\n3. Admin?"); } int get_choice(){ char a = ..
[pwnable.xyz] rwsr write up
[pwnable.xyz] rwsr write up
2020.02.25pwnable.xyz 22번째 rwsr 문제이다. keyword: environ 변수로 stack 주소 Leak Analyze 해당 바이너리의 사용자 정의 함수는 아래와 같다. 이번에는 so 파일까지 주워젔다. ubuntu:~/environment/ctf/pwnable.xyz/22_rwsr $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start handler main print_menu read_ulong setup win gdb로 바이너리를 분석해서 c로 나타내면 아래와 같다. #include void print_menu(){ printf("Menu:\n 1. Read\n 2. Write\n 0. Exit\n> "); } int read..
[pwnable.xyz] bookmark write up
[pwnable.xyz] bookmark write up
2020.02.25pwnable.xyz 24번째 문제 bookmark 이다. Analyze 해당 바이너리의 사용자 정의 함수는 아래와 같다. ubuntu:~/environment/ctf/pwnable.xyz/24_bookmark $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start create_url handler init_login main print_menu read_long setup win gdb로 분석하여 c로 나타내면 다음과 같다. #include void init_login(){ int fd = open("/dev/urandom"); if(fd == -1){ exit(1); } read(fd, bm+256, 0x8); close(fd); } ..
[pwnable.xyz] uaf write up
[pwnable.xyz] uaf write up
2020.02.21pwnable.xyz 19번째 문제 uaf 이다. 이번 문제는 Use After Free 문제 인줄 알았지만, 전혀 아니었다... Analyze 해당 문제의 바이너리를 분석하면 아래와 같이 사용자 정의 함수가 많을 것을 알 수 있다. ubuntu:~/environment/ctf/pwnable.xyz/19_uaf $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start calc delete_save edit_char handler initialize_game main print_menu read_int32 save_game setup win gdb 로 바이너리를 분석해서 c로 나타내면 아래와 같다. #include void initialize..
[pwnable.xyz] Game write up
[pwnable.xyz] Game write up
2020.02.15pwnable.xyz 13번째 Game 문제이다. ubuntu:~/environment/ctf/pwnable.xyz/13_game $ func challenge __libc_csu_fini __libc_csu_init _fini _init _start edit_name find_last_save handler init_game main play_game print_menu read_int32 save_game setup win 해당 바이너리 안에는 사용자 정의 함수가 많은 것을 볼 수 있다. Analyze 필자의 분석 환경은 매우 열악해서(IDA를 쓸 수 없는 상황..) gdb를 통해 해당 바이너리를 분석해서 c로 바꾸어 보았다. #include char saves[40]; char ops = "+-/*..
[pwnable.xyz] TLSv00 write up
[pwnable.xyz] TLSv00 write up
2020.01.28pwnable.xyz 의 10번째 문제 TLSv00 이다. Analyze 문제 파일의 사용자 정의 함수를 보면 많은 함수들이 존재하는 것을 볼 수 있다. 위 함수들을 gdb로 분석하여 c언어로 표현하면 아래와 같다. #include #include char key[64]; // 0x555555756040 char do_comment[16]; // 0x555555756080 char flag[64]; // 0x5555557560a0 void print_menu(){ printf("1. Re-generate key\n2. Load flag\n3. Print flag\n"); } int read_int32(){ memset(&rbp-0x30, 0, 0x20); *(&rbp-0x34) = read(0, &rbp..