简介

在2022年的Defcon大会上,安全研究人员Wietze
Beukema通过对进程级环境变量的研究,提出了一种Dll劫持新思路,下面就其中涉及的技术点展开介绍。

**01 **环境变量

每一个进程都有一个环境块,其中包含一组环境变量及其值。有两种类型的环境变量,用户环境变量和系统环境变量。

用户环境变量 :仅对当前用户有效,位于:HKEY_CURRENT_USER\Environment

系统环境变量
:对所有用户均有效,位于:HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session
Manager\Environment

默认情况下,子进程继承其父进程的环境变量。命令处理器启动的程序继承命令处理器的环境变量。

**02 **劫持原因

程序可能会依赖Windows定义好的环境变量来确定某些文件的位置,尤其对于Windows内置程序来说大量依赖环境变量来寻找系统盘文件。如下展示的是Windows系统盘ws2_32.dll中的代码片段:

正常来说"%SystemRoot%/System32/mswsock.dll"会被解析为"C:/Windows/System32/mswsock.dll",但是这里面有一个不确定的因素就是"%SystemRoot%“,假设我们修改了环境变量”%SystemRoot%"的值为其他文件夹路径且在该路径下存放恶意Dll,那么程序就会加载我们设定的Dll,继而完成Dll劫持。

如果直接更改"%SystemRoot%“的值,会对整个操作系统上运行的程序产生影响,但是我们可以只修改指定进程的环境变量,如创建以下vbs脚本,利用子进程默认继承其父进程环境变量的特性,修改Windows内置进程hostname.exe的环境变量"SystemRoot"为"C:\Evil”。

Set shell = WScript.CreateObject("WScript.Shell")
shell.Environment("Process")("SystemRoot") = "C:\Evil"
shell.Exec("C:\windows\system32\hostname.exe")

操作流程如下:

然后用Procmon监控hostname.exe,可以看到确实会加载"C:\Evil"路径下的Dll。

**03 **持久化

从上面流程可以看到,能够完成Dll劫持的关键在于修改环境变量的值,那么完成持久化的关键就在于维持目标进程环境变量值的修改。下面提供2种持久化方案:

利用注册表修改Windows自启服务的环境变量

这里先引用下Wietze Beukema文章中提到的修改Windows打印机服务的环境变量,看是否会成功加载指定目录下的Dll文件。

1. 首先将恶意Dll"mswsock.dll"放到指定目录"C:\Evil\System32"

2. 在注册表spoolsv服务下创建"Environment"键值修改环境变量

3. 重启spoolsv服务,用Procmon进行监控

可以看到使用上述方式修改Windows服务的环境变量确实能够加载我们指定目录下的Dll文件。但是需要注意的是,有时候为了保证被修改的服务能够正常运行,我们需要将受环境变量影响的Dll全部移动到我们指定的路径下。

实际上能够被利用的Windows服务远不止上面一个,通常来说服务对应一个PE文件,这里我们去看看Windows自带服务的PE文件路径是如何写的就明白了。

可以看到很多服务都依赖环境变量来寻找所对应的PE文件,这里我推荐修改的Windows自启服务是Windows推送通知系统服务(WpnService),修改环境变量后只需移动一个受影响的Dll文件即可,不用管该服务是否能够正常运行。

常规持久化配合创建子进程

我们也可以使用常规持久化方案如创建计划任务或者写注册表来实现自启,然后程序自启后自修改自身环境变量值,最后创建受环境变量影响的Windows可信进程,利用Dll劫持来完成一次隐匿攻击行为。

接下来使用Win32 API来展示下如何修改子进程的环境变量。

1. 子进程Child.exe代码如下:

#include <windows.h>
int main(int argc, char* argv[], char* envp[]) {
char szBuf[MAX_PATH] = {};
GetEnvironmentVariable("SystemRoot", szBuf, sizeof(szBuf));
MessageBox(NULL, szBuf, "Child", MB_OK);
return 0;
}
  1. 父进程Parent.exe代码如下:

    #include <stdio.h>
    #include <windows.h>
    int main(int argc, char* argv[], char* envp[]) {
    SetEnvironmentVariable(“SystemRoot”, “C:\Evil”);
    UINT nRet = WinExec(“C:/Users/Super/Desktop/Child.exe”, SW_HIDE);
    if (nRet > 31)
    {
    printf(“创建子进程成功\n”);
    }
    else
    {
    printf(“创建子进程失败\n”);
    }
    return 0;
    }

3. 运行Parent.exe进程,查看结果

以上需要注意一点的就是,当Child.exe进程需要的权限比Parent.exe进程高时,Parent.exe创建Child.exe进程时会失败,当然也就无法谈起修改其环境变量值了,如下:

**04 **预防和影响范围

环境变量是Windows的一个历史包袱,随着Windows注册表出现,可以在一定程度上代替环境变量。但是为了考虑兼容性,它依然存在且在Windows内部大量使用。关于这点,我们可以对程序进行简单的调试,对ExpandEnvironmentStringsW
API函数下断回溯,就会发现很多Windows内置Dll在使用环境变量来确定某些文件,如下:

我们自己写的程序或者模块可能会引用Windows系统Dll文件,但是Windows内部Dll文件大量引用环境变量,这会让我们的程序可能会受到此类Dll劫持手法的攻击。为了尽可能的减少风险,在编码时我们可以遵循以下规则:

1.
程序代码使用GetWindowsDirectory代替环境变量"%SystemRoot%",或者使用GetSystemDirectory直接拿系统盘System32路径

2. 对系统Dll进行路径检测

3. 对程序加载的Dll进行签名校验

**05 **总结

1.
相对于传统Dll劫持利用Windows加载Dll时的搜索顺序,将恶意Dll存放在目标程序所在文件夹之下来完成Dll劫持。该方式可以保持目标程序所在文件夹的纯净度,可有效规避检测。

2. "海量"的Windows服务和内置进程均受环境变量的影响,这值得引起我们安全研究人员对环境变量的重视,以应对后面可能出现的此类攻击手法。

网络安全工程师企业级学习路线

这时候你当然需要一份系统性的学习路线

如图片过大被平台压缩导致看不清的话,可以在文末下载(无偿的),大家也可以一起学习交流一下。

一些我收集的网络安全自学入门书籍

一些我白嫖到的不错的视频教程:

上述资料【扫下方二维码】就可以领取了,无偿分享

DEFCON议题解读|Dll劫持新思路——修改环境变量相关推荐

  1. linux修改jdk版本无效,关于windows和linux系统更换JDK版本后,修改环境变量也无法生效的原因和解决办法...

    今天遇到了一个问题: 我linux系统之前安装JDK12,今天将其改成了JDK1.8,并修改了环境变量,但是通过java -version命令显示的依旧是JDK12的版本. 这是因为,当使用安装版本的 ...

  2. Mac下修改环境变量

    Mac下修改环境变量 如果使用默认Bash, 首先修改 ~/.bash_profile 文件,添加文件路径,比如: export PATH=~/bin:/usr/local/bin/node:~/Do ...

  3. linux mint(Ubuntu、Debian) 18修改环境变量

    修改环境变量 [plain] view plain copyprint? sudo gedit /etc/profile sudo gedit /etc/profile 在profile文件的末尾添加 ...

  4. java环境变量修改不了_win10系统安装了jdk,修改环境变量配置不生效的解决方法...

    Win10系统安装了jdk,修改环境变量配置不生效怎么办?今天系统天地给大家分享win10系统安装了jdk,修改环境变量配置不生效的解决方法. 访问: win10系统安装了jdk,修改环境变量配置不生 ...

  5. linux修改jdk环境变量6,Linux CentOS 6.5 使用自带jdk修改环境变量(示例代码)

    首先声明,默认jdk指我们安装完CentOS后系统自带jdk,自己下载安装的jdk只需要下载,解压即可,之后步骤与此文一致 1.查看我们默认jdk的位置 指令: which java 我们去看一下发现 ...

  6. window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法

    window下在同一台机器上安装多个版本jdk,修改环境变量不生效问题处理办法 本机已经安装了jdk1.7,而比较早期的项目需要依赖jdk1.6,于是同时在本机安装了jdk1.6和jdk1.7. 安装 ...

  7. MAC IOS ssh 连接下修改环境变量

    根路径: suningdeMac-mini:/ suning$ ls Applications System bin etc net tmp Library Users cores home priv ...

  8. Mac Pro 修改环境变量

    参考:Ubuntu 12 修改环境变量 [实战] 把 php.php-fpm.nginx.mysql 的相关命令路径添加到 用户环境变量 $ vim ~/.bash_profile alias ll= ...

  9. 苹果电脑上使用linux环境变量,mac系统下修改环境变量

    苹果电脑使用率越来越高,在mac系统下研发,性能要比在windows下快不少,既然要开发,免不了要配置环境变量.下面是学习啦小编收集整理的mac系统下修改环境变量,希望对大家有帮助~~ mac系统下修 ...

最新文章

  1. xp创建虚拟服务器,Xp系统怎么创建虚拟目录?Xp系统创建虚拟目录的方法
  2. GAN网络生成:感知损失(Perceptual Losses)
  3. 极光API推送 (v3 版本)
  4. obj: object是什么意思_面试官问你JavaScript基本类型时他想知道什么?
  5. .net aspose.words 域加载图片_使用Python批量替换csdn文章的图片链接
  6. 如何在React中从其父组件更改子组件的状态
  7. jsonp请求html页面,JavaScript中的JSON和JSONP
  8. 2.图像作为函数 | 图像的量化、大小、类型、位置以及Matlab使用_4
  9. 域控服务器取消验证_AD域控
  10. TypeScript 让你不会想用回 JavaScript
  11. Web前端开发解耦1
  12. Atitit.检测文本文件的编码 自动获取文件的中文编码
  13. 【车间调度】基于matlab NSGA-2算法求解多目标车间调度问题【含Matlab源码 071期】
  14. UE4 如何导入外部插件包
  15. 2020 中国大学生计算机设计大赛
  16. win7自带截图工具怎样给菜单截图
  17. 屏蔽CSDN博客广告的油猴脚本
  18. 能否被2整除引发的思考
  19. iOS教程:移动终端游戏动画设计的12个原则
  20. linux下划线后面加变量名,Shell中下划线_与变量的关系

热门文章

  1. 3dsMax里GLTF插件的安装和使用
  2. SwiftUI + RealityKit 实现简单AR测距
  3. 【数通学员心得】成功没有捷径,HCIE也没有侥幸
  4. Unity判断机型是否为iPhoneX,iPhoneXS,iPhoneXR,以及iPhoneXS Max
  5. pyppeteer中文文档
  6. 装修日记19 装修上的风水学问
  7. 扫码枪扫码后触发方法
  8. 如何设置企业KPI,Smartbi给您方法论
  9. 手机如何去视频水印?只需几步轻松搞定
  10. Hadoop3.3.0入门到架构篇之一