本文是针对Windows常见持久控制的第一次说明。
0x00 前言
前段时间有过个需求,判断 Office
是否开启宏,索性将 Windows常见持久控制 中有关 Office
的记录也在后文写一下。
- 判断是否安装了
Microsoft Office
- 判断是否开启了
宏
- 相关利用
0x01 环境说明
1 | Microsoft Windows 7 Ultimate x64 |
0x02 相关判断
VBAWarnings
键值数值数据说明1
2
3
41:启用所有宏
2:禁用所有宏并发出通知
3:禁用无数字部署的所有宏
4:禁用所有宏并且不通知代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55// 通过注册表检测 Office 是否开启宏
private static void OfficeVBAWarnings(string OfficeVersion)
{
List<string> OfficeFeatures = new List<string>()
{
"Excel", "Word", "PowerPoint"
};
foreach (string Features in OfficeFeatures)
{
string basekey = @"SOFTWARE\Microsoft\Office\" + OfficeVersion + @"\" + Features + @"\Security";
RegistryKey registryKey = Registry.CurrentUser.OpenSubKey(basekey);
if (registryKey != null)
{
string[] ValueNames = registryKey.GetValueNames();
if (registryKey.ValueCount == 0)
{
Console.WriteLine(" [>] {0} VBAWarnings: 2", Features);
}
else
{
foreach (string KeyName in ValueNames)
{
object VBAWarnings = registryKey.GetValue("VBAWarnings");
Console.WriteLine(" [>] {0} VBAWarnings: {1}", Features, VBAWarnings);
}
}
}
}
}
// 通过注册表检测 Office 版本
private static void OfficeIsInstall(string OfficeVersion)
{
string basekey = @"SOFTWARE\Microsoft\Office\" + OfficeVersion + @"\Common\InstallRoot";
RegistryKey registryKey = Registry.LocalMachine.OpenSubKey(basekey);
if (registryKey != null)
{
if (registryKey.GetValue("Path") != null)
{
Console.WriteLine(" [>] Microsoft Office Version: {0}", OfficeVersion);
OfficeVBAWarnings(OfficeVersion);
}
}
}
static void Main(string[] args)
{
List<string> OfficeVersions = new List<string>()
{
"8.0", "9.0", "10.0", "11.0", "12.0", "14.0", "15.0", "16.0"
};
foreach (string OfficeVersion in OfficeVersions)
{
OfficeIsInstall(OfficeVersion);
}
}
0x03 Office 模板宏
每次 Office
程序启动时都会加载使用 Office
程序中的基本模板。
相关位置
1 | Word Normal.dotm位置: |
这一部分在倾旋的博客有提到
新建宏名字 –> word
为AutoOpen, Excel
为Auto_Open
使用 GIF
进行演示(Excel 同理)
本地使用相对应的 Office
版本生成的全局宏,替换目标机器对应的 Office
版本的全局宏,可行。
0x04 Office 加载项
Office
中支持不同类型的加载项,从本质上来讲,Office
套装有很多受信任的位置,当放置库文件时,在打开 Office
程序时,会自动加载库文件。在 Office
的信任中心选择禁用加载项,实际上不会禁用WLL,也不会阻止VBA代码执行。
1)Word 的 WLL 加载项
Word
的三个默认加载项位置如下所示:
对用户位置中的 Startup
进一步调查发现,它是 Word 默认存放全局模板
和加载项
的文件夹,当启动Word时,程序会自动加载 Startup
文件夹中所有*.dot、*.dotx或*.dotm
格式的Word文件,也可以托管拓展名为 * .wll
的文件。而* .wll
文件本质上是一个带有额外特定于Office的扩展的DLL
。这意味着* .wll
文件起码可以实现基本的 DLL 功能
,我们只需要将*.dll
重命名为 *.wll
,放入此文件夹中,可获取当前启动 word 的用户
的执行权限。
示例:
1 | int Run() |
在这步骤出现了无法加载 wll
问题,所以我直接提问 Dominic Chell.,他给我的回答是:
1 | 我在测试的时候也遇到了这样的问题,我认为它是使用了 UI 来弹出东西的,所以建议使用一个简单的 MessageBox 进行测试。并且确保是从 attach 当中调用 Run()。 |
exp 思路就不说了。
所以我最后使用了上面代码注释行。成功,结果如下。
2)Excel 的 XLL 加载项
1 | 在HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Options注册表项中添加一个键值 |
Excel
启动时,会自动检索 C:\Users(username)\AppData\Roaming\Microsoft\AddIns
目录,所以不需要写入绝对路径,默认自动加载。
1 | // DemoAddin.xll EXPORTS is xlAutoOpen |
3)PowerPoint 的 VBA 加载项
1 | HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\PowerPoint\AddIns\<AddInName> |
文件格式为 *.ppam
或 *.ppa
,也是与Excel 一样,放入AddIns
目录中。设置 Autoload
键值为 1 ,更改PowerPoint 启动时自动加载加载项。
关于wll(DLL)
、 xll(dll)
和 ppam(VBA)
的利用,可自行研究。
4)更多
更多内容请阅读文章底部的参考文章。
0x05 参考
Office Application Startup
MAINTAINING ACCESS WITH NORMAL.DOTM
Beyond good ol’ Run key, Part 62
Add-In Opportunities for Office Persistence
Persistence: “the continued or prolonged existence of something”: Part 1 – Microsoft Office
EvilClippy