Hereβs a cool thing I figured out in position-independent code. I would rephrase the title as running position-independent code instead of shellcode. Check my previous article Executing Shellcode Directly where I used a minimal PE and pointed the AddressofEntryPoint to the beginning of the PIC.
So the goal is to run shellcode in C without any function pointers or any functions at all, not even a main function For example, this is all the code. I declare the variable name as βmainβ. I am using the Microsoftβs Visual C compiler with no parameters.
char main[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x31\xdb\x64\x8b\x7b\x30\x8b\x7f" "\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b\x77\x20\x8b\x3f\x80\x7e\x0c\x33" "\x75\xf2\x89\xc7\x03\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01" "\xc7\x89\xdd\x8b\x34\xaf\x01\xc6\x45\x81\x3e\x43\x72\x65\x61\x75" "\xf2\x81\x7e\x08\x6f\x63\x65\x73\x75\xe9\x8b\x7a\x24\x01\xc7\x66" "\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9" "\xb1\xff\x53\xe2\xfd\x68\x63\x61\x6c\x63\x89\xe2\x52\x52\x53\x53" "\x53\x53\x53\x53\x52\x53\xff\xd7";
After compiling it wonβt of course run. Why? Well, the initialized data will end up in the β.dataβ section.
This section has no execute permissions. So letβs add execute permissions and see.
Thatβs it! the position independent code executes nicely
Well, this seems a bit of a hassle to change flags each time you want to run shellcode. Letβs tell the linker to give Execute and Write permission to the β.dataβ section while linking.
/* * Author: @OsandaMalith * Website: https://osandamalith.com */ #pragma comment(linker,"/SECTION:.data,EW") char main[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x31\xdb\x64\x8b\x7b\x30\x8b\x7f" "\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b\x77\x20\x8b\x3f\x80\x7e\x0c\x33" "\x75\xf2\x89\xc7\x03\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01" "\xc7\x89\xdd\x8b\x34\xaf\x01\xc6\x45\x81\x3e\x43\x72\x65\x61\x75" "\xf2\x81\x7e\x08\x6f\x63\x65\x73\x75\xe9\x8b\x7a\x24\x01\xc7\x66" "\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9" "\xb1\xff\x53\xe2\xfd\x68\x63\x61\x6c\x63\x89\xe2\x52\x52\x53\x53" "\x53\x53\x53\x53\x52\x53\xff\xd7";
Another tricky way would be to place the shellcode in the β.rdataβ section and merge it with the β.textβ section. And of course, you can give Execute permission to the β.rdataβ section like we did before and execute as well.
/* * Author: @OsandaMalith * Website: https://osandamalith.com */ #pragma comment(linker,"/MERGE:.rdata=.text") char const main[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x31\xdb\x64\x8b\x7b\x30\x8b\x7f" "\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b\x77\x20\x8b\x3f\x80\x7e\x0c\x33" "\x75\xf2\x89\xc7\x03\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01" "\xc7\x89\xdd\x8b\x34\xaf\x01\xc6\x45\x81\x3e\x43\x72\x65\x61\x75" "\xf2\x81\x7e\x08\x6f\x63\x65\x73\x75\xe9\x8b\x7a\x24\x01\xc7\x66" "\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9" "\xb1\xff\x53\xe2\xfd\x68\x63\x61\x6c\x63\x89\xe2\x52\x52\x53\x53" "\x53\x53\x53\x53\x52\x53\xff\xd7";
Now if you see our code is merged in the β.textβ section and it will execute nicely.
You can place the shellcode directly in the β.textβ without modifying the PE structure like this. Thanks to @yair_omer for mentioning this.
#pragma section(".text") __declspec(allocate(".text")) char main[] = "\x90\x90\x90\x90\x90\x90\x90\x90\x31\xdb\x64\x8b\x7b\x30\x8b\x7f" "\x0c\x8b\x7f\x1c\x8b\x47\x08\x8b\x77\x20\x8b\x3f\x80\x7e\x0c\x33" "\x75\xf2\x89\xc7\x03\x78\x3c\x8b\x57\x78\x01\xc2\x8b\x7a\x20\x01" "\xc7\x89\xdd\x8b\x34\xaf\x01\xc6\x45\x81\x3e\x43\x72\x65\x61\x75" "\xf2\x81\x7e\x08\x6f\x63\x65\x73\x75\xe9\x8b\x7a\x24\x01\xc7\x66" "\x8b\x2c\x6f\x8b\x7a\x1c\x01\xc7\x8b\x7c\xaf\xfc\x01\xc7\x89\xd9" "\xb1\xff\x53\xe2\xfd\x68\x63\x61\x6c\x63\x89\xe2\x52\x52\x53\x53" "\x53\x53\x53\x53\x52\x53\xff\xd7";
You can also write shellcode in any number base. For example in decimals:
/* * Author: @OsandaMalith * Website: https://osandamalith.com */ #pragma comment(linker,"/SECTION:.data,EW") int main[] = { -1869574000, -1869574000, -1956324559, 2139828347, 478120716, -1962391669, 1066082423, 856456832, -947260811, -1958971389, -1040091049, 18905739, -1948415545, -972968140, 1128169797, 1969317234, 142508530, 1936024431, 2055989621, 1724317988, -1955648373, -956228486, -55608181, -645282047, -497811535, 1633904893, -494312596, 1397969490, 1397969747, -671132846 };
This is in octal.
/* * Author: @OsandaMalith * Website: https://osandamalith.com */ #pragma comment(linker,"/SECTION:.data,EW") int main[] = { 022044110220, 022044110220, 021331155461, 017742630173, 03437705414, 021302043613, 07742620167, 06303077200, 030742371165, 021317074003, 030200274127, 0110075213, 021367304707, 030600327464, 010317500505, 016530262562, 01037500762, 016331261557, 017242764565, 014661600444, 021333626213, 030700216172, 037453676213, 033142343401, 034224777661, 014130664375, 034242261554, 012324651122, 012324651523, 032777651522 };
Under GCC you donβt need to change section permissions, it will automatically place in the β.textβ section. Make sure your code is position indepdent or else it wonβt work on other Windows systems due to dynamic addressing of DLLs. In this way, you can execute your shellcode without any function pointers. You can check out some of my public shellcodes from here.