2015-11-06 56 views
15

System.Security.Principal.WindowsIdentity合理從安全的被黑客攻擊這樣的情況下,我從Thread.CurrentPrincipalIdentityWindowsIdentity.GetCurrent()trueIsAuthenticated給我的裝配虛假的身份信息得到什麼?當然,沒有什麼是完全防篡改的,但考慮到微軟對.Net的承諾和依賴,我期望這樣的關鍵API可以被鎖定爲難以破解,難以篡改。這是我的一個有效的假設?System.Security.Principal.WindowsIdentity的這種用法是否合理安全?

我的目標是在我的程序集中提供合理的最佳實踐SSO。如果Windows本身受到了威脅,那就超出了我的控制範圍,但是如果(例如)與我的程序集鏈接的應用程序直接提供給我錯誤信息是一件簡單的事情,那麼我就沒有做盡職調查。這是我無知的一大方面。

要清楚,我在尋找硬性信息,而不是關閉袖口的意見。因此,發佈了漏洞利用,或以一種欺騙我的代碼的方式展示了對構造函數的使用,等等。或者在「這是一個有效的假設」的一面,支持它的實體文章,依賴它的已知使用等等。找到他們很幸運,但我已經包括了我在下面的分隔符下發現的內容。

這是我打算如何使用WindowsIdentity

using System.Security.Principal; 
using System.Threading; 
// ... 

// I only want Windows-authenticated users 
WindowsIdentity identity = Thread.CurrentPrincipal == null 
    ? null 
    : Thread.CurrentPrincipal.Identity as WindowsIdentity; 
SecurityIdentifier sid; 

// I can't imagine how an authenticated account would be anonymous, but... 
if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) { 
    // SSO success from thread identity 
    sid = identity.User; 
    // ...check that that SID is allowed to use our system... 
} else { 
    identity = WindowsIdentity.GetCurrent(); 
    if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) { 
     // SSO success from current Windows user 
     sid = identity.User; 
     // ...check that that SID is allowed to use our system... 
    } else { 
     // SSO fail 
    } 
} 

這是一個DLL組件  —可悲的是我們堅持.Net的3.5   —,提供了一個公共的API可以通過限制資源用戶權利。它可能用於桌面應用程序或使用Windows身份驗證的ASP.Net IIS應用程序(使用Windows身份驗證時,ASP.Net在Thread.CurrentPrincipal.Identity上設置WindowsIdentity實例;目前我們不支持其他類型的IIS身份驗證)。

我可以合理地信任來自WindowsIdentity實例的SID嗎?聲稱這樣認證的來源?

它沒有想到我不知道這是否是好的(DOH!),直到this question用戶lc.提出了一個問題,大會將容易受到與它和鏈接的惡意應用程序被欺騙「僞造「那些信息。儘管如此,他沒有任何具體的證據指出爲什麼這可能是一個重大問題。


什麼(小),我發現迄今:

  • This answer使得要求

    您可以相信,當前WindowsIdentity是它說誰是,只要因爲您可以信任應用程序中的任何給定數據。

  • 本書Hacking the Code聲稱,ASP.Net需要WindowsIdentity做文件authorizaton檢查,如果是真的,似乎這是一個相當堅實的基礎,說微軟,至少,認爲不夠好時要與請求相關聯。

  • 我可以找到很多人在他們的代碼中愉快地使用WindowsIdentity信息的例子,但是他們中的大多數人並沒有問他們是否安全。這裏有一個蘊含,但是......

+0

在什麼情況下你問這個?你在談論ASP.NET和桌面應用程序。這可能是顯而易見的,但是[當在一個「pwned」系統上運行時,所有投注都關閉 - 惡意用戶可以以任何他們想要的方式在進程中注入和修改)(http://stackoverflow.com/questions/8357469/如何-可以-我保護,我 - 私人 - funcs中,對反射執行的)。 – CodeCaster

+0

@CodeCaster:如果Windows本身已經妥善妥協,那就超出了我的控制範圍。但是,如果(例如)一個應用程序可以創建一個'WindowsIdentity'實例,將其分配給當前線程,然後調用我的程序集並誘使我相信它們是他們不是的人,那會對我造成失敗勤勉。基本上,我試圖達到合理的最佳實踐SSO。我沒有質疑我是否可以信任上面的API,直到用戶在我的另一個問題上標記它(他可能只是偏執狂),然後我擔心我不知道的東西,在這個領域是哪一個許多。 :-) –

回答

10

你不能相信從Thread.CurrentPrincipal的一個,沒有。沒有任何東西可以阻止代碼完全信任地欺騙它。

我能夠欺騙它在我的環境是這樣的:

var admin = new WindowsIdentity(@"Administrator"); 
var princ = new WindowsPrincipal(admin); 
System.Threading.Thread.CurrentPrincipal = princ; 

...調用代碼之前。在我的機器上,創建的WindowsIdentity對象具有IsAuthenticated,因爲trueIsAnonymous爲false,所以當然,您的代碼會提取我的域管理員的SID。

這並不適用於所有環境下工作,但這應該,只要運行代碼具有足夠的權限來使用反射:(再次,調用代碼之前完成)

var ident = WindowsIdentity.GetCurrent(); 
Thread.CurrentPrincipal = new WindowsPrincipal(ident); 
var userSid = ident.User; 

var fakeSid = new SecurityIdentifier("S-1-3-0"); 

typeof (WindowsIdentity).GetField("m_user", 
    BindingFlags.Instance | BindingFlags.NonPublic).SetValue(ident, fakeSid); 


基本上,沒有任何東西可以阻止在相同的進程中從完全信任下運行的兩段代碼彼此躺在一起。

+0

@Damien_The_Unbeliever:在我的非域環境和我適當的AD環境中,反思就是這樣做的。 **哇,這是可怕的。**在設置'm_user'字段後,'.User'不僅返回我們設置的用戶,而且'.Name'返回他們的域用戶名;所以'WindowsIdentifier'似乎已經被正確的黑客攻擊了。感謝您的時間和幫助。 –

+0

@Damien_The_Unbeliever:**然而**,'新的WindowsIdentity(identityFromThread.Token)'**揭示了欺騙**(並且在我的兩個非惡意用例中正常工作,至少在初始測試中)。我認爲這個答案適合我的實際問題(問題不能移動目標!),因爲我包含了你已經成功欺騙的代碼。當然,我想知道這是否也可以被騙... –

+0

...所以我們有[這個問題](http://stackoverflow.com/questions/33573773/is-it-可能對伎倆這-的WindowsIdentity碼 - 到 - 使用最錯誤的用戶)。 :-) –

相關問題