sulfurious Posted December 22, 2008 Share Posted December 22, 2008 Hi.I am working on a little thing, and ran into a large problem. When implementing ipSec on XP Pro SP2 or SP3, the mmc snap-in is not that great to work with. One can use the command line tool ipseccmd.exe to make static or dynamic rules. In interest of making my own interface to ipSec, I am reading the registry to see what rules are in place. Unfortunately, ipseccmd implemented filters/rules carry a description of text2pol{ GUID }, nothing that I can find changes that. So let's start with a reg edit to get rid of any default values. The default values can be replaced easily from the snap-inWindows Registry Editor Version 5.00 [-HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\IPSec\Policy\Local] [HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\IPSec\Policy\Local]Now we use ipseccmd.exe to simply make a couple static rules:: Make a simple policy to block everything ipseccmd -w REG -p "Block All" -r "Block All" -f *:*:*+*:*:* -n BLOCK :: Make a simple policy to allow ONLY LAN activity ipseccmd -w REG -p "LAN Only" -r "Block All" -f *:*:*+*:*:* -n BLOCK ipseccmd -w REG -p "LAN Only" -r "Allow LAN" -f 0:*:*+192.168.1.*:*:* -n PASSand the link to the resource kit that contains ipseccmdresource kitOf course the ipsec service must be running.Now, if you assign one of the two simple rules, you can type in command prompt ipseccmd.exe show filters. The results will show the text2pol{ GUID } and the parameters for the rules, such as address:port:protocol etc. This is the only place short of the snap-in that you can view this data to my knowledge. Well, almost. Seems the snap-in gets it from some ipsecpol database file. I don't know how to get that, whether through wmi or else. But I can get the binary registry key for the ipsecFilter{} value in question, which does contain the text2pol{ GUID } value. So in a sort, I can look at the output from ipseccmd show filters results, and then reference the registry to find which 'rule' this text2pol{} applies to. However, on closer examination at MSDN, the ipsecData reg value contains all the data I need. However, it is a complicated value. Stated as being implicitly Little Endian. The document shows every segment and byte value etc. I have enough knowledge to understand the BOM on a document, and that Little Endian is transposed. So what I don't completely understand in how to strip apart this REG_BINARY value. You can use _HexToString on it, and you get the text2pol{value}, but not the underlying data such as address:port:protocol which lies within it. Also I don't get how to read exactly a byte string like this as far as transposing Endian. If a segment exists as this B1 B2 B3 B4, depending on the byte length you would read it as B2 B1 B4 B3 or B4 B3 B2 B1. Here is sample code that retrieves the byte array from wmi StdRegProv. A vbs example shows to take the resulting array and concatenate the dec values together. The function "GetBinaryValue" returns an array converted to dec evidentily. I handled the concatenation to make the single value 0 or double 32 become 000 or 032 to keep the order correct. I also returned the hex value that RegRead() returns.expandcollapse popup#include <array.au3> #include <file.au3> Const $HKEY_CLASSES_ROOT = 0x80000000 Const $HKEY_CURRENT_USER = 0x80000001 Const $HKEY_LOCAL_MACHINE = 0x80000002 Const $HKEY_USERS = 0x80000003 Const $HKEY_PERFORMANCE_DATA = 0x80000004 Const $HKEY_CURRENT_CONFIG = 0x80000005 Const $HKEY_DYN_DATA = 0x80000006 Global $FileOut = FileOpen(@DesktopDir & '\byteArray.txt',1) Global $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & @ComputerName & "\root\default:StdRegProv") Global $regParent = 'SOFTWARE\Policies\Microsoft\Windows\IPSec\Policy\Local' _getIpsecData() FileClose($FileOut) Func _getIpsecData() ; get the ipsecFilter subkeys into array Local $a_subkeys = _RegEnumKeys('.','HKLM',$regParent), $x, $y, $a_keys If Not @error Then _ArrayDisplay($a_subkeys,'The list of parent keys') For $x = 0 To UBound($a_subkeys) - 1 ;~ ipsecData : REG_BINARY strictly Little Endian ;~ http://msdn.microsoft.com/en-us/library/cc232443(PROT.10).aspx If StringInStr($a_subkeys[$x],'ipsecFilter{') Then; get only ipsecFilter key values FileWriteLine($FileOut,$a_subkeys[$x]); write the ipsecFilter{ GUID } $iData = _RegReadBinary($a_subkeys[$x],'ipsecData'); read the REG_BINARY key into array FileWriteLine($FileOut,RegRead('HKLM\' & $regParent & '\' & $a_subkeys[$x],'ipsecData')); write the hex value of the key FileWriteLine($FileOut,'') EndIf _ArrayDisplay($iData,'reg binary values') Next EndIf EndFunc #Region ;=============================================================================== ; ; Description: _RegEnumValues ; Parameter(s): computer name - string of remote computer or "." for current computer ; registry tree - contains the sSubKeyName path ; sub key name - A path that contains the named values to be enumerated ; Requirement: None ; Return Value(s): Returns a multi-dimensional array ([0] = key name, [1] = key value, [2] = key type) ; If an error occurs @error is set and 0 is returned ; User CallTip: _RegEnumValues(computer name, registry tree, sub key name) Enumerates the values of the given subkey ; Author(s): Gary Frost (custompcs at charter dot net) ; Note(s): A registry tree can be one of: ; "HKEY_LOCAL_MACHINE" ("HKLM") ; "HKEY_USERS" ("HKU") ; "HKEY_CURRENT_USER" ("HKCU") ; "HKEY_CLASSES_ROOT" ("HKCR") ; "HKEY_CURRENT_CONFIG" ("HKCC") ; ;=============================================================================== Func _RegEnumValues($strComputer, $s_hDefKey, $strKeyPath) Local $hDefKey, $x ;~ Enum $HKEY_CLASSES_ROOT = 0x80000000, $HKEY_CURRENT_USER, $HKEY_LOCAL_MACHINE, $HKEY_USERS, $HKEY_CURRENT_CONFIG = 0x80000005 If $strComputer = "." Then $strComputer = @ComputerName Switch StringUpper($s_hDefKey) Case "HKEY_LOCAL_MACHINE", "HKLM" $hDefKey = $HKEY_LOCAL_MACHINE Case "HKEY_USERS", "HKU" $hDefKey = $HKEY_USERS Case "HKEY_CURRENT_USER", "HKCU" $hDefKey = $HKEY_CURRENT_USER Case "HKEY_CLASSES_ROOT", "HKCR" $hDefKey = $HKEY_CLASSES_ROOT Case "HKEY_CURRENT_CONFIG", "HKCC" $hDefKey = $HKEY_CURRENT_CONFIG Case Else Return SetError(1, 1, 0) EndSwitch Local $a_Type[8] = [7, "REG_SZ", "REG_EXPAND_SZ", "REG_BINARY", "REG_DWORD", "", "", "REG_MULTI_SZ"] Local $arrValueNames, $arrValueTypes ;~ Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\default:StdRegProv") $oReg.EnumValues ($hDefKey, $strKeyPath, $arrValueNames, $arrValueTypes) If Not IsArray($arrValueNames) Then Return SetError(2, 2, 0) Local $a_ret[UBound($arrValueNames) ][3] For $x = 0 To UBound($arrValueNames) - 1 $a_ret[$x][0] = $arrValueNames[$x] $a_ret[$x][1] = RegRead($s_hDefKey & "\" & $strKeyPath, $arrValueNames[$x]) $a_ret[$x][2] = $a_Type[$arrValueTypes[$x]] Next Return $a_ret EndFunc ;==>_RegEnumValues ; Fixed registry keys ;=============================================================================== ; ; Description: _RegEnumKeys ; Parameter(s): computer name - string of remote computer or "." for current computer ; registry tree - contains the sSubKeyName path ; sub key name - A path that contains the named values to be enumerated ; Requirement: None ; Return Value(s): Returns An array of subkey strings ; If an error occurs @error is set and 0 is returned ; User CallTip: _RegEnumKeys(computer name, registry tree, sub key name) Enumerates the subkeys for a path ; Author(s): Gary Frost (custompcs at charter dot net) ; Note(s): A registry tree can be one of: ; "HKEY_LOCAL_MACHINE" ("HKLM") ; "HKEY_USERS" ("HKU") ; "HKEY_CURRENT_USER" ("HKCU") ; "HKEY_CLASSES_ROOT" ("HKCR") ; "HKEY_CURRENT_CONFIG" ("HKCC") ; ;=============================================================================== Func _RegEnumKeys($strComputer, $s_hDefKey, $strKeyPath) Local $hDefKey, $x ;~ Enum $HKEY_CLASSES_ROOT = 0x80000000, $HKEY_CURRENT_USER, $HKEY_LOCAL_MACHINE, $HKEY_USERS, $HKEY_CURRENT_CONFIG = 0x80000005 If $strComputer = "." Then $strComputer = @ComputerName Switch StringUpper($s_hDefKey) Case "HKEY_LOCAL_MACHINE", "HKLM" $hDefKey = $HKEY_LOCAL_MACHINE Case "HKEY_USERS", "HKU" $hDefKey = $HKEY_USERS Case "HKEY_CURRENT_USER", "HKCU" $hDefKey = $HKEY_CURRENT_USER Case "HKEY_CLASSES_ROOT", "HKCR" $hDefKey = $HKEY_CLASSES_ROOT Case "HKEY_CURRENT_CONFIG", "HKCC" $hDefKey = $HKEY_CURRENT_CONFIG Case Else Return SetError(1, 1, 0) EndSwitch Local $arrValueNames ;~ Local $oReg = ObjGet("winmgmts:{impersonationLevel=impersonate}!\\" & $strComputer & "\root\default:StdRegProv") $oReg.EnumKey ($hDefKey, $strKeyPath, $arrValueNames) If Not IsArray($arrValueNames) Then Return SetError(2, 2, 0) Return $arrValueNames EndFunc ;==>_RegEnumKeys Func _RegReadBinary($vKeyPath,$vKeyName) ;~ If $strComputer = "." Then $strComputer = @ComputerName ;~ Switch StringUpper($s_hDefKey) ;~ Case "HKEY_LOCAL_MACHINE", "HKLM" ;~ $hDefKey = $HKEY_LOCAL_MACHINE ;~ Case "HKEY_USERS", "HKU" ;~ $hDefKey = $HKEY_USERS ;~ Case "HKEY_CURRENT_USER", "HKCU" ;~ $hDefKey = $HKEY_CURRENT_USER ;~ Case "HKEY_CLASSES_ROOT", "HKCR" ;~ $hDefKey = $HKEY_CLASSES_ROOT ;~ Case "HKEY_CURRENT_CONFIG", "HKCC" ;~ $hDefKey = $HKEY_CURRENT_CONFIG ;~ Case Else ;~ Return SetError(1, 1, 0) ;~ EndSwitch Local $sValue, $sResult, $max Local $max, $red = '',$cnt = 0,$crr $max = $oReg.GetBinaryValue ($HKEY_LOCAL_MACHINE,$regParent & '\' & $vKeyPath,$vKeyName,$sValue) ;~ http://msdn.microsoft.com/en-us/library/aa390440(VS.85).aspx ;~ MsgBox(0,'max',$max); return value 0 is OK. _ArrayDisplay($sValue,'byte array for binary reg key') For $i = 0 To UBound($sValue) - 1 If StringLen($sValue[$i]) = 1 Then; pad values to be 3 chars total length each $sValue[$i] = '00' & $sValue[$i] ElseIf StringLen($sValue[$i]) = 2 Then $sValue[$i] = '0' & $sValue[$i] EndIf FileWriteLine($FileOut,$i & ' ___ ' & $sValue[$i]); write out the array $sResult&= $sValue[$i] Next FileWriteLine($FileOut,$sResult); write out the concatenated array EndFunc; ->> end RegReadBinary Func _DebugPrint($s_text) $s_text = StringReplace($s_text, @LF, @LF & "-->") ConsoleWrite("!===========================================================" & @LF & _ "!===========================================================" & @LF & _ "-->" & $s_text & @LF & _ "!===========================================================" & @LF) EndFunc ;==>_DebugPrint #EndRegionNotice in the script there are links to the MSDN pages regarding the REG_BINARY key to ipsecData{} and for the GetBinaryValue of the StdRegProv class.Is there anyone here who can help me understand that tech sheet for the ipsecData value? It is a bit cryptic. I understand I will be converting different segments of the binary key value, and I think that depending on the byte lenght will be doing some funky stuff shifting because of it being Little Endian. But I don't completely understand how to do it all.To make matters even worse, if you use ipseccmd to make static rules, as I have above, most references state that you add a common rule, such as 'Block All' to EACH static rule. So that if you looked at the policies in the snap-in, you would see a block all for each policy. This seems to be clutter to me, so I have made one rule 'name' and then any policy also includes that rule name for creation, leaving a much cleaner 'look' to the snap-in when you look at it. However, this appears to create some kind of anomaly wtihin the ipsecData keys. The simple policies like I have above don't show it, but say you had 4 policies being created with ipseccmd. Allow All, Block All, Lan Only and Firewall. Each of these had a rule called 'Block All' (and each needs this rule to perform properly), you would see some ipsecData values contain more than one text2pola{GUID} value. The goal here is to create an interface using AutoIt to the ipsec policies. Quicker and less cluttered than the snap-in. It is possible already to assign/unassign each policy with ipseccmd. It is also easy to set a flag value in another regkey to 'check/ucheck' each rule on a polciy, so you can basically enable or disable the 'rules' with each policy. However, without the interface to the addres:port:protocol, I am afraid it will be pretty crippled. I already piped the output of 'show filters' and parsed it, but still, converting the binary value will show it to contain more info that the parsed output.Does anyone care to help here?Thanks.Sul. Link to comment Share on other sites More sharing options...
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