- 리눅스 커널 디버깅은 일반적인 ELF 바이너리 디버깅과 크게 다르지 않다. - 다만 커널은 운영체제의 핵심적인 기능을 수행하기 때문에, 커널에 브레이크 포인트를 걸고 디버깅하면 커널이 브포에 도달한 순간 운영체제가 정지하게 된다는 차이점이 존재한다. - 따라서 디버깅의 대상이되는 커널과 디버거를 분리하여 디버깅을 진행해야 한다. 커널 모듈이란? - 커널은 한 번 컴파일 되고, 운영체제로 기능하기 시작하면 이를 수정하기 쉽지 않다. - 그런데 커널의 권한으로 실행되야 하는 많은 장치 드라이버의 경우 빈번하게 개발되고 패치되고 있으며, 커널에 심각한 보안상의 문제가 발생하면 이를 즉각적으로 패치하여야 한다. - 따라서 리눅스 개발진은 부족한 확장성을 개선하기 위해 커널에 필요한 기능을 탈부착할 수 있도록..
Pwn
- 사용자 모드 프로그램을 익스플로잇 할 때는 익스플로잇이 잘못되어도 해당 프로그램을 재실행 하면 되지만, 커널 익스플로잇의 경우 크래시가 발생하면 운영체제 전체가 정지된다. - 이 경우 시스템을 재부팅해야지만 익스플로잇을 다시 테스트해 볼 수 있다. - 따라서 로컬에서 진행하는 것이 아닌 가상머신을 이용하여 운영체제를 구동시키는 환경을 만들어야 한다. - 가상머신을 사용할 경우 크래시가 발생해도 그 영향이 가상환경 내로 제한되며, 한번에 여러개의 가상 머신을 구동할 수 있기 때문에 익스플로잇을 테스트하기 용이하게 해준다. 그럼 커널을 ELF바이너리 처럼 실행할 수 없는건가? - 커널 이미지를 일반 바이너리처럼 실행하면 Segmentation Fault가 발생하며, 이는 커널 이미지의 베이스 주소가 커널..
Kernel? - 커널이란 중심부라는 뜻으로, 운영체제의 주요기능을 담당하는 시스템 프로그램이다. - 운영체제가 부팅된 순간부터 종료될 때까지 커널은 메모리에 상주하며 하드웨어 제어, 응용 프로그램을 메모리에 로딩하는 등의 기능을 수행한다. 운영모드 - 시스템에는 파일, 장치, 프로세스등 여러가지의 자원이 존재한다. - 커널은 응용 프로그램이 시스템 자원을 요청할 때(시스템 콜) 권한에 따라 접근을 제어한다. - 커널은 메모리를 커널 공간(Kernel Space), 사용자 공간(User Space)로 나눈다. 사용자 모드 - 프로세서가 사용자 모드(User Mode)에 있을 때, 실행중인 프로세스는 사용자 공간에만 접근할 수 있다. - 각 프로세스는 서로 독립적인 메모리 공간을 가지며 서로의 메모리에 접..
Frame Faking - Fake EBP로 더 잘 알려진 이 기법은 가짜 스택 프레임 포인터를 만들어 프로그램의 실행 흐름을 제어하는 기법이다. - 일종의 스택 pivoting이라고 볼 수 있다. - return 주소 뒤로 더이상 덮어쓰지 못하여 일반적인 ROP나 RTL이 불가능할 때 사용할 수 있다. Leave & Ret Instruction - Frame Faking을 공부하기 전에 먼저 알야할 것이 Reave, Ret 명령의 동작과정이다. Leave - Leave 명령은 2개의 명령으로 나누어져 동작한다고 볼 수 있다. - 실제로 2개로 나누어진 명령은 아니고 내부적으로 이런 식으로 동작한다고 보면 된다. 1. 현재 RBP에 저장되어 있는 값을 RSP에 저장. 현재 함수에서 사용한 스택 프레임을 ..
gets() - \x0a 까지만 입력받는다. - 개행문자가 들어가는 순간 입력안됨. - 마지막 \x0a도 버퍼에 입력되지 않는다. fgets() - \x0a 까지만 입력받는다. - null 문자도 입력받을 수 있다. scanf() - \x20, \x0a, \x09, \x0b, \x0c, \x0d까지만 입력받는다. - null 문자도 입력받을 수 있다. read() - \x0a까지 입력받는다. - 다른 값은 싹 다 버퍼에 들어감
dreamhack, Lazenca 같은 사이트를 보면 pwnable공부 첫 시작은 shellcode이다. 처음 pwnable을 공부했을 때는 왜 쉘코드를 먼저 배우는지 이해하지 못했다. 그냥 인터넷에 있는거 가져다 쓰면 안 되나? 이런 생각을 했었던 것 같다. 지나고 보니 왜 쉘코드를 먼저 배우는지 알 것 같다. pwnable을 하기에 앞서 쉘코드를 통해 배울 수 있는 게 매우 많다. 컴파일 과정, 어셈블리, 함수 호출 규약, 32bit와 64bit의 차이점 등등 또한 CTF에서는 일반적인 쉘코드로는 문제가 풀리지 않아 직접 짜야할 때가 있다. 그래서 나도 shellcode부터 정리를 시작하려고 한다. 먼저 shellcode를 공부하기 전에 어셈블리, 레지스터 관련해서 예전에 정리해둔 이 글을 읽고 오자..