워게임을 풀고 공부+실습을 진행했다.
pwntools: 파이썬 기반 익스플로잇 자동화 도구, 어셈블/디스어셈블/패킹/언패킹 등의 여러 작업 수행 가능
*익스플로잇(exploit): 보안 취약점을 이용하여 공격하도록 설계된 명령, 스크립트, 프로그램
1. pwntools 설치
ubuntu 20.04 환경에서 아래 명령어를 입력해 준다.
$ apt-get update
$ sudo apt-get install python3 python3-pip python3-dev git libssl-dev libffi-dev build-essential
$ python3 -m pip install --upgrade pip
$ python3 -m pip install --upgrade pwntools
설치 확인 명령어
$ python3 -c 'from pwn import *'
실행
python3 - << 'PY' #파이썬 실행
from pwn import * #임포트
2. 패킹/언패킹: struct 모듈 사용 -> pwntools를 사용하면 간편해짐
p32(x): 32비트 정수 x를 리틀엔디언 바이트 문자열로 패킹
u32(b): 바이트열 b를 정수로 언패킹
*패킹(packing): 여러 개의 객체를 하나로 묶는 것 <-> 언패킹(unpacking): 다시 푸는 것


u32로 패킹, 그리고 u32로 패킹한 것을 hex값으로 출력, u32로 패킹했던 것을 다시 언패킹한 결과를 볼 수 있다.
그외 32비트 외에도 8비트, 16비트, 64비트.. 등 가능하다.
3. 조립 및 분해
조립(asm): 어셈블리어 -> 바이트 변환
분해(disasm): 바이트 -> 어셈블리어 변환

asm 명령어로 mov eax, 0을 b8000000000로 변환
disasm 명령어로 바이트를 사진과 같은 어셈블리어로 변환해 준다.
*unhex: 16진수 문자열을 바이트로 변환
*enhex: 바이트 값을 16진수로 보여줌(예시: enhex(b'\xb8\x00\x00\x00\x00') -> b'b800000000')
4. 대상 아키텍처 및 OS 설정
아키텍처: i386(x86, 32-bit), amd64(x86_64, 64-bit) 등
OS: Linux(ELF) vs Windows(PE)
-> 익스플로잇 방식 달라짐. 바이너리의 아키텍처/OS를 확인해서 공격 스크립트를 작성해야 함.

같은 nop이어도 아키텍처가 arm인 경우 사진과 같이 달라지는 것을 확인할 수 있음.
*해당 명령어에서 오류날 경우
arm 아키텍처용 패키지가 없어서 오류남. 아래 코드 복붙할 것.
sudo apt update
# 일반적인 binutils (기본 x86 어셈블리용)
sudo apt install -y binutils
# ARM 32-bit / 64-bit용 cross binutils (일반적으로 이걸 설치하면 pwntools에서 asm('...', arch='arm') 같은게 동작함)
sudo apt install -y binutils-arm-linux-gnueabi binutils-arm-linux-gnueabihf
# 또는 범용(여러 타깃의 binutils 모음)
sudo apt install -y binutils-multiarch
# 추가로 cross gcc가 필요할 경우 (옵션)
sudo apt install -y gcc-arm-linux-gnueabi gcc-arm-linux-gnueabihf
context를 이용해서 전역 변수에 아키텍처, OS, word size, endian 설정 가능
context.arch = 'i386'
context.os = 'linux'
context.endian = 'little'
context.word_size = 32
context의 단축형도 존재한다.

5. 로깅/디버그 출력
log_level로 레벨 변경 가능.
레벨 종류:
- debug: 가장 상세함. 문제 분석/디버깅할 때 유용
- info: 일반 정보 수준. 보통 개발 단계, 자동화 스크립트에서 기본으로 사용
- warning/warn: 비정상적이지만 치명적이지 않은 상황을 알림
- error: 오류 상황 출력
- critical: 치명적 에러
-> pwntools 내부의 자동 로그가 연결될 때 무슨 바이트를 보냈는지, 받았는지를 얼마나 보여줄지 결정함.
context.log_level = 'debug'
6. ELF 조작
ELF(Executable and Linkable Format): 리눅스에서 실행 파일/공유라이브러리/오브젝트 파일을 담는 표준 포맷. 프로그램 구조를 담고 있어 익스플로잇에 중요한 정보 출처가 됨.
e = ELF('/bin/cat')
print(hex(e.address))
0x400000
print(hex(e.symbols['write']))
0x401680
print(hex(e.got['write']))
0x60b070
print(hex(e.plt['write']))
0x401680
ELF('/bin/cat'): 괄호 안의 ELF 파일을 읽어서 파일 내부의 정보를 파싱. 파이썬 객체 형태로 돌려줌.
ELF 속성
e.arch: 아키텍처
e.bits: 32 or 64
e.symbols: 심볼 이름 -> 주소(파일 기준)
e.got: GOT 엔트리 주소 dict
e.plt: PLT 엔트리 주소 dict
e.search(b'/bin/sh'): 바이너리 내에서 바이트/문자열 검색
e.sections / e.segments: 섹션/세그먼트 정보
7. 연결 만들기: 챌린지 바이너리와 통신하기 위해 pwnlib.tubes 모듈 사용
- remote(host, port): TCP 연결(소켓)을 만들어주는 함수
- send(b'data'):
- recv(n): n바이트를 읽음
- recvuntil(delim, drop=False): delim을 만날 때까지 읽고, delim을 포함한 바이트 반환. (true일 경우, delim을 제거해서 반환)
- recvline(): 한 줄을 읽음
- recvall(timeout=...): 가능한 모든 데이터를 읽어 반환
- interactive(): pwntools이 터미널과 원격으로 연결해서 수동 조작할 수 있게 함
- close(): 연결 닫기
conn = remote('ftp.ubuntu.com',21)
conn.recvline()
b'220 ...'
conn.send(b'USER anonymous\r\n')
conn.recvuntil(b' ', drop=True)
b'331'
conn.recvline()
b'Please specify the password.\r\n'
conn.close()
'소학회 > 워게임 추가 공부' 카테고리의 다른 글
| [reversing]Dreamhack_rev-basic-1 추가 공부 (0) | 2026.02.10 |
|---|---|
| [reversing]Dreamhack_simple-operation 추가 공부 (0) | 2026.01.13 |
| [misc]Dreamhack_Exercise: SSH 추가 공부 (0) | 2025.11.04 |
| [web]Dreamhack_session : 자바스크립트 추가 공부 (0) | 2025.09.23 |
| [reversing]H4CKING GAME_Season1 : Keygen 추가 공부 (0) | 2025.05.19 |