전체 글

.fini_array overwrite 기법을 공부하다 main 함수가 호출되기 전, 호출되고 종료되기까지의 과정을 정리해봐야겠다는 생각이 들어 작성하게 됐다. -Main 함수 호출 전- 바이너리가 처음 실행될 시에는 ida로 바이너리를 열었을 때 흔히 보게 되는 _start 함수가 호출된다. 이 start 함수는 바이너리 실행 과정에서 필요한 여러 요소들을 초기화하기 위해 __libc_start_main 함수를 호출하게 된다.(__libc_start_main 함수는 libc에 존재하는 함수기 때문에 ida에서는 코드를 볼 수 없다.), void __usercall __noreturn start(__int64 a1@, __int64 a2@) { unsigned int v2; // esi unsigned ..
· CTF
redpwnCTF 2021의 리버싱 문제 wstrings다. 너무 쉽게 풀려서 조금 허무했던 문제다. 문제 파일로 바이너리가 주어져 있다. 문제 파일을 실행해보면 Welcome to flag checker 1.0. 문구와 flag를 달라는 문구가 출력된 후 입력을 받는다. 입력을 받고 바로 종료되는데, 예상을 해보면 올바른 flag를 찾아 입력하면 correct 같은 성공 문자열이 뜰 것 같으니, flag 값과 입력 값을 비교하는 로직을 분석하여 flag 값을 알아내면 될 것 같다. ida로 확인해본 wstrings 바이너리의 main 함수다. wprintf 함수를 통해 "Welcome to flag checker 1.0. Give me a flag> " 문구를 출력하고 fgetsws 함수를 통해 wch..
· CTF
redpwnCTF의 ret2generic-flag-reader 문제다. 바이너리와 소스코드가 주어져 있다. 바이너리를 실행하면 앞서 푼 포너블 문제와 마찬가지로 여러 문구들이 출력되고 입력을 받는다. 마찬가지로 nx bit가 걸려있다. #include #include #include void super_generic_flag_reading_function_please_ret_to_me() { char flag[0x100] = {0}; FILE *fp = fopen("./flag.txt", "r"); if (!fp) { puts("no flag!! contact a member of rob inc"); exit(-1); } fgets(flag, 0xff, fp); puts(flag); fclose(fp);..
· CTF
redpwnCTF의 beginner-generic-pwn-number-0 문제다. 바이너리와 바이너리의 소스코드가 주어져 있다. 바이너리를 실행시키면 여러 문구들이 출력된 후 사용자의 입력을 받는다. 입력을 받은 후에는 아무 동작 없이 프로그램이 종료된다. 보호 기법으로는 nx bit만 걸려있는 것을 알 수 있다. #include #include #include const char *inspirational_messages[] = { "\"𝘭𝘦𝘵𝘴 𝘣𝘳𝘦𝘢𝘬 𝘵𝘩𝘦 𝘵𝘳𝘢𝘥𝘪𝘵𝘪𝘰𝘯 𝘰𝘧 𝘭𝘢𝘴𝘵 𝘮𝘪𝘯𝘶𝘵𝘦 𝘤𝘩𝘢𝘭𝘭 𝘸𝘳𝘪𝘵𝘪𝘯𝘨\"", "\"𝘱𝘭𝘦𝘢𝘴𝘦 𝘸𝘳𝘪𝘵𝘦 𝘢 𝘱𝘸𝘯 𝘴𝘰𝘮𝘦𝘵𝘪𝘮𝘦 𝘵𝘩𝘪𝘴 𝘸𝘦𝘦𝘬\"", "\"𝘮𝘰𝘳𝘦 𝘵𝘩𝘢𝘯 1 𝘸𝘦𝘦𝘬 𝘣𝘦𝘧𝘰𝘳𝘦 𝘵𝘩𝘦 𝘤𝘰𝘮𝘱𝘦𝘵𝘪𝘵𝘪𝘰𝘯\"", ..
· CTF
sanity-check redpwnCTF 2021의 sanity-check 문제다. flag가 그냥 주어져있다. flag{1_l0v3_54n17y_ch3ck_ch4ll5} discord redpwnCTF 2021의 discord 문제다. redpwnCTF 2021 디스코드 서버에 들어가 rules 채널을 확인한다면 flag를 얻을 수 있다. flag{chall3n63_au7h0r5h1p_1nfl4710n} compliant-lattice-feline redpwnCTF 2021의 compliant-lattice-feline 문제다. nc로 주어진 서버에 접속해주면 flag를 준다. flag{n3tc4t_1s_a_pip3_t0_the_w0rld}
-Return Address Overwrite 개념- return address overwrite란 stack frame의 끝에 존재하는 return address 영역을 overwrite 함으로써, 함수가 끝날 때 원하는 주소, 원하는 함수의 코드로 분기를 변경하도록 하는 기법이다. 가장 기본적인 공격 방법이며, 이 공격을 기반으로 rtl, rop 등의 공격이 연계되므로 잘 이해하고 있어야 한다. return address overwrite를 이해하려면 call 명령어와 ret 명령어에 대해서 이해하고 있어야 한다. 먼저 call 명령어는 call 명령어의 다음 주소를 복귀 주소로 stack에 저장한 뒤, 지정한 주소로 이동한다. 여기서 복귀 주소가 저장된 곳이 return address 영역이다. 함..
이번에 풀이할 문제는 HackCTF의 g++ pwn 문제다. 문제 이름이 g++걸 봐서 c++ 소스 코드를 컴파일해주는 g++ 컴파일러가 생각난다. 문제 파일을 실행해보니 입력을 받고, 입력을 받은 값을 출력해주는 동작을 한다. 혹시하고 입력 값으로 많은 1 값을 줬지만 Segment fault 오류는 터지지 않는 것을 알 수 있다. bof 문제가 아닐 수도 있는 것 같다. 보호기법은 nx만 걸려있는 것을 알 수 있다. ida는 제대로 해석을 못하는 것 같아서 ghidra로 main 함수를 확인해봤다. main 함수는 vuln 함수만 호출한다. vuln 함수를 확인해보면 fgets 함수를 이용해 local_40에 32byte만큼 입력을 받는 것을 알 수 있다. local_40의 크기는 32byte인데, ..
· CTF
Cyberthreatforce CTF의 Bof_1 문제다. 문제 자체가 어렵기 보다는 혼자 어렵게(쉐도우 복싱 미쳤다..ㅋㅋ) 생각해서 풀이 시간이 오래 걸렸다. 공격 시나리오만 제대로 안다면 10분도 안 걸리고 풀 수 있는 문제다. 문제 파일을 실행시킨다면 위와 같이 동작한다. "hello who are you?"라는 문구가 출력되고 입력을 받는데, 입력한 값이 그 다음 줄에 "Hello "와 함께 출력된다. checksec으로 보호기법을 확인해보면 Canary와 NX가 걸려 있는 것을 알 수 있다. 이 때까지만 해도 canary를 우회하는 상상을 했다. canary는 그냥 장식이었다.. ida로 메인 코드를 확인해보면 bof에 취약한 포맷 스트링 %s와 scanf 함수로 입력을 받는 것을 알 수 있다..
-Buffer Overflow의 개념- Buffer Overflow는 말 그대로 메모리 상의 저장공간인 버퍼가 흘러 넘친다는 뜻이다. 사용자의 입력을 받을 때 취약한 함수나 길이 제한을 두지 않아 발생하는 취약점으로, 입력 값보다 입력 값을 저장하는 변수의 크기가 작을 때 오버플로우가 일어난다. 예를들어 500ml를 담을 수 있는 페트병에 1L의 물을 담을 시 물이 넘치게(overflow!) 되는데, buffer overflow도 이와 비슷하다. 메모리 상에서는 입력 값을 저장하는 변수 뿐 아니라, 다른 변수들도(해당 함수에서 쓰이는) 저장돼 있고 sfp(stack frame pointer)와 복귀 주소인 ret도 존재하기 때문에, 500byte를 저장할 수 있는 변수에 1000byte의 입력 값을 저장..
이번에 풀이할 문제는 HackCTF의 RTL_World 문제다. 요즘 HackCTF 문제를 잘 안풀고 있었는데, 갑자기 HackCTF 포너블 문제를 올클해보자는 욕구가 생겨 풀이하게 됐다. 일단 문제 명만 봤을 때는 rtl 공격 기법이 쓰일 것 같다. 문제 파일을 실행해본다면 다음과 같은 문구가 출력된다. 신박해보인다. 저기 나온 선택지를 다 선택해봤지만 딱히 얻을 수 있는 정보는 없었다. 다만 3, 4번은 어느정도의 자본(gold)이 필요하다는 것을 알게됐고, 이 파일의 목적은 binary boss를 죽이는, 즉 exploit하는 것임을 알 수 있었다.(1번 선택지를 선택하면 문제 파일의 보호기법이 출력된다.) 일단 ghidra로 열어봐야겠다. undefined4 main(void) { int iVar..
· Wargame/LOB
cobolt로 로그인하면 goblin 문제를 볼 수 있다. goblin 문제를 실행해본다면 입력을 받은 뒤, 입력을 받은 값을 똑같이 출력해준다. 소스코드를 확인해보면 bof에 취약한 대표적인 함수인 gets 함수로 입력을 받는다. 이 gets 함수는 입력 값의 길이에 제한을 두지 않기 때문에, 입력 값이 저장되는 buffer 변수의 크기인 16byte 이상 입력을 한다면 overflow가 발생한다. 딱봐도 쉘 코드를 buffer에 삽입하기에는 공간이 부족하기 때문에 환경변수를 이용해야 될 것 같다고 생각했다. 일단 buffer가 16byte 크기고 다른 변수들은 존재하지 않기 때문에 굳이 gdb로 열어볼 필요 없이 blind 상태로도 exploit이 가능할 것 같았다. buffer의 크기가 16byte..
· Wargame/LOB
gate 문제를 풀 때 wsl telnet을 이용해 접속했다가 쉘이 얻어지지 않는 문제가 생겨, 이번에는 putty로 접속했다. 문제 파일 cobolt와 소스코드 cobolt.c가 주어져 있다. 문제 파일을 실행해보니 인자를 받는 것을 알 수 있었다. 많은 '1'을 인자로 주니 Segmentation fault가 터진 것을 보아 bof 취약점이 있을 가능성이 높다. 소스코드를 확인해보면 인자 값을 strcpy 함수로 16byte 크기의 buffer에 복사해주는데, gate 때와 마찬가지로 길이를 검증하는 로직이나 함수를 사용하지 않는다. 따라서 인자 값으로 16byte보다 긴 값을 준다면 overflow가 발생한다. gate와 마찬가지로 buf에 쉘 코드를 삽입한 뒤 ret를 buf의 주소로 조작해 쉘을..
dyp4r
dyp4r's Study Blog