Post

[VAPT Report] SSRF를 통한 내부 파일 탈취 취약점 분석

1. Executive Summary

본 보고서는 자체 개발한 PHP 기반 회원 게시판 시스템에 대한 취약점 진단 결과를 담고 있습니다. 진단 결과, SSRF(Server-Side Request Forgery) 취약점이 확인되었으며, 이를 통해 내부 서버 정보 확인은 물론 file:// 스킴을 이용한 서버 내부 파일 탈취까지 가능한 시나리오가 확인되었습니다.

주요 발견사항

항목내용
취약점 유형SSRF (CWE-918)
심각도HIGH
CVSS v3.1 Score7.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.phpimg_urlSSRF (http://, file:// 스킴)

3. Proof of Concept (PoC)

3.1 환경 확인 - 이미지 fetch 기능 정상 동작 확인

게시글 작성 시 외부 이미지 URL을 첨부하면 게시글 조회 시 이미지가 표시됩니다.

이미지 fetch 기능 정상 동작 Figure 1: 이미지 URL 첨부 기능 정상 동작 확인

3.2 Step 1: 내부 서버 응답 확인

이미지 URL 입력란에 http://localhost/를 입력하여 게시글을 저장합니다.

SSRF 취약점 확인 Figure 2: 이미지 URL에 http://localhost/ 입력

게시글을 조회하면 서버가 localhost로 HTTP 요청을 보낸 뒤, 그 응답이 .dat 파일로 저장되어 화면에 노출됩니다.

Apache2 서버 응답 노출 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를 입력하였습니다.

file:// 스킴 입력 Figure 4: 이미지 URL에 file:///var/www/html/logintest/login_process.php 입력

저장된 게시글을 조회하면,

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를 입력하였습니다.

db.php 탈취 시도 Figure 6: 이미지 URL에 file:///var/www/html/logintest/db.php 입력

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 자격증명 탈취 후 직접 접근

공격 흐름:

  1. 공격자가 file:// 스킴으로 db.php 탈취
  2. DB 자격증명(test22 / pass22) 획득
  3. DB에 직접 접속하여 전체 회원 정보 조회/유출

피해 범위:

  • 전체 회원 개인정보 유출
  • DB 내 민감 데이터 전체 노출

시나리오 2: 소스코드 분석을 통한 추가 취약점 발굴

공격 흐름:

  1. file:// 스킴으로 서버 내 PHP 소스코드 수집
  2. 소스코드 분석을 통해 추가 취약점(인증 우회, SQL Injection 등) 발굴
  3. 취약점 연계 공격으로 피해 범위 확대
영향 영역심각도설명
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 조치사항 우선순위

우선순위조치사항난이도예상 소요시간
CriticalURL 스킴 화이트리스트 적용하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하는 기능은 반드시 스킴과 대상 호스트를 검증해야 합니다.

권고사항:

  1. 즉시 조치: URL 스킴 화이트리스트 적용 (http, https만 허용)
  2. 즉시 조치: 내부 IP 범위 접근 차단
  3. 단기 조치: 네트워크 레벨 아웃바운드 트래픽 제한

Report Information

  • 작성자: z1N
  • 작성일: 2026-02-20
  • 문서버전: 1.0
  • 보안등급: 내부용 (Internal Use Only)

This post is licensed under CC BY 4.0 by the author.