单纯编译infector.exe之后需要把要用到的SBv2各个模块用Attach File.exe附加上去,看看附加的批处理文件:
- /*
- "Attach File.exe" Infector.exe "../Include Files/Master Boot Record Loader.bin" ddcad6ec9127c41872ee0d0e0df14883
- "Attach File.exe" Infector.exe "../Include Files/Memory Image RawFS.bin" 8f58eadd7bfff0c557d4b5e9656957a5
- "Attach File.exe" Infector.exe "../Include Files/Cmd.sys" 15137ef73def24f4f00239628a70df43
- "Attach File.exe" Infector.exe "../Include Files/Exe Loader.sys" 9d02867239b96bff7d5e78a234aa4955
- */
Master Boot Record Loader.bin是SBv2的MBR,之后需要备份原MBR再把这个覆盖过去.
Memory Image RawFS.bin是SBv2的硬盘版本,存在的其他版本还有U盘版本,CD/DVD版本
Cmd.sys和Exe Loader.sys是功能模块.
之前的文章说过,Stoned Bootkit把功能模块写入到磁盘的前63个扇区,在v2的版本里面,换了位置,v2在磁盘前面部分只改写了MBR一个扇区,整个Bootkit往后移,移到很后面,移到Unpartitioned space,就是说,移到硬盘后面未使用的磁盘间隙里面吧,看图来说明一下,图1是MBR结构(偏移)表,图2是分区表信息结构(偏移)表,图3是我虚拟机下XP的硬盘MBR:
MBR结构表得知,0x1BE是分区1结构表,16个字节,然后看分区表结构,可以看到最后两个DWORD,就是红框的那两个,前面一个是分区开始的扇区,如图,是0x38(56)个扇区,长度是0xFF9730个扇区,转换一下,(0x38+0xFF9730)*0x200(512字节) = 0x1FF2ED000,这个就是Unpartitioned Space的起始地址,最终SBv2会推倒这部分磁盘空间.
搞清楚SBv2写入到磁盘的什么位置后,看看他是如何组织磁盘结构的,哥做了几张图帮助理解,如果你看作者给出来的paper,那么那个已经过时了,不太准确.
作者使用了一个FileTableEntry的结构来管理放在Unpatitioned Space的文件,这个结构代码如下
- /*
- struct FileTableEntry
- {
- LARGE_INTEGER SectorNumber;
- LARGE_INTEGER Size;
- LARGE_INTEGER OccupiedSize;
- BYTE Reserved[8];
- char MD5[32];
- };
- */
说明一下,SectorNumber是说明文件存放在的扇区索引,索引是从0开始的,我们把Unpatitioned Space想象成这样的声明char UPS[][512];那么访问文件时候计算文件起始地址就是UPS[SectorNumber],使用扇区大小512字节对Unpatitioned Space进行划分估计是BIOS当中提供对整个扇区进行读取的中断功能,方便使用才这样进行划分的.
Size表示文件长度,这个长度是经过512字节进行对齐的,就是说如果你的文件是0.3KB,那么经过对齐,就是0.5KB了.
OccupiedSize这个作者的本意是想存储文件的原始长度,就是没经过对齐的长度,但是很巧合的是上面的各个模块原始大小就已经是512字节对齐了的.
MD5[32]是对文件名称求MD5值,结构体的长度总共是64字节,声明的时候声明8个该结构就刚好是512字节一个扇区的长度,这样方便管理,(前面说过对UPS管理是按扇区来的),FileTable在作者代码中呈现的是这样一种结构,可以动态增长,类似多级索引表.
所以不仅仅能管理8个文件,动态增长是在FileTable[7]写入新的FileTable的信息,类似文件系统的文件夹和文件(自己理解吧少年),下面看看例子,这个是感染之后的FileTable:
图中红框是第三个FileTableOfEntry,也就是FileTable[2],按照上面的图,这个地方存放的文件是Cmd.sys,SectorNumber是0x42,也就是第66个扇区,前面有33KB,包括FileTable[8],OriMBR.bak,SBv2,就是0.5+0.5+32 = 33KB,数字上符合,Cmd.sys的size是0x1000,就是4KB.至于MD5值可以参考下面
- /*
- // RawFS files
- #define MD5_RawFS "dec7f9619477b0ab1591aab2cc632364" // RawFS
- #define MD5_FreeFile "9154b3b4030a02138ed9f2e7f58f29fa" // /Free File
- #define MD5_FileTable "b05b32a085defc9f4299c35ac8f358cd" // /File Table
- // Stoned files
- #define MD5_Bootkit "8f58eadd7bfff0c557d4b5e9656957a5" // /Bootkit
- #define MD5_Bootloader "ddcad6ec9127c41872ee0d0e0df14883" // /Bootloader
- #define MD5_MBR_Backup "0F13C73AAB0D4E000028038C99D3125A" // /Master Boot Record.bak
- #define MD5_FLS "fde793a0d624fb992d846ed743139e1d" // /Stoned/Applications/Forensic Lockdown Software
- #define MD5_HFA "f6e6027fa3b8f5f85809708a28f98f32" // /Stoned/Applications/Hibernation File Attack
- #define MD5_Cmd "15137ef73def24f4f00239628a70df43" // /Stoned/Drivers/Cmd.sys
- #define MD5_ExeLoader "9d02867239b96bff7d5e78a234aa4955" // /Stoned/Drivers/Exe Loader.sys
- */
下面给出Unpatitioned Space布局的表说明,自己做表抓图的男人你伤不起啊
总结一下,infector运行时,首先检查引导区MBR是否完整,并获取Unpatitioned Space的偏移,接着系统是否已经被感染过,不过这部分的代码是有错误的,按照作者的意图,FileTable[0]放入的MD5是MD5_MBR_Backup,而FileTable[1]放入的是MD5_Bootkit,但是检查代码却写成对MD5_RawFS的检查.按下面这样改一下就OK了.
- /*
- //if (_strnicmp(FileTable1[0].MD5, MD5_RawFS, 32) != 0 && // RawFS (MD5)
- if (_strnicmp(FileTable1[0].MD5, MD5_MBR_Backup, 32) != 0 &&
- _strnicmp(FileTable1[1].MD5, MD5_Bootkit, 32) != 0 ) // /Bootkit (MD5)
- */
如果系统未被感染则初始化FileTable[8],之后备份原MBR代码,然后写入自己的MBR代码,接下来就检查infector后面附带的模块(用Attach File.exe附加进来的),然后更新FileTable并写入Unpatitioned Space当中.这样就完成了感染.
代码里面一些说明:
1.作者定义了一个FileAttachmentHeader,并用ATTACHFILE作为搜索附加模块的标志,由于是对自身进行搜索,如何避免搜索到自身的ATTACHFILE这个字符串变量造成错误,可以不要一次性写入ATTACHFILE作为搜索标志,参考代码
- /*
- //避免找到自己,所以把ATTACHFILE分开设置
- BYTE ScanSignature[10] = "ATTACH";
- memcpy(ScanSignature + 6, "FILE", 4);
- */
2.在上面的MBR结构偏移图当中现实0x1BE前6个字节是没有作用的,但是在MS的操作系统中是作为微软磁盘标志的,在写入病毒MBR的时候需要进行修复memcpy(Memory + 440, BootSector + 440, 6);
对磁盘分布跟infector做的坏事有所了解之后就可以看病毒MBR的代码了.