前言:今天逆向一个非常实用的函数RtlAdjustPrivliege这个函数封装在NtDll.dll中(在所有DLL加载之前加载),被微软严格保密,就是说你在MSDN上查不到关于他的任何信息。先来看看这个函数的定义(Winehq给出):
NTSTATUS RtlAdjustPrivilege
(
ULONG    Privilege,
BOOLEAN Enable,
BOOLEAN CurrentThread,
PBOOLEAN Enabled
)参数的含义:
Privilege [In] Privilege index to change.
// 所需要的权限名称,可以到MSDN查找关于Process Token & Privilege内容可以查到Enable [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.
// 输出原来相应权限的状态(打开 | 关闭)很多人大概没有听说过他的大名,但是相信有很多人见过进程提权的过程
拷一段我写的提权上来吧BOOL ImproveProcPriv()
{HANDLE token;//提升权限if(!OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES,&token)){MessageBox(NULL,"打开进程令牌失败...","错误",MB_ICONSTOP);return FALSE;}TOKEN_PRIVILEGES tkp;tkp.PrivilegeCount = 1;::LookupPrivilegeValue(NULL,SE_DEBUG_NAME,&tkp.Privileges[0].Luid);tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;if(!AdjustTokenPrivileges(token,FALSE,&tkp,sizeof(tkp),NULL,NULL)){MessageBox(NULL,"调整令牌权限失败...","错误",MB_ICONSTOP);return FALSE;}CloseHandle(token);return TRUE;
}看看吧,这个提权快要累死了...但是 如果有这个函数就不一样了,你可以只用一个函数就实现这个功能,甚至功能远多于上面的代码...通过恰当的IDE设置和必要的Defination,上面这个函数的功能你完全可以通过一行代码来实现。RtlAdjustPrivilege(SE_DEBUG_NAME,1,0,NULL);正文:下面我们看一下这个函数是怎么运行的,顺便学习下强大的IDA
IDA 载入ntdll.dll (我这里载入的是 WinDBG自动下载的 Symbol里面的英文版本 可能不同的Windows版本略有不同)先把函数的原型给输入IDA 方便一下阅读,然后开始阅读汇编代码了(党和国家考验我们的时候到了)。
看看Graph View 真的是很牛啊...
看看函数最开头...mov     edi, edi        ; 这句话是废指令
push    ebp
mov     ebp, esp
sub     esp, 30h        ; 48个字节的子过程域Auto变量
cmp     [ebp+CurrentThread], 1 ; 判断CurrentThread参数是否被指定为1
mov     eax, dword_7C97B0C8
mov     [ebp+var_4], eax
mov     eax, [ebp+Enabled]
mov     [ebp+IsEnabled], eax ; BOOL *IsEnabled = Enabled;
lea     eax, [ebp+var_28]
push    eax
jz      loc_7C93378B判断是调整进程权限还是线程权限,
CurrentThread == TRUE
push    0
push    28h             ; TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
push    0FFFFFFFEh      ; GetCurrentThread()
call    ZwOpenThreadToken
jmp     loc_7C929A7ACurrentThread == FALSE
push    28h             ; TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY
push    0FFFFFFFFh      ; GetCurrentProcess()
call    NtOpenProcessToken然后两个代码块同时指向这里
loc_7C929A7A:           ; 很明白了吧 判断进程/线程令牌是否成功被打开
test    eax, eax
jl      short loc_7C929AE4 ; 没成功则跳若 执行成功mov     eax, [ebp+Privilege]
mov     [ebp+dwPrivilege], eax
mov     al, [ebp+Enable]
xor     ecx, ecx        ; ecx清零
neg     al
push    esi
mov     [ebp+NewState], 1
mov     [ebp+var_C], ecx
sbb     eax, eax
and     eax, 2
mov     [ebp+var_8], eax
lea     eax, [ebp+ReturnLength] ; 实际返回长度
push    eax
lea     eax, [ebp+OldState]
push    eax             ; 旧的特权 指针
push    10h             ; sizeof(TOKEN_PRIVILEGES)
lea     eax, [ebp+NewState]
push    eax             ; 新的特权 指针
push    ecx             ; FALSE 因为上面有xor ecx,ecx
push    [ebp+TokenHandle]
call    NtAdjustPrivilegesToken ; 调用 AdjustPrivilegesToken提权
push    [ebp+TokenHandle]
mov     esi, eax        ; eax备份
call    ZwClose         ; 关闭 内核对象句柄
cmp     esi, 106h       ; 判断NtAdjustPrivilege执行情况 106h = STATUS_NOT_ALL_ASSIGNED
jz      loc_7C947DF2判断是否执行成功之后,开始输出最后一个参数cmp     [ebp+OldState], 0
mov     ecx, [ebp+IsEnabled]
jnz     loc_7C929E99若 OldState != 0 则mov     al, [ebp+Enable]         ; 应该很明显了 把Enable变量赋给al 也就是eax最后两位若 OldState == 0 则mov     eax, [ebp+var_18]
shr     eax, 1
and     al, 1
jmp     loc_7C929ADF这个函数大致流程就是这样。到这里差不多可以按一下传说中的F5了
int __stdcall RtlAdjustPrivilege(int Privilege, char Enable, char CurrentThread, int Enabled)
{
int result; // eax@2
signed int AdjustResult; // esi@4
char returnValue; // al@7
int v7; // [sp+2Ch] [bp-4h]@1
int IsEnabled; // [sp+4h] [bp-2Ch]@1
int TokenHandle; // [sp+8h] [bp-28h]@2
int dwPrivilege; // [sp+20h] [bp-10h]@4
signed int NewState; // [sp+1Ch] [bp-14h]@4
int v12; // [sp+24h] [bp-Ch]@4
int v13; // [sp+28h] [bp-8h]@4
int OldState; // [sp+Ch] [bp-24h]@4
char ReturnLength; // [sp+0h] [bp-30h]@4
unsigned int v16; // [sp+18h] [bp-18h]@11v7 = dword_7C97B0C8;
IsEnabled = Enabled;
if ( CurrentThread == 1 )result = ZwOpenThreadToken(-2, 40, 0, &TokenHandle);
elseresult = NtOpenProcessToken(-1, 40, &TokenHandle);
if ( result >= 0 )
{dwPrivilege = Privilege;NewState = 1;v12 = 0;v13 = -(Enable != 0) & 2;AdjustResult = NtAdjustPrivilegesToken(TokenHandle, 0, &NewState, 16, &OldState, &ReturnLength);ZwClose(TokenHandle);if ( AdjustResult == 262 )AdjustResult = -1073741727;if ( AdjustResult >= 0 ){if ( OldState )returnValue = (v16 >> 1) & 1;elsereturnValue = Enable;*(_BYTE *)IsEnabled = returnValue;}result = AdjustResult;
}
return result;
}可读性好像仍然不高,看看这个.../******************************************************************************
* RtlAdjustPrivilege          [NTDLL.@]
*
* Enables or disables a privilege from the calling thread or process.
*
* PARAMS
* Privilege     [I] Privilege index to change.
* Enable        [I] If TRUE, then enable the privilege otherwise disable.
* CurrentThread [I] If TRUE, then enable in calling thread, otherwise process.
* Enabled       [O] Whether privilege was previously enabled or disabled.
*
* RETURNS
* Success: STATUS_SUCCESS.
* Failure: NTSTATUS code.
*
* SEE ALSO
* NtAdjustPrivilegesToken, NtOpenThreadToken, NtOpenProcessToken.
*
*/
NTSTATUS WINAPI
RtlAdjustPrivilege(ULONG Privilege,BOOLEAN Enable,BOOLEAN CurrentThread,PBOOLEAN Enabled)
{TOKEN_PRIVILEGES NewState;TOKEN_PRIVILEGES OldState;ULONG ReturnLength;HANDLE TokenHandle;NTSTATUS Status;TRACE("(%d, %s, %s, %p)\n", Privilege, Enable ? "TRUE" : "FALSE",CurrentThread ? "TRUE" : "FALSE", Enabled);if (CurrentThread){Status = NtOpenThreadToken(GetCurrentThread(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,FALSE,&TokenHandle);}else{Status = NtOpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&TokenHandle);}if (!NT_SUCCESS(Status)){WARN("Retrieving token handle failed (Status %x)\n", Status);return Status;}OldState.PrivilegeCount = 1;NewState.PrivilegeCount = 1;NewState.Privileges[0].Luid.LowPart = Privilege;NewState.Privileges[0].Luid.HighPart = 0;NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;Status = NtAdjustPrivilegesToken(TokenHandle,FALSE,&NewState,sizeof(TOKEN_PRIVILEGES),&OldState,&ReturnLength);NtClose (TokenHandle);if (Status == STATUS_NOT_ALL_ASSIGNED){TRACE("Failed to assign all privileges\n");return STATUS_PRIVILEGE_NOT_HELD;}if (!NT_SUCCESS(Status)){WARN("NtAdjustPrivilegesToken() failed (Status %x)\n", Status);return Status;}if (OldState.PrivilegeCount == 0)*Enabled = Enable;else*Enabled = (OldState.Privileges[0].Attributes & SE_PRIVILEGE_ENABLED);return STATUS_SUCCESS;
}http://hi.baidu.com/xuzheng1111/item/e328b2f0d16d042d743c4c1f

对比了一下,其实也就比以往的调用少了一个函数。

以下新的API调用:

 TOKEN_PRIVILEGES tp;tp.PrivilegeCount = 1;int res = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);if (!res){int err = ::GetLastError();TRACE(_T("LookupPrivilegeValue(SE_DEBUG_NAME) Fail!!"));return -1;}    typedef int (__stdcall *PRtlAdjustPrivilege)(ULONG, BOOLEAN, BOOLEAN, PBOOLEAN);PRtlAdjustPrivilege RtlAdjustPrivilege = (PRtlAdjustPrivilege)GetProcAddress(GetModuleHandle(_T("ntdll")), "RtlAdjustPrivilege");while (!RtlAdjustPrivilege){int err = ::GetLastError();TRACE(_T("GetProcAddress(ntdll.dll::RtlAdjustPrivilege) Fail!!"));return -1;}// 实验了下 提权成功了 但是返回值还是NULL 如果这个时候验证返回值将不准确了.BOOLEAN enabled = 0;res = RtlAdjustPrivilege(tp.Privileges[0].Luid.LowPart, TRUE, FALSE, &enabled);//...LowPart   = 0x14if (!res){}int err = ::GetLastError();

以下旧的API调用:

        TOKEN_PRIVILEGES tp;tp.PrivilegeCount = 1;int res = LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid);if (!res){int err = ::GetLastError();TRACE(_T("LookupPrivilegeValue(SE_DEBUG_NAME) Fail!!"));return -1;}tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;res = OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);if(!res){int err = ::GetLastError();            TRACE(_T("OpenProcessToken(TOKEN_ADJUST_PRIVILEGES) Fail!!"));return -1;}res = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL);CloseHandle(hToken);if (!res){int err = ::GetLastError();TRACE(_T("AdjustTokenPrivileges(SE_PRIVILEGE_ENABLED) Fail!!"));CloseHandle(hToken);return -1;}

经过以上提权,能使用 ProcessIdToSessionId得到另一用户的进程的sessionid,

但 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe32.th32ProcessID);

还是不成功,可能还需要其它权限,继续研究中。。。

RtlAdjustPrivilege 一行代码提升进程权限相关推荐

  1. Windows提升进程权限

    Windows提升进程权限 文章一: 在枚举/结束系统进程或操作系统服务时,会出现权限不足而失败的情况,这时就需要提升自己进程到系统权限,其实提升权限的代码很简单的,看过的最经典的应该是<WIN ...

  2. CVPR 2020 Oral:一行代码提升迁移性能,中科院计算所研究生一作

    贾浩楠 发自 凹非寺 量子位 报道 | 公众号 QbitAI 在迁移学习任务中,一直存在这样的问题: 目标域由于没有标签,常常导致分界面附近混淆较多的数据. 中科院计算所的在读研究生崔书豪等,提出了一 ...

  3. 抛开约束,增强模型:一行代码提升 ALBERT 表现

    ©PaperWeekly 原创 · 作者|苏剑林 单位|追一科技 研究方向|NLP.神经网络 本文标题看起来有点"标题党"了,不过所作改动放到 bert4keras 框架 [1] ...

  4. 本周AI热点回顾:一行代码提升训练速度、PyTorch核心技术涉嫌抄袭、bAbI又被屠榜

    01 180所高校获批新增人工智能专业 3 月 3 日,教育部官方网站更新了「关于公布 2019 年度普通高等学校本科专业备案和审批结果的通知」.各高校新增备案专业 1672 个.审批专业 181 个 ...

  5. 【Android 应用开发】Google 官方 EasyPermissions 权限申请库 ( 最简单用法 | 一行代码搞定权限申请 | 推荐用法 )

    文章目录 一.添加依赖 二.在 AndroidManifest.xml 中配置权限 三.权限申请最简单用法 四.推荐使用的用法 五.GitHub 地址 上一篇博客 [Android 应用开发]Goog ...

  6. 用RtlAdjustPrivilege来调整进程权限(VB6.0代码)

    论坛上有朋友说起RtlAdjustPrivilege这个函数,就查了一下,写了个声明与调用示例出来,方便下次调用. 程序代码 Option Explicit Private Declare Funct ...

  7. WSS 代码执行的权限提升

    WSS 代码执行的权限提升 概述: WSS 默认使用身份模拟执行代码,也就是说用当前登录的用户身份执行Web Part或者自定义应用程序的代码访问.在大多数情况下,这种机制能够准确并严格地控制了标准权 ...

  8. 【CVPR2020 Oral】只需一行代码就可提升迁移性能

    关注上方"深度学习技术前沿",选择"星标公众号", 精选文章,第一时间送达! 作者:Hassassin 知乎链接:https://zhuanlan.zhihu. ...

  9. c语言一行代码太长,C语言修改一行代码,运行效率居然提升数倍,这个技巧你知道吗...

    对编译.链接.OS内核.系统调优等技术感兴趣的童鞋,不妨右上角关注一下吧,近期会持续更新相关方面的专题文章!引言 近日,网上看到一篇文章,分析数组访问的性能问题.文章经过一系列"有理有据&q ...

最新文章

  1. rust怎么放篝火_如何为你的露营活动搭建一个持久温暖的篝火
  2. Docker知识3:Docker的体系简介
  3. Python地信专题 | 基于geopandas玩转地图可视化
  4. ccfb类会议有哪些_CCF 计算机会议排名
  5. 新开通博客园,纪念一下。
  6. Tomcat自定义部署
  7. 【英语学习】【Daily English】U10 Education L01 Is this certificate a must?
  8. 国科大学习资料--机器人学导论(张正涛)--2014年期末考试试卷(含答案)
  9. OpenSSL爆出严重bug漏洞 Heartbleed bug CVE-2014-0160
  10. 一个前端报表设计器的设计分析
  11. python画圣诞帽_用Python给头像戴圣诞帽
  12. 2021年焊工(初级)考试报名及焊工(初级)最新解析
  13. 谷歌浏览器Chrome通过命令截图整个网页,screen,通过插件生成gif图片,以及通过插件进行录屏
  14. 基于vc的freetype字体轮廓解析_字体术语集
  15. C++ 重载操作符 <<实现模拟输出语句: cout << endl;
  16. idea 安装破解版mybatis插件
  17. (软考高级)信息系统项目管理师过关经验
  18. ILSpy反编译工具
  19. OC 获取view相对位置_不到1万上30显卡,10700散片配耕升RTX3070炫光OC显卡装机推荐...
  20. 创建文件夹+移动文件

热门文章

  1. 成功解决AttributeError: module 'tensorflow.python.training.training' has no attribute 'SummaryWriter'
  2. ML之xgboost:利用xgboost算法(sklearn+7CrVa)训练mushroom蘑菇数据集(22+1,6513+1611)来预测蘑菇是否毒性(二分类预测)
  3. ML之LiRDNNEL:基于skflow的LiR、DNN、sklearn的RF对Boston(波士顿房价)数据集进行回归预测(房价)
  4. 成功解决ValueError: Expected 2D array, got 1D array instead: Reshape your data either using array.reshap
  5. Matlab中解决出现的错误使用 svmtrain (line 234) Y must be a vector or a character array.问题
  6. ActiveMQ_3Java实现
  7. 【codeforces 742A】Arpa’s hard exam and Mehrdad’s naive cheat
  8. 浅谈JS的数组遍历方法
  9. CentOs Linux 文件位置标记
  10. POJ 1577 Falling Leaves (子母二叉树,给出叶子节点的删除序列,求前序遍历)