Bandit: nivel 28 → 29
Cómo resolver el nivel 28 → 29 de OverTheWire Bandit recuperando una contraseña que fue borrada del README pero sigue viva en el historial de commits de Git.
El nivel anterior era Git para principiantes: el secreto estaba en el README. Este da el paso importante: la contraseña ya no está en el README actual, alguien la “censuró”… pero Git recuerda todo. Vamos a recuperarla del historial de commits. Es, literalmente, uno de los fallos reales más comunes: creer que borrar un secreto de un fichero lo elimina, cuando sigue en la historia del repo.
Las contraseñas de los niveles aparecen como [REDACTED]. Siguiendo las normas de OverTheWire, no publico credenciales: la gracia es que llegues a ellas tú.
Clonar el repo (desde tu máquina)
Igual que en el nivel anterior: el clone se hace desde tu máquina local, no desde dentro de Bandit (si no, choca con el bloqueo de localhost). La credencial de bandit28-git es la contraseña de bandit28.
1
2
3
4
$ cd $(mktemp -d)
$ git clone ssh://bandit28-git@bandit.labs.overthewire.org:2220/home/bandit28-git/repo
$ cd repo
$ cat README.md
El README tiene una sección de credenciales, pero la contraseña aparece tapada con xxxxxxxxxx. En la versión actual no está. Toca mirar atrás.
Bucear en el historial
git log muestra el historial de commits, del más reciente al más antiguo:
1
2
3
4
5
6
7
8
9
$ git log
commit 4357a6e... (HEAD -> master, origin/master, origin/HEAD)
fix info leak
commit fac3dcd...
add missing data
commit a0e6303...
initial commit of README.md
Los mensajes de commit ya cuentan la historia:
initial commit of README.md: el README original.add missing data: alguien añadió datos (probablemente la contraseña real).fix info leak: alguien se dio cuenta de que la contraseña estaba expuesta y la tapó. Este es el commit sospechoso: “arreglar fuga de información” casi siempre significa “quité algo que no debía estar ahí”.
La solución: ver qué cambió ese commit
git show <commit> enseña exactamente qué cambió en un commit. Miro el de fix info leak:
1
2
3
4
5
6
7
8
9
$ git show 4357a6e76c600eb95daf13b1c315b95faab9d4e6
...
diff --git a/README.md b/README.md
@@ -4,5 +4,5 @@ Some notes for level29 of bandit.
## credentials
- username: bandit29
- password: [REDACTED]
+ password: xxxxxxxxxx
Y aquí está la clave: hay que saber leer un diff.
- Las líneas que empiezan por
-son lo que ese commit quitó (la versión vieja). - Las líneas que empiezan por
+son lo que añadió (la versión nueva).
El commit fix info leak borró la línea con la contraseña real (-) y la sustituyó por xxxxxxxxxx (+). O sea, la contraseña que buscamos es justo la de la línea con el -. El intento de “tapar la fuga” solo cambió el fichero en el commit nuevo; la versión anterior, con la contraseña, sigue guardada en el historial.
Esa es toda la lección del nivel: en Git, modificar o borrar algo no lo elimina, crea un commit nuevo. Todo lo anterior sigue accesible. “Arreglar” una fuga borrando el secreto en un commit posterior no sirve de nada si el repo es accesible: cualquiera con el historial lo recupera.
Otras formas de verlo
1. El diff entre el commit anterior y el actual
En vez de git show, puedes comparar directamente las dos versiones:
1
$ git diff fac3dcd 4357a6e
Te enseña el mismo cambio: la contraseña en rojo (-) y el xxxxxxxxxx en verde (+).
2. Leer directamente el README de un commit antiguo
Como sabemos que add missing data (el commit intermedio) ya tenía la contraseña y aún no la habían tapado, podemos leer el fichero tal como estaba en ese commit:
1
$ git show fac3dcd:README.md
La sintaxis git show <commit>:<fichero> muestra el contenido de un fichero en el estado de un commit concreto. Ahí la contraseña está en claro, sin diff que interpretar.
Por qué esto importa en seguridad
Esto es