Step 132. Burp Suite 1: 프록시 가로채기 — 브라우저와 서버 사이에 끼어들기
Level 2 — 보안 입문과 공격 스킬 기초 | 난이도 ★★☆☆☆ | 예상 소요 시간 2시간
전제: Step 131(로그인/세션 웹앱), Step 73(HTTP)을 마쳤다. Kali에는 Burp Suite Community가 내장돼 있다.
- 준비물: Kali(내장 Burp Suite Community) 또는 Windows용 설치본, Step 131의 웹앱. Burp의 GUI 화면은 화면 예시, 프록시 원리 실험은 실측(2026-09-09, 파이썬 미니 프록시 + curl)으로 표시했습니다.
- ⚠️ 이 챕터의 실습은 내 랩·합법 플랫폼 전용입니다. 허가 없는 시스템에 적용하면 범죄입니다.
웹 해킹의 80%는 한 문장으로 요약됩니다 — 요청을 잡아서, 보고, 고쳐서 보낸다. Burp Suite는 그 일을 위한 도구입니다. 브라우저와 서버 사이에 투명한 중간자로 끼어들어, 지나가는 모든 요청을 멈춰 세우고, 내용을 들여다보고, 고친 뒤 보냅니다. 오늘은 그 첫걸음 — 프록시 가로채기(intercept)를 익힙니다.
1. 학습 목표
이 챕터를 끝내면 다음을 할 수 있습니다:
- 프록시가 브라우저와 서버 사이에서 무엇을 하는지 설명할 수 있다
- Burp Suite를 임시 프로젝트로 시작하고 내장 브라우저로 요청을 잡을 수 있다
- Intercept on 상태에서 요청을 Forward/Drop 할 수 있다
- 가로챈 로그인 요청의 파라미터를 고쳐 서버 반응 차이를 관찰한다
- HTTP history에서 Request/Response 원문을 읽을 수 있다
2. 배경 지식 — 오늘의 도구와 개념
오늘의 도구 한눈에 보기
| 구분 | 내용 |
|---|---|
| 언어·환경 | Burp Suite Community(Kali 내장), 대상은 Step 131의 내 웹앱, 원리 실측은 파이썬 + curl |
| 오늘의 도구 | Burp Proxy(Intercept, HTTP history), curl -x(프록시 경유 요청) |
| 필요한 개념 | 프록시, 중간자(MITM), 가로채기(intercept), Forward/Drop, CA 인증서 |
| 오늘의 산출물 | 가로챈 로그인 요청을 변조한 기록 + 프록시 원리 실측 로그 |
2-1. 프록시 — 대리인이자 도청 지점
프록시(proxy)는 "대리인"입니다. 브라우저가 서버에 직접 말하는 대신, 프록시에게 부탁하면 프록시가 대신 전달하고 응답을 가져다줍니다. 원래 용도는 캐시·우회이지만, 보안에서는 이 구조가 곧 관찰 지점이 됩니다 — 모든 요청이 프록시의 손을 지나니까요.
Burp Suite는 127.0.0.1:8080에 프록시를 엽니다. 브라우저가 "모든 트래픽을 저기로 보내"라고 설정되면, 여러분이 로그인 버튼을 누르는 순간의 HTTP 요청이 Burp의 화면에 날것 그대로 나타납니다.
2-2. 가로채기(intercept) — 요청을 멈춰 세우는 버튼
Burp의 Intercept가 켜져 있으면(Intercept on), 요청이 서버로 가기 직전에 멈춥니다. 화면에는 요청 원문이 보이고, 여러분에게 세 가지 선택지가 있습니다.
- Forward — (고쳤다면 고친 채로) 서버로 보낸다
- Drop — 버린다. 서버는 이 요청이 온 줄도 모른다
- 편집 후 Forward — 파라미터, 헤더, 쿠키 무엇이든 고친 뒤 보낸다
Step 131에서 "서버에 도착하는 입력은 전부 조작 가능하다"고 배웠습니다. Intercept가 그 조작을 버튼 한 번으로 만들어 주는 도구입니다.
2-3. HTTPS와 인증서 — 중간자의 유일한 장벽
HTTPS 트래픽은 암호화돼 있어 프록시도 내용을 볼 수 없습니다. Burp는 이를 자체 CA 인증서로 해결합니다 — 브라우저가 Burp를 인증 기관으로 신뢰하게 만들면, Burp가 중간에서 암호화를 풀고 보고 다시 암호화합니다(중간자 구조 그 자체 — 그래서 이 도구는 내 랩에서만 씁니다).
처음에는 이 설정이 번거로우니, 오늘은 Burp 내장 브라우저를 씁니다 — 인증서와 프록시 설정이 미리 잡혀 있어서 켜자마자 요청이 잡힙니다.
3. 따라 하기
3-1. Burp 시작과 내장 브라우저
Kali 메뉴에서 Burp Suite를 실행하고, Temporary project(임시 프로젝트) → 기본 설정 그대로 시작합니다. 상단 탭 중 Proxy → Intercept 하위 탭을 열고, Open browser 버튼을 누릅니다.
화면 예시: 내장 브라우저(Chromium 기반)가 뜨고, 주소창에 내 웹앱 주소(http://127.0.0.1:5000 — Step 131 서버를 미리 띄워 둡니다)를 입력하면 Burp 화면에 요청 원문이 멈춰 섭니다.
GET / HTTP/1.1
Host: 127.0.0.1:5000
User-Agent: Mozilla/5.0 ...
Accept: text/html,...
읽는 법: 브라우저는 아직 로딩 중입니다 — 요청이 Burp에 붙잡혀 있기 때문입니다. 이 화면이 "요청을 멈춰 세운 상태"입니다.
3-2. Forward와 Drop — 요청의 생사를 쥐기
멈춘 요청 앞에서 Forward를 누르면 브라우저의 로딩이 끝나고 페이지가 뜹니다. Drop을 누르면 브라우저는 영원히 기다리다가 오류가 납니다 — 서버에는 요청이 도착한 기록조차 남지 않습니다(서버 로그에 줄이 안 찍힙니다 — Step 131의 3-8 로그를 떠올리세요).
실험 삼아 몇 번 Forward와 Drop을 번갈아 눌러 보고, 손이 익으면 Intercept is on → 클릭해서 off로 바꿉니다. 꺼져 있으면 요청은 멈추지 않고 지나가되, 전부 HTTP history에 기록됩니다 — 평소에는 off로 두고, 잡고 싶은 순간(로그인 전송 직전)에만 켜는 것이 실무 습관입니다.
3-3. 로그인 요청을 가로채서 고치기
이제 오늘의 핵심입니다. Step 131 웹앱의 로그인 폼에 아이디·비밀번호를 입력하고, 전송 직전에 Intercept를 on으로 바꿉니다. 전송 버튼을 누르면 POST 요청이 멈춥니다.
화면 예시 (가로챈 요청):
POST /login HTTP/1.1
Host: 127.0.0.1:5000
Content-Type: application/x-www-form-urlencoded
Content-Length: 24
uid=nadia&pw=blue-fox-31
마지막 줄의 pw=blue-fox-31을 pw=hack으로 고치고 Forward합니다. 서버는 무엇이라 답할까요 — Step 131에서 직접 만든 대로, 비밀번호가 다르면 401과 "로그인 실패" 가 돌아옵니다. 반대로 올바른 값으로 고쳐서내면 302와 세션 쿠키가 돌아옵니다.
왜: 방금 여러분은 브라우저가 만든 요청을 중간에서 바꿔치기했고, 서버는 그것이 원본인지 변조인지 묻지 않았습니다. "폼의 글상자"는 사용자 인터페이스일 뿐, 서버에 도착하는 것은 텍스트 한 덩어리 — 그것을 마음대로 쓸 수 있다는 것이 오늘의 체감입니다.
3-4. 프록시의 원리를 직접 확인하기 — 30줄짜리 미니 Burp
Burp가 GUI 너머에서 하는 일의 본질을 보기 위해, 파이썬으로 최소 프록시를 직접 만들어 실측했습니다. 요청을 받아 내용을 출력한 뒤 진짜 서버에 전달하는, Burp의 축소 모형입니다.
입력: proxy.py(요청을 로그로 출력한 뒤 원래 목적지에 전달하는 30줄짜리 프록시 — 전체 코드는 미션에서 직접 짜 봅니다)를 8080번에 띄우고, curl에게 "프록시를 거쳐 가라"고 지시합니다.
python proxy.py & # 127.0.0.1:8080에서 대기
curl -x http://127.0.0.1:8080 -X POST -d "uid=nadia&pw=blue-fox-31" http://127.0.0.1:5000/login
출력 (2026-09-09 실측, 프록시의 로그):
[프록시 기동] 127.0.0.1:8080 — 요청을 기다립니다
==================================================
[가로챈 요청] POST http://127.0.0.1:5000/login HTTP/1.1
Host: 127.0.0.1:5000
User-Agent: curl/8.11.0
Accept: */*
Proxy-Connection: Keep-Alive
Content-Length: 24
Content-Type: application/x-www-form-urlencoded
[본문] uid=nadia&pw=blue-fox-31
==================================================
읽는 법: -x 옵션이 curl에게 "8080의 프록시에게 부탁해"라고 시킨 것이고, 프록시는 요청 전체 — 헤더는 물론 로그인 본문의 비밀번호까지 — 를 평문으로 봤습니다. Burp가 화면에 보여 주는 것이 정확히 이것입니다. 도구가 다른 것뿐, 원리는 같습니다.
왜: HTTP(암호화 없음) 위에서는 중간자가 모든 것을 읽습니다. 이것이 카페 와이파이가 위험하다는 말의 기술적 실체이고, HTTPS가 필요한 이유이기도 합니다.
3-5. HTTP history — 지나간 모든 요청의 장부
Proxy → HTTP history 탭을 열어 보세요. Intercept를 꺼둔 동안 지나간 요청들이 번호·메서드·주소·상태 코드와 함께 줄줄이 기록돼 있습니다. 한 줄을 클릭하면 아래에 Request/Response 원문이 나란히 나옵니다.
화면 예시 (history 목록):
# Host Method URL Status Length
1 127.0.0.1:5000 GET / 200 124
2 127.0.0.1:5000 GET /login 200 271
3 127.0.0.1:5000 POST /login 302 276
4 127.0.0.1:5000 GET /dashboard 200 160
읽는 법: 이 장부가 Step 131의 서버 로그와 정확히 대응합니다 — 요청자 쪽 장부와 수신자 쪽 장부. 웹 분석은 이 두 장부를 대조하는 일이라고 해도 과언이 아닙니다.
4. 미션과 연습문제
미션 — 로그인 가로채기와 변조 기록
- Burp Suite를 임시 프로젝트로 시작하고, 내장 브라우저로 Step 131 웹앱에 접속합니다.
- Intercept on 상태에서
GET /login을 잡아 Forward와 Drop을 각각 경험합니다. - 로그인 POST를 잡아 비밀번호를 틀린 값으로 고쳐 Forward → 401 응답을 확인하고 화면을 기록합니다.
- 다시 잡아 올바른 값으로 Forward → 302 +
Set-Cookie응답을 HTTP history의 Response 창에서 찾아 기록합니다. - (도전) 3-4의 미니 프록시를 직접 짜 봅니다 — 8080에서 받은 요청의 첫 줄과 본문을 출력하고, 5000번 서버에 전달하는 코드입니다. 소켓은 Step 77~78에서 배웠습니다.
- 위키에
프록시와가로채기.md를 작성합니다 — 프록시 구조도 1개, Intercept의 세 선택지, HTTPS에서 인증서가 필요한 이유 3줄.
연습문제
문제 1. 프록시의 원래 용도(캐시·우회)와 보안에서의 용도(관찰 지점)가 왜 같은 구조에서 나오는지 설명해 보세요.
문제 2. Intercept의 Forward와 Drop의 차이를 서버 로그 관점에서 설명해 보세요.
문제 3. 3-4 실측에서 프록시는 비밀번호를 평문으로 볼 수 있었습니다. 같은 일이 HTTPS에서는 왜 바로는 불가능하고, Burp는 그것을 어떤 구조로 우회하나요?
문제 4. 브라우저의 로그인 폼에서 "비밀번호 글상자"에 별표가 표시되는데도, Burp가 잡은 요청에서는 비밀번호가 보입니다. 이 차이가 말해 주는 것은 무엇인가요?
5. 모범 답안과 완료 기준
미션 모범 답안
검증 포인트:
- 가로채기 흔적: Intercept on에서 요청이 멈춘 화면, Forward 후 페이지가 로드된 화면이 기록돼 있는가.
- 변조의 대비: 같은
POST /login에 대해 틀린 값(401)과 올바른 값(302 +Set-Cookie)의 응답이 나란히 기록돼 있는가 — HTTP history에서 두 요청의 Response를 클릭해 확인하면 됩니다. - 도전 과제의 미니 프록시 뼈대:
import socket
srv = socket.socket()
srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
srv.bind(("127.0.0.1", 8080))
srv.listen(5)
while True:
conn, _ = srv.accept()
data = conn.recv(65536)
print(data.decode("iso-8859-1")) # 가로챈 내용 출력
up = socket.create_connection(("127.0.0.1", 5000))
up.sendall(data) # 진짜 서버에 전달
resp = up.recv(65536)
conn.sendall(resp) # 응답을 돌려줌
up.close(); conn.close()
단순 버전이라 POST 본문이 잘리거나 응답을 한 번만 읽는 한계가 있습니다 — "본문 끝까지 읽기(Content-Length 파싱)"가 진짜 프록시와 장난감 프록시의 차이입니다. 그 지점까지 고민해 봤다면 도전 과제 완료입니다.
연습문제 해답
문제 1 해답. 프록시의 정의 자체가 "모든 트래픽이 손을 지나는 대리인"이기 때문입니다. 대신 전달하려면 내용을 받아야 하고, 받은 내용은 읽을 수 있습니다 — 캐시는 그 가시성을 성능에 쓴 것이고, 보안 도구는 같은 가시성을 관찰·변조에 쓴 것입니다. 구조가 같으니 용도는 주인의 의도로 갈립니다.
문제 2 해답. Forward는 요청을 서버에 전달하므로 서버 로그에 "POST /login HTTP/1.1" 한 줄이 남습니다. Drop은 요청이 서버에 닿지 않으므로 로그에 아무 줄도 생기지 않습니다 — 브라우저만 타임아웃 오류를 겪습니다. 공격 실험에서 Drop은 "이 요청은 없었던 일로" 하는 버튼입니다.
문제 3 해답. HTTPS는 브라우저와 서버가 암호화 채널을 직접 맺으므로, 중간의 프록시에게는 암호문만 지나갑니다. Burp는 자체 CA 인증서를 브라우저에 설치해, 브라우저와 Burp 사이, Burp와 서버 사이의 두 개의 별도 암호화 채널을 맺습니다 — 중간에서 풀어서 보고 다시 암호화하는, 합법적 중간자(MITM) 구조입니다. 이것이 가능한 이유(내가 내 브라우저에 인증서를 깔았다)가 곧 남용 금지의 이유이기도 합니다.
문제 4 해답. 별표 표시는 화면 속임일 뿐 데이터의 보호가 아니라는 것입니다. 폼이 전송하는 순간 비밀번호는 평문 텍스트로 HTTP 본문에 실리고, 중간자는 그것을 그대로 봅니다. "입력창의 가림"과 "전송의 보호(HTTPS)"는 완전히 다른 층의 이야기입니다.
완료 기준 체크리스트
- [ ] Burp Suite를 임시 프로젝트로 시작할 수 있다
- [ ] 내장 브라우저로 요청이 잡히는 것을 확인했다
- [ ] Intercept on에서 Forward와 Drop을 각각 사용할 수 있다
- [ ] 가로챈 로그인 요청의 파라미터를 고쳐 서버 반응 차이를 관찰했다
- [ ] HTTP history에서 Request/Response 원문을 읽을 수 있다
- [ ] HTTP에서 중간자가 평문을 본다는 것을 미니 프록시 실측으로 확인했다
6. 흔한 실수와 해결
벽 1. 브라우저가 계속 로딩만 돌아요
증상: 페이지가 안 뜨고 빙글빙글 돕니다.
원인: Intercept가 on인 채로 요청이 Burp에 멈춰 있습니다. 브라우저의 잘못이 아닙니다.
해결: Burp의 Proxy → Intercept로 가서 멈춘 요청을 Forward 하거나, Intercept is on을 눌러 off로 바꾸세요.
벽 2. 외부 브라우저(파이어폭스/크롬)에서는 아무것도 안 잡혀요
증상: 내장 브라우저는 되는데, 평소 브라우저는 Burp를 지나지 않습니다.
원인: 그 브라우저에 프록시 설정(127.0.0.1:8080)이 없습니다. 브라우저는 스스로 프록시를 찾지 않습니다 — 설정해 줘야 합니다.
해결: 처음엔 내장 브라우저로 충분합니다. 외부 브라우저가 필요하면 브라우저 설정에서 수동 프록시를 127.0.0.1:8080으로 지정하세요 — HTTPS까지 잡으려면 CA 인증서 설치가 추가로 필요합니다(벽 3).
벽 3. HTTPS 사이트에서 인증서 오류가 떠요
증상: 내장이 아닌 외부 브라우저로 HTTPS에 가면 "이 연결은 안전하지 않습니다" 경고가 뜹니다.
원인: 브라우저가 Burp의 CA 인증서를 신뢰하지 않아서, Burp의 중간자 채널을 가짜로 판정합니다.
해결: 프록시 설정이 된 브라우저에서 http://burp에 접속해 CA Certificate를 내려받고, 브라우저의 인증서 관리에서 신뢰 기관으로 등록하세요. 실습이 끝나면 지우는 습관을 들이세요 — 그 인증서가 있는 동안 여러분의 브라우저는 그 키를 가진 중간자를 믿습니다.
벽 4. Burp를 켰더니 8080이 이미 사용 중이래요
증상 (출력 예시): java.net.BindException: Address already in use 계열 오류.
원인: 이전에 켠 Burp나 다른 프로그램(3-4의 미니 프록시 포함!)이 8080을 잡고 있습니다.
해결: 다른 터미널의 프록시·서버 프로세스를 종료하세요. 실습 뒤 띄운 것을 끄는 습관이 이 벽의 예방약입니다.
벽 5. 잡은 요청이 한글로 깨져 보여요
증상: 요청 본문의 한글이 깨진 문자로 표시됩니다.
원인: 표시 인코딩 문제일 뿐, 데이터 자체는 정상인 경우가 대부분입니다.
해결: Burp의 User options → Display에서 폰트와 인코딩(UTF-8)을 확인하세요. 서버가 실제로 받은 값이 궁금하면 서버 쪽 로그(Step 131의 콘솔)와 대조하는 것이 가장 확실합니다.
7. 정리
오늘의 개념
| 개념 | 한 줄 설명 |
|---|---|
| 프록시 | 트래픽의 대리인 — 보안에서는 관찰·변조 지점 |
| 가로채기(intercept) | 요청을 서버 직전에 멈춰 보고 고치는 기능 |
| Forward / Drop | 보내기 / 없었던 일로 하기 |
| HTTP history | 지나간 요청과 응답의 장부 — 서버 로그의 요청자 쪽 쌍 |
| CA 인증서 | Burp가 HTTPS를 열어 보기 위해 브라우저에 심는 신뢰의 뿌리 |
오늘의 명령·조작
| 명령/조작 | 하는 일 |
|---|---|
| Proxy → Intercept → on/off | 가로채기 켜기/끄기 |
| Open browser | 설정 완료된 내장 브라우저 열기 |
| Forward / Drop | 멈춘 요청 보내기 / 버리기 |
| HTTP history 탭 | 지나간 요청·응답 원문 조회 |
curl -x http://127.0.0.1:8080 <URL> |
프록시를 경유해 요청 보내기 |
http://burp |
CA 인증서 다운로드 페이지 |
명령어보다 중요한 감각
오늘 이후로 여러분에게 웹 페이지는 두 겹입니다 — 보이는 화면과, 그 아래에서 오가는 요청 원문. Burp를 켜는 순간 아래층이 열리고, "폼에 입력한다"는 행위가 "텍스트를 서버에 던진다"는 실체로 바뀝니다.
그리고 3-4에서 확인했듯 이 도구의 본질은 30줄의 소켓 코드입니다. Burp는 그 위에 편의를 얹은 것일 뿐 — 원리를 본 여러분은 도구가 없어도 중간자를 만들 수 있고, 그래서 중간자가 무엇을 볼 수 있는지도 정확히 압니다.
전부 체크되면 Step 132 완료입니다. 사이드바의 체크박스를 눌러 진도를 저장하세요.