唤醒沉睡的木马
2020-11-24 13:00:00 Author: mp.weixin.qq.com(查看原文) 阅读量:21 收藏

标题: 唤醒沉睡的木马

给女科学家配了台新笔记本,装系统的重任自然是老砖家。系统好装、软件难配,她有一堆医学科研相关的软件要装,而这些软件并不是我找来的,天晓得从哪里东拼西凑而得,比如同事分享、学校D版、外培分发等等。这我要吐槽,在奔向共产主义的伟大道路上,学校不能给这些科研工作者们购买正版科研软件吗?为什么需要她们自己如此不靠谱地去找?

其中有一个科研软件其缩写是PASS,不是密码,具体是干啥的,咱也不知道,咱也不敢问。印象中曾经给她装过PASS 15,但那天她给的U盘中是PASS2008setup.exe。这得多老的版本,北京欢迎你。虽然心存疑虑,但隔行如隔山,她说装啥就装啥。咣咣咣,一路Next,然后提示注册。我!@#$%^&*,不可能临时剁这种软件啊,这事不是人干的,卸载拉倒。

接着装其他软件,有个32位PhotoShop 13绿色版,居然会向注册表写入如下内容:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts]
"ADMUI3Lg"="C:\\Program Files (x86)\\Adobe\\Adobe Photoshop CS6\\Required\\ADMUI3.fon"

之前并不知道,但删除"Adobe Photoshop CS6"目录时提示有文件被占用,用Process Explorer发现ADMUI3.fon被非PS进程占用,顺藤摸瓜发现如上注册表项。

reg.exe query "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "ADMUI3Lg"
reg.exe delete "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts" /v "ADMUI3Lg" /f

当时只删了注册表项,没有去杀目标进程,而是重启Win10,想看看有没有其他幺蛾子。

当我登进系统时,右下角突然弹出Windows Defender告警,发现高危特洛伊木马。仔细看了告警记录和在线参考链接,确认这是个木马,TMD不是误报。

对于出现这种情况,我有心理准备。夜路走多了,总会碰上鬼,不是我,是女科学家。就她这些来路不明的软件,过去近二十年没出事,只能说运气不错。有个缓解因素,只要条件允许,她从来不敢自己装软件,都是等我来装,如果有幺蛾子,显然我比她敏感得多。要知道,Windows用户面临的不只是小木马,还有那些全家桶大流氓。

说到全家桶大流氓,插播一段。近日清理女科学家用过的一台小上网本,意外发现2014年8月她曾中过百度全家桶,具体表现为5至6个互相保护的驱动以及若干杀不掉的进程,全是百度的,当然,打的幌子都是安全保护类。而在"添加删除"里并没有相关项,估计是她背着我装百度浏览器时中的招。虽然这台上网本要废掉,但我还是尝试干掉这些恶心的全家桶。起初想得挺美,用NTFS权限禁止访问百度的这批PE文件,显然百度考虑了这点,不让我调整NTFS权限。只好用WinPE启动,但我并没有直接删文件,只是把Autoruns中百度相关项清空,注意,Autoruns可以离线使用,本质是离线编辑注册表。正常重启后,再去践踏百度PE们。即便硬盘要安全擦除了,还是乐意看着百度全家桶定向死在我手上。

扯远了,回来看Windows Defender告警。调出Autoruns,扎眼的未知服务:

$ sc qc FMSD
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: FMSD
        TYPE               : 10  WIN32_OWN_PROCESS
        START_TYPE         : 2   AUTO_START
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\Program Files\uicut\juqqo.exe
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : Application File Memory Share
        DEPENDENCIES       :
        SERVICE_START_NAME : LocalSystem

$ reg.exe query "HKLM\SYSTEM\CurrentControlSet\Services\FMSD"

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\FMSD
    Type    REG_DWORD    0x10
    Start    REG_DWORD    0x2
    ErrorControl    REG_DWORD    0x1
    ImagePath    REG_EXPAND_SZ    C:\Program Files\uicut\juqqo.exe
    DisplayName    REG_SZ    Application File Memory Share
    WOW64    REG_DWORD    0x1
    ObjectName    REG_SZ    LocalSystem
    Description    REG_SZ    Application File Memory Share

在services.msc中看到的是"Application File Memory Share"。Autoruns看到的时间戳是"2010-01-12 10:39"。看着像是小毛虫良心木马一枚,暂时不感染其他文件,不搞勒索软件那套,否则麻烦。

删掉相关注册表项和文件目录,重启OS,再次Autoruns,未见明显异常。现在需要知道小木马什么时候装进来的?每个安装包在安装前都会用Windows Defender扫一下,为啥没有提前告警?当时已经装了十多个科研软件,嫌疑最大的是PS,但前面那些安装包也有可能。

如果现在不把这个祸害揪出来、不把这事搞清楚,迟早是颗定时炸弹,我将夜不能昧、寝食难安,过上二十年就是死不瞑目。对于一个决定含笑九泉的人,绝不能忍。

赶紧搞了一个Win10虚拟机,确保Windows Defender升级至最新,打开实时防护,建好快照,从PS开始倒序安装那堆软件。每装一个软件,就手工检查文件目录和注册表项(服务列表),没有用Process Monitor。结果PS没有出状况,当时心凉,看上去是PS之前的其他安装包惹的祸。耐着性子继续倒序安装,相安无事,直至PASS,出现FMSD服务。

先备份PASS2008setup.exe到我自己的U盘,再删除女科学家各U盘上的,给她上了堂社会主义安全教育课,再次强调,过去近二十年我对她做的安全教育不是吓唬她的,凡是我说的,都是对的,我的指示她都得照做,我家只有一个凡是,就是前面这个。纯属YY,如有雷同,绝非巧合。

用Windows Defender扫PASS2008setup.exe,还是不告警。愤而上传至VT,居然是首次提交,是说之前的受害者们没意识到这是个祸害吗?今天又去看了一眼,34/69告警,想知道Win10的Windows Defender啥时候直接告PASS2008setup.exe的警?

大致看了一下,PASS2008setup.exe实际是个自解压文件,执行时向临时目录释放:

Setup.EXE
Setup.ini
Setup.ico
rarinfo.txt
PASS2008setup.exe   // 原始安装包
jTemp.dat           // 带密码的压缩包

假PASS2008setup.exe先启动Setup.EXE,后者再去执行真PASS2008setup.exe。等真PASS2008setup.exe安装结束后,Setup.EXE另有小动作,会解压jTemp.dat,从中释放新的文件,往Services里添加恶意服务。用Process Monitor、Process Explorer即可观察到这些行为。

file -b jTemp.dat
Zip archive data, at least v2.0 to extract

单独检查jTemp.dat,VT没有一个告警,因为这实际是一个带密码的zip文件,没有解压密码时无法真正检查它。它里面的恶意文件释放出来后为Windows Defender所识别,就有了前面所说最早那次告警。

Windows Defender真够弱的,Setup.EXE在无密码自解压压缩包中,Setup.EXE的行为足以告警,为什么不对假PASS2008setup.exe告警?

在虚拟机中可以提取"C:\Program Files\uicut\"目录下的东西,先把实时防护关了,这些东西应该就是从jTemp.dat中释放出来的恶意文件。Setup.EXE释放它们时有简单变形,每次相关目录名、文件名都不一样。

显然Setup.EXE知道jTemp.dat的解压密码,出于莫名的好奇心,很想知道这个解压密码到底是啥?后来我确实把这个密码逆向出来了,下面说说调试思路。

用Process Monitor监控Setup.EXE的行为,搜jTemp.dat,查看对该文件读操作的调用栈回溯,假设附近有zip解压缩操作。这是最初的设想,尝试后觉得过于理想化了。

对zip算法的C实现不熟,但我猜其C实现有可识别特征,或可为findcrypt.plw之类的工具所识别。用IDA反汇编Setup.EXE,用第三方插件"IDA Signsrch"搜,找到zip算法相关特征字节流:

/*
 * 出现这三组特征值,表示该函数提供解压密码
 */

0047EF28             sub_47EF28
...
0047EF4A C7 86 70 01+    mov     dword ptr [esi+170h], 12345678h
0047EF4A 00 00 78 56+
0047EF4A 34 12
0047EF54 C7 86 74 01+    mov     dword ptr [esi+174h], 23456789h
0047EF54 00 00 89 67+
0047EF54 45 23
0047EF5E C7 86 78 01+    mov     dword ptr [esi+178h], 34567890h

参看:

https://github.com/yumeyao/7zip/blob/master/CPP/7zip/Crypto/ZipCrypto.cpp

STDMETHODIMP CCipher::CryptoSetPassword(const Byte *password, UInt32 passwordLen)
{
  Keys[0] = 0x12345678;
  Keys[1] = 0x23456789;
  Keys[2] = 0x34567890;
  UInt32 i;
  for (i = 0; i < passwordLen; i++)
    UpdateKeys(password[i]);
  for (i = 0; i < 3; i++)
    Keys2[i] = Keys[i];
  return S_OK;
}

接下来自然想到动态调试,拦截sub_47EF28,查看入口寄存器,从中获取解压密码。

正常执行假PASS2008setup.exe,出现真PASS2008setup.exe安装界面时用Process Explorer看到进程树:

PASS2008setup.exe
  Setup.EXE
    真PASS2008setup.exe
      msiexec.exe

用cdb attach到Setup.EXE:

net use Z: "\\vmware-host\Shared Folders"
"Z:\Green\Windows Kits\10x86\Debuggers\x86\cdb.exe" -noinh -snul -hd -o -p <pid>

0:001> u 0x47EF28 l 0x20
Setup+0x7ef28:
0047ef28 55              push    ebp
0047ef29 8bec            mov     ebp,esp
0047ef2b 51              push    ecx
0047ef2c 53              push    ebx
0047ef2d 56              push    esi
0047ef2e 57              push    edi
0047ef2f 8955fc          mov     dword ptr [ebp-4],edx              // password[]
0047ef32 8bf0            mov     esi,eax
0047ef34 8b45fc          mov     eax,dword ptr [ebp-4]
0047ef37 e8a061f8ff      call    Setup+0x50dc (004050dc)
0047ef3c 33c0            xor     eax,eax
0047ef3e 55              push    ebp
0047ef3f 68a8ef4700      push    offset Setup+0x7efa8 (0047efa8)
0047ef44 64ff30          push    dword ptr fs:[eax]
0047ef47 648920          mov     dword ptr fs:[eax],esp
0047ef4a c7867001000078563412 mov dword ptr [esi+170h],12345678h
0047ef54 c7867401000089674523 mov dword ptr [esi+174h],23456789h
0047ef5e c7867801000090785634 mov dword ptr [esi+178h],34567890h
0047ef68 8b45fc          mov     eax,dword ptr [ebp-4]
0047ef6b 85c0            test    eax,eax
0047ef6d 7405            je      Setup+0x7ef74 (0047ef74)
0047ef6f 83e804          sub     eax,4
0047ef72 8b00            mov     eax,dword ptr [eax]
0047ef74 8bd8            mov     ebx,eax
0047ef76 85db            test    ebx,ebx
0047ef78 7e18            jle     Setup+0x7ef92 (0047ef92)
0047ef7a bf01000000      mov     edi,1
0047ef7f 8b45fc          mov     eax,dword ptr [ebp-4]              // password[]
0047ef82 0fb65438ff      movzx   edx,byte ptr [eax+edi-1]           // password[i]
0047ef87 8bc6            mov     eax,esi
0047ef89 e8fafeffff      call    Setup+0x7ee88 (0047ee88)           // 类似UpdateKeys()的功能
0047ef8e 47              inc     edi                                // 计数器递增
0:001> bp 0x47EF28
0:001> g

直接Cancel掉真PASS2008setup.exe的安装界面,直奔Setup.EXE的恶意流程,断点命中:

Breakpoint 0 hit
eax=02243f40 ebx=02243f40 ecx=0019f9ac edx=02259a18 esi=0019f9b8 edi=02243f40
eip=0047ef28 esp=0019f960 ebp=0019f990 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
Setup+0x7ef28:
0047ef28 55              push    ebp

简单观察sub_47EF28,入口edx可能是password,看看再说:

0:000db edx
02259a18  36 65 30 39 35 38 65 34-38 61 36 65 39 34 65 32  6e0958e48a6e94e2
02259a28  62 36 61 64 65 35 66 65-38 33 65 62 38 65 64 30  b6ade5fe83eb8ed0
02259a38  00 61 72 53 46 58 30 5c-47 54 65 6d 70 2e 64 61  .arSFX0\GTemp.da
02259a48  74 00 00 00 b0 98 25 02-04 00 00 00 31 00 00 00  t.....%.....1...
02259a58  43 3a 5c 55 73 65 72 73-5c 73 63 7a 5c 41 70 70  C:\Users\scz\App
02259a68  44 61 74 61 5c 4c 6f 63-61 6c 5c 54 65 6d 70 5c  Data\Local\Temp\
02259a78  52 61 72 53 46 58 30 5c-6a 74 65 6d 70 2e 64 61  RarSFX0\jtemp.da
02259a88  74 00 00 00 b0 98 25 02-01 00 00 00 2d 00 00 00  t.....%.....-...

用7-Zip打开jTemp.dat,试一下"6e0958e48a6e94e2b6ade5fe83eb8ed0",解压成功。

0:000> kpn
 # ChildEBP RetAddr
00 0019f95c 0047efee Setup+0x7ef28
01 0019f990 0047f09d Setup+0x7efee
02 0019f9bc 0047ddca Setup+0x7f09d
03 0019fb6c 0047ed58 Setup+0x7ddca
04 0019fc2c 004801f9 Setup+0x7ed58
05 0019fc5c 0048d6ec Setup+0x801f9
06 0019fc84 0048df82 Setup+0x8d6ec
07 0019ff44 0048f9bb Setup+0x8df82
08 0019ff80 779362c4 Setup+0x8f9bb
09 0019ff94 77ed0779 KERNEL32!BaseThreadInitThunk+0x24
00019ffdc 77ed0744 ntdll!__RtlUserThreadStart+0x2f
00019ffec 00000000 ntdll!_RtlUserThreadStart+0x1b

这个调用栈回溯与Process Monitor里看过的几处相差较远,不再细究。

用CFF Explorer看Setup.EXE,识别的特征是"Borland Delphi 4.0"。如果它真是用Delphi开发的,sub_47EF28入口形参与CryptoSetPassword()有差别就不足为奇了,但三组特征值是跑不了的。此番实操了带密码的zip解压算法识别,意外之喜。

没兴趣分析Setup.EXE其他细节,这是上个十年的小马,VT有44/72在告警,没啥分析价值。但我这次是其首次提交。

问女科学家,假PASS2008setup.exe从哪儿来的,她已然不记得了。本意是,若是同事、同行、朋友拷给她的,那我可以帮对方检查一下系统,既然都不记得源头了,只能祝福未知者,自求多福。

小木马沉睡太久,一朝唤醒,不幸落到本怪手上,替它烧一柱香,超度之。

经此一役,鉴于女科学家养马多年,敕封其为XX医科大学弼马温。


文章来源: http://mp.weixin.qq.com/s?__biz=MzUzMjQyMDE3Ng==&mid=2247484523&idx=1&sn=828ccc6cd6d26fcdf2d25b0fc3f51196&chksm=fab2c754cdc54e4237691b772b84a39e21b4b95df7a7df18f913bb6d2c5dc8625afe9c663612#rd
如有侵权请联系:admin#unsafe.sh