PHP Wrapper

개념

  • 파일처럼 보이지만, 실제로는 다른 방식(네트워크, 압축, 메모리 등)으로 데이터를 읽게 해주는 인터페이스
  • PHP의 include(), file_get_contents()같은 함수는 스트림 을 읽는다

중요

  • php://filter/resource:
    • php wrapper를 사용하지 않은것과 결과 동일.
    • 필터는 썼지만, 아무런 변화를 주지 않고 출력한 상태
    • RCE가 일어날 수 있음
    • 대신 소스코드 확인 불가
  • php://filter/convert.base64-encode/resource:
    • 대상 파일을 b64로 인코딩해서 읽고 문자열을 그대로 출력
    • RCE는 일어나지 않음
    • 대신 소스코드 확인 가능

예제 index.php

<?php 
$file = $_GET['file']; 
if(isset($file)) 
{ 
	include("$file".".php"); 
}
else 
{ 
	include("home.php"); 
} 
?>
  • index.php?file=index의 경우:
    • include(“index.php”);로 실행됨
    • index.php를 일반 파일 스트림으로 읽음 index.php를 실행하고 결과를 반환함
    • ?file=php://filter/resource=index와 동일
  • index.php?file=php://filter/convert.base64-encode/resource=index 의 경우:
    • php://filter는 파일을 변형해서 읽는 스트림이다
    • convert.base64-encode로 인해 base64 인코딩이 된다
    • 결과적으로, index.php를 base64로 인코딩해서 문자열로 출력한다 내부 코드는 실행되지 않고 소스코드가 유출되는 효과

Zip Wrapper

  • Zip Wrapper로, zipfile을 스트림으로 읽음.
  • #와 결합하여 압축 파일 내부의 파일을 지정해서 include 할 수 있다. (URL로 사용되는 경우 %23으로 인코딩)
zip://zipfile.zip#malicious.php
  • zipfile.zip 안에 있는 malicious.php를 찾아서, 읽음.
  • include와 결합되면, malicious.php가 실제로 실행됨
  • include("zip://zipfile.zip#malicious.php") : malicious.php를 실행

PHAR

  • PHAR = PHP Archive
  • .zip처럼 파일도 묶으면서 동시에 PHP가 직접 실행/처리할 수 있는 구조를 가진 파일. zip과 비슷하게 내부 파일 접근 가능함
  • include 없이, PHAR 파일을 읽기만 해도 내부 메타데이터가 역직렬화되면서 RCE가 가능함

PHAR를 파싱하는 과정에서 RCE가 일어날 수 있는 대표 함수들

  • PHP Version < 8.0
file_exists()
is_file()
fopen()
file_get_contents()
getimagesize()
exif_read_data()