- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
TL;DR WindowsIdentity
的 Token
属性中是否包含用户 token (例如,someIdentity.Token
) 被欺骗:
var validated = new WindowsIdentity(someIdentity.Token);
...将返回一个实例,该实例声称代表一个用户,该用户实际上尚未通过身份验证,但已将 IsAuthenticated
设置为 true
,有效 .Name
和.User
属性等等?
下面我对此做了一些限制;大概不可能完全防欺骗。
完整的故事:
在this answer , Damien_The_Unbeliever巧妙地证明了我的某些代码可能会被欺骗,使其相信它在 WindowsIdentity
实例中拥有经过身份验证的有效用户,而实际上它并没有。长话短说,我的代码假设如果 Thread.CurrentPrincipal.Identity
是 WindowsIdentity
的实例并且 IsAuthorized
是 true
,它代表一个经过身份验证的用户,我可以依赖 .User
中的 SID:
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....
}
(此代码使用线程而不是 WindowsIdentity.GetCurrent()
是有原因的。)
他用来欺骗的代码(稍作修改):
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);
果然,如果你这样做然后调用我上面的代码,我的代码就会被愚弄。感谢达米安。
因此,以真正的军备竞赛方式,这是我修改后的代码,可以捕捉到恶搞并予以否认:
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....
}
}
如您所见,它从提供的身份中获取 Token
并使用该 token 创建一个新 WindowsIdentity
实例。如果身份的 SID 匹配,我们将继续,并信任经过验证的身份。 (documentation for WindowsIdentity(IntPtr token)
表示 IsAuthenticated
的初始值将为 false
,但假设我使用有效的用户 token 创建它,这在我的测试中是完全错误的。)
我认为可能被欺骗的唯一方法是使用欺骗性的用户 token ,该 token 仍然通过了 Windows 对其进行的验证。这对我来说似乎不太可能。但是,这对我来说是一个无知的领域。
边界:
我应该指出,我只是在尽我的努力,争取达到合理程度的单点登录安全性。如果恶意应用程序已成功开始拦截系统调用/破坏 Windows 本身,那么我对此无能为力。正如 Damien 在对另一个问题的评论中指出的那样,他可能会构建一个完全忽略强命名的主机容器(因此可以给我一个完全伪造的 WindowsIdentity
类型)。很公平。完美杀人。我只是不想像 Damien 善意示范的那样敞开大门。如果我发布了一个系统并且很容易在现场被黑客入侵,我会为此感到非常尴尬。 :-)
最佳答案
为了证明这是可行的,让我们使用一个名为“Microsoft Fakes”的很酷的 Visual Studio 插件(这个名字本身意义重大……)。
Fakes 本身与 Visual Studio 的测试功能相关联,但它将证明这一点。您可以按照标准教程设置项目,并为系统添加假程序集(实际上是 mscorlib + 系统)
这是您在库项目中的代码(我在所有地方都使用了异常,因为它在测试条件下更容易...)。
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");
}
}
}
这是测试项目中的测试代码:
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 中的项目布局:
还要确保修改自动生成的 mscorlib.fakes 文件,如下所示:
<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
命名空间,我建议您对这两个项目使用框架 4.6 并添加相应的 TargetFrameworkVersion 属性。
现在,当您运行测试时,您将看到:
好吧,在你的特定场景下,我可能无法使用假货,但它所依赖的底层技术只是重新路由了所有的API(它比.NET更低,实际上它被称为Detours)我相信并允许所有这些骇客。
总结一下:如果它在我的机器上运行,我可以破解它(除非我没有物理访问我的机器)。
关于c# - 是否有可能诱使此 WindowsIdentity 代码使用错误的用户?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33573773/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!