不能说的秘密之RtlAdjustPrivilege

【内网渗透】mimikatz 基本使用 文章目录前言1. 工具简介2. 提升权限 privilege::debug3. 抓取明文密码 sekurlsa::logonpasswords4. sekurlsa模块 获取密码信息4.1 procdump + mimikatz 加载dmp文件,并导出其中的明文密码4.2 导出lsass.exe进程中所有的票据 sekurlsa::tickets /export5. lsadump模块 读取域控中域成员Hash5.1 读取所有域用户的哈希 lsadump::lsa /patch5.2 查看域内指定用户信息, 阅读详情

前言:

今天逆向一个非常实用的函数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_7C929A7A

CurrentThread == 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]@11

v7 = dword_7C97B0C8;
IsEnabled = Enabled;
if ( CurrentThread == 1 )
    result = ZwOpenThreadToken(-2, 40, 0, &TokenHandle);
else
    result = 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;
      else
        returnValue = 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;
}
mimikatz散列值学习 mimikatz散列值学习 补丁KB2871997 关闭wdigest功能 windows server2012 关闭wdigest,无法获取明文密码 两种方法开启wdigest 抓取用户的明文密码 #使用reg add ##开启 reg add HKLM\SYSTEM\CurrentControlSet\Control\SecurityProviders\WDigest /v UseLogonCredential /t REG_DWORD /d 1 /f ##关闭 reg add HKLM\SYSTE 阅读详情

相关推荐

提权函数之RtlAdjustPrivilege()使用说明

RtlAdjustPrivilege() 这玩意是在 NTDLL.DLL 里的一个不为人知的函数,MS没有公开,原因就是这玩意实在是太NB了,以至于不需要任何其他函数的帮助,仅凭这一个函数就可以获得进程ACL的任意权限!

RtlAdjustPrivilege() 提权函数

RtlAdjustPrivilege(SE_DEBUG_NAME,1,0,NULL); 这玩意是在 NTDLL.DLL 里的一个不为人知的函数,MS没有公开,原因就是这玩意实在是太NB了,以至于不需要任何其他函数的帮助,仅凭这一个函数就可以获得进程ACL的任意权限! 先来看看这个函数的定义(Winehq给出): NTSTATUS RtlAdjustPrivilege ( ULONG Pri...

mmmsss987的博客 5007

Ubuntu下为RK3568开发板搭建Qt交叉编译环境:手把手教你配置Qt Creator和远程调试

本文详细介绍了在Ubuntu系统下为RK3568开发板搭建Qt交叉编译环境的完整流程,包括工具链配置、Qt源码交叉编译、Qt Creator环境设置以及远程调试技巧。通过手把手教程,开发者可以快速掌握RK3568平台的Qt开发环境搭建方法,实现高效的应用开发和部署。

weixin_30776273的博客 372

解决:ERROR kuhl m_privilege simple: Rtiadjustprivilege (20) c0000061

ERROR kuhl m_privilege simple: Rtiadjustprivilege (20) c0000061 打开附件--找到命令行--右键--管理员打开 好了,芜湖~

(●'◡'●) 4278

STM32驱动数码管:从硬件连接到动态显示实现

本文详细介绍了使用STM32单片机驱动数码管的完整流程,从硬件连接到软件实现。内容涵盖共阳/共阴数码管原理、GPIO配置、段码表生成,并重点解析了多位数码管动态显示的核心技术,包括动态扫描原理、消影处理及实战代码,帮助开发者快速掌握这一嵌入式开发基础技能。

p5l2m9n4o6q的博客 574

银河飞腾FT6678实战指南:OpenMP多核并行编程优化技巧

本文详细介绍了在银河飞腾FT6678多核处理器上使用OpenMP进行并行编程的实战技巧与优化方法。从基础语法到环境配置,再到性能优化的五大核心技巧,包括循环并行化、并行粒度控制、reduction子句使用等,帮助开发者充分发挥FT6678的8核计算能力。通过实际案例展示如何将图像处理算法从200ms优化到28ms,并深入探讨了任务调度、内存访问优化等进阶主题。

weixin_29234423的博客 285

C++windows 进程提权

windows进程提权使用到的系统函数代码 使用到的系统函数 OpenProcessToken, LookupPrivilegeValueW,AdjustTokenPrivileges BOOL WINAPI OpenProcessToken( //打开与进程相关联的访问令牌 _In_ HANDLE ProcessHandle, //所要提升进程的句柄 _In_ DWORD DesiredAccess, //选择所要操作的类型,指定请求的访问令牌访问类型 _Outptr_ PH

qq_41883523的博客 2130

Authentication Assertion Tickets,SAP 系统到系统单点登录里的短命凭证

SAP 系统间的身份传递机制存在 Authentication Assertion Ticket 和 SAP Logon Ticket 两种易混淆的凭证。前者用于系统间短时身份委托(有效期2分钟,通过HTTP头传输),后者用于浏览器SSO(可配置有效期,通过Cookie传输)。Assertion Ticket依赖签发系统的数字签名和严格的时间同步,适用于ABAP/Java系统间的后台作业调用。现代SAP架构已转向OAuth 2.0等标准协议,但老系统中仍需注意两种票据的关键差异:传输方式、有效期、接收方限制

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 601

vc++中,怎样实现提升应用程序的操作权限

最近写一个定时开关机的小程序,这就需要用到获得系统的一些权限,简单说就是获取系统的注销,重启,关机的权限,如需使用,需初始化,程序如下:

feilong911hao的专栏 850

【硬刚Hadoop】HADOOP MAPREDUCE(1):概述

本文是对《【硬刚大数据之学习路线篇】从零到大数据专家的学习指南(全面升级版)》的Hadoop部分补充。 1 MapReduce定义 MapReduce是一个分布式运算程序的编程框架,是用户开发“基于Hadoop的数据分析应用”的核心框架。 MapReduce核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。 2MapReduce优缺点 2.1 优点 1)MapReduce易于编程 它简单的实现一些接口,就可以完成一个分布式程序..

微信搜:import_bigdata,大数据领域硬核原创作者 462

【ARXML专题】-2-创建一个Classic CAN(经典CAN2.0)/CANFD的系统描述ARXML文件

目录 1 创建一个AUTOSAR系统描述 2 物理层命名以及创建ECU 3 新建一个Frame 4 新建一个PDU 5 新建一个signal 6 结尾 AUTOSAR System Description Network Explorer是一个文件编辑器,支持可视化和编辑系统描述的AUTOSAR系统描述文件和ECU摘录的通信内容,它支持架构版本4.0.3、4.1.2、4.2.1、4.2.2和4.3.0。AUTOSAR系统描述(ARXML)文件是基于XML的文件格式,描述网络通信的元素...

「汽车电子助手」的博客 1万+

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

论坛上有朋友说起RtlAdjustPrivilege这个函数,就查了一下,写了个声明与调用示例出来,方便下次调用.  程序代码 Option ExplicitPrivate Declare Function RtlAdjustPrivilege Lib "ntdll.dll" ( _    ByVal Privilege As String, _    ByVal bEnable As L...

miaozk2006的专栏 978

【WorkBuddy专栏15】灵感被折叠到「更多」里,真的不重要了吗?——一个「被低估」功能的当下价值与未来演变

【WorkBuddy专栏15】灵感被折叠到「更多」里,真的不重要了吗?——一个「被低估」功能的当下价值与未来演变

AI人人懂 956

提权相关函数

//提升权限 bool EnableSpecificPrivilege(LPCTSTR lpPrivilegeName) { HANDLE hToken = NULL; TOKEN_PRIVILEGES Token_Privilege; BOOL bRet = TRUE; do { if (0 == OpenProcessToken(GetCurrentProcess(), T

wowolook的专栏 4629

USB 网卡——RNDIS 控制消息流程

在其控制端点上获取控制消息时,设备必须在通信类接口的中断 IN 端点上返回通知,每当设备可以返回控制消息时,主机就会轮询该通知。需要注意的是,如果设备由于某种原因收到GET_ENCAPSULATED_RESPONSE,并且无法使用控制端点上的有效数据做出响应,则应返回设置为 0x00 的单字节数据包,而不是 stall 控制端点。下表中定义了此传输。收到 RESPONSE_AVAILABLE 通知后,主机使用下表中定义的GET_ENCAPSULATED_RESPONSE 传输从控制端点读取控制消息。

tyustli 371

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

提权函数之RtlAdjustPrivilege()

提权函数之RtlAdjustPrivilege() RtlAdjustPrivilege() 这玩意是在 NTDLL.DLL 里的一个不为人知的函数,MS没有公开,原因就是这玩意实在是太NB了,以至于不需要任何其他函数的帮助,仅凭这一个函数就可以获得进程ACL的任意权限! 下面是函数定义: ? 1 2 3 4 5 6 7 NTS

sky101010ws的专栏 3391

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

Nt内核函数原型and中文

NtLoadDriver 服务控制管理器加载设备驱动. NtUnloadDriver 服务控制管理器支持卸载指定的驱动程序. NtRegisterNewDevice 加载新驱动文件. NtQueryIntervalProfile 返回数据. NtSetIntervalProfile 指定采样间隔. NtStartProfile 开始取样. NtStopProfile 停止...

dengjiatao9832的博客 738

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

OpenProcessToken等函数的用法

GetCurrentProcessID 得到当前进程的ID OpenProcessToken 得到进程的令牌句柄LookupPrivilegeValue 查询进程的权限 AdjustTokenPrivileges 判断令牌权限 要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关的访问权的OpenProcess操作,只要当前进程具有SeDeDebug权限就可以了。要是一个用户是Admin

编程爱好者 1701

修改进程权限(转载)

函数RtlAdjustPrivliege封装在NtDll.dll中(在所有DLL加载之前加载),被微软严格保密,就是说你在MSDN上查不到关于他的任何信息。 先来看看这个函数的定义(Winehq给出): NTSTATUS RtlAdjustPrivilege ( ULONG Privilege, BOOLEAN Enable, BOOLEAN Cur...

weixin_33674976的博客 230

RtlAdjustPrivilege进程提权,权限ID对照表

SeCreateTokenPrivilege 0x2 SeAssignPrimaryTokenPrivilege 0x3 SeLockMemoryPrivilege 0x4 SeIncreaseQuotaPrivilege 0x5 SeUnsolicitedInputPrivilege 0x0 SeMachineA

zwfgdlc的专栏 4411

windows程序提权方法

Windows下应用程序如果需要做一些系统管理或进程管理之类的工作,经常需要将本进程提权(获取权限令牌); 而通常windows下提权方法有两种,主要的方法是: 1)win32API——AdjustTokenPrivileges; 2)ntdll.dll——RtlAdjustPrivilege; 前者是已公开的win32系统API,后者是非公开的导出函数(藏在ntdll.dll里); 两

sowhat_Ah的专栏 2万+

Windows NT内核函数大全

Nt内核函数大全 NtLoadDriver服务控制管理器加载设备驱动. NtUnloadDriver服务控制管理器支持卸载指定的驱动程序. NtRegisterNewDevice加载新驱动文件. NtQueryIntervalProfile返回数据. NtSetIntervalProfile指定采样间隔. NtStartProfile开始取样. NtStopProfile停止采样...

qq_42577465的博客 2189

突破IDM权限限制:RtlAdjustPrivilege函数实战指南

🚀 **IDM激活脚本的核心技术揭秘** - 你是否曾经为Internet Download Manager的试用期限制而烦恼?想要永久免费使用这款强大的下载工具吗?今天我们将深入探讨IDM激活脚本背后的关键技术原理,特别是RtlAdjustPrivilege函数在Windows系统中的实际应用。 ## 🔍 IDM权限限制破解原理 **IDM权限限制**是许多用户面临的共同问题。Inter

gitblog_00409的博客 532

VC编程提升程序权限

1、先调用GetCurrentProcess函数取得当前进程的句柄, 2、然后调用OpenProcessToken打开当前进程的访问令牌, 3、接着调用LookupPrivilegeValue函数取得你想提升的权限的值, 4、最后调用AdjustTokenPrivileges函数给当前进程的访问令牌增加权限就可以了。 5、一般有了SeDebugPrivilege特权后,就可以杀掉除Idle

业精于勤荒于嬉 行成于思毁于随 1353

VC++中程序提升管理员权限的两种方法

程序的权限不够,应用管理员权限打开程序运行方可。如何使vc程序运行时请求管理员权限?如果是2005或者2008 就简单了,直接 (项目右键—属性—连接器—清单文件—uac执行级别 选择requireAdministrator )中文版 (proj...

xunying6967的博客 7274
上一篇: 应用层与驱动层同步事件处理方法
whatwhyhow
博客等级 码龄23年 5粉丝 4原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值