Native API提权函数RtlAdjustPrivilege
来源:互联网 发布:可以照一寸照的软件 编辑:程序博客网 时间:2024/06/06 00:51
在枚举或结束系统进程,抑或是操作系统服务时,会出现自身进程权限不足而失败的情况,此时需要提升自身进程到系统权限,来完成这些特殊操作。
以下代码就是提升进程权限的一系列操作,具体的内容在《Windows核心编程》中有讲解,更多时候只需要使用就好。
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;}
但是每次提权都要调用这个函数有些不方便,使用Native API就能很快速的进行提权。
Native API中有一个非常好用的提权函数,包括打开其他进程,使用一些高权限的Native API都会使用RtlAdjustPrivilege进行权限提升。这个函数封装在NTDLL.dll中,该DLL在所有DLL加载前已经加载。
函数原型如下:
NTSTATUS RtlAdjustPrivilege( ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled)
各个参数的含义:
Privilege [In] Privilege index to change. Enable [In] If TRUE, then enable the privilege otherwise disable. CurrentThread [In] If TRUE, then enable in calling thread, otherwise process. Enabled [Out] Whether privilege was previously enabled or disabled.
找出微软NTDLL.dll放入IDA进行逆向,可以看出大概的一个流程。
NTSTATUS WINAPIRtlAdjustPrivilege(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;}
根据WRK参考RtlAdjustPrivilege的源码,理解提权函数。
NTSTATUS RtlAdjustPrivilege( ULONG Privilege, BOOLEAN Enable, BOOLEAN Client, PBOOLEAN WasEnabled )/*++Routine Description: This procedure enables or disables a privilege process-wide.Arguments: Privilege - The lower 32-bits of the privilege ID to be enabled or disabled. The upper 32-bits is assumed to be zero. Enable - A boolean indicating whether the privilege is to be enabled or disabled. TRUE indicates the privilege is to be enabled. FALSE indicates the privilege is to be disabled. Client - A boolean indicating whether the privilege should be adjusted in a client token or the process's own token. TRUE indicates the client's token should be used (and an error returned if there is no client token). FALSE indicates the process's token should be used. WasEnabled - points to a boolean to receive an indication of whether the privilege was previously enabled or disabled. TRUE indicates the privilege was previously enabled. FALSE indicates the privilege was previously disabled. This value is useful for returning the privilege to its original state after using it.Return Value: STATUS_SUCCESS - The privilege has been successfully enabled or disabled. STATUS_PRIVILEGE_NOT_HELD - The privilege is not held by the specified context. Other status values as may be returned by: NtOpenProcessToken() NtAdjustPrivilegesToken()--*/{ NTSTATUS Status, TmpStatus; HANDLE Token; LUID LuidPrivilege; PTOKEN_PRIVILEGES NewPrivileges, OldPrivileges; ULONG Length; UCHAR Buffer1[sizeof(TOKEN_PRIVILEGES)+ ((1-ANYSIZE_ARRAY)*sizeof(LUID_AND_ATTRIBUTES))], Buffer2[sizeof(TOKEN_PRIVILEGES)+ ((1-ANYSIZE_ARRAY)*sizeof(LUID_AND_ATTRIBUTES))]; RTL_PAGED_CODE(); NewPrivileges = (PTOKEN_PRIVILEGES)Buffer1; OldPrivileges = (PTOKEN_PRIVILEGES)Buffer2; // // Open the appropriate token... // if (Client == TRUE) { Status = NtOpenThreadToken( NtCurrentThread(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, FALSE, &Token ); } else { Status = NtOpenProcessToken( NtCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &Token ); } if (!NT_SUCCESS(Status)) { return(Status); } // // Initialize the privilege adjustment structure // LuidPrivilege = RtlConvertUlongToLuid(Privilege); NewPrivileges->PrivilegeCount = 1; NewPrivileges->Privileges[0].Luid = LuidPrivilege; NewPrivileges->Privileges[0].Attributes = Enable ? SE_PRIVILEGE_ENABLED : 0; // // Adjust the privilege // Status = NtAdjustPrivilegesToken( Token, // TokenHandle FALSE, // DisableAllPrivileges NewPrivileges, // NewPrivileges sizeof(Buffer1), // BufferLength OldPrivileges, // PreviousState (OPTIONAL) &Length // ReturnLength ); TmpStatus = NtClose(Token); ASSERT(NT_SUCCESS(TmpStatus)); // // Map the success code NOT_ALL_ASSIGNED to an appropriate error // since we're only trying to adjust the one privilege. // if (Status == STATUS_NOT_ALL_ASSIGNED) { Status = STATUS_PRIVILEGE_NOT_HELD; } if (NT_SUCCESS(Status)) { // // If there are no privileges in the previous state, there were // no changes made. The previous state of the privilege // is whatever we tried to change it to. // if (OldPrivileges->PrivilegeCount == 0) { (*WasEnabled) = Enable; } else { (*WasEnabled) = (OldPrivileges->Privileges[0].Attributes & SE_PRIVILEGE_ENABLED) ? TRUE : FALSE; } } return(Status);}
贴了这么多源代码,具体该如何调用Native API,非常简单。
BOOLEAN bPrev;RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE, TRUE, FALSE, &bPrev);
下面是一个调试通过的例子,可以看出Native API是如何使用的。
#include <windows.h>const unsigned int SE_SHUTDOWN_PRIVILEGE = 0x13;typedef enum _SHUTDOWN_ACTION {ShutdownNoReboot,ShutdownReboot,ShutdownPowerOff} SHUTDOWN_ACTION, *PSHUTDOWN_ACTION;typedef int (_stdcall *_RtlAdjustPrivilege)(int, BOOL, BOOL, int *);typedef int (_stdcall *_ZwShutdownSystem)(SHUTDOWN_ACTION);void HookPatch(DWORD OldFunc, DWORD NewFunc){DWORD Pro;VirtualProtect((LPVOID)OldFunc, 20, PAGE_READWRITE, &Pro);*(BYTE *)OldFunc = 0xE9;*(DWORD *)(OldFunc+1) = (NewFunc-OldFunc-5);}__stdcall void HookMessage(int){MessageBox(NULL, "ZwShutdownSystem have been hook", "HookMessage", MB_OK);}int main(){HMODULE hNtDll = LoadLibrary("ntdll.dll");_RtlAdjustPrivilege pfnRtlAdjustPrivilege = (_RtlAdjustPrivilege)GetProcAddress(hNtDll, "RtlAdjustPrivilege");_ZwShutdownSystem pfnZwShutdownSystem = (_ZwShutdownSystem)GetProcAddress(hNtDll, "ZwShutdownSystem");int nEn = 0;int nResult = pfnRtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, TRUE, &nEn);if(nResult == 0x0c000007c){nResult = pfnRtlAdjustPrivilege(SE_SHUTDOWN_PRIVILEGE, TRUE, FALSE, &nEn);}HookPatch((DWORD)pfnZwShutdownSystem, (DWORD)HookMessage);system("pause");pfnZwShutdownSystem(ShutdownReboot);FreeLibrary(hNtDll);return 0;}
- Native API提权函数RtlAdjustPrivilege
- 提权函数之RtlAdjustPrivilege()
- 提权函数之RtlAdjustPrivilege()
- RtlAdjustPrivilege进程提权,权限ID对照表
- 跟踪Native API函数调用
- 跟踪Native API函数调用
- 跟踪Native API函数调用
- 跟踪Native API函数调用
- native API
- Inside the Native API
- Inside the Native API
- Defeating Native API Hooker
- Native API -- ScOpenProcess
- The Native Android API
- native wifi api使用方法
- Native wifi API使用
- Native wifi API使用
- Native wifi API使用
- VMware-workstation-full-8.0.4-744019
- 信任--谈谈企业成功中的人力因素
- One-line Tips Recently Summarized
- read web.config value-
- 获取免费Windows Store开发者账户方法
- Native API提权函数RtlAdjustPrivilege
- css多列等高-利用padding-bottom|margin-bottom正负值相抵
- 用gdb调试c程序 初步 (1)
- Windows 8 微软官方MSDN版 的文件校验信息
- 搜索引擎的检索模型-查询与文档的相关度计算
- Windows 8 经典主题
- C++动态指针数组
- 动态链接库编程
- JVM基本原理--dalvik