Eternal Loop
4 minutos de lectura
Se nos proporciona un archivo ZIP llamado Eternal Loop.zip
:
$ file Eternal\ Loop.zip
Eternal Loop.zip: Zip archive data, at least v2.0 to extract, compression method=store
$ du -h Eternal\ Loop.zip
452K Eternal Loop.zip
$ unzip -v Eternal\ Loop.zip
Archive: Eternal Loop.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
460611 Stored 460611 0% 05-23-2018 01:03 b74de99a 37366.zip
-------- ------- --- -------
460611 460611 0% 1 file
Archivos incompensadores
El archivo ZIP se puede descomprimir con la contraseña hacktkebox
:
$ unzip -P hackthebox Eternal\ Loop.zip
Archive: Eternal Loop.zip
extracting: 37366.zip
$ file 37366.zip
37366.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
$ unzip -v 37366.zip
Archive: 37366.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
460340 Defl:N 460485 0% 05-23-2018 10:02 04db4f8a 5900.zip
-------- ------- --- -------
460340 460485 0% 1 file
El resultado es otro archivo ZIP, que almacena otro archivo ZIP y está protegido con contraseña:
$ unzip 37366.zip
Archive: 37366.zip
[37366.zip] 5900.zip password:
Aquí, podemos deducir que la contraseña es el nombre del archivo ZIP almacenado dentro (5900
):
$ unzip -P 5900 37366.zip
Archive: 37366.zip
inflating: 5900.zip
$ file 5900.zip
5900.zip: Zip archive data, at least v2.0 to extract, compression method=deflate
$ unzip -v 5900.zip
Archive: 5900.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
460067 Defl:N 460212 0% 05-23-2018 10:02 3dda373a 49805.zip
-------- ------- --- -------
460067 460212 0% 1 file
Automatización
El procedimiento anterior se repite muchas veces, por lo que necesitaremos automatizar el proceso. El algoritmo es:
- Ejecutar
unzip
con una contraseña incorrecta para ver el nombre de archivo ZIP interno - Ejecutar
Unzip
con la contraseña correcta - Eliminar el archivo ZIP antiguo
- Continuar con el nuevo archivo ZIP
Decidí usar un programa en Go. Estas son las líneas relevantes:
// ...
func main() {
r := regexp.MustCompile(`(skipping|inflating): (\d+)\.zip`)
output, _ := exec.Command("unzip", "-P", "xxx", "Eternal Loop.zip").CombinedOutput()
password := r.FindStringSubmatch(string(output))[2]
newPassword := "hackthebox"
stage := 1
exec.Command("unzip", "-P", newPassword, "Eternal Loop.zip").Run()
for {
output, _ := exec.Command("unzip", "-P", newPassword, password + ".zip").CombinedOutput()
matches := r.FindStringSubmatch(string(output))
if len(matches) == 0 {
break
}
newPassword = matches[2]
err := exec.Command("unzip", "-P", newPassword, password + ".zip").Run()
if err != nil {
exec.Command("rm", "-r", newPassword + ".zip").Run()
if exec.Command("unzip", "-P", newPassword, password + ".zip").Run() != nil {
break
}
}
exec.Command("rm", "-r", password + ".zip").Run()
password = newPassword
fmt.Printf("[+] Stage: %d\r", stage)
stage++
}
fmt.Println()
}
Si ejecutamos el programa anterior, tendremos esto:
$ go run solve.go
[+] Stage: 500
$ ls
6969.zip 'Eternal Loop.zip' solve.go
Último archivo ZIP
Este último archivo ZIP almacena un archivo llamado DoNotTouch
, y nuevamente está protegido con contraseña:
$ unzip -v 6969.zip
Archive: 6969.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
884736 Defl:N 335169 62% 03-31-2018 07:54 e8183254 DoNotTouch
-------- ------- --- -------
884736 335169 62% 1 file
$ unzip 6969.zip
Archive: 6969.zip
[6969.zip] DoNotTouch password:
Esta vez, la contraseña no es DoNotTouch
:
$ unzip -P DoNotTouch 6969.zip
Archive: 6969.zip
skipping: DoNotTouch incorrect password
Ataque de fuerza bruta
Intentemos encontrar la contraseña usando fcrackzip
y rockyou.txt
:
$ fcrackzip -uDp $WORDLISTS/rockyou.txt 6969.zip
PASSWORD FOUND!!!!: pw == letmeinplease
Ahí está, ahora podemos descomprimir el archivo:
$ unzip -P letmeinplease 6969.zip
Archive: 6969.zip
inflating: DoNotTouch
$ file DoNotTouch
DoNotTouch: SQLite 3.x database, last written using SQLite version 3021000, page size 1024, file counter 26, database pages 864, cookie 0x22, schema 1, UTF-8, version-valid-for 26
Flag
Hay una base de datos SQLite3 en DoNotTouch
, la flag debe tiene que estar ahí. La mejor manera para encontrarla es usar strings
:
$ strings DoNotTouch | grep HTB
1969-01-01 00:00:002069-01-01 00:00:00Chillin with SatanHellHTB{z1p_and_unz1p_ma_bruddahs}
$ strings DoNotTouch | grep -oE 'HTB{.*?}'
HTB{z1p_and_unz1p_ma_bruddahs}
Además, incluí todo el proceso en el programa en Go:
$ go run solve.go $WORDLISTS/rockyou.txt
[+] Stage: 500
[*] Starting brute force attack
[+] Found password: letmeinplease
[*] Running `strings` on file 'DoNotTouch'
[+] Flag: HTB{z1p_and_unz1p_ma_bruddahs}
El script completo se puede encontrar aquí: solve.go
.