是否有可能欺骗这个的WindowsIdentity code到使用错误的用户? [英] Is it possible to trick this WindowsIdentity code into using the wrong user?

查看:258
本文介绍了是否有可能欺骗这个的WindowsIdentity code到使用错误的用户?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

TL; DR 可以包含在用户令牌的WindowsIdentity 令牌财产(例如, someIdentity.Token )是伪造的,这样:

TL;DR Can the user token contained in a WindowsIdentity's Token property (say, someIdentity.Token) be spoofed such that:

var validated = new WindowsIdentity(someIdentity.Token);

...将返回声称重新present还没有,其实,被认证用户,但有 IsAuthenticated 设置<$实例C $ C>真正,有效的 .Name点。用户属性等?

...will return an instance that claims to represent a user that has not, in fact, been authenticated, and yet has IsAuthenticated set true, valid .Name and .User properties, etc.?

下面我穿上这几个界限;这是presumably不可能的完全恶搞型。

Below I put a few boundaries on this; it's presumably impossible to completely spoof-proof.

本完整的故事:

这个答案,的 Damien_The_Unbeliever 巧妙地表明我的一些code可能是被骗去相信它有一个的WindowsIdentity 实例的有效身份验证的用户时,没有。长话短说,我的code的假设,如果 Thread.CurrentPrincipal.Identity 的WindowsIdentity 的一个实例, IsAuthorized 真正,认为它重新presented身份验证的用户,我可以在<依靠SID code>。用户:

In this answer, Damien_The_Unbeliever cleverly demonstrated that some code of mine could be tricked into believing it had a valid authenticated user in a WindowsIdentity instance when it didn't. Long story short, my code was assuming that if Thread.CurrentPrincipal.Identity was an instance of WindowsIdentity and IsAuthorized was true, that it represented an authenticated user and I could rely on the SID in .User:

WindowsIdentity identity = Thread.CurrentPrincipal == null
    ? null
    : Thread.CurrentPrincipal.Identity as WindowsIdentity;

if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) {
    // ...use and trust the SID in identity.User, the
    // username in identity.Name, etc....
}

(有此code使用的是线程,而不是 WindowsIdentity.GetCurrent()。一个原因)

他的code欺骗了(略有修改):

His code to trick that (slightly modified):

var ident = WindowsIdentity.GetCurrent();
Thread.CurrentPrincipal = new WindowsPrincipal(ident);
var fakeSid = new SecurityIdentifier("S-1-3-0"/* E.g., some SID you want to trick me into believing is the real user */);
typeof(WindowsIdentity).GetField("m_user", BindingFlags.Instance | BindingFlags.NonPublic)
    .SetValue(ident, fakeSid);

果然,如果你这样做,然后打电话给我的code以上,我的code被愚弄。荣誉达米安。

And sure enough, if you do that then call my code above, my code gets fooled. Kudos Damien.

因此​​,在真正的军备竞赛的方式,这是我修改code先得欺骗和否认的:

So in true arms race fashion, here's my revised code that catches the spoof and denies it:

WindowsIdentity identity = Thread.CurrentPrincipal == null
    ? null
    : Thread.CurrentPrincipal.Identity as WindowsIdentity;

if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous) {
    var validated = new WindowsIdentity(identity.Token);
    if (!validated.User.Equals(identity.User) || !validated.IsAuthenticated || validated.IsAnonymous) {
        // Something fishy is going on, don't trust it
    } else {
        // Good! Use the validated one
        identity = validated;
        // ...use and trust the SID in identity.User, the
        // username in identity.Name, etc....
    }
}

正如你所看到的,取令牌从所提供的身份和创建的新的的WindowsIdentity 实例使用该令牌。如果身份的SID匹配,我们继续信任验证之一。 (对于的WindowsIdentity(IntPtr的令牌文档) 说, IsAuthenticated 将,但这是完全错误的在我的测试假设我已经有一个有效的用户令牌创建它。)

As you can see, that takes the Token from the provided identity and creates a new WindowsIdentity instance using that token. If the SIDs of the identities match, we continue, trusting the validated one. (The documentation for WindowsIdentity(IntPtr token) says that the initial value of IsAuthenticated will be false, but that's simply wrong in my tests assuming I've created it with a valid user token.)

我可以看到,可能被欺骗将与一个欺骗用户的唯一方式令牌仍然通过了验证Windows不会用它。这似乎不太可能给我。不过,这是无知的我的一个领域。

The only way I can see that that could be tricked would be with a spoofed user token that nevertheless passes the validations Windows does with it. That seems unlikely to me. But then, this is an area of ignorance for me.

边界

我要指出,我只是拍了合理度的单点登录安全在这里,做我因dilience。如果一个恶意的应用程序已成功启动拦截系统调用/破坏Windows本身,还有,但只是不是很多,我将能够做到这一点。由于达明在评论中指出的其他问题,他也许可以建立一个完全忽略强命名(从而可以给我一个完全假的的WindowsIdentity 类型的主机)的容器。很公平。完美杀死。我只是不想离开门像慈祥展示一个开放达明。如果我发布了一个系统,并在现场进行了黑客攻击,很容易,我会pretty该死的尴尬了。 : - )

I should note that I'm just shooting for a reasonable degree of single sign-on security here, doing my due dilience. If a malicious app has successfully started intercepting system calls / compromised Windows itself, well, there's just not a lot I'm going to be able to do about that. As Damien pointed out in comments on that other question, he could probably build a host container that completely ignored strong naming (and thus could give me a completely fake WindowsIdentity type). Fair enough. Perfection kills. I just don't want to leave doors open like the one Damien kindly demonstrated. If I released a system and it were hacked in the field that easily, I'd be pretty darned embarrassed about it. :-)

推荐答案

要证明这是可行的,let'use命名一个很酷的Visual Studio插件的微软正版正货(这个名字本身就意味着很多......)。

To demonstrate this is doable, let'use a cool Visual Studio addon named "Microsoft Fakes" (the name itself means a lot...).

假货本身被连接到测试的Visual Studio特征,但它会证明这一点。您可以按照标准教程设置项目,并添加一个假货总成系统(其实mscorlib程序+系统)

Fakes itself is tied to test features of Visual Studio, but it will prove the point. You can follow the standard tutorials to setup a project, and add a fakes assembly for System (in fact mscorlib + system)

这是在库项目中的code(我用的异常无处不在,因为它在测试条件下更容易...)。

This is your code in a library project (I've used exception everywhere because it's easier in testing condition...).

namespace ClassLibrary1
{
    public class Class1
    {
        public static void MyCheck()
        {
            WindowsIdentity identity = Thread.CurrentPrincipal == null
                ? null
                : Thread.CurrentPrincipal.Identity as WindowsIdentity;

            if (identity != null && identity.IsAuthenticated && !identity.IsAnonymous)
            {
                var validated = new WindowsIdentity(identity.Token);
                if (!validated.User.Equals(identity.User) || !validated.IsAuthenticated || validated.IsAnonymous)
                    throw new Exception("Something fishy is going on, don't trust it");
                else
                    throw new Exception("Good! Use the validated one. name is:" + validated.Name);
            }
            else
                throw new Exception("not in");
        }
    }
}

这是在测试项目测试code:

This is the testing code in the test project:

namespace UnitTestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            using (ShimsContext.Create())
            {
                System.Security.Principal.Fakes.ShimWindowsIdentity.AllInstances.NameGet = (i) =>
                {
                    return "Simon the hacker";
                };

                WindowsIdentity wi = WindowsIdentity.GetCurrent(); // this is the real one "Simon".
                Thread.CurrentPrincipal = new WindowsPrincipal(wi);

                Class1.MyCheck();
            }
        }
    }
}

这是在Visual Studio项目布局:

This is the project layout in Visual Studio:

另外,还要确保你修改了自动像这样生成的文件mscorlib.fakes:

Also make sure you modify the mscorlib.fakes file that was automatically generated like this:

<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/" Diagnostic="true" TargetFrameworkVersion="v4.6">
  <Assembly Name="mscorlib" />
  <ShimGeneration>
    <Clear />
    <Add Namespace="System.Security.Principal" />
  </ShimGeneration>
</Fakes>

这意味着我想整个 System.Security.Principal 命名空间被shimed,我建议你使用框架4.6这两个项目,并添加相应的TargetFrameworkVersion属性。

It means I want the whole System.Security.Principal namespace to be shimed and I suggest you use framework 4.6 for both projects and add the corresponding TargetFrameworkVersion attribute.

现在,当你运行测试,这是你会看到:

Now, when you run the test, this is what you'll see:

好吧,在特定情况下,我可能无法使用假货,但是它依赖于底层技术只是重新路由所有的API(它比实际上.NET更低,这就是所谓的Detours )我相信,并允许所有这些两轮牛车。

Ok, in your specific scenario, I may not be able to use fakes, but the underlying technology it relies on just reroutes all APIs (it's lower than .NET in fact, it's called Detours) I believe and allows all these hackery.

综上所述:如果它运行在我的机器上,我可以破解它(除非我没有我的机器的物理访问)

To sum up: if it runs on my machine, I can hack it (unless I don't have physical access to my machine).

这篇关于是否有可能欺骗这个的WindowsIdentity code到使用错误的用户?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆