tlman12 Posted September 5, 2013 Posted September 5, 2013 I'm trying to script out the unlocking of a bitlocker drive using a DRA certificate. I'm attempting to use the WMI Method UnlockWithCertificateFile and I can't for the life of me figure out what i'm doing wrong or even find an example. I know the certificate and pin work because i can manually unlock the drive using manage-bde -unlock.... when i run my script i get a return value of -2146885623 wich i've looked up to be -2146885623, "Cannot find the requested object." i'm not sure what object its talking about. here is the code started with (minus the pin), its vbscript but i'm getting the same error whether it's vbscript or autoit so i think theres something wrong with my base vbscript code. i cant find any examples online for this method. i generated this script from "WMI Code Creator strComputer = "." Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\CIMV2\Security\MicrosoftVolumeEncryption") ' Obtain an instance of the the class ' using a key property value. Set objShare = objWMIService.Get("Win32_EncryptableVolume.DeviceID='\\?\Volume{a2965903-4af0-11e2-be65-806e6f6e6963}\'") ' Obtain an InParameters object specific ' to the method. Set objInParam = objShare.Methods_("UnlockWithCertificateFile"). _ inParameters.SpawnInstance_() ' Add the input parameters. objInParam.Properties_.Item("PathWithFileName") = "D:\BitLocker.pfx" objInParam.Properties_.Item("Pin") = "PinCode ' Execute the method and obtain the return status. ' The OutParameters object in objOutParams ' is created by the provider. Set objOutParams = objWMIService.ExecMethod("Win32_EncryptableVolume.DeviceID='\\?\Volume{a2965903-4af0-11e2-be65-806e6f6e6963}\'", "UnlockWithCertificateFile", objInParam) ' List OutParams Wscript.Echo "Out Parameters: " Wscript.echo "ReturnValue: " & objOutParams.ReturnValue has anyone ever used this method or can anyone see something i may be doing wrong? also i'm using the windows 8 commandline recovery option, i'm not sure if that makes a difference because i have tested calling other methods and wmi and scripting seem to be fully implemented. i did get it to work in vb.net but vb.net has not beenĀ implementedĀ in the recover
ripdad Posted September 6, 2013 Posted September 6, 2013 Here's a few things that might help you (Not Tested). expandcollapse popup;Ref@MSDN: ;http://msdn.microsoft.com/en-us/library/windows/desktop/aa376483(v=vs.85).aspx Local $oErrorHandler = ObjEvent('AutoIt.Error', '_ObjErrorHandler') Func _Example($sPath, $sPinCode, $strComputer = '.') Local $objWMI, $objShare, $objInParam, $objOutParams $objWMI = ObjGet('winmgmts:{ImpersonationLevel=Impersonate,AuthenticationLevel=PktPrivacy,(Debug,Security)}!\\' & _ $strComputer & '\root\CIMV2\Security\MicrosoftVolumeEncryption') ; Obtain an instance of the the class ; using a key property value. $objShare = $objWMI.Get('Win32_EncryptableVolume.DeviceID="\\?\Volume{a2965903-4af0-11e2-be65-806e6f6e6963}\"') ; Obtain an InParameters object specific ; to the method. $objInParam = $objShare.Methods_('UnlockWithCertificateFile') $objInParam.SpawnInstance_() ; Add the input parameters. $objInParam.Properties_.Item('PathWithFileName') = $sPath; 'D:\BitLocker.pfx' OR D:\\BitLocker.pfx $objInParam.Properties_.Item('Pin') = $sPinCode; 'PinCode' ; Execute the method and obtain the return status. ; The OutParameters object in objOutParams ; is created by the provider. $objOutParams = objWMI.ExecMethod( _ 'Win32_EncryptableVolume.DeviceID="\\?\Volume{a2965903-4af0-11e2-be65-806e6f6e6963}\"', _ 'UnlockWithCertificateFile', $objInParam) ; List OutParams ConsoleWrite('Out Parameters ReturnValue: ' & $objOutParams.ReturnValue) EndFunc Func _ObjErrorHandler() Local $AOE1 = $oErrorHandler.ScriptLine Local $AOE2 = Hex($oErrorHandler.Number, 8) Local $AOE3 = $oErrorHandler.Description Local $AOE4 = $oErrorHandler.WinDescription $oErrorHandler.Clear Local $eMsg = '' If $AOE1 Then $eMsg &= 'Line:' & $AOE1 & ' ' If $AOE2 Then $eMsg &= '(0x' & $AOE2 & ') ' If $AOE3 Then $eMsg &= $AOE3 & ' ' If $AOE4 Then $eMsg &= $AOE4 MsgBox(8240, 'Object Error', $eMsg) Exit EndFunc "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward
tlman12 Posted September 6, 2013 Author Posted September 6, 2013 (edited) Ā Here's a few things that might help you (Not Tested). Ā Thank you that was exactly the feed back from my script that i needed. I got it to work and cleaned it up a little bit, here is the finished product if anyone is interested.Ā the reason i wrote this is because i wanted to be able to distribute my BitLocker DRA cert without distributing a static password. this script works by generating a hashing a set of data retrieved from the computer (common knowledge) that can be generated with minimal knowledge of the PC by a tech with the proper generator. I removed that feature from the script because i can't release exactly how i was doing it. it was based on a hash with a date salt that way it would change constantly.Ā this is tested and working in the Windows 8.1 Command Prompt recovery option. enjoyĀ expandcollapse popup#RequireAdmin #Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_Compile_Both=y #AutoIt3Wrapper_UseX64=y #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;Ref@MSDN: ;http://msdn.microsoft.com/en-us/library/windows/desktop/aa376483(v=vs.85).aspx Local $oErrorHandler = ObjEvent('AutoIt.Error', '_ObjErrorHandler') Const $S_OK = 0 Const $UNKNOWN = 1 Const $ERROR_FILE_NOT_FOUND = 2 Const $BITLOCKER_NOT_ACTIVATED = 80310008 Const $FAILED_AUTHENTICATION = 80310027 Const $BITLOCKE_PROTECTOR_NOT_FOUND = 80310033 Const $CERTIFICATE_PRIVATEKEY_AUTH_FAILED = 80310094 Const $CERTIFICATE_NOT_FOUND = 80070002 Const $CERTIFICATE_PIN_INCORRECT = 80092009 #include <StaticConstants.au3> #include <WindowsConstants.au3> #include <ButtonConstants.au3> #include <ComboConstants.au3> #include <GUIConstantsEx.au3> ;~ Changeable Fields ; Instructions, ; Export the BitLocker Drive Recovery Agent certificate (WITH PRIVATE KEY) ; Place it in the same directory as this script before you compile it. ; Change $sPIN below to reflect the pfx password you exported with. ; $sPassword will set a password to run the script, if left blank unlock will occur automatically without any need for a password. Dim $sPIN = "Secure_Cert_Password" ;Don't forget to change this Dim $sPassword = "Password to run script" Dim $sCertName = "BitLocker.pfx" ;Make sure to name your certificate whatever you put here. FileInstall("BitLocker.pfx",@TempDir & "\BitLocker.pfx",1) ;and change the cert name here Dim $strComputer = "." ;Possiblity to add remote computer later ;~ No need to change below here Dim $sDeviceID $objWMIService = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\CIMV2\Security\MicrosoftVolumeEncryption") $colItems = $objWMIService.ExecQuery("SELECT * FROM Win32_EncryptableVolume") For $objItem in $colItems If $objItem.ProtectionStatus > 0 Then ClipPut($objitem.DeviceID) $sDeviceID = $sDeviceID & "|" & $objItem.DeviceID EndIf Next If $sDeviceID = "" Then MsgBox(64,"Not Encrypted","No BitLocker encrypted drives were found on this computer") Exit Else $sDeviceID = StringTrimLeft($sDeviceID,1) #Region ### START Koda GUI section ### Form= $Form1 = GUICreate("Form1", 325, 105, -1, -1) $Label1 = GUICtrlCreateLabel("Pick the drive you would like to unlock", 64, 8, 192, 17) $Combo1 = GUICtrlCreateCombo($sDeviceID, 8, 32, 305, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL)) $Button1 = GUICtrlCreateButton("Ok", 123, 64, 75, 25) GUISetState(@SW_SHOW) #EndRegion ### END Koda GUI section ### While 1 $nMsg = GUIGetMsg() Switch $nMsg Case $GUI_EVENT_CLOSE Exit Case $Button1 GUISetState(@SW_HIDE) $sDeviceID = GUICtrlRead($Combo1) If $sPassword <> "" Then $string = InputBox("Password required","Please type the correct password to advance","") If $string = $sPassword Then $ret = _UnlockWithCertificateFile(@TempDir & "\" & $sCertName,$sPIN,$sDeviceID) FileDelete(@TempDir & "\" & $sCertName) Switch $ret Case $S_OK MsgBox(64,"Success","Drive should now be unlocked") Case $UNKNOWN MsgBox(16,"Error","An unknown error has occured") Case $ERROR_FILE_NOT_FOUND MsgBox(16,"Error","File Not Found") Case $BITLOCKER_NOT_ACTIVATED MsgBox(16,"Error","BitLocker is not activated on the specified drive") Case $FAILED_AUTHENTICATION MsgBox(16,"Error","Failed Authentication") Case $BITLOCKE_PROTECTOR_NOT_FOUND MsgBox(16,"Error","Specified BitLocker Protector not found") Case $CERTIFICATE_PRIVATEKEY_AUTH_FAILED MsgBox(16,"Error","Certificate Private Key authentication failed") Case $CERTIFICATE_NOT_FOUND MsgBox(16,"Error","Certificate path must be incorrect") Case $CERTIFICATE_PIN_INCORRECT MsgBox(16,"Error","Certificate PIN is incorrect") Case Else MsgBox(16,"Error","An unknown error has occured") EndSwitch Else MsgBox(16,"Error","Password is incorrect") EndIf Exit EndSwitch WEnd EndIf Func _UnlockWithCertificateFile($inPath, $inPinCode, $inDeviceID, $strComputer = '.') Local $objWMI, $objShare, $objInParam, $objOutParams $objWMI = ObjGet('winmgmts:{ImpersonationLevel=Impersonate,AuthenticationLevel=PktPrivacy,(Debug,Security)}!\\' & _ $strComputer & '\root\CIMV2\Security\MicrosoftVolumeEncryption') ; Obtain an instance of the the class ; using a key property value. $objShare = $objWMI.Get("Win32_EncryptableVolume.DeviceID='" & $inDeviceID &"'") ; Obtain an InParameters object specific ; to the method. $objInParam = $objShare.Methods_("UnlockWithCertificateFile").inParameters.SpawnInstance_() ; Add the input parameters. $objInParam.PathWithFileName = $inPath $objInParam.Pin = $inPinCode ; Execute the method and obtain the return status. ; The OutParameters object in objOutParams ; is created by the provider. $objOutParams = $objShare.ExecMethod_('UnlockWithCertificateFile', $objInParam) ; Return OutParams Return Hex($objOutParams.ReturnValue) EndFunc Func _ObjErrorHandler() Local $AOE1 = $oErrorHandler.ScriptLine Local $AOE2 = Hex($oErrorHandler.Number, 8) Local $AOE3 = $oErrorHandler.Description Local $AOE4 = $oErrorHandler.WinDescription $oErrorHandler.Clear Local $eMsg = '' If $AOE1 Then $eMsg &= 'Line:' & $AOE1 & ' ' If $AOE2 Then $eMsg &= '(0x' & $AOE2 & ') ' If $AOE3 Then $eMsg &= $AOE3 & ' ' If $AOE4 Then $eMsg &= $AOE4 MsgBox(8240, 'Object Error', $eMsg) Exit EndFunc Edited September 6, 2013 by tlman12
ripdad Posted September 7, 2013 Posted September 7, 2013 Glad you got it working. "The mediocre teacher tells. The Good teacher explains. The superior teacher demonstrates. The great teacher inspires." -William Arthur Ward
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now