Windows以字符串的形式表示系统权限。例如,“SeCreatePagefilePrivilege”表示该权限用于创建页面文件,“SeDebugPrivilege”表示该权限可用于调试和更改其他进程的内存。为了方便在代码中引用这些字符串,微软在winnt.h中定义了一组宏,如#define SE_DEBUG_NAME TEXT("SeDebugPrivilege")。完整的权限列表可以在msdn 的安全章节中找到。尽管Windows使用字符串来表示权限,但查询或更改权限的API需要LUID来引用相应的权限。 LUID代表本地唯一标识符,是一个64位的值,在当前系统中是唯一的。为了将进程权限升级到指定的权限,我们首先要找到该权限对应的LUID,然后调用LookupPrivilegeValue函数。
简介
在任何进程(包括系统安全进程和服务进程)上执行指定与写入相关的访问权限的OpenProcess 操作,只要当前进程具有SeDeDebug 权限。如果用户是管理员或已被授予相应权限,则可以拥有该权限。然而,即使我们使用管理员帐户在系统安全进程上执行OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID),我们仍然会遇到“Access Denied”错误。原因是什么?原来进程的一些访问权限默认是没有启用(Enabled)的,所以我们首先要做的就是启用这些权限。
流程
1.打开进程访问令牌
2.获取权限的LUID值
3.调整访问令牌权限值
使用函数
OpenProcessToken();
LookupPrivilegeValue();
调整TokenPrivileges();
函数介绍及大致流程
首先需要获取进程访问令牌的句柄,可以通过OpenProcessToken获取。函数原型如下:
BOOL OpenProcessToken(
HANDLE ProcessHandle, //修改访问权限的进程句柄
DWORD DesiredAccess, //对令牌执行什么操作
PHANDLE TokenHandle //返回的访问令牌指针
);第一个参数是修改访问权限的进程句柄;第三个参数是返回的访问令牌指针;第二个参数指定要执行的操作类型。如果要修改访问令牌的权限,我们需要指定第二个参数TOKEN_ADJUST_PRIVILEGES。通过该函数,我们可以获得当前进程的访问令牌的句柄(只需指定该函数的第一个参数为GetCurrentProcess()即可)。然后我们可以调用AdjustTokenPrivileges来修改这个访问令牌。
AdjustTokenPrivileges的原型如下:BOOL 调整TokenPrivileges(
HANDLE TokenHandle, //令牌句柄
BOOL DisableAllPrivileges, //禁用选项
PTOKEN_PRIVILEGES NewState, //权限信息
DWORD BufferLength, //缓冲区大小
PTOKEN_PRIVILEGES PreviousState, //原始状态缓冲区
PDWORD ReturnLength //所需的缓冲区大小
);第一个参数是访问令牌的句柄;第二个参数决定是修改权限还是失去(Disable)所有权限;第三个参数指定要修改的权限,它是指向TOKEN_PRIVILEGES结构体的指针。该结构体包含一个数组,数据组的每一项表示权限类型以及要执行的操作;第四个参数是该结构体的PreviousState指针所指向的缓冲区的大小。如果PreviousState 参数为空,则该参数应为NULL ;第五个参数也是指向TOKEN_PRIVILEGES结构体的指针,该结构体存储了修改前的访问权限信息,可以为null;最后一个参数是实际PRIVILEGES NewState 结构返回的大小。在使用这个函数之前,先看一下结构体TOKEN_PRIVILEGES。其声明如下:
typedef 结构_TOKEN_PRIVILEGES {
DWORD 权限计数;
LUID_AND_ATTRIBUTES 权限[];
} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;PrivilegeCount指的是数组元素的个数,后面跟着一个类型为LUID_AND_ATTRIBUTES的数组。我们看一下结构体LUID_AND_ATTRIBUTES的内容,其声明如下:
typedef 结构_LUID_AND_ATTRIBUTES {
液体液体;
双字属性;
} LUID_AND_ATTRIBUTES, *PLUID_AND_ATTRIBUTES 第二个参数指定我们要执行的操作类型,其特权属性Attributes 可以是以下常量:
SE_PRIVILEGE_ENABLED //使权限生效
SE_PRIVILEGE_ENABLED_BY_DEFAULT //使权限默认有效
SE_PRIVILEGE_REMOVED //移除权限
SE_PRIVILEGE_USED_FOR_ACCESS //要获取对象或服务的访问权限,如果要使用某个权限,请将Attributes指定为SE_PRIVILEGE_ENABLED。第一个参数指权限类型,即LUID的值。 LUID是指本地唯一的标识符。我想大家都熟悉GUID。与GUID要求保证全局唯一不同,LUID只需要保证全局唯一即可。局部唯一性是指在系统的每次运行过程中保证其是唯一的。另外,和GUID一样,LUID也是一个64位的值。相信大家都见过一长串的GUID值。我们如何知道某个权限对应的LUID值呢?
这就要用到另外一个API函数LookupPrivilegevalue,其原形如下:BOOL 查找权限值(
LPCTSTR lpSystemName, //系统名称
LPCTSTR lpName, //权限名称
PLUID lpLuid //本地唯一标识符
);第一个参数是系统的名称。如果是本地系统,则指定NULL即可。第三个参数是返回LUID 的指针。第二个参数是权限的名称,例如“SeDebugPrivilege”。 Winnt.h 中还定义了一些权限名称的宏,例如:
#define SE_BACKUP_NAME TEXT("SeBackupPrivilege")
#define SE_RESTORE_NAME TEXT("SeRestorePrivilege")
#define SE_SHUTDOWN_NAME TEXT("SeShutdownPrivilege")
#define SE_DEBUG_NAME TEXT("SeDebugPrivilege") 这样,通过调用这三个函数,我们就可以使用OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID)来获取任意进程的句柄并指定所有访问权限。
代码实现
#include#includeint main(void)
{
处理令牌_句柄;
//打开访问令牌
if(!OpenProcessToken(GetCurrentProcess(), //修改权限的进程句柄
TOKEN_ALL_ACCESS, //对令牌执行什么操作
token_handle //访问令牌
))
{
printf("openProcessToken 错误");
}
LUID 液体;
if(!LookupPrivilegeValue(NULL, //正在查看的系统本地为NULL。
SE_DEBUG_NAME, //要查看的权限名称
luid //用于接收标识符
))
{
printf("lookupPrivilege值错误");
}
TOKEN_PRIVILEGES tkp;
tkp.PrivilegeCount=1;
tkp.Privileges[0].Luid=luid;
tkp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED;
//调整访问令牌权限
if(!AdjustTokenPrivileges(token_handle, //令牌句柄
FALSE, //是否禁用权限
tkp, //新增权限的权限信息
sizeof(tkp), //权限信息大小
NULL, //用于接收当前权限信息状态的缓冲区
NULL //缓冲区大小
))
{
printf("调整错误");
}
printf("成功");
返回0;
}第五部分~~~~~~~~~~~~~~~
“长大到这个年纪,我都说不出自己最喜欢的电影、最喜欢的歌曲、最喜欢的人的名字。我常常觉得生活其实没那么有趣。有时我也会质疑生命的意义。所有的意义都来自书本别人的话从来没有说服过我,但今天我突然觉得,人生最大的意义就是用余生去寻找我最爱的人。” ——德卡老师的邮箱。
关于深入解析:Windows进程权限提升技术(C语言编写方法)的内容到此结束,希望对大家有所帮助。
【深入解析:Windows进程权限提升技术(C语言编写方法)】相关文章:
2.米颠拜石
3.王羲之临池学书
8.郑板桥轶事十则
用户评论
我一直想学习一下Windows下的进程提权技术,这篇文章能让我入门吗?
有13位网友表示赞同!
c语言实现进程提权听起来很专业,需要一定的编程基础吧?
有5位网友表示赞同!
我想知道这篇文章会详细介绍哪些常用提权技巧?
有20位网友表示赞同!
学习这些方法以后可以做什么呢?能不能分享一些实际应用场景?
有14位网友表示赞同!
这篇文章适合什么等级的开发者阅读?初学者也可以看得懂吗?
有13位网友表示赞同!
我听说Windows的安全机制越来越强大,这篇文章里提到的方法是否还有效?
有19位网友表示赞同!
有没有关于使用这些方法的后果的警告或讨论?需要谨慎操作吗?
有10位网友表示赞同!
作者会分享一些代码片段或者示例,方便理解吗?
有14位网友表示赞同!
我看了一下评论区,好像很多人都在问这个问题,但我始终不太明白“进程提权”是什么意思。
有8位网友表示赞同!
有没有人分享过相关的学习资料或课程,可以帮助我更好地理解这些概念?
有11位网友表示赞同!
我对安全攻防技术很有兴趣,想了解一下Windows下还有哪些其他的安全机制值得探索?
有10位网友表示赞同!
我会定期关注作者的新文章吗?希望能看到更多关于系统安全的精彩内容。
有8位网友表示赞同!
这篇文章会不会涉及到一些敏感的信息或技术,需要特别注意安全问题?
有11位网友表示赞同!
我想知道这篇文章的文末有没有提供一些参考链接或者书籍推荐,可以进一步学习相关知识?
有16位网友表示赞同!
我记得以前在网上看过一篇类似的文章,内容是不是差不多了呢?
有7位网友表示赞同!
期待作者能够在评论区积极回复大家的疑问,解答我们的困惑。
有13位网友表示赞同!
这篇文章能否详细介绍如何利用这些技术进行反恶意软件分析或漏洞挖掘?
有19位网友表示赞同!
有没有人尝试过使用这个方法来增强系统的安全性吗?效果怎么样?
有20位网友表示赞同!
我比较好奇作者为什么要选择C语言来实现进程提权,有什么特别的原因吗?
有9位网友表示赞同!