本人首发于先知社区
手工shellcode注入
0x01
- 这篇文章将介绍如何添加我们的shellcode而不增加大小或更改功能的来对合法的可执行文件进行添加后门。
- 我们可以使用自己的Shellcode注入到特定的可执行文件,而又不增加可执行文件的大小或更改其预期功能,并使其难以检测。
为了保证shellcode和程序的精简
- shellcode不会经过任何编码器的混淆
- 文件大小保持不变。
- 后门程序的功能不受影响
0x02
ASLR
- ASLR(Address space layout randomization)是一种针对缓冲区溢出的安全保护技术,通过对堆、栈、共享库映射等线性区布局的随机化,通过增加攻击者预测目的地址的难度,防止攻击者直接定位攻击代码位置,达到阻止溢出攻击的目的。
所以我们需要先检查程序是否开启了ASLR
PS脚本地址:https://github.com/NetSPI/PESecurity
看来这是一个好靶子。
0x03
实现过程
在代码区段中创建新的节头,或在内存中找到合适的位置植入我们的Shell代码,这两种方法均在下面演示。
在程序执行开始时从堆栈中复制操作码。
将这些指令替换为我们自己的操作码,以将应用程序的执行流劫持到内存中的所需位置。
将shellcode添加到该内存位置。
将寄存器设置回第一步中复制的堆栈,以正常执行流程。
添加新的区段
该方法背后的原理是在PE文件中创建一个新的区段,在新创建的区段中添加我们的shellcode,然后指向该部分的执行流程。可以使用诸如LordPE之类的工具来修改区段表。
- 用Lord PE打开目标程序,并在区段表底部添加节标题(这里是.demo)
- 将虚拟大小和原始大小相加1000字节。请注意,十六进制为1000(十进制为4096字节)。
- 使该区段可执行,因为我们必须将Shellcode放在此节中,因此它必须是可读可写可执行的。
- 将文件另存为原始文件。
现在执行该文件,它将无法运行,因为我们添加了一个1000h字节的新段,但是该区段为空。
所以只要我们填充了该区段就能正常执行。
所以我们在文件末尾添加1000h字节,因为现在文件包含一个1000字节的区段,但该部分为空,我们必须用什么填充它,现在选择用null(00)填充它。如下所示,使用任何十六进制编辑器在文件末尾添加1000个十六进制字节。
添加后保存并运行,此时程序就可以正常运行了(确保程序可执行后进入下一步)。
劫持执行流程
现在在Ollydbg中执行以下操作:转到内存部分,然后双击PE标头。
我们可以看到我们的新部分 .demo 已添加了指定的权限。下一步是将程序的执行流劫持到我们新添加的 .demo 段中。当我们执行程序时,它应指向 要放置shellcode的代码的.demo 部分。
首先复制前3个操作码到记事本,稍后在恢复执行流程时将需要它们。 我们复制 .demo的起始地址00412000 打开Ollydbg的程序,更换程序起始地址代码为JMP 00412000。
现在保存修改后的文件,此时文件的执行流程已经被劫持了。现在重新用Ollydbg打开,右键跟随jmp,你就会发现程序已经被劫持到我们所创建的那一片全为00的了。
msfvenom -p windows/messagebox text=”it’s demo” -f hex
右键复制到可执行文件,此时会进入数据块,使用msf生成payload,复制,在Ollydbg中选中那一块00段 右键 > 二进制 >二进制粘贴然后保存文件
此时修改后的程序就能成功执行我们的shellcode了。弹框证明。
此时shellcode已被执行,我们应该恢复程序正常的执行流程。
- 将shellcode最后一句跳转改为nop.
- 使用popfd,popod进行恢复堆栈的操作。
- 然后将原程序起始位置的汇编码复制到这里。
- 最后跳转回原来的执行地址。
- 保存文件,程序应能正常工作并保留原有功能。
* 此时我们算是初步完成了,不过由于添加了新的区段导致了程序体积变大,所以我们会用另一种办法解决这个问题 *
事实上虽然程序大小有变化,但是我们可以无限制的放入shellcode,即我们可以使用复杂的shellcode,这将会对bypass AV有帮助。
代码空洞
代码空洞是程序存储器中的空块,可用于注入shellcode。我们可以使用现有的代码洞来植入我们的shellcode。我们几乎可以在任何PE中找到不同大小的代码空洞。代码空洞的大小很重要! 我们希望代码空洞大于我们的shellcode,以便我们可以注入shellcode,而不必将其拆分为较小的块。
在代码空洞中注入shellcode是不会影响程序大小的,唯一需要注意的是shellcode应尽可能的小。
在kali中使用cave_miner检查原程序(未经修改)是否存在代码空洞。
1 | cave_miner search /root/Hash.exe #可用--size 筛选符合大小的空洞,适用于空洞特别多的程序。 |
在这里我们有一个899字节的空洞,就决定是它了。
记下空洞的虚拟地址。虚拟地址是洞穴的起始地址。我们将通过跳转到虚拟地址来劫持执行流程。现在我们需要将shellcode植入到空洞中。在这里可以看到代码洞穴仅是可读的,我们必须使其可写和可执行才能执行我们的shellcode。我们通过LORDPE来修改。
在用户交互时触发Shellcode
现在我们有了一个可以使用的代码空洞,所以就决定把shellcode放这里了。
此次汇编代码改为跳转到我们得到的空洞地址:jmp 0041123d ,保存
再次用Ollydbg打开,跟随jmp到我们的代码空洞。
右键>复制到可执行文件>选择,然后复制shellcode,右键>二进制>二进制粘贴
然后最后一句还是改为nop,然后添加popfd,popad,以恢复堆栈,然后保存。
如能正常执行shellcode即进入下一步,跳转回程序执行流程。
最后完整还原代码如图。
在文件大小不变的情况下,实现了shellcode注入,且程序功能不受影响。
参考链接:https://haiderm.com/fully-undetectable-backdooring-pe-file