【问题标题】:Generating Shellcode from an exe?从exe生成Shellcode?
【发布时间】:2016-11-04 20:00:34
【问题描述】:

所以最近我一直在学习低级编程语言(例如汇编,据我了解,它只是符号二进制)并且遇到了 Shellcoding(例如“\x4D...”等)。我发现您可以将 Shellcode 输入到 C/C++ 应用程序中然后执行它 - 我的问题是,是否可以从现有的 exe 应用程序生成 Shellcode,然后在 C/C++ 应用程序中使用这个生成的 Shellcode?我是否误解了 Shellcoding 的可能性?非常感谢 - 一个对低级编程知识非常有限的人

【问题讨论】:

  • 几点注意事项:汇编是机器码的符号形式(它是告诉CPU做什么的数字序列),二进制只是一种写法数字(不是特定于机器代码),而“\x4D”是一个十六进制符号,它也只是一种书写数字的方式(不是特定于 shellcode)。 Shellcode 只是用作漏洞利用负载的机器代码。

标签: c++ c exe shellcode


【解决方案1】:

是否可以从现有的 exe 应用程序生成 Shellcode,然后在 C/C++ 应用程序中使用生成的 Shellcode

Answer: No. Shellcode 是 base-independent,可执行的 PE 文件有大量的 header 等,你不能在执行某些操作之前执行它/

Shellcode - 这是一个非常大的问题。

首先,你需要知道kernel32、user32 libs等外部库的函数地址存储在Import Adress Table中,由windows-loader在启动时填充。所有内存工作都是通过地址完成的,即在编译阶段进行计算。所以需要自己找地址。

要从 shellcode 调用函数,您必须拥有自己的函数地址加载器。这个加载器必须加载kernel32.dll库,搜索GetProcAddress函数并填写IAT

你不知道你的shellcode会被加载到哪个地址,你可以从这样的代码中知道,调用“delta-offset”

call    delta
 delta:
pop     ebp
sub     ebp,offset delta

现在在 ebp 中是实际地址的偏移量,因此要获得函数地址的变量,您需要加上偏移量,例如:

lea eax, [variable]
add eax, ebp; adding a delta-offset
mov ecx, dword ptr DS:[eax]

要编译代码以供将来使用,您应该使用 FASM 之类的东西,编译后使用 WinHex 编辑器 -> 复制 -> 全部复制 -> GREP C 源代码

你会得到类似 "\x00\x28" 等的东西,要调用它,你需要为你的 shellcode 数组设置执行权限,并通过 jmp/call/etc 等命令处理程序更改 EIP

有一个例子显示在Windows系统的Hello, World MessageBox

# include <stdlib.h>
# include <stdio.h>
# include <string.h>

# include <windows.h>


int
main(void)
{
  char *shellcode = "\x33\xc9\x64\x8b\x49\x30\x8b\x49\x0c\x8b"
    "\x49\x1c\x8b\x59\x08\x8b\x41\x20\x8b\x09"
    "\x80\x78\x0c\x33\x75\xf2\x8b\xeb\x03\x6d"
    "\x3c\x8b\x6d\x78\x03\xeb\x8b\x45\x20\x03"
    "\xc3\x33\xd2\x8b\x34\x90\x03\xf3\x42\x81"
    "\x3e\x47\x65\x74\x50\x75\xf2\x81\x7e\x04"
    "\x72\x6f\x63\x41\x75\xe9\x8b\x75\x24\x03"
    "\xf3\x66\x8b\x14\x56\x8b\x75\x1c\x03\xf3"
    "\x8b\x74\x96\xfc\x03\xf3\x33\xff\x57\x68"
    "\x61\x72\x79\x41\x68\x4c\x69\x62\x72\x68"
    "\x4c\x6f\x61\x64\x54\x53\xff\xd6\x33\xc9"
    "\x57\x66\xb9\x33\x32\x51\x68\x75\x73\x65"
    "\x72\x54\xff\xd0\x57\x68\x6f\x78\x41\x01"
    "\xfe\x4c\x24\x03\x68\x61\x67\x65\x42\x68"
    "\x4d\x65\x73\x73\x54\x50\xff\xd6\x57\x68"
    "\x72\x6c\x64\x21\x68\x6f\x20\x57\x6f\x68"
    "\x48\x65\x6c\x6c\x8b\xcc\x57\x57\x51\x57"
    "\xff\xd0\x57\x68\x65\x73\x73\x01\xfe\x4c"
    "\x24\x03\x68\x50\x72\x6f\x63\x68\x45\x78"
    "\x69\x74\x54\x53\xff\xd6\x57\xff\xd0";

  DWORD why_must_this_variable;
  BOOL ret = VirtualProtect (shellcode, strlen(shellcode),
    PAGE_EXECUTE_READWRITE, &why_must_this_variable);

  if (!ret) {
    printf ("VirtualProtect\n");
    return EXIT_FAILURE;
  }

  printf("strlen(shellcode)=%d\n", strlen(shellcode));

  ((void (*)(void))shellcode)();

  return EXIT_SUCCESS;
}

您可能正在寻找 RunPE 算法。该算法可以在另一个内部执行PE可执行文件。您正在打开另一个进程、复制部分、填充 IAT 表并从新入口点恢复目标进程。这是一种代码注入技术,使用了我的恶意软件。所以我不会解释如何实现它

【讨论】:

  • 答案是 Windows 特定的,但问题不是。对于 Linux,答案恰恰相反。
【解决方案2】:

Shellcode 是用作漏洞利用有效负载的机器代码(例如buffer overflow)。根据所使用的漏洞,它可能有限制,例如最大长度,或不允许某些字节值(例如零)。对于 shellcode 的定义,没有万能的答案。

不过,一般来说:是的,原则上可以在 shellcode 中嵌入一个完整的程序。它可以采用小型包装器的形式(可能是用汇编手写的),将程序写入新的.exe 文件然后运行它,或者它可以使用更复杂的技术来替换内存中的当前程序。可能有一些自动化工具可以创建这种 shellcode,虽然我不知道具体的。

但是,你的问题的语气让我觉得你可能误解了一些重要的事情:

我发现你可以将 Shellcode 输入到 C/C++ 应用程序中然后执行它

这是一个错误,而不是功能。能够将新代码注入正在运行的程序中,而该程序并非专门允许这样做,这是一个重大的安全漏洞。在过去的几十年里,这类事情一直是许多安全漏洞的根源,开发人员花费了大量的精力来防止它发生。

如果可以将 shellcode 注入到程序中,那么程序就会被破坏。

【讨论】:

    猜你喜欢
    • 2019-12-03
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多