PHP 파일 포함 취약점 및 스트림 래퍼 심층 분석

파일 포함 개념 및 취약점 발생 원리

PHP 개발 과정에서 모듈화를 위해 특정 코드를 별도의 파일로 작성하고, 필요할 때 해당 파일을 로드하여 사용하는 기능을 파일 포함(File Inclusion)이라고 합니다. 그러나 포함할 파일의 경로가 사용자로부터 입력받는 변수에 의해 동적으로 결정될 경우, 보안 검증이 부족하면 공격자가 서버 내의 임의 파일을 읽거나 외부의 악성 코드를 실행할 수 있는 취약점이 발생합니다.

일반적으로 개발자가 파일 경로에 대한 유효성 검증을 제대로 수행하지 않거나, 우회 가능한 필터링을 적용한 경우에 이러한 취약점이 드러납니다. 공격자는 경로 조작을 통해 민감한 설정 파일이나 소스 코드를 탈취할 수 있습니다.

주요 파일 포함 함수 비교

PHP 는 파일 로딩을 위해 네 가지 주요 함수를 제공합니다. 각 함수는 파일 존재 여부 발생 시의 오류 처리 방식과 중복 포함 방지 여부에서 차이를 보입니다.

  • include(): 지정된 파일을 찾지 못할 경우 경고(Warning)만 발생시키며, 스크립트는 이후 코드를 계속 실행합니다.
  • include_once(): include() 와 동일하지만, 해당 파일이 이미 로드된 상태라면 중복하여 포함하지 않습니다.
  • require(): 파일을 찾지 못할 경우 치명적 오류(Fatal Error)를 발생시키고 스크립트 실행을 즉시 중단합니다.
  • require_once(): require() 와 동일하게 동작하되, 중복 로딩을 방지합니다.

또한 포함되는 파일의 확장명과 무관하게 PHP 파서가 해석 가능한 코드라면 실행되며, 그렇지 않은 경우 소스 코드가 그대로 노출될 위험이 있습니다.

서버 환경 및 설정 확인

파일 포함 취약점 exploits 은 서버의 운영체제 종류와 php.ini 설정에 따라 성공 여부가 결정됩니다. 특히 원격 파일 포함 (RFI) 을 위해서는 allow_url_include 설정이 활성화되어 있어야 합니다.

운영체제 식별 방법

서버가 Linux 기반인지 Windows 기반인지 확인하기 위해 다음과 같은 방법을 사용할 수 있습니다.

  • 시스템 파일 접근: /etc/hosts 파일 읽기가 성공하면 Linux 일 가능성이 높으며, 실패할 경우 Windows 일 가능성이 있습니다.
  • 대소문자 구분: Linux 파일 시스템은 대소문자를 엄격히 구분하지만, Windows 는 구분하지 않습니다. 파일名の 대소문자를 변형하여 접근해 보면 OS 를 추론할 수 있습니다.

스트림 래퍼 (Stream Wrappers) 프로토콜

PHP 는 파일 시스템 접근 외에도 다양한 스트림 래퍼를 지원합니다. 취약점 분석 시 이러한 프로토콜을 이해하는 것이 중요합니다.

file://

로컬 파일 시스템에 접근するための 기본 프로토콜입니다. allow_url_fopenallow_url_include 설정과 무관하게 작동하며, 명시적으로 명시하지 않아도 PHP 가 기본적으로 사용합니다.

file:///etc/hostname
file://C:/Windows/system.ini

php://

입출력 스트림 (I/O streams) 에 접근할 수 있는 래퍼입니다. allow_url_include 설정에 따라 사용 가능한 스트림이 제한될 수 있습니다.

스트림 이름 기능 설명
php://input HTTP 요청 본문을 읽기 전용 스트림으로 접근합니다. POST 데이터 등을.raw 형태로 읽을 수 있습니다.
php://output 쓰기 전용 스트림으로, printecho 와 유사하게 출력 버퍼에 데이터를 작성합니다.
php://fd 특정 파일 설명자 (File Descriptor) 에 직접 접근합니다. (PHP 5.3.6 이상)
php://memory
php://temp
임시 데이터 저장을 위한 스트림입니다. memory 는 메모리에만 저장하며, temp 는 특정 크기 이상 시 임시 파일로 저장합니다.
php://filter 스트림 오픈 시 데이터를 필터링하거나 인코딩 변환을 수행하는 메타 래퍼입니다.

php://input 은 요청된.raw 데이터를 직접 처리할 수 있게 해주며, php://filter 는 데이터가 스트림을 통과할 때 인코딩 변환 (예: base64) 을 적용하여 소스 코드를 우회적으로 읽는 데 활용되기도 합니다.

data://

PHP 5.2.0 이상에서 지원하며, 실제 파일 없이 데이터 자체를 파일 스트림처럼 취급합니다. 원격 파일 포함 설정이 모두 활성화되어 있을 때 PHP 코드를 직접 실행하는 데 사용될 수 있습니다.

data://text/plain,
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==

이 방식을 사용하면 서버에 파일을 업로드하지 않아도 인라인으로 코드를 주입하여 실행시킬 수 있습니다.

태그: PHP web-security LFI RFI Stream-Wrappers

8월 19일 23:44에 게시됨