if you have a bit of extra space to work with, sometimes it’s just easier to encode shellcode in this way rather than figure out the badchars. or, you might only be able to use alphanumerics. either way, msfvenom has you covered… with a little extra effort needed on our part
here’s the alphanumeric encoding option in action:
msfvenom <whatever> -e x86/alpha_mixed
but what you will actually get is an alphanumeric string with a few instructions of non-alphanumeric assembler at the front – hardly ideal!
let’s have a closer look:
egghunter.rb -e HX0R -a x86 -p windows -f raw | msfvenom –payload – -a x86 –platform windows -e x86/alpha_mixed -f raw | shellnoob –intel –from-bin – –to-asm –
mov eax,esp # .byte 0x89,0xe0 # copy esp
fxch st(5) # .byte 0xd9,0xcd #
fnstenv [eax-0xc] # .byte 0xd9,0x70,0xf4 # dump state
pop esi # .byte 0x5e # eip is now at esp, pop it
6 of these the first 7 EIP-finding bytes of the alphanum decoder aren’t alphanumeric, which is defeating the whole point of the alphanumeric encoder!
these FNSTENV instruction helps the decoder find the location of EIP. the location of EIP is necessary so the alphanum decoder can calculate where to start its decoding from. the behavior of these EIP-finding instructions is rather detrimental to the stack, and so if you are jumping to ESP then you will need some NOPs in front of your shellcode, otherwise the FNSTENV instruction will cause corruption. on x86, this FNSTENV instruction writes x1C bytes to ESP-xC (so that ESP then points to EIP, which can be popped off), which means that your instructions need to be x10 past where ESP points at to get clear of the write (hence 16 NOPs). it confused me at first that a this state-saving operation on ESP would cause data to ‘grow upwards’, but then i realized that FNSTENV isn’t a ‘save state to stack’ instruction (like PUSHAD/PUSHFD), it’s just a ‘dump state at address’ instruction (in this case esp-xC)!
but getting back on topic… there is a neat way of eradicating this non-alphanumeric preamble, using msfvenom’s ‘BufferRegister’ option
if you can get a register to point exactly to EXACTLY the start of your shellcode [no nop sleds allowed!], then you’re golden
here’s an example where we know that when we reach our shellcode, EDI will point directly at it (probably because we did a JMP EDI):
egghunter.rb -e HX0R -a x86 -p windows -f raw | msfvenom –payload – -a x86 –platform windows -e x86/alpha_mixed -f raw BufferRegister=EDI
the first thing this shellcode does is save EDI, so it knows where it started from (as we can see, courtesy of shellnoob):
push edi # .byte 0x57 # .ascii “57”
from there it can work out where to start decoding (EDI + something)