• <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>
            Session

            我們平常所說的Session是指一次終端登錄, 這里的終端登錄是指要有自己的顯示器和鼠標鍵盤等, 它包括本地登錄和遠程登錄。在XP時代每次終端登錄才會創建一個Session,但是在Vista后所有的服務程序都運行在Session 0, 其他終端會依次運行在session 1, session 2...

            Logon Session

            登錄Session是指不同帳號的登錄,它包括System登錄, 網絡登錄及活動交互登錄等。 我們在任務管理器里可以看到各種進程運行在不同的帳號下,比如System, Local Service, xxx Account等, 這些帳號有不同的權限。這里要注意區分上面的終端登錄Session, 每個終端登錄Session內有好幾個Logon Session.

            Window Station

            按MSDN的說法,一個Window Station管理一個剪貼板(Clipboard),一個原子表(Atom Table)和一組桌面(Desktop)。為什么要有Window Station這個概念? 實際上每個Window Station對應一個Logon Session, 也就是說通過Window Station, 把不同的帳號進行隔離,防止他們相互影響, 試想其他人在你機器上執行一個DCOM對象,如果沒有Window Station隔離,他可以直接操作你的桌面了。一個終端登錄Session可以有多個Window Station,但只能有一個可交互的活動Window Station, 也就是Winsta0.

            Desktop

            每個Window Station可以創建多個Desktop, 我們平時和3個Desktop打交道比較多(WinLogon, Disconnect, Default), 他們分別代表登錄桌面,屏保桌面和我們工作的桌面。我們也可以自己通過CreateDesktop創建桌面, 并通過SwitchDesktop進行切換。


            Sid

            Sid表示Security Identifier, 它是一串唯一標志符, 它可以表示代表一個帳號, 一個用戶組或是一次用戶登錄等, 具體可以參考這里

            Token

            Token和進程相關聯, 每個進程創建時都會根據Logon Session權限由LSA(Local Security Authority)分配一個Token(如果CreaeProcess時自己指定了Token,  LSA會用該Token, 否則就用父進程Token的一份拷貝,由大部分進程是由Explorer.exe創建, 所以我們大部分時候都復制了explorer.exe的Token), 里面含有該進程的安全信息,包括用戶帳號, 組信息, 權限信息和默認安全描述符(Security Descriptor)等, 我們可以通過GetTokenInformation查詢某個Token的詳細情況。具體可以參考這里


            DACL和SACL

            DACL(discretionary access control list)用來標志某個安全對象允許被哪些對象訪問。SACL(system access control list )用來記錄某個安全對象被訪問的情況。具體可以參考這里


            Security Descriptor

            每個安全對象在創建時都可以指定一個安全描述符(Security Descriptor), 如果沒有指定就用進程默認的, 該描述符指定了哪些對象可以訪問該安全對象。大部分情況下我們都是傳NULL, 也就是用該進程Token中默認的。具體可以參考這里

            Integrity level

            這是UAC提供的新特性, 強制完整性控制(Mandatory Integrity Control), 它標志某進程的安全性級別, 安全級別的高低很大程度和該標志相關聯。


            下面的圖表示了Session, Window Station和Desktop的關系:


            下面的圖表示當某程序試圖訪問某個安全對象時, 系統是如何檢測的:系統會檢測Object的DACL列表, 根據當前進程的Token,判斷當前進程(線程)是否允許訪問該Object。



            我們用Process Explorer查看某個進程的屬性時, Security頁的信息如何理解? 



            User和SID項表示創建該進程的用戶情況,可以通過GetTokenInformation, 將第二個參數指定成TokenInformationClass來查詢。

            Session項上面提到過了,表示終端登錄session ID,可以通過GetTokenInformation, 將第二個參數指定成TokenSessionId來查詢, 也可以通過 API ProcessIDToSessionID來獲取

            Logon Session表示Logon Session的authority id, 可以通過GetTokenInformation, 將第二個參數指定成TokenStatistics來查詢。系統登錄的Logon Session id是999(0x3E7), 這里要區分還有一個概念是Logon Session SID, 他們是不同的概念, 前者某種程度上反映了Logon Session的類型, 后則是某次登陸的標志(SID)。

            Virtualized是Vista之后才有的概念,表示該程序是否啟用了UAC virtualization, 對于沒有指定manifest的老程序會使用數據重定向機制。可以通過GetTokenInformation的TokenVirtualizationAllowed/TokenVirtualizationEnabled來查詢。

            Group是指該用戶所在的用戶組。我們可以看到盡管我們的用戶在Administrators組里,但是上面卻顯示是Deny的,為什么?因為在Vista之后, UAC打開時, 除非我們顯式的Run As Admin, 否則我們的程序都默認運行在標準用戶權限下。同時我們注意到上面還有Mandatory label\Medium Mandatory Level項,表示該程序運行的完整性級別, 它包括Untrust, Low, Medium, Hight, System等, 級別越低,權限也就越低。我們可以通過GetTokenInformation的TokenIntegrityLevel來進行查詢。

            Privilege表示該進程的權限, 我們可以看到好多權限默認是Disabled, 實際上我們可以通過AdjustTokenPrivileges進行提升。 我們可以通過GetTokenInformation的TokenPrivileges進行查詢。

            Kernel Object User Object GDI Object的使用范圍?

            Kernel Object可以跨進程使用, 如果指定成Global, 還可以跨session.  XP時代即使不指定成Global, 服務程序和普通應用程序也可以通過Kernel Object通訊,但是Vista之后就不行了, 因為他們在不同的Session了。
            User Object可以跨進程使用, 但是User Object的使用范圍是Window Station, 它不能垮Window Station, 更別說跨session了。我們看不到服務程序彈出的界面, 那是因為服務程序和我們的桌面運行在不同的Window Station, 除非你指定“允許服務程序與桌面交互”, 顯式讓服務程序運行在活動桌面的Window Station (WinStat0) 。
            GDI Object只有在創建它的進程里有效。


            怎樣以管理員的身份運行某個程序?

            其實就是右鍵Run as Admin, UAC打開時會有確認窗口。
            ::ShellExecute(0, L"runas",L"C:\\Windows\\Notepad.exe",0,0,SW_SHOWNORMAL);


            如何判斷當前進程是否運行在管理員賬號下?

            這里包含2個概念 一個是運行程序的賬號是管理員賬號, 另外一個是當前運行的環境是管理員環境。
            我們下面的Am_I_In_Admin_Group(TRUE)相當于Windows API IsUserAnAdmin()

            //如果bCheckAdminMode是TRUE, 則除了檢測Admin賬號外,還檢測是真的運行在Admin環境, 否則只是檢測Admin賬號。

            BOOL Am_I_In_Admin_Group(BOOL bCheckAdminMode /*= FALSE*/)
            {
            BOOL   fAdmin;
            HANDLE  hThread;
            TOKEN_GROUPS *ptg = NULL;
            DWORD  cbTokenGroups;
            DWORD  dwGroup;
            PSID   psidAdmin;
            SID_IDENTIFIER_AUTHORITY SystemSidAuthority= SECURITY_NT_AUTHORITY;
            if ( !OpenThreadToken ( GetCurrentThread(), TOKEN_QUERY, FALSE, &hThread))
            {
            if ( GetLastError() == ERROR_NO_TOKEN)
            {
            if (! OpenProcessToken ( GetCurrentProcess(), TOKEN_QUERY, 
            &hThread))
            return ( FALSE);
            }
            else 
            return ( FALSE);
            }
            if ( GetTokenInformation ( hThread, TokenGroups, NULL, 0, &cbTokenGroups))
            return ( FALSE);
            if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER)
            return ( FALSE);
            if ( ! ( ptg= (TOKEN_GROUPS*)_alloca ( cbTokenGroups))) 
            return ( FALSE);
            if ( !GetTokenInformation ( hThread, TokenGroups, ptg, cbTokenGroups,
            &cbTokenGroups) )
            return ( FALSE);
            if ( ! AllocateAndInitializeSid ( &SystemSidAuthority, 2, 
            SECURITY_BUILTIN_DOMAIN_RID, 
            DOMAIN_ALIAS_RID_ADMINS,
            0, 0, 0, 0, 0, 0, &psidAdmin) )
            return ( FALSE);
            fAdmin= FALSE;
            for ( dwGroup= 0; dwGroup < ptg->GroupCount; dwGroup++)
            {
            if ( EqualSid ( ptg->Groups[dwGroup].Sid, psidAdmin))
            {
            if(bCheckAdminMode)
            {
            if((ptg->Groups[dwGroup].Attributes) & SE_GROUP_ENABLED)
            {
            fAdmin = TRUE;
            }
            }
            else
            {
            fAdmin = TRUE;
            }
            break;
            }
            }
            FreeSid ( psidAdmin);
            return ( fAdmin);
            }



            如何提升權限?


            注意只有原來是Disable的權限才可以提成Enable, 如果原來就沒有這個權限, 是提不上去的。

            BOOL EnablePrivilege(HANDLE hToken, LPCTSTR lpszPrivilegeName)
            {
                TOKEN_PRIVILEGES tkp = {0};
                BOOL bRet = LookupPrivilegeValue( NULL, lpszPrivilegeName, &tkp.Privileges[0].Luid );
                
            if(!bRet) return FALSE;

                tkp.PrivilegeCount = 1;
                tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
                bRet = AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof(tkp), NULL, NULL );

                
            return bRet;
            }


            如何判斷用戶的進程完整性級別?

            該信息包含在Integrity  Level的SID里,通過GetTokenInformation, 第二個參數設置成TokenIntegrityLevel,大概代碼如下, 詳細可以參考后面下載的源代碼。

            void CIntegrityLevel::Print(std::wostream& os) const
            {
                SID* pSid = (SID*)m_pIntegrity->Label.Sid;
                DWORD rid = pSid->SubAuthority[0];

                LPCTSTR lpszIntegrity = L"Unknown";
                
            switch (rid)
                
            {
                
            case SECURITY_MANDATORY_UNTRUSTED_RID:
                    
            {
                        lpszIntegrity = L"Untrusted";
                        
            break;
                    }

                
            case SECURITY_MANDATORY_LOW_RID:
                    
            {
                        lpszIntegrity = L"Low";
                        
            break;
                    }

                
            case SECURITY_MANDATORY_MEDIUM_RID:
                    
            {
                        lpszIntegrity = L"Medium";
                        
            break;
                    }


                
            case SECURITY_MANDATORY_MEDIUM_PLUS_RID:
                    
            {
                        lpszIntegrity = L"Medium +";
                        
            break;
                    }

                
            case SECURITY_MANDATORY_HIGH_RID:
                    
            {
                        lpszIntegrity = L"High";
                        
            break;
                    }

                
            case SECURITY_MANDATORY_SYSTEM_RID:
                    
            {
                        lpszIntegrity = L"System";
                        
            break;
                    }

                
            default:
                    
            {
                        lpszIntegrity = L"XXXXX";
                    }

                }


                os << L"Integrity: " << lpszIntegrity << endl;
            }



            如何指定程序默認啟動運行的級別?

            在VC里配置Manifest文件。
            asInvoker:默認選項,新的進程將簡單地繼承其父進程的訪問令牌
            highestAvailable:應用程序會選擇該用戶允許范圍內盡可能高的權限。對于標準用戶來說,該選項與asInvoker一樣,而對于管理員來說,這就意味著請求Admin令牌。
            requireAdministrator:應用程序需要Admin令牌。運行該程序時,標準用戶將要輸入管理員的用戶名和密碼,而管理員則要在彈出的確認對話框中進行確認。



            上面只是我自己的一些理解和總結, 由于不是專門搞安全相關的, 如果有不正確的地方, 歡迎指正。

            部分資料: Designing Applications to Run at a Low Integrity Level

            注,這是部分測試代碼:MySecurityTest

            posted on 2013-08-25 07:58 Richard Wei 閱讀(10975) 評論(3)  編輯 收藏 引用 所屬分類: windows desktop

            FeedBack:
            # re: 淺析Windows安全相關的一些概念
            2013-09-03 09:15 | bukebushuo
            高手啊,學習了  回復  更多評論
              
            # re: 淺析Windows安全相關的一些概念
            2013-09-03 21:57 | Richard Wei
            @bukebushuo
            不敢,最近工作中用到這塊東西,所以花點時間總結了下,順便分享  回復  更多評論
              
            # re: 淺析Windows安全相關的一些概念[未登錄]
            2015-11-06 01:53 | squall
            學習了!

            現在搞vc的越來越少了,但高手都在這個圈子啊。。  回復  更多評論
              
            久久亚洲国产成人影院| 久久国产成人精品麻豆| 精品久久久久久久久久中文字幕 | 久久久久亚洲精品天堂久久久久久| 亚洲中文字幕无码久久2020| 三级片免费观看久久| 香蕉久久永久视频| 久久精品国产亚洲AV香蕉| 一级做a爰片久久毛片看看| 久久这里只精品99re66| 狠狠色丁香久久婷婷综合_中 | 日韩精品久久久久久久电影| 人妻无码精品久久亚瑟影视| 久久性生大片免费观看性| 亚洲?V乱码久久精品蜜桃 | 久久久久综合网久久| 国产精品熟女福利久久AV| 久久夜色精品国产亚洲av| 久久久噜噜噜久久中文字幕色伊伊| 久久www免费人成看片| 久久精品国产亚洲av麻豆色欲| 精品久久一区二区三区| 久久国产综合精品五月天| 一级做a爰片久久毛片免费陪| 日韩人妻无码精品久久久不卡| 久久亚洲欧美国产精品| 国产免费久久精品99久久| 久久亚洲AV无码精品色午夜| 国产美女久久精品香蕉69| 精品久久久久一区二区三区| 久久久亚洲AV波多野结衣| 成人国内精品久久久久影院| 香蕉99久久国产综合精品宅男自 | 99久久做夜夜爱天天做精品| 久久久无码人妻精品无码| 久久精品国产99国产精品| 无码日韩人妻精品久久蜜桃 | 精品久久久久久久久久中文字幕| 久久久久国产日韩精品网站| 99久久国产综合精品网成人影院 | 久久国产精品-久久精品|