Old (2021.01 ~ 2021.12)/Pwnable

.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 ..
-Return Address Overwrite 개념- return address overwrite란 stack frame의 끝에 존재하는 return address 영역을 overwrite 함으로써, 함수가 끝날 때 원하는 주소, 원하는 함수의 코드로 분기를 변경하도록 하는 기법이다. 가장 기본적인 공격 방법이며, 이 공격을 기반으로 rtl, rop 등의 공격이 연계되므로 잘 이해하고 있어야 한다. return address overwrite를 이해하려면 call 명령어와 ret 명령어에 대해서 이해하고 있어야 한다. 먼저 call 명령어는 call 명령어의 다음 주소를 복귀 주소로 stack에 저장한 뒤, 지정한 주소로 이동한다. 여기서 복귀 주소가 저장된 곳이 return address 영역이다. 함..
-Buffer Overflow의 개념- Buffer Overflow는 말 그대로 메모리 상의 저장공간인 버퍼가 흘러 넘친다는 뜻이다. 사용자의 입력을 받을 때 취약한 함수나 길이 제한을 두지 않아 발생하는 취약점으로, 입력 값보다 입력 값을 저장하는 변수의 크기가 작을 때 오버플로우가 일어난다. 예를들어 500ml를 담을 수 있는 페트병에 1L의 물을 담을 시 물이 넘치게(overflow!) 되는데, buffer overflow도 이와 비슷하다. 메모리 상에서는 입력 값을 저장하는 변수 뿐 아니라, 다른 변수들도(해당 함수에서 쓰이는) 저장돼 있고 sfp(stack frame pointer)와 복귀 주소인 ret도 존재하기 때문에, 500byte를 저장할 수 있는 변수에 1000byte의 입력 값을 저장..
계기 지금까지 ftz, lob 등 shellcode가 필요한 wargame을 풀 때면 구글링을(ex : 32bit shellcode 검색) 통해 얻은 shellcode로 풀이를 진행했었다. 그런 식으로 풀이를 하다가 갑자기 오늘 이런 생각이 들었다. "굳이 인터넷에서 남이 만든 쉘 코드를 가져올 필요 없이 내가 직접 원하는 기능을 하는 쉘 코드를 만들면 되지 않을까?" 쉘 코드를 만든다면 어셈블리어에 대한 이해도가 높아질 것이며, 또한 구글링을 통해 얻는 쉘 코드는 기능적 제약 사항이 있으므로 공부 삼아 직접 만들어보기로 했다. System Call 쉘 코드를 만들기 전 알아야하는 지식으로 system call이 있다. srop 공격을 공부해봤다면 쉽게 알 수 있는 내용인데, 이 system call이란..
우리 집에 GDB 있는데 메모리 보고 갈래? (3) 3에서는 소스 파일이 없다 가정한 상태로 ida, gdb를 이용해 취약점을 찾고 exploit을 진행한다. 보통 정적 분석은 ida, 동적 분석은 gdb를 활용한다고 한다. ida hexray가 제대로 작동하지 않아서 (完)우리집에 GDB 있는데… 메모리 보고갈래?(3)의 사진을 참고했다. 보면 거의 비슷하게 코드가 디컴파일 된 것을 볼 수 있다. ㄷㄷ 보면 strcpy로 인자로 입력된 문자열을 v4에 넣어주는데, argv[1]을 복사할 때 버퍼를 검사하는 로직이 없다. v4, v5는 지역 변수이므로 스택에 있기에 스택 오버플로우가 일어날 수 있는 것이다. v5가 1이 되면 쉘을 열 수 있으므로 스택 오버플로우로 v5의 값에 접근하면 될 것 같다. gd..
우리 집에 GDB 있는데 메모리 보고 갈래? (2) #include #include void func2() { puts("func2()"); // "func2()"를 출력 } void sum(int a, int b) { // int형 매개 변수 a, b를 받음 printf("sum : %d\n", a+b); // 더한 값을 출력 func2(); // func2 함수 실행 } int main(int argc, char *argv[]) { int num=0; char arr[10]; sum(1,2); // sum 함수에 인자 1, 2를 보냄 strcpy(arr,argv[1]); // 실행시 입력 받은 인자를 arr로 복사(취약점 발생!!) printf("arr: %s\n", arr); // arr 출력 if..
우리 집에 GDB 있는데 메모리 보고 갈래? (1) 위 사진이 바로 우리 집에 GDB 있는데 메모리 보고 갈래? (1)에서 다룰 내용의 사진이다. 1에서는 주소, 메모리 영역에 대해서 다룬다. -Address- 32bit 노트북을 보면 램이 4gb 밖에 없다. 그 이유는 위 사진처럼 4gb 램은 이런 저런 복잡한 수식을 거쳐서 2^32Byte의 주소를 가질 수 있는데, 32bit의 경우 1bit는 0, 1을 가질 수 있으므로 2^32, 즉 최대 2^32 Byte의 주소를 가질 수 있기 때문에 2^32 Byte의 주소를 넘어가게 되는 4gb 초과로는 인식하지 못하는 것이다. 리버싱을 공부해보면 주소가 00000000 ~ FFFFFFFF까지 존재하다는 점을 알 수 있는데, 이는 이진수 주소 0000...(3..
dyp4r
'Old (2021.01 ~ 2021.12)/Pwnable' 카테고리의 글 목록