To help the attendees of my Brucon White Hat Shellcode workshop, I wrote a new program to generate simple shellcode. I’m releasing it now.
People regularly ask me for malware so they can test their security setup. First, that’s a bad idea, and second, you can do without.
Why is using malware a bad idea? It’s dangerous and not reliable. Say you use a trojan to test your sandbox. You notice that your machine is not compromised. But is it because your sandbox contained the trojan, or because the trojan failed to execute properly? It might surprise you, but there’s a lot of unreliable malware out in the wild.
So how can you reliably test your sandbox without risking infection, or even worse, have malware escape into your corporate network? Just use simple shellcode that creates a file in a location your sandbox should prevent, like system32.
To generate this shellcode with simple-shellcode-generator.py, create a text file (call it createfile.def) with these 2 lines:
kernel32.dll CreateFileA str 0x0 0x0 0x0 0x2 0x80 0x0 kernel32.dll CloseHandle eax
Each line in this definition file instructs the generator to generate assembler code to lookup the address of the WIN32 API function, and to call it with the arguments you provide. The first column defines the dll that contains the function to call, the second column is the actual API function, and the rest are arguments to this function. The arguments you provide are copied literally into the generated assembler code, except for 3 keywords.
Keyword int is used to represent any DWORD, it will result in the generation of a push 0x0.
Keyword str is used to reserve space for a string, and the address of the string is used as argument.
Keyword pint is user to reserve space for a DWORD, and the address of the DWORD is used as argument.
To generate our shellcode, issue this command:
simple-shellcode-generator.py -o createfile.asm createfile.def
This generates the following assembler code:
; Shellcode generated by simple-shellcode-generator.py ; Generated for NASM assembler (http://www.nasm.us) ; https://DidierStevens.com ; Use at your own risk ; ; History: ; 2011/09/23: generated BITS 32 KERNEL32_HASH equ 0x000D4E88 KERNEL32_NUMBER_OF_FUNCTIONS equ 2 KERNEL32_CREATEFILEA_HASH equ 0x00067746 KERNEL32_CLOSEHANDLE_HASH equ 0x00067E1A segment .text call geteip geteip: pop ebx ; Setup environment for kernel32.dll lea esi, [KERNEL32_FUNCTIONS_TABLE-geteip+ebx] push esi lea esi, [KERNEL32_HASHES_TABLE-geteip+ebx] push esi push KERNEL32_NUMBER_OF_FUNCTIONS push KERNEL32_HASH call LookupFunctions ; call to CreateFileA push 0x0 push 0x80 push 0x2 push 0x0 push 0x0 push 0x0 lea eax, [STRING1-geteip+ebx] push eax call [KERNEL32_CREATEFILEA-geteip+ebx] ; call to CloseHandle push eax call [KERNEL32_CLOSEHANDLE-geteip+ebx] ret %include "sc-api-functions.asm" KERNEL32_HASHES_TABLE: dd KERNEL32_CREATEFILEA_HASH dd KERNEL32_CLOSEHANDLE_HASH KERNEL32_FUNCTIONS_TABLE: KERNEL32_CREATEFILEA dd 0x00000000 KERNEL32_CLOSEHANDLE dd 0x00000000 STRING1: db "String 1", 0
You can replace “String 1” on line 57 with the file you want to create: “C:\Windows\System32\testfile.txt”.
This shellcode uses the library sc-api-functions.asm you can find in my shellcode repository.