Iriton's log

Tool: gdb & pwntools 본문

Pwnable/Study

Tool: gdb & pwntools

Iriton 2024. 3. 20. 11:45

*본 포스트는 Dreamhack - Systemhacking Lecture 을 참고하여 작성되었습니다.

gdb & pwndbg

gdb는 리눅스의 대표적인 디버거

오픈 소스

실습

https://github.com/scwuaptx/Pwngdb

가이드라인을 따라서 다운로드 후

// 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;
}

해당 코드를 컴파일 한다.

컴파일 방법은 주석 참고

여기서 gcc 컴파일러 옵션의 -no-pie는 PIE를 생성하지 않도록 지정하는 것이다.

PIE(Position Independent Executable)는 프로그램을 실행할 때마다 메모리 주소가 무작위로 바꾼다.

보안에는 좋지만 분석을 하기에는 무리가 있다.

따라서 해당 옵션을 추가함으로써 분석을 용이하게 한다.

Entry Point

readelf -h [파일명] 명령어로 실행 전 헤더 분석이 가능하다.

리눅스에서는 실행파일 형식을 ELF로 규정하고 있다.

Entry Point는 401050인 것을 확인할 수 있다.

 

gdb debugee

디버거로 debugee 파일을 연다. 그럼 pwndbg가 자동으로 실행된다.

entry 명령어는 진입점부터 프로그램을 분석할 수 있게 해주는 명령어이다.

명령어를 실행하고 보면 401050을 가리키고 있는 걸 확인할 수 있다.

Interface

인터페이스를 살펴 보면 4개의 영역으로 나뉜다.

  1. REGISTERS: 레지스터의 상태
  2. DISASM: rip부터 여러 줄에 걸쳐 디스어셈블된 결과
  3. STACK: rsp부터 여러 줄에 걸쳐 스택의 값
  4. BACKTRACE: 현재 rip에 도달할 때까지 어떤 함수들이 중첩되어 호출됐는지

break & continue & run

  • break
    • 특정 주소에 중단점을 설정해서 그 구간에 멈추게 함
    • b 명령어로 대체 가능
  • continue
    • 중단된 프로그램 계속 실행
    • c 명령어로 대체 가능
  • run
    • 단순히 실행만 시키는 명령어라 bp가 없다면 끝까지 실행된다.
    • r 명령어로 대체 가능

disassemble

gdb가 제공하는 디스어셈블 명령어

$ disassemble main

위와 같이 함수 이름을 인자로 전달하면 함수가 반환될 때까지 전부 디스어셈블 하여 보여준다.

📍 u, nearpc, pdisass는 pwndbg에서 제공하는 디스어셈블 명령어이다. 가독성 좋게 출력해 준다.

navigate

bp에서부터는 한 줄씩 자세히 분석해야 한다.

이때 쓰이는 명령어가 ni, si이다.

한 줄씩 실행한다는 공통점이 있지만

ni(next instruction)는 서브루틴의 내부로 들어가지 않는 반면

si(step into)는 서브루틴 내부로 들어간다는 차이점이 존재한다.

finish라는 명령어로 함수의 끝까지 한 번에 실행할 수 있다.

examine

가상 메모리에 존재하는 임의 주소의 값을 관찰하고 싶을 때 x 명령어를 이용한다.

특정 주소에서 원하는 길이만큼의 데이터를 원하는 형식으로 인코딩하여 볼 수 있다.

1. rsp부터 80바이트를 8바이트씩 hex형식으로 출력

2. rip부터 5줄의 어셈블리 명령어 출력

3. 특정 주소의 문자열 출력

telescope

pwndbg가 제공하는 강력한 메모리 덤프 기능이다.

특정 주소의 메모리 값들을 보여주는 것에서 그치지 않고 메모리가 참조하고 있는 주소를 재귀적으로 탐색하여 값을 보여준다.

vmmap

가상 메모리의 레이아웃을 보여준다.

어떤 파일이 매핑된 영역일 경우 해당 파일의 경로까지 보여준다.

python

  • run 명령어의 인자로 $()와 함께 파이썬 코드를 입력하면 값을 전달할 수 있다.
    • ex) pwndbg > r $(python3 -c "print('\xff' * 100)")
  • $() 와 함께 파이썬 코드를 입력하면 값을 입력할 수 있습니다. 입력값으로 전달하기 위해서는 <<< 를 사용한다.
    • ex) pwndbg> r $(python3 -c "print('\xff' * 100)") <<< $(python3 -c "print('dreamhack')")

 

pwntools API 사용법

pwntools — pwntools 4.14.0dev documentation

 

pwntools — pwntools 4.14.0dev documentation

© Copyright 2016, Gallopsled et al.. Revision 14c0d73f.

docs.pwntools.com

 

1. process & remote

process 함수: 익스플로잇을 로컬 바이너리 대상으로 사용하는 함수

remote 함수: 원격 서버를 대상으로 사용하는 함수

2. send

데이터를 프로세스에 전송하기 위해 사용한다.

3. recv

프로세스에서 데이터를 받기 위해 사용한다.

recv(n) - 최대 n바이트를 받는 것, 그만큼 받지 못해도 에러 발생 X

recvn(n) - 정확히 n바이트 데이터를 받지 못하면 계속 기다린다.

4. packing & unpacking

익스플로잇을 작성하다 보면 어떤 값을 리틀 엔디언의 바이트 배열로 변경하거나, 또는 역의 과정을 거쳐야 하는 경우가 자주 있는데 그때 사용한다.

5. interactive

쉘을 획득했거나 익스플로잇의 특정 상황에 직접 입력을 주면서 출력을 확인하고 싶을 때 사용하는 함수

호출하고 나면 터미널로 프로세스에 데이터를 입력하고 프로세스의 출력을 확인할 수 있다.

6. ELF

ELF 헤더에는 익스플로잇에 사용될 수 있는 각종 정보가 기록되어 있다.

pwntools를 사용하면 이 정보를 쉽게 참조 가능하다.

7. context.log

익스플로잇에 버그가 발생하면 익스플로잇도 디버깅 해야 한다.

context.log.level 변수로 조절할 수 있다.

  • error: 에러만 출력
  • debug: 대상 프로세스와 익스플로잇 간에 오가는 모든 데이터
  • info: 비교적 중요한 정보들만 출력

8. context.arch

pwntools 쉘코드를 생성하거나 코드를 어셈블, 디스어셈블 하는 기능을 가지고 있다.

이들은 공격 대상의 아키텍처에 영향을 받는다.

pwntools는 아키텍처 정보를 프로그래머가 지정할 수 있게 하

9. shellcraft

자주 사용하는 쉘 코드를 저장해서 공격에 필요한 쉘 코드를 쉽게 꺼내 쓸 수 있게 한다.

10. asm

어셈블 기능

아키텍처를 미리 지정해야 한다.

'Pwnable > Study' 카테고리의 다른 글

Background: Calling Convention  (0) 2024.04.01
Exploit Tech: Shellcode  (0) 2024.03.27
x86 Assembly  (0) 2024.03.19
Background: Linux Memory Layout  (0) 2024.03.19
Background: Computer Architecture  (1) 2024.03.19
Comments