An Utsusemi of Keramas

Tales of security research, penetration testing, red teaming, and general hacking shenanigans.

14 October 2018

Non-alphanumeric characters in my alphanumeric encoded payload - Exploration with NNM 7.53

by Keramas

After watching the Defcon 16 talk by Muts in regard to the 0-day they discovered in the NNM service and how they overcame all the crazy obstacles they were faced with, I wanted to learn more about this and explore it in-depth.

DEFCON 16: BackTrack Foo - From bug to 0day:
https://www.youtube.com/watch?v=gHISpAZiAm0

Original PoC:
https://www.offensive-security.com/0day/hp-nnm-ov.py.txt

While I will not be doing a full walkthrough of the exploit process as it is explained in depth in the DC16 talk (I highly recommend watching the video!) as well as other articles, I just wanted to share some learning that took place during my studies.

To summarize the difficulties of writing this exploit, while it appeared to be a simple SEH overwrite, it became much more complicated due to a severely restricted character set. This means:

-Need to find a POP POP RET address that conforms to only the characters that can be used.
-Cannot use an egghunter as it is. It will need to be encoded.

The encoding process is essentially witchcraft, and there is a great explanation on the process by Vellosec:
https://vellosec.net/2018/08/carving-shellcode-using-restrictive-character-sets/

Based on this encoding technique, I created a script to facilitate the encoding process when using Matt Miller's 32 byte egghunter shellcode:
https://github.com/Keramas/EgghunterShellcodeCarver

In order to study this exploit, I spun up a Windows 2003 SP2 server and found an ISO for NNM. However, I discovered that the version I found and installed was version 7.53, which was not the exact version in the original PoC.

Using the following script based off of the PoC, there was an issue after execution was redirected to my reverse shell shellcode.



In the original PoC, a bind shell payload was delivered at the very end of the GET request. However, in version 7.53, this is not possible as the length of the data sent at the end of the request is checked and limited to around 150 bytes in length, which is not nearly long enough for an encoded payload.




The payload at the end did not have to follow the same restricted character set, but now it is not possible to place a payload there. It now needs to be moved somewhere into the forefront of the buffer, and it needs to adhere to the strict character rules.

Alphanumeric shellcode to the rescue! Or so I thought...



Uh, those aren't alphanumeric, msfvenom. What gives? When using msfvenom to create an alphanumeric payload, the first couple of bytes are actually not alphanumeric. This is because these bytes are "needed in order to find the payloads absolute location in memory and obtain a fully position-independent shellcode". Due to this, we can't use this payload as-is because these bytes are not in the good character set, and it will disrupt the exploit.

Well, we can just encode it using the same SUB encoding method used for the egghunter shellcode to carve this shellcode into EAX, but there is a better way which results in less of a headache.

Luckily msfvenom has an argument that can be used to eliminate this as long as we know the exact address where our shellcode begins. (Source: https://www.offensive-security.com/metasploit-unleashed/alphanumeric-shellcode/)



Let's look at the instructions for Matt Miller's egghunter code.

You'll notice that once the egg is found, the final instruction is JMP EDI.




Since we know that the beginning of our shellcode will be at the address where EDI points to, we can tell msfvenom this by using the following syntax in our command:

BufferRegister=EDI

This removes the need to add those non-alphanumeric characters to the beginning of our payload, and our payload can then be 100% alphanumeric.



Modifying the script, we can put the egg and our reverse shell shellcode into the beginning of our buffer, which results in a successful reverse shell being sent back to the attacker machine.



Once the egghunter locates our egg, it jumps to EDI, which is where our reverse shell shellcode is located at the very beginning of our crash buffer. The payload is composed of allowable characters, and runs smoothly kicking us back a reverse shell.



Conclusion & takeaway:
When using an egghunter such as Matt Miller's, it is possible to easily use a fully alphanumeric encoded msfvenom payload by specifying that the shellcode start is located at EDI.

While this may be common knowledge, I spent a lot of time yesterday working on this exploit by myself and discovering this, so I hope this blog post comes in handy to anyone else who is curious and comes across this.









tags: