diff --git a/2026/J:g-/README.md b/2026/J:g-/README.md new file mode 100644 index 0000000..5a248e5 --- /dev/null +++ b/2026/J:g-/README.md @@ -0,0 +1,41 @@ +# Desarrollo Seguro de Aplicaciones + +En esta carpeta se encuentran resueltos 4 retos correspondientes al evento **PascalCTF 2026** realizado el sábado 31/01/2026. + +## Alumno + +- Nombre: Jeremías Salsamendi +- Legajo: 17057/7 +- Perfil de ctf: [J-](./imgs/perfil.png) + +## Equipo + +- Nombre: J:g- +- Perfil del equipo en ctf: [J:g-](./imgs/equipo.png) + +## Evento + +- Nombre del evento: PascalCTF 2026 +- Página del evento: https://ctftime.org/event/2767 + - [Captura de pantalla](./imgs/pascalctf.png) +- Fecha de inicio: 31/01/2026 +- Fecha de cierre: 01/01/2026 + +## Retos + +|**Reto**| **Categoría** | +|--|--| +|ZazaStore | Web| +|Travel Playlist | Web| +|PDFile | Web| +|JSHit | Web| + +- [Scoreboard](./imgs/scoreboard.png) + +## Aclaraciones + +Los retos estan resueltos dentro del directorio `ctfs`. Cada reto tiene su propio subdirectorio. Los retos se componen de un `writeup.md` que explica cómo fue resuelto, un `script.py` que resuelve el reto automáticamente y un directorio `imgs` con capturas de pantalla del reto. Además hay un archivo `requirements.txt` para instalar las dependencias de python que sirven para todos los retos. + +La versión de python utilizada es la 3.11. + +Para algunos retos proveían los archivos necesarios para hacer funcionar el reto localmente, en esos casos se añadió un archivo comprimido con el nombre `challenge.zip` al directorio del reto. \ No newline at end of file diff --git a/2026/J:g-/Trabajo Final DSA 2023.pdf b/2026/J:g-/Trabajo Final DSA 2023.pdf new file mode 100644 index 0000000..21560f9 Binary files /dev/null and b/2026/J:g-/Trabajo Final DSA 2023.pdf differ diff --git a/2026/J:g-/ctfs/jshit/imgs/Captura desde 2026-01-31 17-43-07.png b/2026/J:g-/ctfs/jshit/imgs/Captura desde 2026-01-31 17-43-07.png new file mode 100644 index 0000000..1dedd45 Binary files /dev/null and b/2026/J:g-/ctfs/jshit/imgs/Captura desde 2026-01-31 17-43-07.png differ diff --git a/2026/J:g-/ctfs/jshit/imgs/resumen.png b/2026/J:g-/ctfs/jshit/imgs/resumen.png new file mode 100644 index 0000000..7cacc97 Binary files /dev/null and b/2026/J:g-/ctfs/jshit/imgs/resumen.png differ diff --git a/2026/J:g-/ctfs/jshit/res/deofuscated.js b/2026/J:g-/ctfs/jshit/res/deofuscated.js new file mode 100644 index 0000000..02739c5 --- /dev/null +++ b/2026/J:g-/ctfs/jshit/res/deofuscated.js @@ -0,0 +1,14 @@ +() => { + const pageElement = document.getElementById('page'); + const flag = document.cookie.split('; ').find(row => row.startsWith('flag=')); + const pageContent = `
+

Welcome to JSHit

+

+ ${flag && flag.split('=')[1] === 'pascalCTF{1_h4t3_j4v4scr1pt_s0o0o0o0_much}' + ? 'You got the flag gg' + : 'You got no flag yet lol'} +

`; + pageElement.innerHTML = pageContent; + console.log("where's the page gone?"); + document.getElementById('code').remove(); +} \ No newline at end of file diff --git a/2026/J:g-/ctfs/jshit/script.py b/2026/J:g-/ctfs/jshit/script.py new file mode 100644 index 0000000..7452799 --- /dev/null +++ b/2026/J:g-/ctfs/jshit/script.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +"""JSHit CTF solver - Extrae y desofusca JSFuck para obtener la flag""" + +import re +import subprocess +import tempfile +import os + +# Extraer código JSFuck del HTML local +with open('src/JSHit.html', 'r') as f: + html = f.read() + +jsfuck = re.search(r']*id="code"[^>]*>(.*?)', html, re.DOTALL).group(1).strip() + +# Ejecutar en Node.js con DOM mock +node_code = f''' +const document = {{ + getElementById: () => ({{ innerHTML: '', remove: () => {{}} }}), + cookie: '' +}}; + +({jsfuck})(); +''' + +with tempfile.NamedTemporaryFile(mode='w', suffix='.js', delete=False) as f: + f.write(node_code) + temp = f.name + +try: + output = subprocess.run(['node', temp], capture_output=True, text=True, timeout=5).stdout + + # Extraer flag del código desofuscado (también revisar stderr) + full_output = subprocess.run(['node', temp], capture_output=True, text=True, timeout=5) + combined = full_output.stdout + full_output.stderr + jsfuck + + flag = re.search(r"pascalCTF\{[^}]+\}", combined) + print(f"Flag: {flag.group(0)}" if flag else "Flag not found in output") +finally: + os.unlink(temp) diff --git a/2026/J:g-/ctfs/jshit/src/JSHit.html b/2026/J:g-/ctfs/jshit/src/JSHit.html new file mode 100644 index 0000000..6192ea8 --- /dev/null +++ b/2026/J:g-/ctfs/jshit/src/JSHit.html @@ -0,0 +1,15 @@ + + + + + + JSHit + + + +
+ + + \ No newline at end of file diff --git a/2026/J:g-/ctfs/jshit/writeup.md b/2026/J:g-/ctfs/jshit/writeup.md new file mode 100644 index 0000000..b8c550a --- /dev/null +++ b/2026/J:g-/ctfs/jshit/writeup.md @@ -0,0 +1,47 @@ +# CTF JSHit — Wrap-up + +**Clasificación**: CWE-506 — Embedded Malicious Code + +## Resumen + +Se identificó y explotó JavaScript ofuscado (JSFuck) en una página web. El script ofuscado contenía la flag hardcodeada. + +## Flag + +[Código para conseguir la flag automáticamente](./script.py) +``` +pascalCTF{1_h4t3_j4v4scr1pt_s0o0o0o0_much} +``` + +## Proceso + +### 1. Inspección inicial desde el navegador + +Se accedió al sitio `https://jshit.ctf.pascalctf.it` y al usar el inspector de elementos no se observó código JavaScript. + +Esto se puede comprobar si se abre [el sitio localmente](./src/JSHit.html) + +### 2. Ejecución de código sin script visible + +Se accedió a la consola y se observó el mensaje "where's the page gone?". Esto evidencia que hubo una ejecución de código en algún momento. + +### 3. Observación de la response sin "procesar" por el navegador + +Se hizo la petición mediante `curl` para analizar el contenido que llega desde el servidor sin que haya intervención del navegador: +```bash +curl https://jshit.ctf.pascalctf.it > src/index.html +``` +Se observó que el html tiene un elemento `