渗透技巧——快捷方式文件的参数隐藏技巧
0x00 前言
最近,phrozensoft在博客中介绍了关于快捷方式的利用技巧,实现了将应用程序存储在快捷方式当中,当用户打开快捷方式时,通过vbs脚本释放应用程序并运行。
我对此很感兴趣,因为快捷方式的参数默认存在长度限制,最大为260,并且我在研究jsrat的过程也遇到过这个问题(最后通过调用sct文件解决了长度限制问题)
phrozensoft分享了Delphi格式的POC代码,本文将要对其进行测试,研究lnk的文件格式,开发出对应powershell实现的POC代码,简单分析该技术的利用和防御方法
phrozensoft博客地址:
https://www.phrozensoft.com/2016/12/shortcuts-as-entry-points-for-malware-poc-part-2-19
0x01 简介
Delphi
是Windows平台下著名的快速应用程序开发工具
Borland公司研发
也可以在LINUX平台上开发应用,其在LINUX上的对应产品Kylix
常用版本:
- Borland Delphi 7
- Delphi 2010
0x02 Delphi POC测试
phrozensoft博客中也分享了其他功能的poc,如生成lnk文件的python脚本,本文暂不介绍,只测试其中的Delphi POC
环境搭建:
测试系统:Win7 x86
Delphi版本:Delphi 2010
注:
使用Delphi 7会存在编译不通过的错误,提示“File not found System.sysutils.dcu”
换用Delphi 2010后,poc作细微修改编译通过
1.新建工程
打开Delphi 2010
选择File-New-Other-Console Application
直接复制poc代码,提示错误,如图
2.修改poc
经测试,System.SysUtils需要更改为SysUtils
编译通过,如图
3.编译
选择Project-Build All Projects
如图,编译成功,生成Project1.exe
4.测试
新建test.txt,填入超过260个字符的数据:
echo 123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678123456781234567812345678
cmd下执行如下命令:
Project1.exe test.txt test.lnk
生成test.lnk
查看命令行参数,只能看到长度为260的字符串,如图
然而,lnk文件的大小为2.45kb,如图
(看起来我们发现了有趣的地方)
cmd下打开test.lnk,lnk文件的参数正常执行,显示的字符超过超过260个,没有被截断,如图
使用16进制编辑器Hex Editor查看lnk文件格式,如图
注:
无法使用UltraEdit,UltraEdit打开lnk文件默认会打开lnk指向的文件 实例如图,指向cmd.exe
0x03 Lnk文件格式介绍
1、整体结构
- 文件头
- Shell Item Id List段
- 文件位置信息段
- 描述字符段
- 相对路径段
- 工作目录段
- 命令行段
- 图标文件段
- 附加信息段
2、文件头结构
1.
偏移 | 长度 | 说明 |
---|---|---|
0h | 4字节 | 固定值,字符为L |
如图
2.
偏移 | 长度 | 说明 |
---|---|---|
4h | 4字节 | GUID |
如图
3.
偏移 | 长度 | 说明 |
---|---|---|
14h | 4字节 | 属性标志位 |
将该四字节以二进制表示,如果0-6位为1,分别代表该lnk文件包含以下属性:
0位 有shell item id list 1位 指向文件或文件夹 2位 存在描述字符串 3位 存在相对路径 4位 存在工作路径 5位 存在命令行参数 6位 存在自定义图标
如图
偏移14h,取4字节为000000f5,二进制表示为11110101
0、2、4、5、6位为1,对应包含如下属性:
- 有shell item id list
- 存在描述字符串
- 存在工作路径
- 存在命令行参数
- 存在自定义图标
4.
偏移 | 长度 | 说明 |
---|---|---|
18h | 4字节 | 目标文件属性 |
1ch | 8字节 | 文件创建时间 |
24h | 8字节 | 文件修改时间 |
2ch | 8字节 | 文件最后一次访问时间 |
34h | 4字节 | 目标文件长度 |
38h | 4字节 | 自定义图标个数 |
3ch | 4字节 | 窗口执行方式:1.正常2.最小化3.最大化 |
40h | 4字节 | 热键 |
3、shell item id list
由14h位置得出test.lnk存在shell item id list,所以从4ch开始的第一个段为shell item id list
偏移 | 长度 | 说明 |
---|---|---|
4ch | 2字节 | shell item id list总长度 |
如图
shell item id list总长度为0129
下一段(描述字符串)的起始地址为004e+0129=0177h
4、描述字符串
偏移 | 长度 | 说明 |
---|---|---|
004e+0129=0177h | 2字节 | 长度(Unicode),实际长度要乘以2 |
如图
描述字符串长度为000c(Unicode)
下一段(工作路径)的起始地址为0177+2+000c×2=0191h
5、工作路径
偏移 | 长度 | 说明 |
---|---|---|
0177+2+000c×2=0191h | 2字节 | 长度(Unicode),实际长度要乘以2 |
如图
工作路径长度为0012(Unicode)
下一段(命令行参数)的起始地址为0191+2+0012×2=01b7h
6、命令行参数
偏移 | 长度 | 说明 |
---|---|---|
0191+2+0012×2=01b7h | 2字节 | 长度(Unicode),实际长度要乘以2 |
如图
命令行参数长度为039f(Unicode)
下一段(自定义图标)的起始地址为01b7+2+039f×2=08f7h
7、自定义图标
偏移 | 长度 | 说明 |
---|---|---|
01b7+2+039f×2=08f7h | 2字节 | 长度(Unicode),实际长度要乘以2 |
如图
自定义图标长度为000bf(Unicode)
下一段(自定义图标)的起始地址为08f7+2+000b×2=090fh
0x04 实现原理
结合Delphi的POC代码和Lnk文件格式,对比正常lnk文件和poc文件差异,发现只有命令行参数长度不同
故推断出原理:
只要命令行参数长度超过260即可!
测试powershell代码:
$file = Get-Content "c:\test\test.txt"
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("c:\test\test.lnk")
$Shortcut.TargetPath = "%SystemRoot%\system32\cmd.exe"
$Shortcut.IconLocation = "%SystemRoot%\System32\Shell32.dll,21"
$Shortcut.Arguments = ' '+ $file
$Shortcut.Save()
test.txt中写入如下内容:
/c start calc.exe
执行命令后生成的test.lnk文件格式如图,260个空格字符后面接着为payload代码
查看文件参数,显示如图,均被空格字符填充,payload成功隐藏
运行test.lnk,弹出计算器,payload成功执行
完整过程如下图
gif在线地址:
https://raw.githubusercontent.com/3gstudent/BlogPic/master/2016-12-31/5-1.gif
0x05 利用思路
可将payload放置在260个空字符之后
这样无法在文件属性查看payload,只能通过文件格式去分析
payload加密后分析难度也会变大
0x06 防御
注意lnk文件大小
必要情况下,直接分析16进制lnk文件格式
0x07 小结
对于lnk文件,虽然通过查看文件属性无法看到lnk文件的命令行参数,但不代表其不存在,在此提醒用户注意