CreateProcessAsUser之创建进程时指定父进程与UAC(UAC原理)

2024-02-24 10:18

本文主要是介绍CreateProcessAsUser之创建进程时指定父进程与UAC(UAC原理),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

UAC

UAC(user account control),这里科普下UAC的功能,其实UAC就是大家常见的安装软件或者启动程序的时候的出现的全屏变暗的一个提示框,正常的UAC级别下,会检测程序是否有数字签名(可识别程序),以及他的数字签名是否合法,这对于一部分低端的木马具有提醒作用,所以除非特殊情况,不要乱对UCA降权。
在这里插入图片描述

UAC运行原理:

在Windows Vista操作系统中。
用户账户主要有两种:标准用户(stand user) 和 管理员用户 (administrator)
一般在计算机上创建的第一个用户将成为管理员,后续用户默认设置为标准用户。

为什么要有UAC
Windows Vista以前的操作系统,一旦以管理员身份登录的用户被攻破,那就权限崩溃,所以用户们不得不使用标准用户身份登录,一些特殊情况才使用管理员权限。

而有了UAC 用户不在需要专门以标准用户去登录。

因为当一个标准用户登录到计算机时,Vista将创建一个新的登录会话,并通过一个操作系统创建的、与刚刚创建的这个登录会话相关联的shell程序(例如Windows Explorer)作为访问令牌颁发给用户。

而当一个管理员登录到计算机时,Windows Vista的处理方式却与先前版本的Windows有所不同。虽然系统创建了一个新的登录会话,但却为该登录会话创建了两个不同的访问令牌,而不是先前版本中的一个。第一个访问令牌提供了管理员所有的许可和权限,而第二个就是所谓的“受限访问令牌”,有时候也叫做“过滤访问令牌(filtered token)",该令牌提供了少得多的许可和权限。实际上,受限访问令牌所提供的访问权限和标准用户的令牌没什么区别。然后系统将使用该受限访间令牌创建 shell应用程序。这也就意味着即使用户是以管理员身份登录的,其默认的运行程序许可和权限仍为标准用户。

若是该管理员需要执行某些需要额外许可和权限的、并不在受限访间令牌提供权限之内的操作,那么他/她可以选择使用非限制访问令牌所提供的安全上下文来运行该应用程序。在由受限访问令牌“提升到非限制访间令牌的过程中,Windows Vista将通过给管理员提示的方式确认该操作,以其确保计算机系统的安全。恶意代码不可能绕过该安全提示并在用户不知不觉中得到对计算机的完整控制。

UAC提权

进程完整性级别,系统的每个进程有相应的完整性级别标志,与资源的完整性级别相互验证,以提供额外的安全保护。

用户态进程可以设置如下四种完整性级别:

1.Low
2.Medium
3.High
4.System

管理员的标准用户模式下(未提升)是(Medium)完整性级别
经过提升后拥有高(High)完整性级别。
运行于Local System之下的账户拥有(System)完整性级别

提权简单流程:

  1. 获取需要查询的进程的访问令牌
  2. 根据令牌获取指定类型信息,得到表示完整性级别的SID
  3. 根据该进程的SID,决定是否需要用户确认,然后进行提权。

《深入解析Windows操作系统》里面讲解了UAC的原理,里面的意思是这样解释UAC提权的:

当用户允许一次UAC提权时,AIS服务(AppInfo Service)调用的CreateProcessAsUser() 函数创建进程并且赋予恰当的管理员权限,在理论上说AIS服务(所在的进程)是提权后辣个进程的父进程。

然而,当我们用一些进程查看管理工具 进行查看时,会发现已经被提权的进程,它的父进程是创建它的进程,而不是AIS服务(所在的进程)。

这是因为AIS利用了CreateProcessAsUser() API中的一个新的功能,这里的新功能就是将要被提权的进程的父进程设置成创建该进程的进程,如果我们利用一下该API,就可以把一个进程的父进程设置为任意进程。

如果把木马进程的父进程设置为 杀软 或者csrss.exe ,notepad.exe 等可信进程,那么对于依据父进程可疑(进程链)来查杀的杀软就轻易绕过了。(360绕不过,估计慢慢的都会意识到这点)。

下面的代码就是关于CreateProcessAsUser()的使用:

原理->MSDN:
如果是CreateProcessAsUser 的dwCreationFlags 的参数被设置为EXTENDED_STARTUPINFO_PRESENT, 这就是有扩展启动信息的结构体,
这里的IpStartupInfo参数需要填好STARTUPEX 结构
这个结构由STARTUOINFO结构和PROC_THREAD_ATTRIBUTE_LIST 指针构成

typedef struct _STARTUPINFOEX {STARTUPINFO                 StartupInfo;PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
} STARTUPINFOEX, *LPSTARTUPINFOEX;

也就是说,调用CreateProcessAsUser 且设置dwCreationFlags参数的值为EXTENDED_STARTUPINFO_PRESENT,此时再将结构体中的PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList 值设置目标父进程的属性。

下面看具体代码:

//一般情况下,创建子进程的进程 就是子进程的父进程。而这部分代码功能: 去指定任何一个有相应权限的进程为新创建进程的父进程#include <iostream>
#include <Windows.h>
#include <Tlhelp32.h> //因为Tlhelp32.h 中一些宏定义是在windows.h中定义的,所以Tlhelp32.h 要定义在windows.h的后面
#pragma comment(lib, "Advapi32.lib")int main()
{
/LPVOID pAlloc1;LPVOID pAlloc2;HANDLE hfile;PIMAGE_NT_HEADERS pPeHeader;PIMAGE_SECTION_HEADER pSectionHeader;int lastError, ReadInfo = 0;DWORD BytesRead = 0;CONTEXT Context = { 0 };Context.ContextFlags = CONTEXT_ALL;PROCESSENTRY32 pe;// explorer.exe的进程IDDWORD  pid = 0;HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);pe.dwSize = sizeof(PROCESSENTRY32);if (!Process32First(hSnapshot, &pe))return 0;do{pe.dwSize = sizeof(PROCESSENTRY32);if (Process32Next(hSnapshot, &pe) == FALSE)break;if (wcscmp(pe.szExeFile, L"cmd.exe") == 0){pid = pe.th32ProcessID;break;}} while (1);CloseHandle(hSnapshot);/* 以全部权限打开explorer.exe 进程 */HANDLE handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);/* 创建启动信息结构体 */STARTUPINFOEXA si;/* 初始化结构体 */ZeroMemory(&si, sizeof(si));/* 设置结构体成员 */si.StartupInfo.cb = sizeof(si);SIZE_T lpsize = 0;/* 用微软规定的特定的函数初始化结构体 */InitializeProcThreadAttributeList(NULL, 1, 0, &lpsize);//首先要获取到需要初始化的大小char * temp = new char[lpsize];/* 转换指针到正确类型 */LPPROC_THREAD_ATTRIBUTE_LIST AttributeList = (LPPROC_THREAD_ATTRIBUTE_LIST)temp;/* 真正为结构体初始化属性参数 */InitializeProcThreadAttributeList(AttributeList, 1, 0, &lpsize);//设置AttributeList结构体属性个数以及初始化它的大小/* 用已构造的属性结构体更新属性表 */if (!UpdateProcThreadAttribute(AttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, &handle, sizeof(HANDLE), NULL, NULL)){//更新AttrubuteList 属性,添加PROC_THREAD_ATTRIBUTE_PARENT_PROCESS属性printf("UpdateProcThreadAttribute failed ! (%d).\n", GetLastError());}/* 移交指针,这里已更换了父进程的属性表是 explorer.exe */si.lpAttributeList = AttributeList;PROCESS_INFORMATION pi;ZeroMemory(&pi, sizeof(pi));//当调用下面的api 且createFlags的参数是EXTENDED_STARTUPINFO_PRESENT时,lpStartupInfo就需要有扩展的信息,也就是这条属性:PPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;if (CreateProcessAsUserA(NULL, 0, "C:\\Users\\Administrator\\Desktop\\Play.exe", 0, 0, 0, EXTENDED_STARTUPINFO_PRESENT, 0, 0, (LPSTARTUPINFOA)&si, &pi)){printf("CreateProcessAsUserA success !  \n");}else{printf("CreateProcessAsUserA failed ! (%d). \n ", GetLastError());}/* 处理后事 */DeleteProcThreadAttributeList(AttributeList);delete temp;printf("exit");getchar();return 0;
}

UAC绕过有些复杂呀,以后有机会试试。
关于绕过UAC的文章链接:
https://www.freebuf.com/vuls/183914.html

这篇关于CreateProcessAsUser之创建进程时指定父进程与UAC(UAC原理)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/741784

相关文章

Python一次性将指定版本所有包上传PyPI镜像解决方案

《Python一次性将指定版本所有包上传PyPI镜像解决方案》本文主要介绍了一个安全、完整、可离线部署的解决方案,用于一次性准备指定Python版本的所有包,然后导出到内网环境,感兴趣的小伙伴可以跟随... 目录为什么需要这个方案完整解决方案1. 项目目录结构2. 创建智能下载脚本3. 创建包清单生成脚本4

python获取指定名字的程序的文件路径的两种方法

《python获取指定名字的程序的文件路径的两种方法》本文主要介绍了python获取指定名字的程序的文件路径的两种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要... 最近在做项目,需要用到给定一个程序名字就可以自动获取到这个程序在Windows系统下的绝对路径,以下

SpringBoot实现不同接口指定上传文件大小的具体步骤

《SpringBoot实现不同接口指定上传文件大小的具体步骤》:本文主要介绍在SpringBoot中通过自定义注解、AOP拦截和配置文件实现不同接口上传文件大小限制的方法,强调需设置全局阈值远大于... 目录一  springboot实现不同接口指定文件大小1.1 思路说明1.2 工程启动说明二 具体实施2

ShardingProxy读写分离之原理、配置与实践过程

《ShardingProxy读写分离之原理、配置与实践过程》ShardingProxy是ApacheShardingSphere的数据库中间件,通过三层架构实现读写分离,解决高并发场景下数据库性能瓶... 目录一、ShardingProxy技术定位与读写分离核心价值1.1 技术定位1.2 读写分离核心价值二

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深入浅出Spring中的@Autowired自动注入的工作原理及实践应用

《深入浅出Spring中的@Autowired自动注入的工作原理及实践应用》在Spring框架的学习旅程中,@Autowired无疑是一个高频出现却又让初学者头疼的注解,它看似简单,却蕴含着Sprin... 目录深入浅出Spring中的@Autowired:自动注入的奥秘什么是依赖注入?@Autowired

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Spring创建Bean的八种主要方式详解

《Spring创建Bean的八种主要方式详解》Spring(尤其是SpringBoot)提供了多种方式来让容器创建和管理Bean,@Component、@Configuration+@Bean、@En... 目录引言一、Spring 创建 Bean 的 8 种主要方式1. @Component 及其衍生注解

Linux系统管理与进程任务管理方式

《Linux系统管理与进程任务管理方式》本文系统讲解Linux管理核心技能,涵盖引导流程、服务控制(Systemd与GRUB2)、进程管理(前台/后台运行、工具使用)、计划任务(at/cron)及常用... 目录引言一、linux系统引导过程与服务控制1.1 系统引导的五个关键阶段1.2 GRUB2的进化优

Python中的filter() 函数的工作原理及应用技巧

《Python中的filter()函数的工作原理及应用技巧》Python的filter()函数用于筛选序列元素,返回迭代器,适合函数式编程,相比列表推导式,内存更优,尤其适用于大数据集,结合lamb... 目录前言一、基本概念基本语法二、使用方式1. 使用 lambda 函数2. 使用普通函数3. 使用 N