判斷權限上下文

關于判斷一個進程的提升權限方式以及目前的權限
這里使用一個自定義的函數GetProcessElevation來獲取

BOOL GetProcessEleation(TOKEN_ELEVATION_TYPE* pElevationType, BOOL* pIsadmin){
    HANDLE hToken = NULL;
    DWORD dwSize;
    if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)
        return(FALSE);
    if(GetTokenInformation(hToken,TokenElevationType,pElevationType,sizeof(TokenElevationType),&dwSize)){
        BYTE adminSID[SECURITY_MAX_SID_SIZE];
        CreateWellKnownSid(WinBuiltinAdministratorsSid,NULL,&adminSID,&dwSize);
        if(*pElevationType == TokenElevationTypeLimited){
            HANDLE hUnfilteredToken = NULL;
            GetTokenInformation(hToken,TokenLinkedToken,(VOID*)&hUnfilteredToken,sizeof(HANDLE),&dwSize);
            if(CheckTokenMembership(hUnfilteredToken,&adminSID,pIsadmin))
                bResult = TRUE;
            CloseHandle(hUnfilteredToken);
        }else{
            *pIsadmin = IsUserAnAdmin();
            bResult = TRUE;
        }
    }
    CloseHandle(hToken);
    return(bResult);
}

有點雜 上解釋
首先這里傳進去的兩個參數:

  • 第一個:TOKEN_ELEVATION_TYPE* pElevationType
    這貨有三個備選值 分別表示這樣的意思:
    TokenElevationTypeDefault 以默認用戶運行
    TokenElevationTypeDeFull 成功提權 令牌未篩選
    TokenElevationTypeLimited 受限權限 對應一個篩選后的令牌
    然后我們后面的GetTokenInformation就可以獲取到這個信息了
  • 第二個:BOOL* pIsAdmin
    看名字都知道 這是用來記錄是不是admin賬戶的
    然后整個函數里面就只有*pIsAdmin = IsUserAnAdmin 調用了這貨

具體機制的解釋:
首先用OpenProcessToken 果斷上函數原型

BOOL WINAPI OpenProcessToken(
    _In_   HANDLE ProcessHandle,
    _In_   DWORD DesiredAccess,
    _Out_  PHANDLE TokenHandle
);

可以看到第一個是我們要訪問的進程的handle 第二個是我們要的請求 第三個返回一個令牌的handle供我們使用
這里第二個參數傳入的是TOKEN_QUERY 表示請求一個訪問令牌
第三個就會把這個訪問令牌的handle返回回來

在這一步成功之后 接下來就要去獲取一些信息了 這里使用的是GetTokenInformation函數

BOOL WINAPI GetTokenInformation(
    _In_       HANDLE TokenHandle,
    _In_       TOKEN_INFORMATION_CLASS TokenInformationClass,
    _Out_opt_  LPVOID TokenInformation,
    _In_       DWORD TokenInformationLength,
    _Out_      PDWORD ReturnLength
);

還是先上函數原型

第一個參數傳的自然就是剛剛獲取的訪問令牌的handle
第二個是一個枚舉類型 有多種選項任挑選 然后獲取到的東西會對應給第三個參數
所以第三個參數就是獲取到的信息了
這里我們第二個參數傳入的是TokenElevationType 這貨會接收一個TOKEN_ELEVATION_TYPE
然后存到第三個參數里面也就是我們一開始傳入的那個pElevationType
第四和第五兩個參數 一個要傳入第三個參數的類型的大小 一個返回值的大小

接下來是調用CreateWellKnownSid函數來為管理用用戶組創建一個安全描述符
先初始化一個adminSID數組 內存開到SECURITY_MAX_SID_SIZE即最大,然后重復利用dwSize來存這個數組的大小

還是上一下函數原型:

BOOL WINAPI CreateWellKnownSid(
    _In_       WELL_KNOWN_SID_TYPE WellKnownSidType,
    _In_opt_   PSID DomainSid,
    _Out_opt_  PSID pSid,
    _Inout_    DWORD *cbSid
);```

> 第一個參數依然是一個枚舉 表示要創建的SID的類型
    第二個傳入NULL表明使用本地電腦
    第三個是個輸出 用剛剛建的adminSID來接收
    第四個就是剛剛那個dwSize
    這里獲取到的adminSID是給下面的CheckTokenMembership函數用的

然后就要對應不同情況進行不同的處理了
    當令牌被篩選過的時候 我們就需要再把沒篩選過的令牌全部給檢查一遍
    看看有沒有管理員
    未篩選的話 就直接IsUserAnAdmin
最后獲取到的信息:
    其實就是兩個傳進去的參數
    參看前面就清楚了
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容