【问题标题】:Vbscript detect whether UAC-elevatedvbscript 检测 UAC 是否升高
【发布时间】:2008-10-25 03:12:18
【问题描述】:

我的 vbscript 如何检测它是否在 UAC 提升的上下文中运行?

检测用户并查看用户是否在管理员组中没有问题。但这仍然不能回答在 Vista 或 Windows 2008 下运行时进程是否提升了 privs 的问题。请注意,我只需要检测这个状态;不要试图提升或(错误..)去提升。

【问题讨论】:

  • 请注意,下面添加了一个比已接受的答案更好的答案。

标签: windows-vista vbscript windows-server-2008 uac


【解决方案1】:

我最终确定的方法取决于 Vista 和 Windows 2008 都有 whoami.exe 实用程序,它会检测拥有该进程的用户的完整性级别。几个屏幕截图在这里有所帮助:

WHOAMI, normal and elevated, on Vista http://lh3.ggpht.com/_Svunm47buj0/SQ6ql4iNjPI/AAAAAAAAAeA/iwbcSrAZqRg/whoami%20-%20adminuser%20-%20groups%20-%20cropped.png?imgmax=512

您可以看到,当 cmd 运行提升时,whoami /groups 报告“高”强制完整性级别和与非提升运行时不同的 SID。图中,最上面的会话是正常的,下面的会话在UAC提示后正在运行。

知道了,这是我使用的代码。它主要检查操作系统版本,如果是 Vista 或 Server 2008,则调用运行 whoami.exe /groups 的 CheckforElevation,并在输出中查找字符串 S-1-16-12288。在这个例子中,我只是回显状态;在实际脚本中,我会根据结果分支到不同的操作。

sub GetOSVersion
Dim strComputer, oWMIService, colOSInfo, oOSProperty, strCaption, strOSFamily
strComputer = "."
Set oWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colOSInfo = oWMIService.ExecQuery("Select * from Win32_OperatingSystem")
'I hate looping through just to get one property. But dunno another way!
For Each oOSProperty in colOSInfo 
  strCaption = oOSProperty.Caption 
Next
If InStr(1,strCaption, "Vista", vbTextCompare) Then strOSFamily = "Vista"
If InStr(1,strCaption, "2008", vbTextCompare) Then strOSFamily = "2008"
If InStr(1,strCaption, "XP", vbTextCompare) Then strOSFamily = "XP"
If InStr(1,strCaption, "2003", vbTextCompare) Then strOSFamily = "2003"
If InStr(1,strCaption, "2000", vbTextCompare) Then strOSFamily = "2000"
If strOSFamily = "" Then 
    Wscript.Echo "No known OS found. (Script can detect Windows 2000, 2003, XP, Vista, 2008.)" 
Else 
    Wscript.Echo "OS Family = " & strOSFamily
End If
Select Case strOSFamily 'if Vista/2008 then call CheckforElevation
Case "Vista"
    CheckforElevation
Case "2008"
    CheckforElevation
Case Else
    Exit Sub
End Select
end sub

sub CheckforElevation 'test whether user has elevated token 
Dim oShell, oExecWhoami, oWhoamiOutput, strWhoamiOutput, boolHasElevatedToken
Set oShell = CreateObject("WScript.Shell")
Set oExecWhoami = oShell.Exec("whoami /groups")
Set oWhoamiOutput = oExecWhoami.StdOut
strWhoamiOutput = oWhoamiOutput.ReadAll
If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then boolHasElevatedToken = True
If boolHasElevatedToken Then
    Wscript.Echo "Current script is running with elevated privs."
Else
    Wscript.Echo "Current script is NOT running with elevated privs."
End If
end sub

【讨论】:

  • 当然这很糟糕。访问 GetTokenInformation API 会更干净。但显然这超出了 VBscript 的范围。哦,好吧 - 我们尽我们所能。
【解决方案2】:

这是我的简短解决方案:

Function IsElevated
    IsElevated = CreateObject("WScript.Shell").Run("cmd.exe /c ""whoami /groups|findstr S-1-16-12288""", 0, true) = 0
End function 

此函数是独立的,执行时不会显示任何闪烁的控制台窗口。

【讨论】:

  • 太好了,这比公认的答案要好。
【解决方案3】:

我发布的解决方案是几个可用于生产的 VBScript,它们利用 whoami 来查找此信息。关于它们的一个很酷的事情是,如果您将资源工具包版本 whoami.exe 的副本放在脚本旁边(或每台机器的 system32 文件夹中),它们可以与 XP 一起使用(有关 XP 上可用的信息)。

CSI_IsSession.vbs 包含一个函数,可以告诉您几乎所有关于 UAC 或脚本正在运行的当前会话的信息。

VBScriptUACKit.vbs(使用 CSI_IsSession.vbs)允许您通过重新启动自身来选择性地在脚本中提示 UAC。经过设计和调试,可在多种执行场景下工作。

两个脚本都包含演示如何使用核心脚本代码的示例代码。

【讨论】:

  • 哇,你真的研究过这个!您的 CSI_IsSession.vbs 链接上的博客文章充满了很好的信息;感谢那。但是,如果不调用 whoami.exe,vbscript 无法做到这一点,这仍然是一个遗憾。
【解决方案4】:

在 WSH Jscript 中略短

function isElevated(){
    var strCaption  = "";
    for (var enumItems=new Enumerator(GetObject("winmgmts:\\\\.\\root\\CIMV2").ExecQuery("Select * from Win32_OperatingSystem")); !enumItems.atEnd(); enumItems.moveNext()) {
        strCaption  +=  enumItems.item().Caption;
    }
    if(/Vista|2008|Windows\s7|Windows\s8/.test(strCaption)){
        return (new ActiveXObject("WScript.Shell").run('cmd.exe /c "whoami /groups|findstr S-1-16-12288"', 0, true)) == 0;
    }else{return true}
}    

WScript.Echo(isElevated());

【讨论】:

    猜你喜欢
    • 2010-09-10
    • 2010-09-10
    • 1970-01-01
    • 1970-01-01
    • 2016-02-25
    • 1970-01-01
    • 2012-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多