【技术分享】从Locky新变种谈敲诈者木马的一些免疫技巧

admin 2023-12-08 02:53:54 AnQuanKeInfo 来源:ZONE.CI 全球网 0 阅读模式

https://p4.ssl.qhimg.com/t01f800e11e2faa540b.png

0x1 前言

Locky敲诈者木马算是敲诈者木马中传播时间较长,变种较多的一款。在最近一段时间里,其变种Thor、Aesir开始频繁出现。这些Locky变种之间的核心加密功能代码几乎是相同的,只是改动了加密的后缀名,不过相比较老版本的Locky敲诈者,此类新变种在自我防御机制上有了较大改变,例如利用全局原子表代替注册表项存储标志字符串以应对对于相关注册表项的检测。不过即使填补了旧版Locky的坑,Locky新变种依然存在一些可以用来免疫的点,本文就旨在通过对Locky新变种的一些技术细节的分析来谈谈对此类木马的免疫手段。


0x2 先看看Locky的新变化

1.  感染方式的变化

感染方式上其实不能称作变化,应该称之为扩展。早期的Locky一般通过邮件传播,恶意代码存在于邮件附件Word文档中,通过调用Word宏执行恶意代码。而Locky新变种的感染方式有所增加,除了Word宏执行恶意代码之外,也存在以JS脚本作为邮件附件进行感染的变种。除外,Locky新变种借助PowerShell或PowerShell+Rundll32组合执行恶意代码。下图展示的是一款Locky新变种使用的代码执行方式,其使用PowerShell启动恶意程序进程。

http://p5.qhimg.com/t01ec51db20b0a96f72.png

图1 使用PowerShell启动恶意程序进程

2.  标志字符串存储的变化

老版本Locky敲诈者会访问一些相关的注册表项并将一些标志字符串存储在注册表中,例如HKCUSoftwareLocky注册表项。这些标志字符串用来判断该计算机中的文件是否已被加密,以及此次加密工作是否完成。此类方法最大的缺陷在于用户可以设置ACL阻止任何用户访问相关注册表项或者自定义一个相同的注册表项来“欺骗”敲诈者。

Locky新变种摈弃了注册表,转而使用全局原子表来存放相关的标志字符串。由于访问全局原子表并不需要打开操作,一般用户也不知道如何往全局原子表中添加全局原子来“欺骗”敲诈者,因此该方法相比较使用注册表存储标志字符串的方法更加有效。
          

http://p6.qhimg.com/t01416eb0acdbb296c7.png

图2 程序查询原子表相关字符串以判断计算机是否已被感染

3.  密钥和加密

老版本Locky敲诈者从服务器获取RSA公钥,当然这么做并不能保证程序能正常获得RSA公钥。由于存放密钥的地址经常发生变更,可能用户感染敲诈者时该地址已失效,因此在服务器存放RSA公钥并不能保证每次都能加密成功。Locky新变种采用了和大部分敲诈者一样的方式,将RSA公钥硬编码到程序中,这就能保证成功加密文件。

在加密方式上,Locky新变种和老版本相同,使用微软提供的一系列API完成加密工作。


0x3 再说说对Locky新变种的免疫手法

1.  从Rundll32.exe入手

正如上文提到的,Locky新变种在恶意代码的运行方式上相比较老版本复杂的多,主要也是从对抗杀软这方面考虑。在这些新变种中,使用最为广泛的当属Rundll32.exe运行恶意dll的方式。微软对于Rundll32.exe的使用做了限制,使用命令行调用Rundll32.exe时命令行必须满足以下格式。

http://p8.qhimg.com/t015078ac0e4a3b6e63.png

而对于使用Rundll32.exe执行的导出函数,其必须参数必须满足如下要求。

http://p1.qhimg.com/t01c2ec6d717a6b17f0.png

但是查看Locky新变种释放的恶意Dll发现该Dll并无导出函数。

http://p1.qhimg.com/t01110eb658fac42899.png

图3 IDA显示Dll无导出函数

其实这是恶意Dll使用的伎俩。由于Rundll32.exe执行Dll导出函数的流程是LoadLibraryExW—GetProcAddress—ExportFuntion,第一步LoadLibraryExW会导致Dllmain的执行,而恶意Dll在Dllmain中将自身的代码从内存中解除映射,并映射新的代码,新的代码中定义了导出函数,因此该恶意Dll就完成了导出函数从无到有的转变。

http://p9.qhimg.com/t0101c60ba970712066.png

图4 完成代码重建后Dll“生”出了导出函数

使用这种方法构造了一种无导出函数的Dll调用导出函数的假象。也为分析造成了一些困扰。不过该恶意程序为了实现代码的重建也是付出了一定的代价,这也算是一个可以防御的点。

之所以说恶意程序付出了一定代价,是因为其使用了TLS(线程局部存储)技术,该技术解决了多线程中线程操作全局变量带来的冲突问题。下图展示了Dll的区段组成,可以很清楚地看到.tls段。

http://p3.qhimg.com/t017e9c25e229640f55.png

图5 Dll的区段中存在.tls段

对于WinXP而言,在程序执行主功能代码之前会初始化静态定义的线程局部变量,因此在程序执行主功能前已经分配一部分内存用于存储线程局部变量,如果程序运行中动态调用一个Dll(例如使用LoadLibary函数调用Dll),且该Dll中也静态定义了线程局部变量,由于存储线程局部变量的空间已经固定,将导致Dll的线程局部变量无法初始化,从而导致Dll调用失败。同理,Rundll32.exe在执行主功能代码之前已经初始化静态定义的线程局部变量,在执行过程中调用LoadLibraryExW函数加载恶意Dll。根据恶意Dll存在tls段可以确定该Dll静态定义了线程局部变量,这样就会导致LoadLibraryExW函数调用失败,Rundll32.exe弹出警告框如下所示。

http://p3.qhimg.com/t01ad0d9509593a0cdb.png

图6 Rundll32弹出对话框

在Win7及以上版本的操作系统中,允许Dll静态定义线程局部变量,因此Rundll32.exe正常运行,而WinXP也就天然免疫了该变种的入侵——虽是无心插柳,但也可以算是一种免疫手段了吧。

2.  从系统语言入手

对于Locky,Cerber,XTBL这类疑似俄产敲诈者而言,其最大的特点莫过于自动忽略俄语系国家,对于系统语言为俄语的国家不执行加密工作。因此如果能够让自身系统语言为俄语则可免除这一大系列敲诈者的攻击。当然,直接修改系统语言是不可取的,毕竟绝大部分中国人看不懂俄语,那如何利用系统语言防御诸如Locky这类俄系敲诈者呢,这就需要一些小技巧的辅助。

在Locky新变种中使用GetSystemDefaultLangID,GetUserDefaultLangID和GetUserDefaultUILanguage三个函数判断系统语言,这与老版本Locky敲诈者相同。

http://p7.qhimg.com/t01854049d18ee4c3ec.png

图7 Locky判断系统语言

从上图可以很明显的看出,程序对这三个函数的返回值与0x3ff相与后再进行判断,也就是说程序判断的其实是返回值低10位的数值。这三个函数的返回至类型为LANGID,其定义格式如下所示。

http://p2.qhimg.com/t01bd267e5ab6050a87.png

可以看出,低10位表示的是主语系,也就是说只要系统主语系为0x19(俄语)即不进行加密。而对于LANGID,其主语系和子语系都存在可供用户自定义的区域(主语系为0x200-0x3ff,子语系为0x20-0x3f)。因此可以自定义这样一种LANGID,其主语系为0x19(俄语),而自定义其子语系,并将该LANGID和中文相关资源(例如日历,语言,计数方式)绑定,这样就可以生成一种LANGID主语系为俄语的中文,可以称它为俄语(中国)。将其设为系统默认语言可以使GetSystemDefaultLangID和GetUserDefaultLangID返回值低10位为0x19,躲避敲诈者的感染。

当然,如果寻求更加方便的方法,可以使用NLS(National Language Support)来进行当前区域的设定。NLS提供了一种Replacement locale方法,可以在不改变LocaleID的情况下修改它所对应的语言,日历形式,计数形式等。NLS这么做旨在为使用语言和所处区域不同的人群提供一种兼容性的设置,现在可以利用它来防御敲诈者。由于LANGID是LocaleID的一部分,且Replacement locale方法并不会修改旧的LocaleID,因此可以把俄罗斯的LocaleID和中国的相关设置绑定,让系统语言为中文,LANGID为0x19(俄语),从而免疫俄系敲诈者。

当然,如果还想更加方便,可以使用微软提供的工具Locale Builder,该工具可以自定义各种语言和区域搭配。

上述方法可以修改GetSystemDefaultLangID,GetUserDefaultLangID返回值,而对于GetUserDefaultUILanguage返回值的修改,可以使用MUI(Multilingual User Interface)相关接口,MUI允许用户加载语言资源,相比较NLS更加灵活,在此不在赘述。

综上,从系统语言入手防御俄系敲诈者对于个人防御而言算是比较有效的一种方法,但可能会影响其他程序的稳定性,不过这不失为一种值得考虑的方式。

3.  从全局原子入手

之前提到Locky新变种通过查找全局原子表中指定名称的全局原子确定该计算机是否已被感染。如果事先往全局原子表中添加名称相同的全局原子就可让敲诈者误以为该计算机已经被感染过从而放弃加密。添加全局原子使用的函数时GlobalAddAtom。不过该种方法实用性不高,因为需要事先知道敲诈者使用的全局原子名称,而每一个新变种使用的全局原子名称各不相同,这将防不胜防。

http://p4.qhimg.com/t0107ae461f08d53ba2.png

图8 程序完成加密后往全局原子表添加原子作为标志

4.  从磁盘入手

Locky敲诈者在加密文件之前会对磁盘进行遍历,其遍历方式是通过硬编码在程序中的盘符来作为遍历的盘符,从A盘遍历到Z盘,如下图所示。

http://p3.qhimg.com/t0192924c182e535f4f.png

图9 程序遍历磁盘

由于程序通过盘符遍历磁盘,因此可以创建一个无盘符的磁盘或者删除相关磁盘的盘符,该磁盘可用于存储重要文档,数据,使用时再为其分配盘符便可正常访问。这样敲诈者木马在遍历磁盘的时候不会遍历到该无盘符磁盘,这也可以保证该磁盘中的文件不会被敲诈者木马加密。除此之外程序忽略了具有FILE_READ_ONLY_VOLUME属性的盘符,因此也可以为盘符设置相应属性躲避敲诈者的加密。

5.  顺道聊聊XTBL敲诈者

Locky敲诈者能完成诸多功能的一个主要原因在于其拥有较高权限。由于Locky敲诈者的执行大多来自于Word宏的加载,其父进程为Word进程,这很容易让其进程链以管理员权限运行。而另一类利用JS脚本作为邮件附件感染系统的变种也可能因为用户忽略其安全性允许其运行而具有管理员权限。高权限也为程序的一系列行为“铺路”。

不过另一款敲诈者XTBL敲诈者就遇到了一些权限难题。在其进行加密操作之前会对当前进程所处环境进行判断,如果不是以管理员权限运行该程序则会通过Runas来提升权限。如下图所示。

https://p4.ssl.qhimg.com/t012b2a9b94f49b81c9.png

图10 XTBL使用Runas提权

这项操作存在一个缺陷,就是无论在WinXP还是WinXP以上系统都会弹出提示框。由于XTBL敲诈者主要是针对服务器,而且一般通过入侵服务器植入恶意程序,因此入侵者可以手动解决这个问题。但假如个人计算机感染了XTBL敲诈者,那么弹窗就将使该程序变得更加可疑。由于在提权操作之前程序执行代码重组和密钥生成的操作,这些操作需要一定的时间,这也使弹窗的时间点更加可疑。而该提权代码无限循环执行提权操作,因此用户只有允许其以管理员权限运行才能关掉提示框,这也是个比较可疑的地方。因此用户可以结合这几个可疑的点来警惕XTBL敲诈者的侵袭。


0x4 总结

以上分享了一些利用Locky新变种的固有缺陷或者考虑不周的特性来免疫它的攻击的方法,对于个人用户而言虽具有一定效果和加之,但想更全面的抵御各类木马的侵袭,依然需要安全软件的防护。

安全意识的提高、安全习惯的养成、安全软件的防护,只有这三方面共同的协作,才能真正有效而全面的保障大家的安全。三者缺一不可,切不能掉以轻心。

weinxin
版权声明
本站原创文章转载请注明文章出处及链接,谢谢合作!
评论:0   参与:  0