• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            saiksy

            記錄生活中的點點滴滴

            C++博客 首頁 新隨筆 聯系 聚合 管理
              13 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks
            RtlAdjustPrivilege(SE_DEBUG_PRIVILEGE,1,0,NULL);

            這個函數封裝在NtDll.dll中(在所有DLL加載之前加載),被微軟嚴格保密,就是說你在MSDN上查不到關于他的任何信息。

            .常量 SE_BACKUP_PRIVILEGE, 
            "17", 公開
            .常量 SE_RESTORE_PRIVILEGE, 
            "18", 公開
            .常量 SE_SHUTDOWN_PRIVILEGE, 
            "19", 公開
            .常量 SE_DEBUG_PRIVILEGE, 
            "20", 公開


            先來看看這個函數的定義(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(-2400&TokenHandle);
            else
                result 
            = NtOpenProcessToken(-140&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;
            }


            posted on 2011-05-08 17:22 saiksy 閱讀(741) 評論(0)  編輯 收藏 引用 所屬分類: 技術雜項
            亚洲伊人久久大香线蕉综合图片 | 狠狠色丁香久久综合婷婷| 久久久久这里只有精品| 久久久久久亚洲精品不卡 | 久久精品一区二区国产| 久久夜色精品国产亚洲| 一级a性色生活片久久无少妇一级婬片免费放 | 国产精品久久久久AV福利动漫| 久久综合九色综合97_久久久| 亚洲AⅤ优女AV综合久久久| 中文字幕精品久久久久人妻| 久久亚洲AV成人出白浆无码国产| 久久线看观看精品香蕉国产| 久久久久亚洲AV无码观看| 国内精品久久国产大陆| 久久久久久久久久久| 久久精品国产69国产精品亚洲| 久久伊人五月天论坛| 国产成人精品白浆久久69| 免费无码国产欧美久久18| 四虎国产精品免费久久5151 | 久久婷婷久久一区二区三区| 伊人久久大香线蕉亚洲五月天| 99久久国产主播综合精品| 成人综合伊人五月婷久久| 精品久久久久久久久免费影院| 91久久香蕉国产熟女线看| 日产精品久久久久久久| 99久久国产综合精品女同图片| 久久久久亚洲av成人无码电影| 欧美精品一区二区精品久久| 无码超乳爆乳中文字幕久久| 亚洲国产精品综合久久网络 | 伊人久久综合精品无码AV专区| 久久人人爽人人爽人人片AV东京热| 国产精品久久久久影视不卡| 久久久精品人妻一区二区三区蜜桃| 亚洲欧美精品一区久久中文字幕 | 国产精品久久久久久久久软件 | 国产精品禁18久久久夂久| 久久影院综合精品|