cnhackteam7 发布于2022年11月8日 分享 发布于2022年11月8日 0x00 前言 知名恶意软件Poweliks利用后门技术,在注册表启动位置创建特殊的注册表键值,并通过mshta执行有效载荷。 对于这个特殊的注册表项,正常情况下是无法访问的。这是什么原理?如何读取、创建和删除?本文将一一介绍。 0x01 简介 本文将介绍以下内容: 如何隐藏注册表 隐藏注册表的实现 编程中应注意的问题 0x02 原理 注册表项名称是特殊构造的:它以“\0”开头,后跟任何字符(不是数字)。 对于Windows系统来说,“\0”(即0x0000)会被识别为字符串的终止符,所以在读取字符串的过程中遇到开头的“\0”时,会被解释为终止符并提前截断,导致读取错误。 要使用Native API设置注册表,需要使用OBJECT_ATTRIBUTES结构作为参数来指定读取字符串的长度。 只要长度设置正常,就可以读取正确的字符串,避免这个bug。 因此,我们可以通过Native API创建这个特殊的注册表名称。 更重要的是,像regedit.exe等对注册表的操作,通常会调用Win32 API,使得注册表不可读,从而实现所谓的“隐藏”。 综上所述,创建方法是:通过Native API创建一个以”\0”开头的键值 0x03 编写程序实现 注册表由Native API操作,参考的工程地址为: https://www . code project . com/Articles/14508/Registry-Manipulation-Using-NT-Native-API 作者Dan Madden,他的代码使用了类封装。 个人倾向于使用最基础的api实现,所以参考他的代码重新设计。 对于本机API,所需的结构如下: 1.获取Native API的地址 与注册表操作相关的本地API可以从ntdll.dll获得。 关键代码如下: h instance hinst stub=GetModuleHandle(_ T(' ntdll . dll ')); NtOpenKey=(LPNTOPENKEY)GetProcAddress(hinst stub,' NtOpenKey '); 2.Native API的重定义和声明 原生API在使用前需要重新定义和声明。 一些关键代码如下: typedef NTSTATUS(STDAPICALLTYPE NTOPENKEY) ( 在HANDLEKeyHandle中, 在ULONGDesiredAccess中, 在po object _ attributes object attributes中 ); typedef NTOPENKEY FAR * LPNTOPENKEY; LPNTOPENKEYNtOpenKey 3. 特殊结构体的使用 与注册表操作相关的Native API将使用以下结构,这些结构需要定义和声明。 InitializeObjectAttributes _STRING _UNICODE_STRING _对象_属性 _KEY_INFORMATION_CLASS _ KEY _基本信息 _关键字_值_部分信息 _关键字_值_信息_类 RtlInitAnsiString RtlAnsiStringToUnicodeString Dan Madden的项目实现了创建一个隐藏的注册表项(注册表项的名称以\0开头),通过正常的Native API创建、读取和删除这个注册表项下的键值。 最基础的api的实现过程就不赘述了,打包的API源代码可以参考文末给出的链接。 测试Dan Madden项目中包含的函数: 1.创建隐藏注册表项 MyCreateHiddenKey(' \ \ Registry \ \ Machine \ \ Software \ \ testhidden '); 注册表工具regedit.exe无法打开该键值,如下图所示。 2.在该注册表下创建注册表键值 首先获取此注册表项的句柄: hKey=MyOpenHiddenKey(' \ \ Registry \ \ Machine \ \ Software \ \ test hidden '); 在注册表项下创建键值test1,并将其指定为: MySetValueKey(hKey,' test1 ',' 0123456789abcdef ',REG _ SZ); 读取该注册表项下的项test1的内容: MyQueryValueKeyString(hKey,' test1 '); 删除该注册表项下的键值test1: MyDeleteValueKey(hKey,' test1 '); 删除注册表项: MyDeleteKey(hKey); 程序输出下图,成功操作隐藏注册表项下的正常键值。 接下来,向Dan Madden的项目添加新功能:创建、读取和删除隐藏的注册表项。想法如下: 要隐藏注册表项,只需在注册表项名称的第一个位置填写“\0”。 原则上在对应的注册表项名称的第一位也填“\0”,但更要注意参数传递。 1.不需要修改的功能 创建注册表项、打开注册表项、删除注册表项的功能都不需要修改,用正常的名字就可以了。 链接帖子 意见的链接 分享到其他网站 更多分享选项…
推荐的帖子