1

我寫這個的JScript驗證本地Windows用戶帳戶:身份驗證本地Windows用戶帳戶

function ValidateCredentials(strUsername, strPassword) { 
    var ADS_SECURE_AUTHENTICATION = 1; 
    var objWMISvc = GetObject("winmgmts:\\\\.\\root\\cimv2"); 
    var colItems = objWMISvc.ExecQuery("Select * from Win32_ComputerSystem"); 
    for (var it = new Enumerator(colItems); !it.atEnd(); it.moveNext()) { 
    var objItem = it.item(); 
    if (objItem.PartOfDomain) 
     continue; 
    var strWorkgroup = objItem.Domain; 
    var strComputer = objItem.Name; 
    var strPath = "WinNT://" + strWorkgroup + "/" + strComputer + "/" + 
     strUsername + ",user"; 
    try { 
     var objIADS = GetObject("WinNT:").OpenDSObject(strPath, strUsername, 
     strPassword, ADS_SECURE_AUTHENTICATION); 

     WScript.Echo("OK"); 
    } catch(e) { 
     WScript.Echo("Invalid Username/Password"); 
    } 
    } 
} 

ValidateCredentials(WScript.Arguments(0), WScript.Arguments(1)); 

當我從命令提示符下運行它,它工作得很好,無論是作爲管理員以及普通用戶。當腳本被作爲LocalSystem用戶運行的服務進程調用時,它不起作用。而是調用OpenDSObject,然後引發一個異常,錯誤代碼爲-2147023584(指定的登錄會話不存在,它可能已被終止)。

這裏有什麼問題,我認爲LocalSystem帳戶實際上比管理員帳戶更具特權或可信?

您可以將其保存到一些.js文件試圖爲自己的腳本,然後從這樣的命令提示符下運行:

的Cscript.exe validate.js名爲myUsername MYPASSWORD

+0

LocalSystem帳戶實際上沒有管理員帳戶的特權/可信度。這只是...不同的信任。也就是說,它有一些沒有普通用戶帳戶的權利 - 但它也有一些限制,幾乎沒有其他帳戶有。 –

+0

這在任何情況下都不是安全問題,即Windows出於安全原因不會故意阻止您這樣做。只是在這種情況下,不管OpenDSObject究竟在做什麼都不支持。 (它可能從配置爲在實際帳戶中運行的服務工作。) –

+0

@HarryJohnston是的,如果我將服務配置爲以管理員身份運行,但我不願意這樣做,因爲系統中的每個服務都配置爲運行作爲本地系統或網絡服務,所以我不知道它是否會有任何安全隱患......順便說一句,這個服務是OpenVPN。 – PaulK

回答

1

如果你只是想驗證密碼,我會避免以上所有。有一種有點不同的方法可以很好地處理未經授權的帳戶。其實你要確保這個賬號實際上並沒有權利更改密碼。

使用此方法,您可以撥打NetUserChangePassword,它需要您指定用戶的現有密碼才能在更改之前進行身份驗證。

當您從無權更改該用戶密碼的帳戶執行此操作時,顯然會失敗(因此其密碼不會更改)。我們關心的究竟是如何它失敗。如果通過返回ERROR_INVALID_PASSWORD失敗,那麼你知道密碼是錯誤的。如果通過返回ERROR_ACCESS_DENIED而失敗,則密碼正確,並且該功能失敗,因爲您從中調用該帳戶的帳戶無權更改該用戶的密碼。

因此,不要求像LocalSystem或管理員這樣的高度特權帳戶,這可以讓您從根本上沒有任何權限的帳戶執行任務(強烈偏好,甚至沒有權限更改自己的密碼) 。

+0

太好了,謝謝!爲了記錄,我還在MSDN上找到了[本文](https://support.microsoft.com/en-us/kb/180548/),它解釋瞭如何使用LogonUser WinAPI函數來實現相同的功能。 – PaulK

+0

@Jerry,這是行爲記錄? –

+0

@哈里約翰斯頓:是的,沒有。它可以/將返回這兩個值的事實是。我不確定他們(當前)是否有關於錯誤值之間的優先級的任何文檔,所以如果您傳遞錯誤的密碼*並且*沒有更改密碼的權限,您將得到的返回值是' ERROR_INVALID_PASSWORD'。 –