标题: 唤醒沉睡的木马 创建: 2020-11-23 15:25 更新: 链接: https://scz.617.cn/windows/202011231525.txt 给女科学家配了台新笔记本,装系统的重任自然是老砖家。系统好装、软件难配,她 有一堆医学科研相关的软件要装,而这些软件并不是我找来的,天晓得从哪里东拼西 凑而得,比如同事分享、学校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\10\x86\Debuggers\x86\cdb.exe" -noinh -snul -hd -o -p 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:000> db 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 0a 0019ffdc 77ed0744 ntdll!__RtlUserThreadStart+0x2f 0b 0019ffec 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医科大学弼马温。