转贴自http://hi.baidu.com/mikeoldyang/blog/item/3ce1dd458dda7f4b510ffe99.html
我想这个是很多做网管的需要干的事情,禁用USB存储。
前提是我们不能从BIOS里面禁用,一个是容易破解(拔电池),主要还是因为我们还需要使用USB鼠标以及Bitlocker的的,所以只能从系统里面动脑筋。
首先是KB555324,http://support.microsoft.com/kb/555324/zh-cn这里介绍的方法需要自定义一个组策略,看上去好像很好很强大,很简单,可是有一个致命的问题,谁也无法保证那个OU下就一定没有服务器的计算机账号,此时就容易误杀,比不上用脚本可以先判断一下。或者你会说可以用WMI筛选,不过就我们的环境目前没权限设这个,而且也不太会写。另外就是到底效果咋样,能否禁掉还未可知。这位看客可能要说了,KB说的还有假?不错,我相信KB,但是有时会不适用。何出此言?请继续往下看
然后就是KB823732,http://support.microsoft.com/kb/823732/zh-cn这个方法应该是很好,很根本了(微软服务所言),然后我又借用http://www.cnitblog。 COM / joyclear /存档/ 2008/05/10 / 43525.html所说的用XCACLS来设权限,可是在XPSP2以及之前的版本中都没有XCACLS这个命令,只有CACLS这个命令,而CACLS的问题是不带/ Y参数,汉语中类似的所以找了http://support.microsoft.com/kb/135268/zh-cn来实现,有看官可能要说了,你可以使用网络共享的XCACLS来啊,唉,这不是有本地自带的命令,就尽量用本地的了吗。
好,万事俱备,开始脚本吧,好像很简单,也就3〜4行的批处理啊,XP是好的,可是在Vista的下就有问题了,如果插入新设备,Vista中总是还能找到,如果是旧设备,在计算机管理中卸载掉再插入闪存,Vista还是能够使用。而且会把HKEY_LOCAL_MACHINE / SYSTEM / CurrentControlSet / Services / UsbStor下面的开始值自动改回到3,真是见鬼了。说法,在拒绝INF和PNF文件后,装新设备时会由于没有权限读这两个文件,导致安装失败,可是好像Vista的就是有办法。个天杀的,把老子搞得一点脾气没有,小事变成大事了。搞不定啊。
个NND,你不是会把注册表改回来吗,老子把注册表的权限也给你拒绝掉,看你咋整?后来发现(无数次实验),只要在上述健的位置,把SYSTEM账号给拒绝掉,就真的可以在Vista中下也禁用掉USB了,那连两个INF和PNF文件都不要做任何修改,这可是微软都不知道的哦。可是问题来了,鼠标点点改注册表权限是方便的,用脚本或者命令该咋办呢?翻便微软网站也只找到一个REGINI命令,可是要命的是看了半天帮助,也没找到可以设置拒绝权限的选项。找到SETACL这个超级权限管理工具,我用的是0.904版的,用法比较简单,http://www.helge./setacl/program/setacl0.904/setacl.exe现在新的是2.0版本的,功能超强,参数众多,当然用的也比较累了http:///project/showfiles.php?group_id=69165
这下基本技术就解决了,下面是写脚本和部署了,因为客户端没有管理员权限,所以脚本必须要用在计算机策略中的开机脚本中,然而很显然公司里面肯定还是有人要使用USB存储的,比如说老板们,当他们填写申请单来要求开通的时候,helpdesk怎样才能很方便的来为他们解除限制呢?而解除限制是分两块的,一个是把注册表权限给改回来,另外一个是让组策略以后不能再次生效。前者可以写一个恢复的脚本,后者就通过组策略的安全设置喽。建一个组,然后在GPMC中设置那个组策略中这个组被拒绝。然后在恢复的脚本中加入将计算机账号加入到这个组的功能。
关于还原的脚本,还有一个问题就是,如果就是一个很简单的脚本,没有任何安全措施,一旦将来这个脚本流传出去(很有可能),那么每个人都可以运行一下来解除限制,到那时。这个限制也就是一个摆设了所以首先脚本要加密,其次要在运行的时候验证用户身份,只有特定账号才可以使用。
好了,整个技术和管理思路就是这样了,下面就是两个脚本最好还要说一下就是,我发现Vista和XP在usbstor.inf和usbstor.pnf上最大的不同是,XP下这两个文件的所有者是管理员,而在Vista下的所有者是系统,而为USB安装驱动经实验是使用的系统账号,并不是之前想当然的觉得是当前登录的账号,所以KB823732在Vista下不能生效的原因就是虽然拒绝了系统账号去读这两个文件,可是由于业主是系统,所以系统照样可以读到,就照样可以安装USB存储,然后再自动的把开始的值改回3。
哈哈,我的解释是不是很有说服力啊。
'------------------------------------------------- --------------------------- 'DisableUSB.vbs'VBScript program to RestoreUSB'Date :12/10/2008 '版本:3.0 - 删除其他限制 “作者:杨苏扬在AMD苏州 ”--------------------------------------- -------------------------------------
'------------------------- '获取操作系统 '-------------------- ----- 错误恢复下一步
strComputer =“。” 设置objWMIService = GetObject(“winmgmts:”_ &“{impersonationLevel = impersonate}!//”&strComputer&“/ root / cimv2”) Set colOperatingSystems = objWMIService.ExecQuery _ (“Select * from Win32_OperatingSystem”) For Each objOperatingSystem in colOperatingSystems
OS = objOperatingSystem.Caption 如果InStr(OS,“XP”)> 0则 OSType = 0 Elseif InStr(OS,“2000 Professional”)> 0然后 OSType = 0 Elseif InStr(OS,“2000 Server”)> 0然后 OSType = 1 ELSEIF InStr函数(OS, “2000高级服务器”)> 0,则 OSTYPE = 1 ELSEIF InStr函数(OS, “2003”)> 0然后 OSTYPE = 1 ELSEIF InStr函数(OS,的“Vista”)> 0然后 OSTYPE = 0 ELSEIF InStr函数(OS, “2008”)> 0,则 OSTYPE = 1个 否则 OSTYPE = 0 END IF WINDIR = objOperatingSystem.WindowsDirectory 接着 “Wscript.echo OSTYPE 如果OSTYPE = 1然后 WScript的。退出 结束if
'Wscript.echo Windir
' ------------------------- ' Copy SetACL ' ------------------------- Source = "//amd.com/SysVol/amd.com/Policies/{C6178A2D-90FC-4663-AB81-0B9B737C11A0}/Machine/Scripts/Startup/SetACL.exe" Destination = Windir & "/system32/"
SetACL = Windir & "/system32/SetACL.exe" Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(SetACL) Then
'-------------------------------------- 'Check size '-------------------------------------- Set objFile1 = objFSO.GetFile(SetACL) If objFile1.Size <> 163840 Then objFSO.CopyFile Source, Destination, OverwriteExisting End If
Else objFSO.CopyFile Source, Destination, OverwriteExisting
End If
' ----------------------------------------------- ' Modify registry ' ----------------------------------------------- const HKEY_LOCAL_MACHINE = &H80000002 'strComputer = "." Set StdOut = WScript.StdOut Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!//" &_ strComputer & "/root/default:StdRegProv")
strKeyPath = "SYSTEM/CurrentControlSet/Services/USBSTOR" strValueName = "Start" dwValue = 4 oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue
strKeyPath1 = "SYSTEM/CurrentControlSet/Control/StorageDevicePolicies" strValueName1 = "WriteProtect" dwValue1 = 1 oReg.CreateKey HKEY_LOCAL_MACHINE,strKeyPath1 oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath1,strValueName1,dwValue1
Wscript.Sleep 1000
' ----------------------------------------------- ' Deny system permission on registry ' ----------------------------------------------- Set Wwsh = CreateObject("WScript.Shell")
ExecRun1 = "cmd /c " & SetACL & " MACHINE/System/CurrentControlset/Services/usbstor /registry /deny system /full"
Set wExec1 = Wwsh.Exec(ExecRun1) Rcode = wExec1.StdOut.ReadAll
下面RestorUSB的脚本需要配合一个password.htm文件来使用,这个文件的作用就是验证身份,并且隐藏密码。这个RestoreUSB的脚本功能还是很强大的,
1. 验证身份 2. 验证是否在域中 3. 把计算机账号加到组中(需要运行账号有AD中相应的权限) 4. 恢复注册表权限 5. 如果在Restore的时候发生错误,会自动把log发出来。
看官可以自己看是否有必要搞得这么复杂,毕竟各自的环境不同。
' ---------------------------------------------------------------------------- ' RestoreUSB.vbs ' VBScript program to RestoreUSB ' Date: 12/10/2008 ' Version: 3.0 ' By: Mike Yang at AMD Suzhou ' ----------------------------------------------------------------------------
On Error Resume Next
' ########################################################################### ' Get privilege account, e.g admin_xxx or acct_xxx ' ###########################################################################
' Dim Shell Dim oShell Set oShell = WScript.CreateObject ("WSCript.shell")
' ------------------------- ' Get User & Password ' ------------------------- Set objExplorer = WScript.CreateObject _ ("InternetExplorer.Application", "IE_")
objExplorer.Navigate "file://///ssuzfile22/helpdesk$/RestoreUSB/Password.htm" objExplorer.ToolBar = 0 objExplorer.StatusBar = 0 objExplorer.Width = 620 objExplorer.Height = 420 objExplorer.Left = 100 objExplorer.Top = 100 objExplorer.Visible = 1
Do While (objExplorer.Document.Body.All.OKClicked.Value = "") Wscript.Sleep 250 Loop
' -------------------------------------------------------------- strUserName = objExplorer.Document.Body.All.UserName.Value strUser = "amd/" & strUserName strPassword = objExplorer.Document.Body.All.UserPassword.Value strASRNo = objExplorer.Document.Body.All.ASRNo.Value ' --------------------------------------------------------------
strButton = objExplorer.Document.Body.All.OKClicked.Value objExplorer.Quit Wscript.Sleep 250
If strButton = "Cancelled" Then Wscript.Quit End If If strUsername = "" or strPassword = "" or strASRNo = "" Then Wscript.Quit End If
' ------------------------- ' Check input User ' ------------------------- adminxxx = Left(strUser,10) 'Wscript.echo adminxxx
acctxxx = Left(strUser,9) 'Wscript.echo acctxxx
err.clear TASRN0 = Int(strASRNo) If err <> 0 Then err.clear Wscript.echo "" _ & "Your input is error, the ASR number must be number."
run8 = "//ssuzfile22/helpdesk$/RestoreUSB/RestoreUSB.vbe" 'Wscript.echo run8 oShell.run run8,true Wscript.quit
Elseif Len(strASRNo) <> 6 Then
Wscript.echo "" _ & "Your input is error, the ASR number must have 6 numbers"
run8 = "//ssuzfile22/helpdesk$/RestoreUSB/RestoreUSB.vbe" 'Wscript.echo run8 oShell.run run8,true Wscript.quit End if
If adminxxx <> "amd/admin_" and acctxxx <> "amd/acct_" and strUser <> "amd/amdhelpdesk" Then
Mailto = "mike.yang@amd.com" MailSubject = "Input error name: " & struser MailTextbody = "Input error name: " & struser SendMail Mailto,MailSubject,MailTextbody
Wscript.echo "" _ & "Error!! You must use acct_xxx, admin_xxx or amdhelpdesk to run the tools. " & chr(10) & chr(13) _ & "And you must use minuscule to inpute,like acct_yjay , please input again."
run8 = "//ssuzfile22/helpdesk$/RestoreUSB/RestoreUSB.vbe" 'Wscript.echo run8 oShell.run run8,true Wscript.quit End If
' ------------------------- ' Authenticate User ' -------------------------
Const ADS_SECURE_AUTHENTICATION = 1 Const ADS_USE_ENCRYPTION = 2
strPath = "OU=Suzhou,dc=amd,dc=com"
Set root = GetObject("LDAP:") Set objOU = root.OpenDSObject("LDAP://SSUZDC3/" & strPath, strUser, strPassword, _ ADS_USE_ENCRYPTION AND ADS_SECURE_AUTHENTICATION)
SuzDN = objOU.distinguishedName If err = 424 then
Mailto = "mike.yang@amd.com" MailSubject = "Logon failure: " & struser MailTextbody = "Logon failure: " & struser SendMail Mailto,MailSubject,MailTextbody
Wscript.echo "" _ & "Logon failure: unknown user name or bad password, please input again."
run8 = "//ssuzfile22/helpdesk$/RestoreUSB/RestoreUSB.vbe" 'Wscript.echo run8 oShell.run run8,true wscript.quit
ElseIf err <> 0 Then
Mailto = "mike.yang@amd.com" MailSubject = "Get Suzhou OU failure: " & struser MailTextbody = "Get Suzhou OU failure: " & struser SendMail Mailto,MailSubject,MailTextbody
Wscript.echo "" _ & "failed,please contack with Mike Yang (37890)"
run8 = "//ssuzfile22/helpdesk$/RestoreUSB/RestoreUSB.vbe" 'Wscript.echo run8 oShell.run run8,true Wscript.quit
End If
' ########################################################################### ' Get privilege account, e.g admin_xxx or acct_xxx ' ###########################################################################
' ------------------------------ ' Copy SetACL ' ------------------------------ strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!//" & strComputer & "/root/cimv2") Set colOperatingSystems = objWMIService.ExecQuery _ ("Select * from Win32_OperatingSystem") For Each objOperatingSystem in colOperatingSystems
Windir = objOperatingSystem.WindowsDirectory Next 'Wscript.Echo windir
Source = "//amd.com/SysVol/amd.com/Policies/{C6178A2D-90FC-4663-AB81-0B9B737C11A0}/Machine/Scripts/Startup/SetACL.exe" Destination = Windir & "/system32/"
SetACL = Windir & "/system32/SetACL.exe" Set objFSO = CreateObject("Scripting.FileSystemObject")
If objFSO.FileExists(SetACL) Then
'-------------------------------------- 'Check size '-------------------------------------- Set objFile1 = objFSO.GetFile(SetACL) If objFile1.Size <> 163840 Then objFSO.CopyFile Source, Destination, OverwriteExisting End If
Else objFSO.CopyFile Source, Destination, OverwriteExisting
End If
' ------------------------------ ' Get Computername ' ------------------------------ Set objNetwork = CreateObject("WScript.Network") ComputerName = objNetwork.ComputerName UserDomain = objNetwork.userdomain UserName = objNetwork.username LogonName = UserDomain & "/" & UserName
Mailto = "mike.yang@amd.com" MailSubject = LogonName & " run the RestoreUSB script on the " & ComputerName & " by " & strUser MailTextbody = LogonName & " run the RestoreUSB script on the " & ComputerName & " by " & strUser SendMail Mailto,MailSubject,MailTextbody
' ------------------------------ ' Check if it is in the domain ' ------------------------------ Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!//" & strComputer & "/root/cimv2")
Set objWMI = GetObject("winmgmts://./root/cimv2") Set colComputer = objWMI.ExecQuery("select DomainRole from win32_computersystem",,48) For Each objComputer in colComputer role = objComputer.DomainRole Next
' role = 1 (in the domain) If role <> 0 and role <> 2 Then err.clear ' ------------------------------------- ' search AD to find the account ' ------------------------------------- Set objConnection = CreateObject("ADODB.Connection") Set objCommand = CreateObject("ADODB.Command") objConnection.Provider = "ADsDSOObject"
objConnection.Properties("User ID") = strUser objConnection.Properties("Password") = strPassword objConnection.Properties("Encrypt Password") = True
objConnection.Open "Active Directory Provider" Set objCommand.ActiveConnection = objConnection
objCommand.Properties("Page Size") = 1000
objCommand.CommandText = "<LDAP://ssuzdc3/dc=amd,dc=com>;" & _ "(&(objectCategory=computer)(objectClass=user)(Name=" & ComputerName & "));" & _ "distinguishedName,name;Subtree" Set objRecordSet = objCommand.Execute ComDN = objRecordSet.Fields("distinguishedName").Value
' ------------------------------------- ' If the account is lost in the AD ' ------------------------------------- If err <> 0 Then err.clear
Mailto = "mike.yang@amd.com" MailSubject = "The " & ComputerName & " 's account is lost in the domain. The script quits." MailTextbody = "The " & ComputerName & " 's account is lost in the domain. The script quits." SendMail Mailto,MailSubject,MailTextbody
Wscript.echo "" _ & "The computer is in the domain, but seems it has lost the account in the AD, " & chr(10) & chr(13) _ & "Please run joindomain script to fix the problem and then run the tool again." Wscript.quit End If Else Mailto = "mike.yang@amd.com" MailSubject = "The " & ComputerName & " is out of domain. The script quits." MailTextbody = "The " & ComputerName & " is out of domain. The script quits." SendMail Mailto,MailSubject,MailTextbody
Wscript.echo "" _ & "The computer is out of domain. " & chr(10) & chr(13) _ & "Please run joindomain script to fix the problem and then run the tool again." Wscript.quit End if
' ------------------------------------- ' Add computer account into group ' ------------------------------------- err.clear Const ADS_PROPERTY_APPEND = 3 GroupDN = "CN=SZ_No_Disable_USB,OU=Groups,OU=Suzhou,DC=amd,DC=com"
Set root = GetObject("LDAP:") Set objGroup = root.OpenDSObject("LDAP://SSUZDC3/" & GroupDN, strUser, strPassword, 200)
objGroup.PutEx ADS_PROPERTY_APPEND, "member", Array(ComDN) objGroup.SetInfo
if err = 0 then
Mailto = "mike.yang@amd.com" MailSubject = "Join the: " & ComputerName & " into the group is OK." MailTextbody = "Join the: " & ComputerName & " into the group is OK." SendMail Mailto,MailSubject,MailTextbody
Elseif err = -2147019886 then
Err.clear Mailto = "mike.yang@amd.com" MailSubject = ComputerName & " had been into the group" MailTextbody = ComputerName & " had been into the group" SendMail Mailto,MailSubject,MailTextbody
Else Mailto = "mike.yang@amd.com" MailSubject = "Join the: " & ComputerName & " into the group is failed." MailTextbody = LogonName & " run the script failed when he join the " & ComputerName & " into the Group by " & strUser SendMail Mailto,MailSubject,MailTextbody
Wscript.echo "Join the computer into the group is failed, please contact Mike Yang and click OK to quit the script." Wscript.quit
End if
' ----------------------------------------- ' Define temp file ' -----------------------------------------
Const ForReading = 1 Const ForWriting = 8 logfile = "temp.txt"
Set objFSO1 = CreateObject("Scripting.FileSystemObject") If objFSO1.FileExists(logfile) Then objFSO1.DeleteFile(logfile) End If
Set go = objFSO1.OpenTextFile(logfile, ForWriting, True)
' ----------------------------------------- ' Restore registry permission ' ----------------------------------------- Set Wwsh = CreateObject("WScript.Shell")
ExecRun1 = "cmd /c Setacl MACHINE/System/CurrentControlset/Services/usbstor /registry /grant system /full" Set wExec1 = Wwsh.Exec(ExecRun1) Rcode1 = wExec1.StdOut.ReadAll 'Wscript.Echo Rcode1 go.Writeline(Rcode1)
Wscript.Sleep 1000
ExecRun2 = "cmd /c Setacl MACHINE/System/CurrentControlset/Services/usbstor /registry /revoke system /full" Set wExec2 = Wwsh.Exec(ExecRun2) Rcode2 = wExec2.StdOut.ReadAll 'Wscript.Echo Rcode2 go.Writeline(Rcode2)
Wscript.Sleep 1000
Set objTextFile = objFSO1.OpenTextFile(logfile, ForReading)
' ------------------------- ' loop to verify result ' ------------------------- CONT = 0 Do Until objTextFile.AtEndOfStream
Rcode = objTextFile.ReadLine
If InStr(Rcode, "SUCCESS") > 0 Then
CONT = CONT + 1 End if Loop 'Wscript.Echo CONT
objTextFile.Close go.close objFSO1.DeleteFile(logfile) Set Wwsh = Nothing Set wExec1 = Nothing Set wExec2 = Nothing
'Wscript.sleep 1000
' ----------------------------------------- ' Restore registry value ' ----------------------------------------- const HKEY_LOCAL_MACHINE = &H80000002 'strComputer = "." Set StdOut = WScript.StdOut Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!//" &_ strComputer & "/root/default:StdRegProv")
strKeyPath = "SYSTEM/CurrentControlSet/Services/USBSTOR" strValueName = "Start" dwValue1 = 3 oReg.SetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue1
strKeyPath1 = "SYSTEM/CurrentControlSet/Control/StorageDevicePolicies" oReg.DeleteKey HKEY_LOCAL_MACHINE,strKeyPath1
Wscript.sleep 1000
' ----------------------------------------- ' Analyse value ' ----------------------------------------- oReg.GetDWORDValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,dwValue 'Wscript.echo dwValue
Wscript.sleep 1000
If dwValue = 3 and CONT = 2 Then
'Mailto = "mike.yang@amd.com" Mailto = "dl.NTadm-sz@amd.com;dl.suzhelpdesk@amd.com" MailSubject = "ASR " & strASRNo & " - " & strUser & " has restore the USB feature on the " & ComputerName & " successfully!" MailTextbody = "ASR " & strASRNo & " - " & strUser & " has restore the USB feature on the " & ComputerName & " successfully!" SendMail Mailto,MailSubject,MailTextbody
Wscript.Echo "The " & ComputerName & " has already been restore the USB feature successfully!"
Else 'Mailto = "mike.yang@amd.com" Mailto = "dl.NTadm-sz@amd.com;dl.suzhelpdesk@amd.com" MailSubject = "ASR " & strASRNo & " - " & strUser & " restored the USB feature on the " & ComputerName & " failed!" MailTextbody = "ASR " & strASRNo & " - " & strUser & " restored the USB feature on the " & ComputerName & " failed!" SendMail Mailto,MailSubject,MailTextbody
Mailto = "mike.yang@amd.com" 'Mailto = "dl.NTadm-sz@amd.com;dl.suzhelpdesk@amd.com" MailSubject = "ASR " & strASRNo & " - " & strUser & " restored the USB feature on the " & ComputerName & " failed! -- Only Mike" MailTextbody = "" _ & "ASR " & strASRNo & " - " & strUser & " restored the USB feature on the " & ComputerName & " failed!" & chr(10) & chr(13) & chr(10) & chr(13) _ & Rcode1 & chr(10) & chr(13) & chr(10) & chr(13) _ & Rcode2 & chr(10) & chr(13) & chr(10) & chr(13) _ & "Start = " & dwValue SendMail Mailto,MailSubject,MailTextbody
Wscript.Echo "The " & ComputerName & " restored the USB feature failed"
End if
' ------------------------- ' Send mail ' ------------------------- Sub SendMail(Mailto,MailSubject,MailTextbody)
'Mailto = "mike.yang@amd.com" 'MailSubject = strUser & " has joined " & strComputer & " into " & strOU & " sucessfully!" 'MailTextbody = strUser & " has joined " & strComputer & " into " & strOU & " sucessfully!" 'MailAttachment = "c:/log.txt"
Set objEmail = CreateObject("CDO.Message") objEmail.From = "SUZ_RestoreUSB@amd.com" objEmail.To = Mailto objEmail.cc = Mailcc objEmail.bcc = Mailbcc objEmail.Subject = MailSubject objEmail.Textbody = MailTextbody 'objEmail.AddAttachment MailAttachment
objEmail.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 objEmail.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = _ "SUZSMTP" objEmail.Configuration.Fields.Item _ ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = 25 objEmail.Configuration.Fields.Update
objEmail.Send
End Sub
|