[VAPT Report] SSRF를 통한 내부 파일 탈취 취약점 분석
1. Executive Summary
본 보고서는 자체 개발한 PHP 기반 회원 게시판 시스템에 대한 취약점 진단 결과를 담고 있습니다. 진단 결과, SSRF(Server-Side Request Forgery) 취약점이 확인되었으며, 이를 통해 내부 서버 정보 확인은 물론 file:// 스킴을 이용한 서버 내부 파일 탈취까지 가능한 시나리오가 확인되었습니다.
주요 발견사항
| 항목 | 내용 |
|---|---|
| 취약점 유형 | SSRF (CWE-918) |
| 심각도 | HIGH |
| CVSS v3.1 Score | 7.7 (High) |
| 영향받는 기능 | 게시글 작성 (외부 이미지 URL fetch 기능) |
| 발견 일자 | 2026-02-20 |
2. 취약점 상세 분석
2.1 취약점 개요
SSRF(Server-Side Request Forgery)는 공격자가 서버로 하여금 공격자가 지정한 URL로 요청을 보내도록 유도하는 취약점입니다.
본 시스템의 게시글 작성 기능(member_insert.php)에는 외부 이미지 URL을 입력받아 서버에서 직접 fetch하는 기능이 존재하며, 입력값에 대한 검증 없이 file_get_contents($img_url)을 호출하고 있습니다. 이를 통해 내부 네트워크 접근 및 서버 내부 파일 탈취가 가능합니다.
1
2
3
4
5
6
7
8
$img_url = $_POST["img_url"] ?? "";
if ($img_url) {
$img_data = file_get_contents($img_url); // SSRF 발생 지점
if ($img_data !== false) {
$fetched_img_name = "img_" . date("Y_m_d_H_i_s") . ".dat";
file_put_contents($upload_dir . $fetched_img_name, $img_data);
}
}
2.2 취약점 발견 위치
| 위치 | 취약 파라미터 | 공격 벡터 |
|---|---|---|
member_insert.php | img_url | SSRF (http://, file:// 스킴) |
3. Proof of Concept (PoC)
3.1 환경 확인 - 이미지 fetch 기능 정상 동작 확인
게시글 작성 시 외부 이미지 URL을 첨부하면 게시글 조회 시 이미지가 표시됩니다.
Figure 1: 이미지 URL 첨부 기능 정상 동작 확인
3.2 Step 1: 내부 서버 응답 확인
이미지 URL 입력란에 http://localhost/를 입력하여 게시글을 저장합니다.
Figure 2: 이미지 URL에 http://localhost/ 입력
게시글을 조회하면 서버가 localhost로 HTTP 요청을 보낸 뒤, 그 응답이 .dat 파일로 저장되어 화면에 노출됩니다.
Figure 3: Burp Suite 캡처 - Apache2 Ubuntu Default Page 응답값 노출
Burp Suite 분석:
1
2
3
4
GET /logintest/file/img_2026_03_22_01_33_53.dat HTTP/1.1
HTTP/1.1 200 OK
<title>Apache2 Ubuntu Default Page: It works</title>
서버가 내부 localhost로 HTTP 요청을 보내고, 그 응답이 파일로 저장되어 클라이언트에게 노출됩니다. 이는 SSRF공격에 취약함을 뜻합니다.
3.3 Step 2: file:// 스킴으로 소스코드 탈취
file:// 스킴은 HTTP 요청이 아니라 파일 시스템을 직접 읽기 때문에 PHP 실행 없이 소스코드 원본을 가져올 수 있습니다.
이미지 URL 입력란에 file:///var/www/html/logintest/login_process.php를 입력하였습니다.
Figure 4: 이미지 URL에 file:///var/www/html/logintest/login_process.php 입력
저장된 게시글을 조회하면,
Figure 5: Burp Suite 캡처 - login_process.php 소스코드 전체 노출
login_process.php 노출 내용:
1
2
3
<?php
// MySQL 연결
$mysqli = mysqli_connect('localhost', 'test22', 'pass22', 'logintest');
DB 계정 정보가 포함된 로그인 처리 로직 전체가 노출됩니다.
3.4 Step 3: DB 설정 파일 탈취
별도로 분리해서 관리하는 db.php 파일도 확인해 보았습니다.
file:///var/www/html/logintest/db.php를 입력하였습니다.
Figure 6: 이미지 URL에 file:///var/www/html/logintest/db.php 입력
Figure 7: Burp Suite 캡처 - db.php DB 계정 정보 전체 노출
db.php 노출 내용:
1
2
3
4
5
6
7
<?php
$host = 'localhost';
$username = 'test22';
$password = 'pass22';
$database = 'logintest';
$conn = mysqli_connect($host, $username, $password, $database);
DB 호스트, 계정명, 패스워드, DB명까지 전부 노출되었습니다.
4. 영향도 분석 (Impact Assessment)
4.1 심각도 평가
CVSS v3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:N
| 항목 | 값 | 설명 |
|---|---|---|
| Attack Vector (AV) | Network (N) | 네트워크를 통한 원격 공격 가능 |
| Attack Complexity (AC) | Low (L) | 공격 난이도 낮음 |
| Privileges Required (PR) | Low (L) | 일반 사용자 권한으로 공격 가능 |
| User Interaction (UI) | None (N) | 피해자 개입 불필요 |
| Scope (S) | Changed (C) | 내부 시스템까지 영향 범위 확대 |
| Confidentiality (C) | High (H) | 소스코드, DB 자격증명 등 민감 정보 탈취 |
| Integrity (I) | None (N) | 직접적인 데이터 변조 없음 |
| Availability (A) | None (N) | 가용성 영향 없음 |
최종 점수: 7.7 (HIGH)
4.2 예상 공격 시나리오
시나리오 1: DB 자격증명 탈취 후 직접 접근
공격 흐름:
- 공격자가
file://스킴으로db.php탈취 - DB 자격증명(
test22 / pass22) 획득 - DB에 직접 접속하여 전체 회원 정보 조회/유출
피해 범위:
- 전체 회원 개인정보 유출
- DB 내 민감 데이터 전체 노출
시나리오 2: 소스코드 분석을 통한 추가 취약점 발굴
공격 흐름:
file://스킴으로 서버 내 PHP 소스코드 수집- 소스코드 분석을 통해 추가 취약점(인증 우회, SQL Injection 등) 발굴
- 취약점 연계 공격으로 피해 범위 확대
| 영향 영역 | 심각도 | 설명 |
|---|---|---|
| DB 자격증명 | 상 | 호스트, 계정, 패스워드 전체 노출 |
| 소스코드 기밀성 | 상 | 내부 로직, 인증 처리 코드 노출 |
| 추가 취약점 노출 | 중 | 소스코드 분석 기반 연계 공격 가능 |
| 서비스 신뢰도 | 중 | 보안 사고 발생 시 신뢰도 급락 |
5. 보안 대응 (Remediation)
5.1 URL 검증 및 화이트리스트 적용 (필수)
허용된 스킴 및 도메인만 요청 가능하도록 제한
1
2
3
4
5
6
$parsed = parse_url($img_url);
$allowed_schemes = ['http', 'https'];
if (!in_array($parsed['scheme'], $allowed_schemes)) {
die('허용되지 않는 스킴입니다.');
}
5.2 내부 IP 접근 차단 (필수)
127.0.0.1, localhost, 10.x.x.x, 192.168.x.x 등 내부 IP 범위 차단
1
2
3
4
5
6
7
$host = $parsed['host'];
$ip = gethostbyname($host);
$blocked = ['127.0.0.1', '::1', 'localhost'];
if (in_array($ip, $blocked) || preg_match('/^(10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.)/', $ip)) {
die('내부 주소로의 요청은 허용되지 않습니다.');
}
5.3 조치사항 우선순위
| 우선순위 | 조치사항 | 난이도 | 예상 소요시간 |
|---|---|---|---|
| Critical | URL 스킴 화이트리스트 적용 | 하 | 30분 |
| Critical | 내부 IP 접근 차단 | 중 | 1시간 |
| High | 네트워크 단에서 웹 서버 아웃바운드 제한 | 중 | 별도 협의 |
6. 참고 자료 (References)
6.1 취약점 정보
- CWE-918: Server-Side Request Forgery (SSRF)
- https://cwe.mitre.org/data/definitions/918.html
- OWASP Top 10 2021: A10:2021 - Server-Side Request Forgery (SSRF)
- https://owasp.org/Top10/A102021-Server-Side_Request_Forgery%28SSRF%29/
- OWASP SSRF Prevention Cheat Sheet
- https://cheatsheetseries.owasp.org/cheatsheets/Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html
6.2 주요정보통신기반시설 기술적 취약점 분석·평가 방법 상세가이드
- 한국인터넷진흥원 (2026)
- 관련 항목: 서버사이드 요청 위조 (SSRF)
7. 결론 (Conclusion)
본 취약점 진단을 통해 게시판 시스템의 외부 이미지 fetch 기능에서 HIGH 등급의 SSRF 취약점을 발견하였습니다. file:// 스킴을 활용하면 서버 내부 PHP 소스코드 및 DB 자격증명까지 탈취 가능한 수준으로, 단일 취약점이지만 실질적인 피해 범위가 매우 넓습니다.
결론:
file_get_contents()에 사용자 입력을 그대로 넣는 순간 SSRF에 매우 취약해집니다.http://스킴으로 내부 서비스 스캔,file://스킴으로 소스코드 탈취까지 가능하므로 URL을 서버에서 직접 fetch하는 기능은 반드시 스킴과 대상 호스트를 검증해야 합니다.
권고사항:
- 즉시 조치: URL 스킴 화이트리스트 적용 (
http,https만 허용) - 즉시 조치: 내부 IP 범위 접근 차단
- 단기 조치: 네트워크 레벨 아웃바운드 트래픽 제한
Report Information
- 작성자: z1N
- 작성일: 2026-02-20
- 문서버전: 1.0
- 보안등급: 내부용 (Internal Use Only)