Windows核心编程_提权
在Windows下编程有些涉及到硬件或者跨内存的API会发现失效了,原因是因为权限问题,这也是Windows出于安全的保护,但是事物都有两面性的,Windows又为我们提供了提权的API!
1.AdjustTokenPrivileges方式为用户创建一个令牌权限并提权
步骤:
1.打开进程权限获得对此进程访问的权限OpenProcessToken
2.查看系统权限内容LookupPrivilegeValue
3.根据权限内容对其进行提权AdjustTokenPrivileges
函数介绍:
OpenProcessToken
作用:得到指定进程上的令牌地址
BOOL OpenProcessToken(
__in HANDLE ProcessHandle, //要修改访问权限的进程句柄
__in DWORD DesiredAccess, //指定你要进行的操作类型,进行AdjustTokenPrivileges提权必须使用TOKEN_ADJUST_PRIVILEGES方式来提权
__out PHANDLE TokenHandle //返回的访问令牌指针
);
LookupPrivilegeValue
作用:查看系统上所允许的令牌权限
BOOL LookupPrivilegeValue(LPCTSTR lpSystemName,LPCTSTR lpName,PLUID lpLuid);
第一个参数表示所要查看的系统,本地系统直接用NULL
第二个参数指向一个以零结尾的字符串,指定特权的名称,如在WinNT h头文件定义。例如,此参数可指定常数,se_security_name,或其对应的字符串,“sesecurityprivilege ";。
第三个参数用来接收所返回的制定特权名称的信息。
函数调用成功后,信息存入第三个类型为LUID的结构体中,并且函数返回非0。
LUID结构体介绍:TOKEN_PRIVILEGES contains information about a set of privileges for an access token.typedef struct _TOKEN_PRIVILEGES{ULONG PrivilegeCount; //数组元素的个数LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]; //数组.类型为LUID_AND_ATTRIBUTES} TOKEN_PRIVILEGES, *PTOKEN_PRIVILEGES;
PrivilegeCount
指定 特权数组的个数(因为下一个参数是一个数组)
Privileges
一个LUID_AND_ATTRIBUTES结构体. 每个结构体包括LUID和特权的属性. 特权的属性可以是下列值的组合:
属性 描述
SE_PRIVILEGE_ENABLED_BY_DEFAULT 特权默认启用
SE_PRIVILEGE_ENABLED 特权启用.
SE_PRIVILEGE_USED_FOR_ACCESS 特权被用来访问一个对象或服务。这个标志 被用于 标识有关特权,因为通过一组客户端应用程序,可能包含不必要的特权
AdjustTokenPrivileges
AdjustTokenPrivileges这个函数启用或禁止 指定访问令牌的特权。
启用或禁用特权一个有TOKEN_ADJUST_PRIVILEGES访问的访问令牌.
BOOL AdjustTokenPrivileges(
HANDLE TokenHandle, //包含特权的句柄
BOOL DisableAllPrivileges,//禁用所有权限标志
PTOKEN_PRIVILEGES NewState,//新特权信息的指针(结构体)
DWORD BufferLength, //缓冲数据大小,以字节为单位的PreviousState的缓存区(sizeof)
PTOKEN_PRIVILEGES PreviousState,//接收被改变特权当前状态的Buffer
PDWORD ReturnLength //接收PreviousState缓存区要求的大小
);
参数
TokenHandle
包含要修改特权的访问令牌的标识(句柄).这个句柄必须有TOKEN_ADJUST_PRIVILEGES访问令牌.如果PreviousState不是NULL,这个句柄还必须有TOKEN_QUERY访问特权.
DisableAllPrivileges
标志这个函数是否禁用该令牌的所有特权.如果为TRUE,这个函数禁用所有特权,NewState参数无效.如果为假,以NewState参数指针的信息为基础来修改特权.
NewState
一个TOKEN_PRIVILEGES结构体的指针指定了一组特权和他们的属性.
如果参数DisableAllPrivileges为FALSE,AdjustTokenPrivileges 启用或禁用这些令牌的特权.
如果你给一个特权设置了SE_PRIVILEGE_ENABLED的属性,这个函数将启动特权,否则禁用特权.
如果DisableAllPrivileges为TRUE,这个参数无效.
BufferLength
标志参数PreviousState指针以字节大小缓存区(sizeof).
如果参数PreviousState是NULL,这个参数可以为NULL.
PreviousState
这个函数填充一个TOKEN_PRIVILEGES结构体【指针】,它包括该函数修改之前任何特权状态.这个参数可以为NULL.
如果指定的缓冲区太小,无法收到完整的修改权限列表,这个函数失败并不会修改任何特权.
这个函数设置了一个 拥有修改权限完成列表【 参数ReturnLength 】的字节数 的指针变量.[结果的Buffer]
ReturnLength
接收 参数PreviousState的缓存区指针的 字节大小 的 变量指针(长度指针).
如果PreviousState为NULL,这个参数可以为NULL.
返回值
如果这个函数成功,返回非0.为了确定这个函数是否修改了所有指定的特权,可以调用GetLastError函数,当这个函数返回下面的值之一时就代表函数成功:
值 |
描述 |
ERROR_SUCCESS |
这个函数修改了所有指定的特权。 |
ERROR_NOT_ALL_ASSIGNED |
这个令牌没有参数NewState里指定一个或多个的权限。(一个或多个没有修改成功). 即使权限没有被修改。这个函数也可能成功(返回这个error值) 表明 参数PreviousState 被修改。 |
如果这个函数失败,返回0.要得到更多的错误信息,调用GetLastError.
备注
AdjustTokenPrivileges函数不能添加新的特权到访问令牌.它只能启用或禁用令牌现行的令牌.要想确定这个令牌的特权,调用GetTokenInformation函数.
请注意,参数NewState可以不给令牌指定权限,这不会导致函数失败.
在这种情况下,这个函数修改令牌现有的特权,其他特权无效,并成功返回.
调用GetLastError函数,以确定这个函数修改了所有指定的特权.
PreviousState参数表明特权被修改.
参数PreviousState 返回一个 包含 修改权限 原始状态的结构体 TOKEN_PRIVILEGES,
这样就可以在随后调用AdjustTokenPrivileges函数时,传递PreviousState指针到 参数NewState ,来恢复原来的状态.
最后关闭令牌对象即可
CloseHandleBOOL CloseHandle(HANDLE hObject);
参数
hObject :代表一个已打开对象handle。
返回值
TRUE:执行成功;
FALSE:执行失败,可以调用GetLastError()获知失败原因。
使用方法:
HANDLE hToken; //令牌指针if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) //ADJUST提权{TOKEN_PRIVILEGES tp; //存储权限结构体tp.PrivilegeCount = 1;tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; //要获取的权限类型if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid)) //查看权限{AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); //提权}CloseHandle(hToken); //关闭提权}
2.RtlAdjustPrivilege
此方法是MSDN没有公开的函数,相比上面的提权方法这个API更加直接,此函数存在于NsDll里
RtlAdjustPrivilege
NTSTATUS RtlAdjustPrivilege(ULONG Privilege,BOOLEAN Enable,BOOLEAN CurrentThread,PBOOLEAN Enabled)
参数的含义:
Privilege // 所需要的权限名称msdn公开权限名,但没用给出具体作用,可以通过给出名来判别:SE_BACKUP_PRIVILEGE, "17"SE_RESTORE_PRIVILEGE, "18"SE_SHUTDOWN_PRIVILEGE, "19"SE_DEBUG_PRIVILEGE, "20"//需要自己手动声明出来#defineEnable [In] If TRUE, then enable the privilege otherwise disable.// 如果为True 就是打开相应权限,如果为False 则是关闭相应权限CurrentThread [In] If TRUE, then enable in calling thread, otherwise process.// 如果为True 则仅提升当前线程权限,否则提升整个进程的权限Enabled [Out] Whether privilege was previously enabled or disabled.// 输出原来相应权限的状态(打开 | 关闭)
使用方法:
const unsigned long SE_DEBUG_PRIVILEGE = 0x14; //声明调试权限typedef int(__stdcall *fRtlAdjustPrivilege)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);int main(int argc, char** argv) {HMODULE hNtDll = LoadLibrary("ntdll.dll");//得到dll句柄if (!hNtDll)return;fRtlAdjustPrivilege funcAdjustPrivilege =(fRtlAdjustPrivilege)GetProcAddress(hNtDll, "RtlAdjustPrivilege"); //获取APIif (funcAdjustPrivilege){BOOLEAN oldStatus;funcAdjustPrivilege(SE_DEBUG_PRIVILEGE, true, false, &oldStatus); //调用API}FreeLibrary(hNtDll); //释放dll}
Windows核心编程_提权相关推荐
- Windows核心编程_设置Windows开机自动登录
设置自动登录的方法在Windows中已经给出了非常方便的方法,当Windows内核进入登入界面时会检查HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\ ...
- Windows核心编程_获取鼠标指定位置的RGB颜色值
Windows核心编程_获取鼠标指定位置的RGB颜色值 大家平常会见到很多屏幕取色工具,其原理都是获取鼠标位置的屏幕像素点颜色! 一般思路都是:获取鼠标位置,然后取出鼠标指向的屏幕像素点颜色! Get ...
- Windows核心编程_关闭Windows
下面介绍几种在Windows编程中关闭Windows的几种方式 首先介绍一个API ExitWindowsEx 这个API是WIndows下为开发人员提供的对操作系统睡眠的几种方式 API介绍: 函数 ...
- Windows核心编程_注册表操作和小练习程序关联
大家有没有见过就是当我们下载一个软件比如视频播放器 下载之后我们电脑上的视频文件图标都变成了这个视频播放器的图标,然后打开时也是默认调用此视频播放器来播放 下面就给大家介绍如何在Windows平台上实 ...
- Windows核心编程_远线程方式实现Dll注入
之前有介绍过HOOK的方式注入,这次介绍以其它方式注入,而无须HOOK,要知道在Windows这个浩荡的海洋里,API就是宝藏,找到足够多的宝藏那么你就是海贼王~! 实现思路如下: 首先打开一个进程的 ...
- Windows核心编程_代码段共享_LocalAlloc/GlobalAlloc区别
数据段共享 数据段共享起源于Windows16位的时代,在Win16操作系统时代下,16位windows用一个全局堆和局部堆来管理内存,每一个应用程序或dll装入内存时,代码段被装入全局堆,而系统又为 ...
- Windows核心编程_判断是否管理员权限运行
在Windows安全性越来越强的情况下,不常于XP时代,几乎毫无安全可言,各种对内核文件操控的rin3API不需要权限就可以运行和随意修改,如常见的注册表需改! 但是Win8以后安全性得到了强力的提升 ...
- Windows核心编程_窗口透明组件不透明
经过前几篇对界面编程的学习,已经对Windows窗口消息有了更加深刻的理解,今天就教大家写一个窗口透明而组件却不透明的小示列! 这个demo并不难,而且还非常的简单,如果你看过我的前几篇针对界面编程写 ...
- Windows核心编程_修改其它进程里的内存值+示例:修改游戏分数
最近一直忙于Opencv图像处理方面的学习,以及工作,没有更新C/C++专栏方面的博客了,所以今天就给大家写个应用层方面的编程代码,可用于参考学习,本篇博客将运用WindowsSDK库所提供的API来 ...
最新文章
- Quart 2D 绘制图形简单总结
- easyUI 添加排序到datagrid
- 在JDK 8中连接字符串
- Linux将硬盘转化为pv,Linux扩展硬盘 物理卷(PV) 卷组(VG) 逻辑卷(LV)
- ib网卡命令_infiniband交换机配置命令总结
- html5网页制作图文混排,03第3章制作图文混排网页.docx
- IOS 创建简单表视图
- Zen Coding Visual Studio plugin 配置
- 24K 内存上诞生的操作系统,是如何改变计算机世界的?
- 【opencv入门篇】 10个程序快速上手opencv【上】
- 全国地图钻取(openlayers6+高德地图api行政区划)
- 努比亚手机浏览器 安全证书失效_今日热闻 | OnePlus 8海外版发布、Redmi科幻大片第一部公布、努比亚Play 5G宣布、快播正式破产拍卖...
- 本地计算机如何使用代理服务器,自动设置代理ip
- 2020年总结以及2021年的计划
- 【Trailhead题目解析】Prepare your salesforce org for users - 2Update the Exchange Rate with ACM
- Android 12 悬浮通知/横幅通知状态栏应用图标显示不全
- ElasticSearch 之 Linux 安装 ElasticSearch-7.15.2(ELK、IK)
- 天文学 python_4个天文学入门Python工具
- 点云旋转平移(一)—基础知识介绍
- Python学习笔记:Python基础使用
热门文章
- Linux服务器authorized_keys添加公钥后登录仍需要密码
- Tcl Tutorial 笔记2 · set ““ {} [] \
- 所有表单对象_表单太多汇总太累?请看这里,我们带你一键汇总
- php安装包进行安装吗,php的一键安装包有哪些php环境搭建
- liunx 环境下docker安装mysql
- jsp 页面刷新,EasyUI刷新、加载
- matlab求数的因子,matlab中因子分析的函数factoran如何使用??
- php判断学生姓名,PHP基础案例三:判断学生星座
- linux安装运行jmeter,Linux下安装运行Jmeter程序
- python如何打印文字_python怎么打印字符