*This course review is written rather differently from others you may have read. I doubt I need to re-invent the wheel here; build on the great reviews written by folks such as Space Raccoon, nop (allegedly guilty of breaking the Offsec mail server by accident), and epi052. Rather, this review takes a slightly more philosophical approach.
“And now, when we try to run our msfvenom-encoded shell, it fails. It dawns on us that we have to write our own ROP decoder. And we have strict space limits in the code cave that WriteProcessMemory points to.”Adapted from EXP-301, when trying to introduce yet another new technique.
What we see on exploit-db and numerous articles on zero-days is not representative of the amount of sleep and patience lost in the midst of reverse engineering and exploit development. Thankfully, with EXP-301, one gets a whiff of how hard it actually is.
Before We Learn How to Fly, We Must Learn How to Run. But Before We Learn How to Run, We Must Learn How to Walk.
Starting from exploit-db is a reasonable starting point. That was how I first got to know about exploit development, through the then-PWK course (today it has since been rebranded as PEN-200). PEN-200 also taught stack-based buffer overflows. Of course, this was eons ago; Offsec recognises that finding an application being vulnerable to just stack-based BOF without defences is unrealistic, resulting in buffer overflows have been moved from PEN-200 to the common library as part of modernising the PEN-200 syllabus..
But most applications today come with defences such as Data Execution Protection (DEP) on Windows (equivalent to the NX bit in Linux), Address Space Layout Randomisation (ASLR), buffer security checks like the /GS flag and Structured Exception Handling. These mitigations have been around for a long time, necessitating any attacker who intends to develop exploits against Windows binaries to learn how these techniques can be bypassed. This sets the stage for EXP-301.
But the world of exploit development is far more than just these. Even laypersons are empowered with more powerful mitigations today. For instance, on a Windows 11 Professional machine, one can enable not just DEP and ASLR, but Control Flow Guard (CFG) too (CFG is not part of the EXP-301 course). Even if the developer forgot to compile an application with DEP and ASLR, Windows can impose mandatory protections on these binaries. And this is only scratching the surface, at least according to how Offsec thinks of their course line-up.
Similar views are shared by other course providers who provide exploit development training, such as Corelan’s Boot Camp. Corelan also qualifies their Boot Camp as such:
We believe it is important to start the course by explaining the basics of stack buffer overflows and exploit writing, but this is most certainly not “your average” entry level course. In fact, this is a true bootcamp and one of the finest and most advanced courses you will find on Win32 stack based exploit development.
Corelan’s description of Corelan’s Boot Camphttps://www.corelan-training.com/index.php/training/bootcamp/
This is not fear-mongering. Exploit development is an arduous journey. Many great infosec professionals have been diverted, exhausted and burnt out through this journey.
Assembling Pain (pun intended)
In exploit development, we often have to write raw Assembly (ASM) instructions You will see this covered in EXP-301 through the Keystone Engine. It is probably a great relief for those who thought instructions must be assembled with our trusty NASM shell only.
Writing in ASM is not intimidating once one gets over the initial psychological hurdle. This is especially because feedback in ASM is in the debugger once these instructions are being executed. For me, I did an introductory one-day crash course on x86 shellcoding through our local infosec community, Division 0. One day is generally enough to overcome such jitters.
Probably the harder part in writing such low-level language is the documentation maze when calling low-level APIs.
It is easier to illustrate this with an example. Suppose we want to write custom shellcode to create a new service (for persistence reasons). This requires the use of the CreateServiceA API, whose documentation is found on MSDN. The function prototype is as follows:
SC_HANDLE CreateServiceA( [in] SC_HANDLE hSCManager, [in] LPCSTR lpServiceName, [in, optional] LPCSTR lpDisplayName, [in] DWORD dwDesiredAccess, [in] DWORD dwServiceType, [in] DWORD dwStartType, [in] DWORD dwErrorControl, [in, optional] LPCSTR lpBinaryPathName, [in, optional] LPCSTR lpLoadOrderGroup, [out, optional] LPDWORD lpdwTagId, [in, optional] LPCSTR lpDependencies, [in, optional] LPCSTR lpServiceStartName, [in, optional] LPCSTR lpPassword );
Microsoft is detailed here in specifying the various values required for important, non-optional parameters, even if the API looks intimidating. Also, CreateServiceA is likely to be used by many developers, which aids the exploit developer obtain the right values for the API.
This is not the case for all APIs. An API such as this does not explain the use of a few unnamed parameters, leaving the shellcoder with an extra task of finding third-party resources in the hope someone has had a similar issue and knows how the API should be called. If you encounter such an API in your shellcoding journey, you need to Google harder. You will need this skill, which is thankfully also taught in PEN-300 when using Win32 APIs to write AV bypasses.
So… If It’s So Hard, Did Offsec Do a Good Job Teaching This?
First of all, I think the course coverage is great. There is not always an agreement on how exploit development should be covered. In fact, the old OSCE (which I did) took a fuzzing approach that differs from the current EXP-301, which include copious amounts of reverse engineering. Reading Corelan would suggest certain techniques being covered that EXP-301 does not describe. Examples include Venetian shellcode, using the PUSHAD technique for ROP chains. But in the same vein, EXP-301 covers custom shellcoding and highlights its usefulness in DEP bypasses through a few exercises, as well as explained the exploit development process using WriteProcessMemory as the method to bypass DEP, in full.
This is perhaps a long-winded way of highlighting that even the basics of exploit development can be extensive. Hence, the focus of such a course should instead be oriented around providing the student the opportunity to learn for themselves, so that they can navigate by themselves in this intimidating, highly area of infosec. Teaching exploit development is hard, and Offsec nailed this.
Mom, the Application “Hacks Itself”!
One of the most fascinating aspects in exploit development is “return-oriented programming” (ROP). For laypersons, ChatGPT provides an excellent analogy to ROP chains.
Thankfully, ChatGPT still cannot construct great ROP chains yet. ROP chaining highlights an extremely important point in infosec: creativity is extremely important for any infosec professional who works in the offensive domain; ROP chaining differs from application to application, bad characters and silly gadgets can throw unexpected spanners in the works, requiring creative workarounds. Yet, it is so cool watching (on a debugger) how an application uses its own code, starts facilitating the attacker, and eventually resulting in our shellcode being executed. It’s art. Follow a DEP bypass tutorial and watch this unfold before your very eyes. Then, do it yourself and watch yourself control the magic, instruction by instruction.
Like any course review, people read them to mentally prepare for the exam. Let me provide some tips. You probably already know them, but re-iterating them in context is helpful.
- Prepare a good theme for WinDbg. An example of a good theme is as follows: https://github.com/0xbad53c/osed-tools/blob/main/dark-green-x64.wew. Immunity-like for Immunity fans.
- Practice at LEAST some of the extra miles. Improve your DEP bypass skills. The more you ROP, the better you ROP.
- Learn how to read MSDN and re-create a bind shell, through reading MSDN. (This is one of the extra miles.)
- Lurk the Discord channel for exp-301. There are copious amounts of questions which can speed up your learning. I myself found common cause with other EXP-301 students who faced similar issues!
If you have taken the OSCP and OSEP examinations, you will find the OSED exam different. The emphasis moves away from speed at pwning objectives to being able to stay mentally composed in large-sounding assignments. A few useful tips for the first-time exam taker when being faced with such assignments.
- Break the assignment down into smaller parts.
- Since you must explain the use of the code written, it may help writing key points for the report in parallel with the assignments. Some insert copious amounts of in-line comments to explain their code. Do what you must to explain the key lines. When in doubt, explain it.
- Make sure you know how to use your calculator to perform simple arithmetic tasks. Overflow math, negation e.t.c.. You can use WinDbg’s calculator but I used a separate calculator app on my host machine (default calculator). By that extension, keep converters handy. ASCII to hex and vice-versa, little endian writing (I used a piece of paper just to copy bytes from my screen, but you can prepare Cyberchef or any other magic.)
- Your exploits will keep failing and you’ll keep handling errors. Keep calm, for the path to a successful exploit is usually filled with a lot of prior failures. Miscalculated offsets, writing wrong gadgets, POP-ping the wrong addresses by accident, having shellcode being mangled out of the blue by a stray gadget. All of these can happen, and will happen.
- In line with breaking down the assignment into smaller parts, take each part at a steady pace. I went one hour, and then some minutes of break (having some tea helps, because it was an hourly trip to the restroom thanks to the diuretics!). I wasn’t entirely strict with this, slowly making longer runs, but that is OK.
Is it Worth Trying Harder Through OSED for OSCE3?
To be fair, most people I know in infosec will never touch a single line of ASM ever, such as security engineers, SOC analysts and risk analysts. Even web application pentesters will hardly touch ASM. But let us not be so myopic.
At times, simply reading courses directly relevant to present work is self-defeating for one’s self-development and career transition possibilities. Rather, take these courses as an opportunity to develop fluency in different areas of infosec for further development. All of us are human. Humans can eventually become bored in a domain they have worked in in many years. Humans can also seek opportunity in a different domain. Being fluent in low-level languages, for instance, certainly enables a better appreciation for the world of Win32 APIs compared to say, a web application developer, whose world is likely much more abstract, full of frameworks, to solve a different type and complexity of problem. Appreciating Win32 APIs better can in turn, lead to an interest in DFIR, which could facilitate a red-to-blue mid-career transition. Many infosec friends I know have transitioned across different fields. But to be able to recognise doors and open them, one must first be able to read the room, and experiment with the features of the room.
To put self-development into perspective, I used a timeline of an average career person to explain why careers are not likely to be based on only one skill or ability.
After viewing this timeline, let us answer these questions:
- What types of work do I want to explore?
- What is the probability I will eventually get bored of my current work?
This discussion is pertinent for those in infosec because there is so much to cover. Infosec is one of the industries where there is likely so much knowledge and content that even if one studied the same domain for five years and 10 hours per day, one cannot cover everything (adapted from Morten’s comments). But the ability to learn means the ability to chart one’s career trajectory and transition, experimenting with many different areas of infosec. Sometimes, in the murkiness of day-to-day work, we forget the longer-term game: being able to explore different areas of work, and stretch career longevity.
My own reasons were somewhat less noble, though. My first motivation was personal — it was a personal target for me to want to at least be able to say I have a certain level of skill and proficiency in a variety of offensive infosec skills (web, infra, binary). The process of wanting a coin made me go through a journey of offensive infosec discovery.
I simply present two different motivations why one could consider taking an exploit development course. Unlike web application and infrastructure consulting opportunities, it is rarer to find opportunities to perform exploit development on a day-to-day basis, which indeed raises valid concerns on whether such a course will be worth the money.
Among the trio of reviews, this is probably the most philosophical, and probably for good reason, for it was the OSED for me that unlocked the OSCE3. Occasionally, it is important to reflect on the philosophical underpinnings behind our career and education choices. Why did we first pick up ethical hacking skills? What are my inner motivations to continue on my infosec journey? And what must I do to do justice to my own career? Sometimes we do not have answers to these questions ourselves. And that’s normal. But the only way to find answers to these questions is to try to search for them.