也谈rootkit 注册表信息隐藏

本文深入探讨了Windows注册表的隐藏技术,包括用户态和核心态下的隐藏方法,重点介绍了通过修改hive内存结构中的特殊指针hook来实现注册表项的隐藏。文章详细解析了注册表的结构,如HIVE_BLOCK、CELL_DATA、HBIN等,并展示了如何通过hook GetCellRoutine函数来达到隐藏注册表项的目的。此外,还提供了隐藏注册表项的示例代码,揭示了注册表隐藏的具体实现过程。
注册表是Windows系统存储关于计算机配置信息的数据库,包括了系统运行时需要调用的运行方式的设置,是系统的核心。操作系统是用特殊的文件 (Hive文件)来存储注册表的内容,并提供给用户相关的编程接口(APIs)来进行注册表的操作,例如Advapi32.dll中的Registry Functions(如:RegEnumKey)。在Windows操作系统中,函数的调用有着极其规范的层次结构,如下图所示是系统实现 RegEnumKey函数的调用体系。
名称:  2.JPG
查看次数: 389
文件大小:  24.9 KB
注册表隐藏就是将系统呈现给用户的注册表信息进行修改,使得用户或检测工具无法直观地发现事实上存在的注册表内容。目前的注册表隐藏,大都采用的是Hook技术。根据它们不同的运行环境和模式,把常见的注册表隐藏技术称为用户态下注册表隐藏技术和核心态下注册表隐藏技术。它们通常是利用IAT Hook, Inline Hook、远程线程注入、SSDT Hook等方式来实现。网上比较多见的核心态隐藏技术是ssdt hook NtEnumerateKey 和inline hook CmEnumerateKey。然而这些方法已经很容易被防御体系发现。

本文是通过修改hive内存结构中的特殊指针hook实现注册表项的隐藏。关于hive文件结构,论坛中曾经有两人写过相关的文章,一篇是炉子大牛写的《HIVE格式解析》,另一篇是HSQ大牛写的《注册表监控弱点演示程序 v0.2 逆向ASM源码及相关资料》,另外,Petter Nordahl-Hagen写过一个hive文件存取库,我整理了下,也附在本篇文章之后,方便大家查阅。

相信看过网上这几篇的朋友一定还有些疑虑,到底注册表的工作原理是怎样的呢?我们今天通过一个驱动代码来揭开它神秘的面纱。

在磁盘上,注册表并不是简单的一个大文件,而是一组称为hive的单独文件。每个hive文件包含了一颗注册表树。有一个键作为该树的根。子键和他们的值存储在根的下面。当配置管理器(注册表的执行体子系统)加载hive的时候,会在HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet /Control/hivelist子键下的注册表值中记录下每个hive的路径。下面是我本机注册表hivelist子键导出的信息:

[HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Control/hivelist]

"//REGISTRY//MACHINE//HARDWARE"=""

"//REGISTRY//MACHINE//SECURITY"="//Device//HarddiskVolume1//WINDOWS//system32//config//SECURITY"

"//REGISTRY//MACHINE//SOFTWARE"="//Device//HarddiskVolume1//WINDOWS//system32//config//SOFTWARE"

"//REGISTRY//MACHINE//SYSTEM"="//Device//HarddiskVolume1//WINDOWS//system32//config//SYSTEM"

"//REGISTRY//USER//.DEFAULT"="//Device//HarddiskVolume1//WINDOWS//system32//config//DEFAULT"

"//REGISTRY//MACHINE//SAM"="//Device//HarddiskVolume1//WINDOWS//system32//config//SAM"

"//REGISTRY//USER//S-1-5-20"="//Device//HarddiskVolume1//Documents and Settings//NetworkService//NTUSER.DAT"

"//REGISTRY//USER//S-1-5-20_Classes"="//Device//HarddiskVolume1//Documents and Settings//NetworkService//Local Settings//Application Data//Microsoft//Windows//UsrClass.dat"

"//REGISTRY//USER//S-1-5-19"="//Device//HarddiskVolume1//Documents and Settings//LocalService//NTUSER.DAT"

"//REGISTRY//USER//S-1-5-19_Classes"="//Device//HarddiskVolume1//Documents and Settings//LocalService//Local Settings//Application Data//Microsoft//Windows//UsrClass.dat"

"//REGISTRY//USER//S-1-5-21-1550111154-316279633-4274931122-1006"="//Device//HarddiskVolume1//Documents and Settings//Jason//NTUSER.DAT"

"//REGISTRY//USER//S-1-5-21-1550111154-316279633-4274931122-1006_Classes"="//Device//HarddiskVolume1//Documents and Settings//Jason//Local Settings//Application Data//Microsoft//Windows//UsrClass.dat"

通过这个信息我们看到,在C:/WINDOWS/system32/config目录中存储着HKLM所有项的hive文件以及一个HKU的DEFAULT hive文件,其他的HKU下的hive文件存储在c:/Documents and Settings等子目录下。在hivelist记录的这些信息中,我们看到hive文件只能加载到HKLM和HKU下。如图:
名称:  1.JPG
查看次数: 695
文件大小:  30.7 KB

配置管理器从逻辑上将一个hive分成一些称为block的分配单元。如图:
名称:  3.jpg
查看次数: 683
文件大小:  12.3 KB

其方式类似于文件系统将一个磁盘分成簇。根据定义,注册表block的大小为4096字节(4kb)。当新的数据要扩展一个hive时,该hive总是按照 block的粒度来增加。hive的第一个block称为base block. 里面包含了一些全局信息,包括一个特征签名regf、更新的序列号,时间戳,hive格式版本号、校验和以及该hive的内部文件名(如:/Device /HarddiskVolume1/WINDOWS/system32/config/SECURITY)。

结构如下:
lkd> dt _hbase_block

nt!_HBASE_BLOCK
   +0x000 Signature         : Uint4B
   +0x004 Sequence1         : Uint4B
   +0x008 Sequence2         : Uint4B
   +0x00c TimeStamp         : _LARGE_INTEGER
    +0x014 Major             : Uint4B
    +0x018 Minor             : Uint4B
    +0x01c Type              : Uint4B
    +0x020 Format            : Uint4B
    +0x024 RootCell          : Uint4B
    +0x028 Length            : Uint4B
    +0x02c Cluster           : Uint4B
    +0x030 FileName          : [64] UChar
   +0x070 Reserved1         : [99] Uint4B
    +0x1fc CheckSum          : Uint4B
    +0x200 Reserved2         : [894] Uint4B
    +0xff8 BootType          : Uint4B
    +0xffc BootRecover       : Uint4B
windows将一个hive所存储的注册表数据组织在一种称为cell的容器中。一个cell可以容纳一个键、一个值、一个安全描述符、一列子键或者一列键值。其对应的结构如下:

typedef struct _CELL_DATA
{
     union _u
    {
         CM_KEY_NODE       KeyNode;
         CM_KEY_VALUE      KeyValue;
         CM_KEY_SECURITY   KeySecurity;     // Variable security descriptor length
         CM_KEY_INDEX      KeyIndex;        // Variable sized structure
         CM_BIG_DATA       ValueData;       // This is only for big cells; a list of cells
                                          // all of the length CM_KEY_VALUE_BIG

         HCELL_INDEX       KeyList[1];      // Variable sized array
         WCHAR             KeyString[1];    // Variable sized array
     } u;
} CELL_DATA, *PCELL_DATA;

该结构中嵌套了一个联合体,用于代表cell可以存放的不同类型的数据。

下面给出CELL_DATA可以存放的几种不同类型的cell结构:

lkd> DT _CM_KEY_NODE
nt!_CM_KEY_NODE
    +0x000 Signature         : Uint2B
    +0x002 Flags             : Uint2B
    +0x004 LastWriteTime     : _LARGE_INTEGER
    +0x00c Spare             : Uint4B
    +0x010 Parent            : Uint4B
    +0x014 SubKeyCounts      : [2] Uint4B
    +0x01c SubKeyLists       : [2] Uint4B
    +0x024 ValueList         : _CHILD_LIST
    +0x01c ChildHiveReference : _CM_KEY_REFERENCE
    +0x02c Security          : Uint4B
    +0x030 Class             : Uint4B
    +0x034 MaxNameLen        : Pos 0, 16 Bits
    +0x034 UserFlags         : Pos 16, 4 Bits
    +0x034 VirtControlFlags : Pos 20, 4 Bits
    +0x034 Debug             
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值