In this blog post, I summarise my experience taking the Offsec Exploit Developer (OSED) course, including required knowledge, the exam, and my personal highlights.
Overview
The EXP-301 course, aka "Windows User Mode Exploit Development" (WUMED) is the last of Offsec's revamped Offensive Security Certified Expert (OSCE3) courses, and was released to refresh the low level exploit development portion of the old OSCE that has since been retired.
The course thoroughly covers the basics of x86 exploit development starting with 'vanilla' buffer overflows, egghunters, custom shellcoding, and gradually adding more challenging bypass techniques for basic security mechanisms such as DEP and ASLR, before finishing with format string vulnerabilities. Initially, where the OSCE taught the basics of vulnerability discovery through fuzzing, OSED focuses solely on reverse engineering using IDA Freeware.
Disclaimer: If you're currently doing the course and are just looking for some advice, feel free to jump straight to the General tips section.
What do I need to know?
I came into the course having completed the original PWK (pre-2020) which had a basic buffer overflow chapter, as well as the x86 Assembly Language and Shellcoding on Linux course from Pentester Academy, both of which were great prep material before starting EXP-301. Most of the content was new to me as I had limited experience of low level exploitation before this; I had followed the odd Corelan tutorial, and recreated some of the basic buffer overflow and SEH exploits for Windows XP, but not much else.
Before starting the labs, I would recommend getting familiar with reading and writing intel assembly as this will help throughout the course, especially when tackling the custom shellcoding and DEP modules. It will also help to have some experience reading C/C++ code and scripting exploits in Python 3. The Python code covered in the course isn't particularly complex, but it's good to be comfortable with the language.
What will I learn?
The EXP-301 covers the basics of reverse engineering and exploit development for Windows from the ground up. Whilst the course focuses solely on 32-bit exploitation, many of the concepts taught can be applied to 64-bit targets with some extra work. I would say this is a fair approach, as quite a few of the topics are complex enough to dig into for someone with limited prior experience.
The course starts where the old PWK left off with a buffer overflow exploit targeting the Sync Breeze application. Before jumping straight into this however, the introductory chapters provide an overview of x86 architecture and a primer on how to use WinDbg. Just as well, as you can expect to spend a lot of time staring at a debugger during EXP-301. From here, the course adds additional layers of complexity common to exploit development, including SEH, buffer space restrictions, DEP and ASLR. It then walks the student conceptually through various common bypass mechanisms before building out the proof-of-concept exploits in Python.
WinDbg and the free version of IDA Pro are the primary static and dynamic analysis tools used in EXP-301. As with their other courses, Offsec prioritises the core functionality of the tooling without really delving into the paid features. Although this means you miss out on several powerful utilities such as IDAPython, this decision helps keep the course accessible, as IDA Pro doesn't come cheap. Using the free edition, EXP-301 covers the process of decompiling a binary, synchronising its memory layout with WinDbg and locating vulnerabilities using both tools together in tandem. Anyone familiar with reverse engineering will know that this can feel like searching for a needle in a haystack at times, and whilst it's tricky to directly teach someone how to be a good reverse engineer, the course does explain the underlying mindset before letting you figure the rest out yourself.
Other featured tooling includes basic Metaspoit usage for building MSFvenom payloads and running Meterpreter listeners, but where the course shines in its insistence on writing your own custom tools and scripts, going as bare metal as crafting purpose built, position-independent shellcode in assembly. The custom shellcode module was one of my favourite in the course, as it helps you get comfortable with chaining together Win32 APIs, which previously I'd only worked with using higher level languages.
Towards the end, the course rounds off with format string vulnerabilities, and looks at how you can abuse them to obtain read and write primitives in memory. All in all, the final two chapters felt a bit detached from the rest of the course which is otherwise oriented around buffer overflow exploitation. That said, the kind of thinking applied is really interesting, and whilst the exploitation scenarios covered are less common nowadays, the principles taught can be applied to more complex bug classes.
For a more detailed breakdown on what is covered, check out the course syllabus here.
OSED exam
Based on the OSED exam guide, the OSED exam is as follows:
- 48-hour technical challenge
- 24-hour report time
- 3 x assignments worth 100 points total (2 x 30 points, 1 x 40 points)
- 60 points passing score
Overall, I found the OSED exam to be tough but fair. In line with the other 300-level exams, you can expect to encounter the course topics again but in more challenging ways. Whilst nothing particularly new will be thrown your way, expect to be challenged to think outside the box, and make sure you go in with a solid grasp of the fundamentals.
As with the other courses, do as many extra miles and challenges as you have time for. I personally didn't look too heavily outside of the course for practice, as all that you need is already covered in the modules. What helps is to practice and learn different approaches to achieve the same objective. For instance with DEP, it helps to be comfortable bypassing it using different Win32 APIs, or choosing an alternative DLL to source your ROP gadgets from. When writing your own shellcode, try chaining together different Win32 APIs, or build something completely different to what's taught. For reversing, it's good to practice with other smaller applications outside of the course. Signatus and QuoteDB from bmdyy are both good practice and will help to refine your reverse engineering methodology.
Needless to say, take breaks and step away from the exam when you need to, especially if you've been on the same task for a while. I find it helps to take the odd screenshot whilst in the middle of the exam, and then go back through the process once your exploits are finished to thoroughly document your approach.
A few days after submission, I got the confirmation through that I passed:
How are the labs?
The EXP-301 lab environment consists of a single Windows 10 developer VM with a selection of enterprise applications and tools for carrying out exploit development. This includes WinDbg, Visual Studio code, the SysInternals suite, and technique specific tools such as RP++. The remainder of the tooling can be installed on your own Linux based virtual machine. I personally used Kali Linux with VMware Fusion on a 2017 Intel MacBook Pro to cover the Metasploit framework tools which are also used in the course, however these can always be installed on any other compatible flavour of Linux based on personal preference.
During the exercises, you will be able to remotely access the Windows 10 developer machine over the lab VPN whilst following along with each chapter's content. Besides the chapter software, most chapters feature some additional programs for you to do extra miles with. This gives you time to get familiar with the exploit development process and how each tool works. I'd also recommend to have a go at scripting some of your own tools, especially for parts of the process which require more time. For example, creating a Python script which highlights bad characters in a blob of shellcode may come in handy.
Once you have completed each chapter's lab exercises and as many extra miles as you can, there are three challenge assignments at the end of the course. These are designed to reinforce all of the previous learning from each chapter through different tasks. In some cases, this may involve fully reverse engineering an application to build an exploit, or modifying an off-the-shelf PoC to obtain RCE on a more modern version of Windows. In my opinion, these are all well worth doing.
I would say the lab exercises are great for putting the theory into practice, but I found it useful to complete as many extra miles as possible as well. Most of the exercises can generally be completed by simply following along with the course videos and notes, but by themselves won't necessarily help you develop the creative, out-of-the-box thinking that you will need to succeed in the exam and as an exploit developer.
Personal highlights
For me there were a lot of high points in the course, including the DEP, ASLR and custom shellcode chapters. Most of the enjoyment I got from the challenges and exercises was from taking creative risks and watching them pay off, for instance when constructing a ROP chain or optimising shellcode by hand. Whilst you definitely get a sense of progression as you near the end of the course, there is still a lot of ground to cover before you can start applying your knowledge to writing modern exploits. That said, I would consider EXP-301 as a well-rounded starting point on that journey.
Once you have completed the chapter exercises and extra miles, the challenges at the end tie all of the course content together and offer indication of how prepared you are for the exam. Without spoiling them, I enjoyed tackling something that wasn't previously covered in the chapters and found it useful to work with more practice material ahead of the exam.
General tips
In no particular order, the following are tips and tricks that I picked up along the way whilst studying the EXP-301 course:
- When bypassing DEP, work through a few different methods of achieving the same outcome. This can be applied to your choice of Win32 API, the module you use to source your ROP gadgets or the gadgets themselves.
- Get creative with custom shellcode and build some things outside of course. Find ways to optimise your assembly code, and always make sure that it's null byte free and position independent.
- Write custom tooling to help automate parts of the exploit development process e.g., bad character identification, argument conversion, pushing strings to the stack, selection of ROP gadgets etc.
- Write each Python exploit out by hand to build the muscle memory with the language if you are not already proficient in it.
- Keep code snippets and proof-of-concept scripts in an accessible place where it can be easily substituted into code, modified and tested. I tend to keep all of my notes in Obsidian as it supports various formatting styles and code syntax.
- If you use Sublime Text, I recommend SublimeHighlight plugin, as it can be used to copy code in Rich Text Format (RTF). This helps with quickly copying and pasting any proof-of-concept code into the report whilst retaining its formatting.
- Post on the EXP-301 Discord channel for help or to discuss ideas and solutions. If you run into an issue, chances are that someone else has run into that same issue and posted about it.
What's next?
With the EXP-301 course completed and my OSCE3 journey at its end, there's a couple other Offsec courses I'm interested in looking at. Given I used the Learn One subscription, I still have several months of access to the PEN-210 content. Besides that, a long-term goal of mine has been to gradually work towards the EXP-401 course, aka OSEE. Given the knowledge gap between that and the content of EXP-301, looking at other platforms such as RET2 WarGames could be a decent stepping stone into 64-bit exploitation, and a good opportunity to skill up in Linux before pivoting back to Windows.