سؤال

كيف يمكن لـ vbscript اكتشاف ما إذا كان يعمل في سياق UAC مرتفع أم لا؟

ليس لدي مشكلة في اكتشاف المستخدم ومعرفة ما إذا كان المستخدم ضمن مجموعة المسؤولين.لكن هذا لا يزال لا يجيب على سؤال ما إذا كانت العملية تحتوي على خصوصيات مرتفعة أم لا، عند التشغيل تحت نظام التشغيل Vista أو Windows 2008.يرجى ملاحظة أنني بحاجة فقط إلى ذلك يكشف هذه الحالة؛لا تحاول أن ترفع أو (تخطئ..) أن تقلل من الارتقاء.

هل كانت مفيدة؟

المحلول

تعتمد الطريقة التي استقرت عليها أخيرًا على حقيقة أن نظامي التشغيل Vista وWindows 2008 لديهما الأداة المساعدة whoami.exe، وهي تكتشف مستوى سلامة المستخدم الذي يملك العملية.تساعد بعض لقطات الشاشة هنا:

WHOAMI، عادي ومرتفع، على نظام التشغيل 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، فإنه يستدعي CheckforElevation الذي يقوم بتشغيل whoami.exe /groups، ويبحث عن السلسلة 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

نصائح أخرى

وهنا لي حل أقصر:

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

وهذه هي وظيفة تقف وحدها، ولن يتم عرض أي إطار وحدة التحكم وميض عند تنفيذها.

والحل وأنا على نشر هو إنتاج زوجين VBScripts استعداد هذا النفوذ whoami للعثور على هذه المعلومات. شيء واحد بارد عنها هو أنها تعمل مع XP (للحصول على معلومات المتوفرة على XP) إذا قمت بوضع نسخة من الإصدار أدوات موارد من whoami.exe بجانب النصي (أو في المجلد System32 من كل جهاز).

CSI_IsSession.vbs يحتوي على وظيفة واحدة يمكن أن أقول لكم أي شيء تقريبا كنت تريد لمعرفة UAC أو الدورة الحالية هو السيناريو تعمل تحت.

VBScriptUACKit.vbs (والذي يستخدم CSI_IsSession.vbs) يسمح لك للمطالبة انتقائي لUAC في السيناريو قبل استئناف نفسها. وقد تم تصميم وتصحيحه على العمل في ظل العديد من سيناريوهات التنفيذ.

وكل البرامج النصية تحتوي على نموذج التعليمات البرمجية التي يوضح كيفية استخدام التعليمات البرمجية النصية الأساسية.

وأقصر قليلا في 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());
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top