OSED Prep Series #3: Writing Custom Shellcode

Content

  1. Why write custom shellcode?
  2. The Manual Way
  3. The Automated Way
  • wait where is #1 and #2? #1 will cover basic buffer overflow and #2 will cover SEH based attacks. But those will come later.

1) Why write custom shellcode?

The most practical reason is in the OSED Exam Guide. It is part of the exam.

https://help.offsec.com/hc/en-us/articles/360052977212-EXP-301-Windows-User-Mode-Exploit-Development-OSED-Exam-Guide

Second, you control what APIs to call and the asm instructions you use. Sometimes you are “restricted” on what APIs you can use or you may want to achieve different functionalities other than spawning calc.exe or executing a reverse shell. You can also (most probably) avoid bad chars right from the get go, so you don’t have to worry about pesky things like ROP decoders.

Third, you could use automated tools such as msfvenom or epi05’s shellcoder.py (which is great by the way) but you end up not understanding how it works and when something dont work out (and they will), you will be left unable to troubleshoot why. Oh and if you are using WriteProcessMemory to bypass DEP (which is something i go through here >insert link!), you cant use a msfvenom payload because it comes with a decoder stub which fails because your “codecave” is set back to non-write after WriteProcessMemory executes.

Last, you feel leet i guess?

2) The Manual Way

In summary, our shellcode should do the following:

  1. Resolve kernel32.dll dynamically (kernel32.dll will be imported by your target program because it is the foundation to many other APIs)
  2. Resolve the memory addresses of LoadLibrary and GetProcAddress (which are part of kernel32.dll)
    • LoadLibrary allows you to import other dlls should you need and GetProcAddress allows you to resolve APIs symbols (and their address)
  3. acsa

Note: For any calling convention on a 32-bit system, the EAX, EDX, and ECX registers are considered volatile, which means they can be clobbered during a function call. Use EAX, EDX and ECX for temporal manipulation operations since these are unlikely to have any effects beyond the function.

There are a lot of WinAPIs out there that do specific things like creating a new process (CreateProcessA). These APIs can either be found inside the usual kernel32.dll, or can be found in other places such as user32.dll, userenv.dll, advapi32.dll for example.

For the purpose of this OSED prep series, we will focus on the essentials.