gdb & pwndbg
(1) gdb
gdb는 리눅스의 대표적인 디버거로, 오픈소스로 개발되어 무료로 설치할 수 있다.
본 로드맵에서 설명된 pwndbg를 통해 실습을 진행할 예정이다.
1. pwngdb 설치
- 아래 깃허브 링크를 참고하여 우분투 환경에서 pwngdb 설치를 진행하였다
- 참고 자료 : https://github.com/scwuaptx/Pwngdb
📌 설치 과정에서 git 명령어가 없는 경우
'sudo apt-get install git' 명령어를 통해 git 명령어를 설치할 수 있다.
2. 실습 예제 파일 실행
// Name: debugee.c
// Compile: gcc -o debugee debugee.c -no-pie
#include <stdio.h>
int main(void) {
int sum = 0;
int val1 = 1;
int val2 = 2;
sum = val1 + val2;
printf("1 + 2 = %d\n", sum);
return 0;
}
▶ 이후, gdb debugee로 디버깅을 시작할 수 있다.
(2) entry
리눅스는 실행 파일 형식으로 ELF를 규정하고 있다. ELF는 크게 헤더와 여러 섹션들로 구성되어 있다.
- 헤더 : 실행에 필요한 여러 정보가 적혀 있음
- 섹션 : 컴파일된 기계어 코드, 프로그램 문자열을 비롯한 여러 데이터가 포함되어 있음
▶ ELF 헤더 중 진입점(EP) 필드 실행 시, 집임점의 값부터 프로그램을 실행한다. readelf로 확인해본 결과, debugee의 진입점은 0x401050임을 알 수 있다.
✅ entry 명령어- 진입점부터 프로그램을 분석할 수 있게 해주는 gdb의 명령어- entry 명령어 실행 이후 결과는 앞서 실습한 프로그램의 진입점 주소와 일치하는 것을 볼 수 있다.
(3) context
프로그램은 실행되면서 레지스터를 비롯한 여러 메모리에 접근한다. 따라서 디버거를 이용하여 프로그램의 실행 과정을 자세히 관찰하려면 컴퓨터의 각종 메모리를 한눈에 파악할 수 있는 것이 좋음
▶ 맥락 (context) : pwndbg가 주요 메모리들의 상태를 프로그램이 실행되고 있는 맥락을 의미
✅ 맥락의 구분
1. REGISTERS : 레지스터의 상태
2. DISASM : rip부터 여러 줄에 걸쳐 디스어셈블된 결과
3. STACK : rsp부터 여러 줄에 걸쳐 스택의 값
4. BACKTRACE : 현재 rip에 도달할 때까지 어떤 함수들이 중첩되어 호출됐는지 보여줌
(4) break&continue / run
1. break & continue
- break : 특정 주소에 중단점(breakpoint)를 설정하는 기능
- continue : 중단된 프로그램을 실행시키는 기능
▶️ break로 원하는 함수에 중단점을 설정하고, 프로그램을 계속 실행하면 해당 함수까지 멈추지 않고 실행한 다음 중단된다. 그러면 중단된 지점부터 다시 세밀하게 분석할 수 있음
2. run
- 단순히 실행만 시키는 명령어
- 중단점을 설정해놓지 않았다면 프로그램이 끝까지 멈추지 않고 실행
(5) disassembly
- gdb는 기계어를 디스어셈블(Disassemble)하는 기능을 기본적으로 탑재
- 디스어셈블된 결과를 가독성 좋게 출력해주는 기능 또한 존재
✅ disassemble 명령어
- gdb가 기본적으로 제공하는 디스어셈블 명령어
- 함수 이름을 인자로 전달하면 해당 함수가 변환될 때까지 전부 디스어셈블하여 보여줌
✅ u, nearpc, pdisass 명령어
- pwndbg에서 제공하는 디스어셈블 명령어
- 디스어셈블된 코드를 가독성 좋게 출력해줌
(6) navigate
📌 ni, si 명령어
공통점) 모두 어셈블리 명령어를 한 줄 실행
차이점)
- ni : 서브루틴의 내부로 들어가지 않음
- si : 서브루틴의 내부로 들어감
✅ ni (next instruction) 명령어
: printf 함수 바로 다음으로 rip가 이동한 것을 확인할 수 있음
✅ si (step info) 명령어
: printf 함수를 호출하는 지점까지 다시 프로그램을 실행시킨 뒤, si를 입력하면 아래와 같이 printf 함수 내부로 rip가 이동한 것을 확인할 수 있음
▶ 프로그램을 분석 시, 어떤 함수의 내부까지 궁금할 때는 si를, 그렇지 않을 때는 ni를 사용할 수 있음
✅ finish 명령어: step into로 함수 내부에 들어가서 필요한 부분을 모두 분석했는데, 함수의 규모가 커서 ni로는 원래 실행 흐름으로 돌아가기 어려울 경우 finish 명령어를 사용하여 함수의 끝까지 한 번에 실행 가능
(7) examine
가상 메모리에 존재하는 임의 주소의 값을 확인하고 싶을 경우, x 명령어를 이용하여 특정 주소에서 원하는 길이만큼의 데이터를 원하는 형식으로 인코딩하여 볼수 있음
✅ examine 예시
1. rsp부터 80바이트를 8바이트씩 hex형식으로 출력
2. rip부터 5줄의 어셈블리 명령어 출력
3. 특정 주소의 문자열 출력
(8) telescope / vmmap
✅ telescope- pwndbg가 제공하는 강력한 메모리 덤프 기능
- 특정 주소의 메모리 값들을 보여주는 것에서 그치지 않고, 메모리가 참조하고 있는 주소를 재귀적으로 탐색하여 값을 보여줌
✅ vmmap- 가상 메모리의 레이아웃 보여줌- 어떤 파일이 매핑 된 영역일 경우, 해당 파일의 경로까지 보여줌
출처 : 드림핵 (https://dreamhack.io/lecture/roadmaps/2)
'Security > System Hacking' 카테고리의 다른 글
[Exploit Tech] Shellcode (0) | 2024.09.09 |
---|---|
[Tool] pwntools (0) | 2024.09.09 |
[Dreamhack] ssp_001 (0) | 2024.09.01 |
[Dreamhack] ssp_000 write-up (2) | 2024.09.01 |
[Background] x86 Assembly (0) | 2024.09.01 |