Share
## https://sploitus.com/exploit?id=FBBAD7AF-E45C-5CE3-AEBC-C4A956769C6F
# FUGIO Production Guide
## Introduction
**FUGIO** is the first automatic exploit generation (AEG) tool for PHP object injection (POI) vulnerabilities. When exploiting a POI vulnerability, an attacker crafts an injection object by carefully choosing its property values to invoke a chain of existing class methods or functions (gadgets) for finally triggering a sensitive function with attack payloads. The technique used in composing this exploit object is called **property-oriented programming (POP)**.
FUGIO identifies feasible POP gadget chains considering the availability of gadgets and their caller-callee relationships via static and dynamic analyses. FUGIO then conducts a feedback-driven fuzzing campaign for each identified POP chain, thus producing exploit objects.
This production version of FUGIO provides a comprehensive solution for:
- **POI Detection**: Automatically detecting PHP object injection vulnerabilities
- **Static Analysis**: Analyzing source code to identify classes, methods, and functions
- **Dynamic Analysis**: Monitoring runtime behavior to capture gadget availability
- **POP Chain Identification**: Finding feasible chains from magic methods to sink functions
- **Automatic Exploit Generation**: Generating working exploit payloads through fuzzing
For more details, please refer to our [paper](https://www.usenix.org/conference/usenixsecurity22/presentation/park-sunnyeo), "FUGIO: Automatic Exploit Generation for PHP Object Injection Vulnerabilities", presented at USENIX Security 2022.
---
## Prerequisites
- **Operating System**: Ubuntu 18.04 or compatible Linux distribution
- **PHP Version**: PHP 7.2 (required for this production version)
- **Python**: Python 3.x
- **Web Server**: Apache with mod_php enabled
- **Docker**: For running RabbitMQ
- **Root/Sudo Access**: Required for file system operations and Apache configuration
---
## Installation and Setup
### Step 1: Environment Check
```bash
# Check PHP version (must be PHP 7.2)
php -v
# Check if RabbitMQ is running
sudo docker ps | grep rabbitmq
# If RabbitMQ is not running, start it:
sudo docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 \
-e RABBITMQ_DEFAULT_USER=fugio \
-e RABBITMQ_DEFAULT_PASS=fugio_password \
rabbitmq:management
```
### Step 2: Deploy Target Application to Web Server
```bash
# Copy application to document root
sudo cp -r ~/FUGIO/vulnerable_app /var/www/html/
# Set proper permissions
sudo chown -R www-data:www-data /var/www/html/vulnerable_app
sudo chmod -R 755 /var/www/html/vulnerable_app
# Verify file exists
ls -la /var/www/html/vulnerable_app/index.php
```
### Step 3: Generate Hook File
```bash
# Run FUGIO initially to generate hook file
cd ~/FUGIO
sudo ./run_FUGIO_72.sh vulnerable_app --doc_root=/var/www/html
# Wait until you see "[#] Exploitable!" then press Ctrl+C to stop
# Hook file will be created at: Files/hook_sensitive_functions.php
```
### Step 4: Create .htaccess to Load Hook File
```bash
# Create .htaccess automatically
sudo ./htaccess.py on /var/www/html
# Or create manually:
HOOK_FILE="/home/duong/FUGIO/Files/hook_sensitive_functions.php"
sudo bash -c "echo 'php_value auto_prepend_file $HOOK_FILE' > /var/www/html/.htaccess"
# Verify
cat /var/www/html/.htaccess
```
### Step 5: Configure Apache to Allow .htaccess
```bash
# Check Apache configuration
sudo grep -r "AllowOverride" /etc/apache2/sites-available/
# If not found, add to /etc/apache2/sites-available/000-default.conf:
sudo nano /etc/apache2/sites-available/000-default.conf
# Add inside :
#
# AllowOverride All
#
# Restart Apache
sudo systemctl restart apache2
```
### Step 6: Test Hook File Loading
```bash
# Test with script (if available)
chmod +x test_hook.sh
./test_hook.sh
# Or test manually:
curl -s http://127.0.0.1/vulnerable_app/index.php | grep -i "r353t"
# Should see "r353t" in the response
```
---
## Running FUGIO
### Step 7: Start FUGIO Detection
```bash
# Terminal 1: Run FUGIO
cd ~/FUGIO
sudo ./run_FUGIO_72.sh vulnerable_app --doc_root=/var/www/html
# Wait until you see:
# CLASSES: 6 (Before autoload)
# [#] Exploitable!
# - Injected Function: unserialize()
#
# FUGIO will then wait for trigger...
```
### Step 8: Trigger POI (In Another Terminal)
```bash
# Terminal 2: Trigger POI vulnerability
cd ~/FUGIO
python3 vulnerable_app/trigger_poc.py http://127.0.0.1/vulnerable_app/index.php
# Or test with real payload:
python3 vulnerable_app/test_real_payload.py http://127.0.0.1/vulnerable_app/index.php user
```
### Step 9: View Results
Return to Terminal 1 (running FUGIO), you will see:
- FUGIO detected POI
- FUGIO found POP chains
- Final exploit results
---
## Understanding FUGIO Output
FUGIO generates output files in different directories corresponding to each step in the analysis process. This section explains the location and how to read each type of file.
### 1. POI Detector (Object Injection Vulnerability Detection)
**Output Location:**
- **Terminal output** when running `./run_FUGIO_72.sh`
- **Apache error log**: `/var/log/apache2/error.log`
**How to Read:**
```bash
# View terminal output when running FUGIO
sudo ./run_FUGIO_72.sh vulnerable_app
# Or view Apache error log
sudo tail -f /var/log/apache2/error.log
```
**Detection Sign:**
```
[#] Exploitable! - Injected Function: unserialize()
```
**Related Files:**
- `Files/hook_sensitive_functions.php` - Hook file injected into app to detect POI
---
### 2. Static Analyzer (Static Analysis)
**Output Location:**
```
Files/dump_files/[target_path].dump
```
**Examples:**
- Target: `vulnerable_app` โ `Files/dump_files/vulnerable_app.dump`
- Target: `home/user/app` โ `Files/dump_files/home.user.app.dump`
**Format:**
- **Binary format**: Python pickle file
- **Content**: Dictionary containing `target_file_list` with structure:
```python
{
'file_path': FileObject(
class_list: {
'ClassName': ClassObject(
method_list: {...},
property_list: {...}
)
},
func_list: {...}
)
}
```
**How to Read:**
```python
import pickle
# Read dump file
with open('Files/dump_files/vulnerable_app.dump', 'rb') as f:
target_file_list = pickle.load(f)
# View file list
for file_name, file_obj in target_file_list.items():
print(f"File: {file_name}")
print(f" Classes: {len(file_obj.class_list)}")
print(f" Functions: {len(file_obj.func_list)}")
# View classes
for class_name, class_obj in file_obj.class_list.items():
print(f" Class: {class_name}")
print(f" Methods: {len(class_obj.method_list)}")
```
**Or use script:**
```bash
python3 read_fugio_outputs.py vulnerable_app
```
---
### 3. Dynamic Analyzer (Dynamic Analysis)
**Output Location:**
- **RabbitMQ**: Runtime data sent via RabbitMQ
- **Apache error log**: `/var/log/apache2/error.log` (hook activity)
- **Eval file**: `Files/eval_file.php` (code evaluated at runtime)
**How to Read:**
#### a) Apache Error Log:
```bash
sudo tail -f /var/log/apache2/error.log | grep -i "r353t\|count:"
```
#### b) Eval File:
```bash
cat Files/eval_file.php
```
#### c) RabbitMQ Messages:
- Data sent via queue `trigger_func_channel`
- Format: JSON with fields:
```json
{
"TRIGGER_FUNC": "unserialize",
"FUNC_ARGV": [...],
"CLASSES": [...],
"USER_CLASSES": [...],
"USER_FUNCTIONS": [...],
"GLOBALS": {...},
"CONSTANTS": {...}
}
```
**Note:**
- Dynamic analysis data is not saved to files, only processed real-time
- To view details, monitor RabbitMQ or Apache log
---
### 4. POP Chain Identifier (POP Chain Identification)
**Output Location:**
```
Files/fuzzing/[target_path].[timestamp]/PUT/proc[proc_id]_[chain_id]_[len]_[depth]_[idx]_[no_this].chain
```
**Example:**
```
Files/fuzzing/vulnerable_app.251130214406/PUT/proc0_0_3_2_1_0.chain
```
**Format:**
- **Text file**: PHP code
- **Content**: POP chain serialized as PHP code for fuzzing
**How to Read:**
```bash
# View chain file
cat Files/fuzzing/vulnerable_app.251130214406/PUT/proc0_0_3_2_1_0.chain
# Or use script
python3 read_fugio_outputs.py vulnerable_app
```
**File Name Structure:**
- `proc[proc_id]`: Process ID (0, 1, 2, ...)
- `[chain_id]`: Chain ID within that process
- `[len]`: Chain length (number of gadgets)
- `[depth]`: Total depth of chain
- `[idx]`: Total index
- `[no_this]`: Number of gadgets not using `$this`
**Example Content:**
```php
'User',
'method' => '__destruct',
'file' => 'index.php',
...
],
[
'class' => 'FileHandler',
'method' => 'read',
'file' => 'index.php',
...
],
...
];
}
?>
```
---
### 5. POP Chain Fuzzer (POP Chain Fuzzing)
**Output Location:**
#### a) PUT Files (Program Under Test):
```
Files/fuzzing/[target_path].[timestamp]/PUT/
โโโ put-head.php # PUT header
โโโ put-body.php # PUT body (classes + functions)
โโโ inst_PUT.php # Instrumented PUT (with instrumentation code)
```
#### b) Exploit Files:
**PROBABLY_EXPLOITABLE** (Chain reached sink but not verified):
```
Files/fuzzing/[target_path].[timestamp]/PUT/PROBABLY_EXPLOITABLE/
โโโ [payload_file]_[seed_value]_[sink_function]
```
**EXPLOITABLE** (Successful exploit):
```
Files/fuzzing/[target_path].[timestamp]/PUT/EXPLOITABLE/
โโโ [payload_file]_[seed_value]_[sink_function]
```
**How to Read:**
#### PUT Files:
```bash
# View PUT body (contains classes and functions)
cat Files/fuzzing/vulnerable_app.251130214406/PUT/put-body.php
# View instrumented PUT
cat Files/fuzzing/vulnerable_app.251130214406/PUT/inst_PUT.php
```
#### Exploit Files:
```bash
# View successful exploit
cat Files/fuzzing/vulnerable_app.251130214406/PUT/EXPLOITABLE/*
# View probably exploitable
cat Files/fuzzing/vulnerable_app.251130214406/PUT/PROBABLY_EXPLOITABLE/*
```
**Exploit File Format:**
```php
O:4:"User":2:{s:4:"name";s:5:"admin";s:8:"filepath";s:13:"/etc/passwd";}
```
**The serialized object** (last line) is the payload that can be used for exploitation:
```php
O:4:"User":2:{s:4:"name";s:5:"admin";s:8:"filepath";s:13:"/etc/passwd";}
```
---
## Automated Output Reading Script
Use the `read_fugio_outputs.py` script to automatically read all outputs:
```bash
python3 read_fugio_outputs.py vulnerable_app
```
The script will display:
1. โ
Static Analyzer output (dump file)
2. โ
PUT files
3. โ
POP chains
4. โ
Exploit files
5. โ
Dynamic Analyzer info
6. โ
POI Detector info
---
## Output File Summary
| Step | Directory/File | Format | How to Read |
|------|----------------|--------|-------------|
| **1. POI Detector** | Terminal + Apache log | Text | `tail -f /var/log/apache2/error.log` |
| **2. Static Analyzer** | `Files/dump_files/[target].dump` | Pickle | `pickle.load()` in Python |
| **3. Dynamic Analyzer** | RabbitMQ + `Files/eval_file.php` | JSON + PHP | Monitor RabbitMQ or view eval_file.php |
| **4. POP Chain** | `Files/fuzzing/[target].[time]/PUT/proc*.chain` | PHP text | `cat` or text editor |
| **5. PUT Files** | `Files/fuzzing/[target].[time]/PUT/put-*.php` | PHP text | `cat` or text editor |
| **6. Exploits** | `Files/fuzzing/[target].[time]/PUT/EXPLOITABLE/` | PHP + Serialized | `cat` to view payload |
---
## Practical Examples
### Find all exploits:
```bash
find Files/fuzzing -name "EXPLOITABLE" -type d
find Files/fuzzing -path "*/EXPLOITABLE/*" -type f
```
### View latest chain:
```bash
ls -lt Files/fuzzing/*/PUT/proc*.chain | head -1 | xargs cat
```
### View successful exploit:
```bash
# Find exploit file
EXPLOIT=$(find Files/fuzzing -path "*/EXPLOITABLE/*" -type f | head -1)
# View content
cat "$EXPLOIT"
# Extract payload (last line)
tail -1 "$EXPLOIT"
```
### Count number of chains:
```bash
find Files/fuzzing -name "proc*.chain" | wc -l
```
---
## Important Notes
1. **Dump files** (.dump) are only created on the first run of FUGIO. If source code changes, delete the dump file to regenerate.
2. **Fuzzing directory** is created with timestamp, format: `[target].[YYMMDDHHMMSS]`
3. **Chain files** are only created when FUGIO finds a chain from magic method to sink.
4. **Exploit files** are only created when fuzzing successfully triggers sink function.
5. **Dynamic analysis** data is not saved to files, only exists in RabbitMQ and Apache log.
---
## Troubleshooting
### Error 500 when triggering:
```bash
# View error log
sudo tail -20 /var/log/apache2/error.log
# Test PHP syntax
php -l /var/www/html/vulnerable_app/index.php
```
### Hook not loading:
```bash
# Check .htaccess
cat /var/www/html/.htaccess
# Check hook file
ls -la Files/hook_sensitive_functions.php
# Restart Apache
sudo systemctl restart apache2
```
### "NO CLASS FILE" messages:
- This is normal, classes will be detected in dynamic analysis
- Important: must see "[#] Exploitable!" and "Injected Function: unserialize()"
### Cannot find dump file?
```bash
# Check directory
ls -la Files/dump_files/
# Run FUGIO again to create dump
sudo ./run_FUGIO_72.sh vulnerable_app
```
### No chain files?
- Check if sink functions exist
- Check if magic methods exist
- View terminal output for debugging
### No exploit files?
- Chain may not have been fuzzed successfully
- Check `PROBABLY_EXPLOITABLE` directory
- View fuzzing statistics in terminal
---
## Critical Requirements
1. **Must run FUGIO with sudo** - Required permissions to create hook file
2. **RabbitMQ must be running** - Must start before running FUGIO
3. **Apache must have AllowOverride All** - Required to load .htaccess
4. **Hook file must be created** - Must be generated before creating .htaccess
5. **Trigger must send to correct URL** - Must match the URL where app is running
---
## Command Reference
### Basic FUGIO Execution:
```bash
sudo ./run_FUGIO_72.sh [target] --doc_root=[document_root]
```
### Enable/Disable Monitoring:
```bash
# Enable
sudo ./htaccess.py on /var/www/html
# Disable
sudo ./htaccess.py off /var/www/html
```
### View Real-time Logs:
```bash
# Apache error log
sudo tail -f /var/log/apache2/error.log
# Filter for FUGIO activity
sudo tail -f /var/log/apache2/error.log | grep -i "r353t\|count:"
```
---
## References
- **FUGIO Paper**: [USENIX Security 2022](https://www.usenix.org/conference/usenixsecurity22/presentation/park-sunnyeo)
- **FUGIO Artifact**: [GitHub Repository](https://github.com/WSP-LAB/FUGIO?tab=readme-ov-file)
- **FUGIO Artifact (Benchmarks)**: [FUGIO-artifact](https://github.com/WSP-LAB/FUGIO-artifact)
---
## Support
For issues, questions, or contributions, please refer to the main FUGIO repository or contact the development team.
**Version**: Production Release
**Last Updated**: 2024