TL; DR token của user có thể chứa trong một Token
tài sản (ví dụ, someIdentity.Token
) WindowsIdentity
's được giả mạo như vậy:Có thể đánh lừa mã WindowsIdentity này bằng cách sử dụng sai người dùng không?
var validated = new WindowsIdentity(someIdentity.Token);
... sẽ trở lại một trường hợp mà tuyên bố để đại diện cho một người dùng trên thực tế, chưa được xác thực, và chưa có IsAuthenticated
đặt true
, hợp lệ .Name
và .User
thuộc tính, v.v ...?
Dưới đây tôi đặt một vài ranh giới về điều này; có lẽ không thể hoàn toàn chống giả mạo.
Câu chuyện đầy đủ:
Trong this answer, Damien_The_Unbeliever khéo léo chứng minh rằng một số mã của tôi có thể bị lừa tin rằng nó đã có một người dùng xác thực hợp lệ trong một trường hợp WindowsIdentity
khi nó thì không. Dài truyện ngắn, mã của tôi đã giả định rằng nếu Thread.CurrentPrincipal.Identity
là một thể hiện của WindowsIdentity
và IsAuthorized
là true
, mà nó đại diện cho một người dùng xác thực và tôi có thể dựa vào các SID trong .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....
}
(Có một lý do mã này . đang sử dụng các chủ đề chứ không phải là WindowsIdentity.GetCurrent()
)
mã của mình để lừa đó (thay đổi chút ít):
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);
Và chắc chắn eno ugh, nếu bạn làm điều đó thì hãy gọi mã của tôi ở trên, mã của tôi bị lừa. Kudos Damien.
Vì vậy, trong thời trang thật sự chạy đua vũ trang, đây là mã sửa đổi của tôi mà bắt spoof và phủ nhận nó:
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....
}
}
Như bạn thấy, mà mất Token
từ bản sắc được cung cấp và tạo ra một mớiWindowsIdentity
bằng cách sử dụng mã thông báo đó. Nếu các SID của danh tính khớp nhau, chúng tôi tiếp tục, tin tưởng vào một SID được xác thực. (Các documentation for WindowsIdentity(IntPtr token)
nói rằng giá trị ban đầu của IsAuthenticated
sẽ false
, nhưng điều đó chỉ đơn giản là sai trong các thử nghiệm của tôi giả sử tôi đã tạo ra nó với một mã thông báo người dùng hợp lệ.)
Cách duy nhất tôi có thể thấy rằng có thể bị lừa sẽ với một mã thông báo người dùng giả mạo mà vẫn vượt qua các xác nhận hợp lệ của Windows với nó. Điều đó dường như không xảy ra với tôi. Nhưng sau đó, đây là một lĩnh vực vô minh đối với tôi.
Ranh giới:
Tôi nên lưu ý rằng tôi chỉ chụp cho một lý mức độ single sign-on an ninh ở đây, làm dilience do của tôi. Nếu một ứng dụng độc hại đã khởi động thành công việc chặn các cuộc gọi hệ thống/Windows bị xâm phạm, thì không có nhiều khả năng tôi sẽ làm được điều đó.Như Damien đã chỉ ra trong các bình luận về câu hỏi khác, anh ta có lẽ có thể xây dựng một container chứa hoàn toàn bỏ qua việc đặt tên mạnh (và do đó có thể cho tôi một loại hoàn toàn giả mạo WindowsIdentity
). Đủ công bằng. Sự hoàn hảo giết chết. Tôi chỉ không muốn để cánh cửa mở ra như một chiếc Damien vui lòng chứng minh. Nếu tôi phát hành một hệ thống và nó đã bị tấn công trong lĩnh vực đó một cách dễ dàng, tôi sẽ khá xấu hổ về điều đó. :-)
Ngoài khả năng của tôi để trả lời, nhưng câu hỏi tuyệt vời! Vui mừng khi thấy câu trả lời được đưa ra :) – levelonehuman
@levelonehuman Suy nghĩ của tôi chính xác! –
"Skeet không làm hỏng tôi ngay bây giờ!" ;-) –