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

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

k8s按需创建PV和使用PVC详解

《k8s按需创建PV和使用PVC详解》Kubernetes中,PV和PVC用于管理持久存储,StorageClass实现动态PV分配,PVC声明存储需求并绑定PV,通过kubectl验证状态,注意回收... 目录1.按需创建 PV(使用 StorageClass)创建 StorageClass2.创建 PV

Redis中Hash从使用过程到原理说明

《Redis中Hash从使用过程到原理说明》RedisHash结构用于存储字段-值对,适合对象数据,支持HSET、HGET等命令,采用ziplist或hashtable编码,通过渐进式rehash优化... 目录一、开篇:Hash就像超市的货架二、Hash的基本使用1. 常用命令示例2. Java操作示例三

Linux创建服务使用systemctl管理详解

《Linux创建服务使用systemctl管理详解》文章指导在Linux中创建systemd服务,设置文件权限为所有者读写、其他只读,重新加载配置,启动服务并检查状态,确保服务正常运行,关键步骤包括权... 目录创建服务 /usr/lib/systemd/system/设置服务文件权限:所有者读写js,其他

Redis中Set结构使用过程与原理说明

《Redis中Set结构使用过程与原理说明》本文解析了RedisSet数据结构,涵盖其基本操作(如添加、查找)、集合运算(交并差)、底层实现(intset与hashtable自动切换机制)、典型应用场... 目录开篇:从购物车到Redis Set一、Redis Set的基本操作1.1 编程常用命令1.2 集

Redis中的有序集合zset从使用到原理分析

《Redis中的有序集合zset从使用到原理分析》Redis有序集合(zset)是字符串与分值的有序映射,通过跳跃表和哈希表结合实现高效有序性管理,适用于排行榜、延迟队列等场景,其时间复杂度低,内存占... 目录开篇:排行榜背后的秘密一、zset的基本使用1.1 常用命令1.2 Java客户端示例二、zse