反病毒攻防研究第015篇:病毒感染标志的添加

一、前言

对于感染型病毒而言,如果对同一个目标文件多次进行感染,有可能导致目标文件损坏,使得无法执行。所以病毒程序往往会在第一次感染时对目标文件写进一个感染标志,这样在第二次遇到该文件时,首先判断一下该文件中是否包含有感染标志,如果有,则不再感染,如果没有感染标志则进行感染(关于文件的感染,可参见《反病毒攻防研究第004篇:利用缝隙实现代码的植入》《反病毒攻防研究第005篇:添加节区实现代码的植入》)。所谓的感染标志其实就是在PE文件中无关紧要的位置写入的一个字符串,所以感染标志的添加、读取与判断操作,其实就是基本的文件读写操作。

二、感染标志的添加

在PE文件结构中存在着许多不实用的字段,比如在IMAGE_DOS_HEADER中,只有e_magic与e_lfanew这两个字段才是重要的,前者用于验证本文件是否为PE文件,后者保存着PE文件的偏移位置。因此可以从第二个字段,即e_cblp(Bytes on last page of file)开始,写入我们的感染标志。这里将该标志设定为“Hack”这四个字符。需要注意的是,将感染标志添加到文件中,应当首先将“Hack”转化为十六进制数值,然后再反向写入(小端显示),代码如下:

#define VIRUSFLAG 0x6b636148         // 感染标志,这里为“Hack”
// 感染标志的写入。三个参数分别为:欲感染文件的句柄、欲写入感染标志的位置
// 以及感染标志
BOOL AddSig(HANDLE hFile, DWORD dwAddr, DWORD dwSig)
{
    DWORD dwNum = 0;
    // 在文件中设置读写位置
    SetFilePointer(hFile, dwAddr, 0, FILE_BEGIN);
    // 写入感染标志
    if(WriteFile(hFile, &dwSig, sizeof(DWORD), &dwNum, NULL))
    {
        MessageBox(NULL, "感染标志添加成功!", "提示", MB_OK);
        return TRUE;
    }
    else
    {
        MessageBox(NULL, "感染标志添加失败!", "提示", MB_OK);
        return FALSE;
    }
}

然后编写检测感染标志的代码:

// 感染标志检测
BOOL CheckSig(HANDLE hFile, DWORD dwAddr, DWORD dwSig)
{
    DWORD dwSigNum = 0;
    DWORD dwNum = 0;

    SetFilePointer(hFile, dwAddr, 0, FILE_BEGIN);
    ReadFile(hFile, &dwSigNum, sizeof(DWORD), &dwNum, NULL);

    if(dwSigNum == dwSig)
    {
        return TRUE;
    }

    return FALSE;
}

我们需要令“病毒”程序在每次感染前先调用CheckSig()函数,依据其返回值来判断目标文件是否已经被感染过,然后再决定是否需要进行感染。主函数代码如下:

#include <windows.h>
#define FILENAME "helloworld.exe"    // 欲添加感染标志的文件名
#define offsetof(struct_t,member) (size_t)&(((struct_t *)0)-> member)
int main()
{
    HANDLE hFile = NULL;
    hFile = CreateFile(FILENAME,
                       GENERIC_READ | GENERIC_WRITE,
                       FILE_SHARE_READ,
                       NULL,
                       OPEN_EXISTING,
                       FILE_ATTRIBUTE_NORMAL,
                       NULL);
    if(CheckSig(hFile, offsetof(IMAGE_DOS_HEADER, e_cblp), VIRUSFLAG))
    {
        MessageBox(NULL, "本文件已经被感染过!", "提示", MB_OK);
        return -1;
    }
    AddSig(hFile, offsetof(IMAGE_DOS_HEADER, e_cblp), VIRUSFLAG);

    return 0;
}

程序将感染标志写入了IMAGE_DOS_HEADER中的e_cblp位置,它不会对程序的执行产生任何影响。这里需要说明的是,程序中我们使用了offsetof()这个宏,它本来是被定义在stddef.h中的,这里我将其拿出来专门定义。这个宏的作用是求某个结构体的特定成员在结构体里面的偏移量,对于本程序来说就是求e_cblp在IMAGE_DOS_HEADER中的偏移,也就是2(因为它之前的e_magic占用了两个字节)。

这里给大家分析一下(size_t)&(((struct_t*)0)-> member)的意义。首先,(struct_t *)0是一个指向struct_t类型(本程序中为IMAGE_DOS_HEADER)的指针,其指针值为 0,所以其作用就是把从地址 0 开始的存储空间映射为一个struct_t类型的对象。((struct_t *)0)-> member是访问类型中的成员member(本程序中为e_cblp),相应地 &((struct_t *)0)->
member) 就是返回这个成员的地址。由于对象的起始地址为 0,所以成员的地址其实就是相对于对象首地址的成员的偏移地址。最后再通过类型转换,转换为 size_t 类型(32位是unsigned int,64位是long unsigned int)。

三、程序测试

为了测试我们的程序,这里依旧使用《反病毒攻防研究第004篇:利用缝隙实现代码的植入》中所编写的“helloworld.exe”程序。将两个程序放在同一个目录下,感染前先用Hex
Editor Neo查看一下“helloworld.exe”程序的DOS头部分:

图1 感染前的DOS头

然后运行本程序,再次查看DOS头部:

图2 感染后的DOS头

可见,我们的感染是成功的。

四、小结

给文件添加感染标志对于文件来说不会产生任何影响,很多感染型病毒都会给目标文件添加感染标志,比如“熊猫烧香”就会在程序中添加“WhBoy”标志。因此当时李俊所编写的“熊猫烧香”病毒专杀工具(李俊版)就是通过检测文件中是否有“WhBoy”标志来判断文件是否被感染,但是这种检测方法却过于粗糙了。

时间: 2024-10-18 09:25:07

反病毒攻防研究第015篇:病毒感染标志的添加的相关文章

反病毒攻防研究第012篇:利用Inline HOOK实现主动防御

一.前言 之前文章中所讨论的恶意程序的应对方法,都是十分被动的,即只有当恶意程序被执行后,才考虑补救措施.这样,我们就会一直处于后手状态,而如果说病毒的危害性极大,那么即便我们完美地修复了诸如注册表项,服务项等敏感位置,并且删除了病毒本身,但是它依旧可能已经破坏了系统中非常重要的文件,造成了不可逆的损伤.因此这篇文章就来简单讨论一下利用Inline HOOK技术实现主动防御,在病毒执行前,就主动将危险函数劫持,如同一道防火墙,保护我们计算机的安全. 二.Inline HOOK原理 我们平时所使用

反病毒攻防研究第009篇:DLL注入(上)——DLL文件的编写

一.前言 我之前所编写的用于模拟计算机病毒的对话框程序都是exe文件,所以运行时必将会产生一个进程,产生进程就非常容易被发现.而为了不被发现,可以选择将对话框程序创建为DLL文件.这种文件会加载到已有进程的地址空间中,这样就不会再次创建出进程,隐蔽性相对较好,DLL注入也是恶意程序总会使用的手段.这次我带算用几篇文章的篇幅来论述DLL注入的问题,而这篇文章就首先来讨论一下如何把我之前的对话框程序改写为DLL文件. 二.编写对话框DLL程序 这里我依旧使用VC++6.0,创建一个简单的Win32

反病毒攻防研究第004篇:利用缝隙实现代码的植入

一.前言 现在很多网站都提供各式各样软件的下载,这就为黑客提供了植入病毒木马的良机.黑客可以将自己的恶意程序植入到正常的程序中,之后发布到网站上,这样当用户下载并运行了植入病毒的程序后,计算机就会中毒,而且病毒可能会接着感染计算机中的其他程序,甚至通过网络或者U盘,使得传播面积不断扩大.而本篇文章就来剖析病毒感染的实现原理,首先需要搜索正常程序中的缝隙用于"病毒"(用对话框模拟)的植入,之后感染目标程序以实现"病毒"的启动.当然,讨论完这些,我依旧会分析如何应对这种

反病毒攻防研究第010篇:DLL注入(中)——DLL注入与卸载器的编写

一.前言 我在上一篇文章中所讨论的DLL利用方法,对于DLL文件本身来说是十分被动的,它需要等待程序的调用才可以发挥作用.而这次我打算主动出击,编写DLL注入与卸载器,这样就可以主动地对进程进行注入的操作了,从而更好地模拟现实中恶意代码的行为. 二.DLL注入的原理 如果想让DLL文件强制注入某个进程,那么就需要通过创建远程线程来实现.这里需要注意的是,所谓的"远程线程",并不是跨计算机的,而是跨进程的.举例来说,进程A在进程B中创建一个线程,这就叫做远程线程.从根本上说,DLL注入技

反病毒攻防研究第011篇:DLL注入(下)——无DLL的注入

一.前言 一般来说,想要将自己编写的程序注入到其它进程中,是必须要使用DLL文件的,这种方法已经在上一篇文章中讨论过了.但是事实上,可以不依赖于DLL文件来实现注入的.只不过这种方法不具有通用性,没有DLL注入那样灵活,因为它需要把代码写入"注入程序"中,一旦想要注入的内容发生了变化,就需要重写整个"注入程序".而不像DLL注入那样,只要修改DLL程序即可.即便如此,无DLL进行注入的方式,也是一种值得讨论的方法. 二.无DLL注入的基本原理 在注入与卸载方面,无论

反病毒攻防研究第005篇:添加节区实现代码的植入

一.前言 上一篇文章所讨论的利用缝隙实现代码的植入有一个很大的问题,就是我们想要植入的代码的长度不能够比缝隙大,否则需要把自身的代码截成几个部分,再分别插入不同的缝隙中.而这次所讨论的方法是增加一个节区,这个节区完全可以达到私人订制的效果,其大小完全由我们自己来决定,这样的话,即便是代码较长,也不用担心.而这种方式最大的缺陷就是不利于恶意代码自身的隐藏,因此在现实中可能并不常用.其实,我在这里讨论节区的添加,是为了以后更加深入的讨论打下基础,因为在加壳以及免杀技术中,经常会对PE文件添加节区.这

反病毒攻防研究第008篇:简单木马分析与防范part2

一.前言 一般来说,木马是既有客户端也有服务器端的.上次讨论的不过是一种特殊情况,毕竟不是人人都懂得DOS命令,因此现在木马的客户端也都是做成非常直观的界面形式,方便操作.本篇文章会从客户端与服务器端两个方面进行讨论,与上次的讨论不同的是,这次我会直接把用来模拟病毒的对话框程序放入服务器端,这样只要成功连接,那么就可以通过由客户端所发出的命令来让服务器端直接执行对话框程序.用这种思想,可以给服务器端增加很多功能,但是在这里仅仅讨论对话框的打开. 二.服务器端的实现 这里所讨论的木马依旧是命令行下

反病毒攻防研究第007篇:简单木马分析与防范part1

一.前言 病毒与木马技术发展到今天,由于二者总是相辅相成,你中有我,我中有你,所以它们之间的界限往往已经不再那么明显,相互之间往往都会采用对方的一些技术以达到自己的目的,所以现在很多时候也就将二者直接统称为"恶意代码".这次我打算用两篇文章的篇幅来讨论病毒与简单的木马相互结合的分析与防范方法.本篇也就是第一篇,讨论的是利用只有服务器端的木马程序实现"病毒"的启动.而在下一篇中,我会讨论既有服务器端又有客户端的木马程序与"病毒"相结合的分析与防范.

网络攻防研究第001篇:尝试暴力破解某高校研究生管理系统学生密码

前言 如果你是在校大学生,而且还对网络攻防比较感兴趣的话,相信你最开始尝试渗透的莫过于所在院校的学生管理系统.因为一般来说这样的系统往往比较薄弱,拿来练手那是再合适不过的了.作为本系列的第一篇文章,我将会利用暴力破解的方式,尝试对某高校的研究生管理系统的学生密码进行破解.由于这个管理系统的网站属于该高校的内网资源,外网是无法访问的,因此大家就不要尝试按照文中的内容来对文中出现的网址进行访问了.利用本文所论述的暴力破解思想,可以帮助大家更好地认识我们的网络,也有助于了解目标网站是否安全.那么在这里