취약점 개요(CWE-22, 99)

"지정된 리소스 경로를 벗어나 허락되지 않은 리소스에 접근할 수 있는 취약점"

 

경로에는 절대 경로(Absolute Path)와 상대 경로(Relative Path)가 있다.

 

절대 경로(Absolute Path)는 "C:\windows\test.php" 처럼 처음부터 끝까지의 모든 경로를 의미한다.

 

상대 경로(Relative Path)는 " C:\windows\" 의 경로에 있다고 가정하면 windows 디렉토리가 중심이 되고, ..\ 로 상위 경로로 이동할 수 있다. 즉 현 디렉토리를 기준으로 한 상대적인 경로이다.

예시로 C:\test2.php 파일이 있을 때 ..\test2.php 로 현재 경로에서 상위 경로로 이동해 test2.php 파일 실행 가능하다.

 

이를 이용해 허락되지 않은 리소스 접근이 가능하며, Path Traversal 취약점은 경로를 조작(벗어나)하여 허락되지 않은 리소스에 접근할 수 있는 취약점이라 정의할 수 있다.

공격 방법

 

공격대상 기본 경로에는 index.php 파일 및 2개의 디렉토리, help 경로에는 help.php 파일이 있다.

 

 

상위 경로에는 위 사진과 같은 파일들이 있으며, 그 이상으로는 웹 설정 상 웹 루트를 벗어나지 못한다.

 

 

cat 명령어와 상대 경로 이동 값을 이용해 상위 경로의 view_source.php 파일 열람이 가능하다. 취약 함수 별 그리고 운영환경에 따라 cat 같은 시스템 명령어가 필요한 것도 있으며, 필요 없는 것도 있다. 이는 상황에 따라 다르다.

 

 

절대 경로(Absolute Path)를 이용해도 동일한 결과를 얻을 수 있다.

 

* 개인용

LFImap 사용, 이 내에 log poisoning, reverse shell, php wrapper 등 기능이 많음. 사용법 학습 필요

예상 피해

정보 유출 가능. 이는 개인정보, 계정정보, 공격 범위 확장을 위한 시스템 정보 등이 있다.

 

즉 해당 시스템에 있는 가능한 모든 정보를 가져올 수 있으며, 정보 범위는 웹에서 허용하는 최대 범위에 따라 다르다.

 

또한 서버에서 심볼릭 링크로 이동 가능하도록 설정 시 정보 수집 범위 확장이 가능하다.

보안대책

1. 코드 내 특수 문자 필터링 기능 삽입

2. WAF(Web Application Firewall) 도입

3. 심볼릭 링크 허용 금지

4. 웹 루트 경로 설정

 

위 중 특수 문자 필터링만 제대로 되어도 문제는 없지만, 다중 보안이 중요하기에 모두 적용하여야 한다.

 

하나씩 살펴보자.

 

1. 코드 내 특수 문자 필터링 기능 삽입

 

안전하지 않은 코드

import os
from django.shortcuts import render

def get_info(request):

  request_file = request.POST.get('request_file')
  (filename, file_ext) = os.path.splitext(request_file)
  file_ext = file_ext.lower()

  if file_ext not in ['.txt', '.csv']:
    return render(request, '/error.html', {'error':'파일을 열 수 없습니다.'})

  with open(request_file) as f:
    data = f.read()

  return render(request, '/success.html', {'data':data})

 

request_file 은 사용자 입력 값, 이를 파일명과 확장자를 나눈 후 확장자를 검증한다.

그리고 파일을 오픈한 후 렌더링하여 success.html 로 돌려준다.

 

파일명에 대한 검증이 없다. 확장자만 맞으면 허용된 범위 내 모든 자료를 가져올 수 있다.

 

예시로 상위 경로에 secret.txt 파일이 있을 시 ../secret.txt 로 가져올 수 있다.

 

안전한 코드

import os
from django.shortcuts import render

def get_info(request):

  request_file = request.POST.get('request_file')
  (filename, file_ext) = os.path.splitext(request_file)
  file_ext = file_ext.lower()

  if file_ext not in ['.txt', '.csv']:
    return render(request, '/error.html', {'error':'파일을 열 수 없습니다.'})

    filename = filename.replace('.', '')
    filename = filename.replace('/', '')
    filename = filename.replace('\\', '')

    try:
      with open(filename + file_ext) as f:
        data = f.read()
    except:
      return render(
        request, "/error.html", {"error':'파일을 열 수 없습니다.'"}
      )
      return render(request, '/success.html', {'data':data})

 

특수문자를 공백으로 리플레이스한다.

 

그러나 중요파일로 이동하는 심볼릭 링크가 웹 디렉토리에 있고, 이 사용을 허용할 시 정보 유출이 가능하다.

 

예시

1. test.lnk -> /etc/secret.txt 로 연결되어 있음

2. test.lnk 접근 시 /etc/secret.txt 열람

def get_safe_path(filename):
    safe_path = os.path.realpath(os.path.join(BASE_DIR, filename))  # 절대경로 변환
    if not safe_path.startswith(BASE_DIR):  # BASE_DIR 내부 파일만 허용
        raise ValueError("🚨 경로 탐색 공격 탐지됨!")
    return safe_path

 

위 코드로 보완이 가능하지만, 모든 요청에 대해서 이를 검증하기엔 리소스 낭비이다.

따라서 웹 서버 설정에서 Followsymlink 같은 설정을 이용하여 차단하는 것이 효율적이다.

 

2. WAF(Web Application Firewall) 도입

 

ModSecurity, NAXSI, Shadow Daemon, AWS WAF 등 오픈소스 WAF가 많다. 웹 서버에 맞춰 특성화 되어 있는 경우가 대부분이니 이에 맞춰 도입하여야 한다.

웹 방화벽 사용 서버 및 언어
ModSecurity Apache, Nginx, IIS
NAXSI Nginx 전용
Shadow Daemon 독립 실행 (PHP, Python, Perl)
OpenWAF Nginx
WebKnight IIS 전용

3. 심볼릭 링크 허용 금지

패스

 

4. 웹 루트 경로 설정

 

Apache(httpd.conf 또는 apache2.conf

DocumentRoot /var/www/html/public
<Directory /home/user/public_html>
    AllowOverride All
    Require all granted
</Directory>

 

DocumentRoot 이용하여 웹 루트를 public으로 지정

 

php 내장 서버 이용 시 php -S 명령과 -t 를 이용해 지정 가능

php -S localhost:8000 -t /var/www/html

 

참고문헌

1. KISA 주요정보통신기반시설 기술적 취약점 분석 평가 방법 상세가이드

2. KISA Python_시큐어코딩_가이드(2023년_개정본)

'주요통신기반시설 취약점 가이드 > 주통기 웹' 카테고리의 다른 글

파일 업로드(File Upload)  (0) 2025.03.18
크로스 사이드 스크립트(XSS)  (0) 2025.03.18
관리자 페이지 노출  (0) 2025.02.20
LDAP Injection  (0) 2025.02.19
Buffer Overflow  (0) 2025.02.19

+ Recent posts