Everyone and their dog seems to want to use download and execute shellcode in their exploits. Even though this has some drawbacks:
- You need to create an .exe file on the system, which will very likely draw unwanted attention.
- You cannot use an API that downloads your file to a temporary location, because that will likely not retain the .exe extention.
- You need to make an assumption about where a safe place is to write your .exe file, which means you can guess wrong and the code fails.
- You need to store the string ‘.exe’ in the download & execute shellcode, which means this is 4 bytes larger.
- You need to spawn an extra process, which will very likely draw attention.
- You leave cleaning up the exploited process to the download & execute shellcode, which means this needs to be larger.
To get around these problems, I created download and LoadLibrary shellcode: a shellcode that will download a DLL file to a temporary file and load it into the exploited process using LoadLibrary. The benefits of this approach are:
- Smaller code.
- You can use the URLDownloadToCacheFileA API function in urlmon that downloads and saves your DLL to a temporary file, meaning you do not need to provide a location.
- No need to create an .exe file on the system: the extention of a DLL is irrelevant.
- No need to spawn an extra process.
- You can clean up the exploited process from the code in the DLL instead of the shellcode.
The size of the final shellcode depends on the length of the URL for your DLL. For most recent version of the code it is 138 bytes + the length of the URL. This is a pretty decent reduction from the average download and execute shellcodes of 200+ bytes (excluding the URL) that I found around the interwebs.
Project homepage:
http://code.google.com/p/w32-dl-loadlib-shellcode/


4 Comments to “Download and LoadLibrary shellcode released”
2010/01/11
Just worth pointing out CreateProcess does not require an .exe extension in order to run, it will run what ever file you give it, and there is a chance that if you have twatted the process through exploitation then your LoadLibrary might just cause the process to blow up more.
2010/01/11
Maybe I should have mentioned that I was assuming one would use WinExec because CreateProcess requires more complex arguments to be set-up, which costs even more then 4 bytes. While CreateProcess may allow you to create a process from a file without an .exe extention, I do not believe WinExec does.
LoadLibrary does indeed pose a larger risk of failing in the face of mayor corruption of the stack and/or heap. So, one should only use this shellcode if one is able to limit the damage to the stack and/or heap to areas that do not affect LoadLibrary or do a bit of clean-up when needed. It makes sense to automatically test your exploit works a large number of times to make sure you haven’t missed anything (but that goes for any exploit).
Mind you that this is not intended to be a complete replacement for download & execute shellcode but an alternative that may be better suited in some situations.
2010/01/11
WinExec doesn’t require it either, it is only ShellExecute which relies on the extension, just because that is how it works out what to do with the file.
2010/01/17
Fair enough, I had a look to see how small a shellcode I could make using WinExec when I remembered another reason why LoadLibrary shellcode is so much smaller: it only requires calls to two distinct functions; LoadLibrary & URLDownloadToCacheFileA. The code stores the two 16-bit hashes in the EDI register and it uses all other registers in the hash calculating code. So, there is no place where I can store a third hash for WinExec. I would need to rewrite the code to use the stack as additional storage, which would mean the code would become (a lot) larger. Switching to smaller hashes, so I can store all three in EDI is very likely to be impossible because URLDownloadToCacheFileA is found in urlmon.dll, which is not one of the first loaded modules. This means that collisions with other functions in modules loaded before urlmon are very likely and will cause the code to fail.