FredAI Posted December 13, 2011 Author Posted December 13, 2011 In fact, with admin rights, UVK or the task manager were able to kill the process, which are not very good news for me. I was planning of using this to prevent UVK from being closed by third party applications. My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
superg Posted December 13, 2011 Posted December 13, 2011 (edited) Hmm, sorry to hear that... it should still be protected from third party applications which aren't running with elevated privileges. That's better than all 3rd party apps. Perhaps creating a "companion process" which enforces file/process DACL's on UVK and will restart UVK if its' terminated unexpectedly? That could also be a step closer... Edited December 14, 2011 by superg
FredAI Posted December 14, 2011 Author Posted December 14, 2011 Yes, but it could also lead to an infinite loop of run/kill process. You see, modern malware writers know which are the most recent and effective malware removal tools, and create code to detect if they are started, and immediately close them. Since UVK is getting known all over the world, soon, it will be on the kill list. I must find a way to prevent it. My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
FredAI Posted December 16, 2011 Author Posted December 16, 2011 Ok I updated again. See the first post. Now it supports all object types. @superg: I added a function to the example that denies everyone access to the current process (@AutoItPid). To do exactly the same thing as your python script use: #include 'Permissions.au3' Local $Hndl = _Permissions_OpenProcess(@AutoItPID) _SetObjectStringSecurityDescriptor($Hndl, 'O:S-1-1-0G:S-1-1-0D:(D;;0xe0801;;;DU)(D;;0xe0801;;;SY)(D;;0xe0801;;;WD)S:P', $SE_KERNEL_OBJECT) MsgBox(0,'', _GetObjectStringSecurityDescriptor($Hndl, $SE_KERNEL_OBJECT)) However, to make this work for me, I had to delete the Domain Users ace (D;;0xe0801;;;DU). I think it's because my pc is not in a domain. Anyway, since this security descriptor already has an access denied ace to everyone (D;;0xe0801;;;WD), the result will be the same as if you just use: #include 'Permissions.au3' Local $Hndl = _Permissions_OpenProcess(@AutoItPID) _DenyAllAccess($Hndl, $SE_KERNEL_OBJECT,'Everyone') MsgBox(0,'', _GetObjectStringSecurityDescriptor($Hndl, $SE_KERNEL_OBJECT)) I hope it's what you needed. My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
superg Posted December 17, 2011 Posted December 17, 2011 Looks great! I appreciate your efforts. I will test more on a domain when I return to work next week; until then enjoy your weekend!
arcker Posted December 21, 2011 Posted December 21, 2011 Hi FredAlFirst : great script ! really, I wanted to do something like this for years but didn't understood whole thing with security descriptor. So that's a great stepwhat you posted here.I've a question actually : the script reads dacl, but not inherited dacl, maybe i'm missing something.I use those two functions to retrieve this, from your udf :Local $Dacl = _GetObjectDacl($oName) if $Dacl <> 0 then _MergeDaclToArray($Dacl, $aPermissions)Is it normal or we have to make more programmation to get inheritance dacl ? I've seen getinheritancesource : http://msdn.microsoft.com/en-us/library/windows/desktop/aa446640(v=VS.85).aspx but I wonder.Thanx you if you can explain this. -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
FredAI Posted December 21, 2011 Author Posted December 21, 2011 Hi Arcker. Glad you like the UDF. The inheritance, we must try to understand how it works. You see, inherited aces are not part of the DACL of a child object. They are part of the Dacl of the parent, grand parent, or whatever is the object that propagates them. An ace created with the $SUB_CONTAINERS_AND_OBJECTS_INHERIT flag is propagated trough the security descriptors of all the sub containers and objects. You can't edit this ace in a child object, because the ace doesn't belong to it, but you can remove it by clearing the Dacl, or editing the security descriptor. When you edit an object's Dacl with _EditObjectPermissions, inherited aces are not deleted, unless you clear the Dacl. To restore the inherited aces use the _TreeResetPermissions function. My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
arcker Posted December 22, 2011 Posted December 22, 2011 Hi Fred,Yeah totallyI've found some articles that demonstrates it. I know the problem is you use the getexplicitaccess, that means, "access on this object only".I'm making some modification, just for tests, and see if it works, to show inherited access.The ACL Editor in windows already manages this, as you said, with "child" objects. So when you make a modification to the parent,all of the acl of the child are changed too, but with "inherited" flag. This is not automatical : the acl editor just change child objects. So everytime we change the DACL on the parent, child object have to be edited too. That's what you do with your _TreeResetPermissions -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
arcker Posted December 22, 2011 Posted December 22, 2011 For now, i've managed to get inherited aces too ! Now i've to get the SIDs properly, then I'll post here. Maybe it could help somebody. Just listing for now, not more. -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
FredAI Posted December 22, 2011 Author Posted December 22, 2011 (edited) OK, I think I may have found your solution. Here's a new function that gets a Dacl containing all aces, including the inherited ones: Func _GetObjectDaclIncludeInherit($oName, $_SE_OBJECT_TYPE = $SE_FILE_OBJECT) Local $sSD = _GetObjectStringSecurityDescriptor($oName,$_SE_OBJECT_TYPE ) $sSD = StringReplace($sSD,'ID;',';') Local $pSD = _ConvertStringSecurityDescriptorToSecurityDescriptor($sSD) Return _GetSecurityDescriptorDacl($pSD) EndFunc ;==> _GetObjectDaclIncludeInherit Now, an important thing: I made the _MergeDaclToArray function filter the trustees, and add only one ace per trustee from the Dacl to the array. I thought this was obvious. Since access denied aces have priority over the access granted ones, then why use the latter if the trustee is the same? To change this feature, you'll have to modify the function, and add a new parameter: $Filter. If $Filter is set to 0, all aces will be added to the array, even if the corresponding trustee is already present in it. Func _MergeDaclToArray(ByRef $Dacl, ByRef $aPerm, $Filter = 1) If Not IsArray($aPerm) Or UBound($aPerm,2) < 3 Then Return SetError(1,0,0) Local $_EXPLICIT_ACCESS, $t_EXPLICIT_ACCESS = 'DWORD;DWORD;DWORD;ptr;DWORD;DWORD;DWORD;ptr' Local $aCall = DllCall($h__Advapi32Dll,'DWORD','GetExplicitEntriesFromAcl','ptr',$Dacl,'ulong*',0,'ptr*',0) If @error Or $aCall[0] Then Return SetError(2,0,0) Local $uB = UBound($aPerm), $l = 0, $TrusteeExists, $E = $aCall[2], $eaSID, $aPermSid, $pEa = $aCall[3] For $i = 2 To $E $t_EXPLICIT_ACCESS &= ';DWORD;DWORD;DWORD;ptr;DWORD;DWORD;DWORD;ptr' Next $_EXPLICIT_ACCESS = DllStructCreate($t_EXPLICIT_ACCESS, $pEa) For $i = 0 To $uB -1 If Not IsDllStruct($aPerm[$i][0]) Then $aPerm[$i][0] = _GetSidStruct($aPerm[$i][0]) Next For $i = 1 To $E $eaSID = DllStructGetData($_EXPLICIT_ACCESS, $l+8) If $eaSID = 0 Then ContinueLoop $TrusteeExists = 0 If $Filter Then For $c = 0 To $uB -1 $aCall = DllCall($h__Advapi32Dll,'BOOL','EqualSid','ptr',$eaSID,'ptr',DllStructGetPtr($aPerm[$c][0])) If Not @error Then $TrusteeExists = $aCall[0] If $TrusteeExists Then ExitLoop Next EndIf If Not $TrusteeExists And _IsValidSid($eaSID) Then ReDim $aPerm[$uB+1][3] $aPerm[$uB][0] = DllStructCreate('byte SID['&_GetLengthSid($eaSID)&']',$eaSID) $aPerm[$uB][1] = Number(DllStructGetData($_EXPLICIT_ACCESS,$l+2) = 1) $aPerm[$uB][2] = DllStructGetData($_EXPLICIT_ACCESS,$l+1) $uB += 1 EndIf $l += 8 Next Return $pEa EndFunc ;==> _MergeDaclToArray I'll update the UDF with these changes soon. Just have to test if everything is working fine. Edit: I just can't find a way to indent the code. Can someone explain how it's done? Edited December 22, 2011 by FredAI My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
FredAI Posted December 22, 2011 Author Posted December 22, 2011 I guess our posts got crossed My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
FredAI Posted December 22, 2011 Author Posted December 22, 2011 Can you post the code you used to get the inherited aces? My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
arcker Posted December 22, 2011 Posted December 22, 2011 Hi fred, Indeed I've not finished. I've used MSDN docs with some new functions : Maybe you use it as I do to get inherited access : GetAclInformation to retrieve the ACEs count then GetAce to get the Ace on each ACL to retrieve SID and AceFlags + AceTypes. Advantage : $aPerm doesn't need redim anymore, since we know the size before => faster Tell me if you use the same, I won't spoil your work with my dirty work I don't see what you used to get inherited. -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
arcker Posted December 22, 2011 Posted December 22, 2011 Good News ! It works ! Just to have to clean the code then i'll post it. Inside there is some code "tips" so I have to add comments since I play with binary a little. -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
FredAI Posted December 22, 2011 Author Posted December 22, 2011 (edited) Well, I don't know if it will be faster, since your method envolves much more dll calls, but I hope so.Here's what my method does:I have a folder in my D: drive I created to test these functions. It has lots of sub folders and small files I use to ensure the permissions are propagated.So, the first line of the function retrieves the security descriptor's string:Local $sSD= _GetObjectStringSecurityDescriptor($oName,$_SE_OBJECT_TYPE)In my test I got:O:S-1-5-21-2153025588-2166620488-548753688-1000D:AI(A;OICIID;0x1301bf;;;AU)(A;OICIID;FA;;;SY)(A;OICIID;FA;;;BA)(A;OICIID;0x1200a9;;;BU)All the aces in this security descriptor are inherited. OICIID means Object inherit ace + Containers inherit ace + Inherited ace.then the line sets all inherited aces as non inherited simply using a stringreplace statement:$sSD = StringReplace($sSD,'ID;',';')So the string became:O:S-1-5-21-2153025588-2166620488-548753688-1000D:AI(A;OICI;0x1301bf;;;AU)(A;OICI;FA;;;SY)(A;OICI;FA;;;BA)(A;OICI;0x1200a9;;;BU)And the 3rd and 4th lines get the Dacl from the new string. Now all the aces can be edited with the UDF functions.The array of permissions was initialized as follows:Local $aPerm[1][3] $aPerm[0][0] = 'Administrators' $aPerm[0][1] = 1 $aPerm[0][2] = $GENERIC_ALLThe I called _MergeDaclToArray($Dacl,$aPerm,0) (the modified function, see my last post).$aPerm had been redimmed to 5, meaning the 4 aces had been added. Edited December 22, 2011 by FredAI My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
arcker Posted December 22, 2011 Posted December 22, 2011 (edited) Hi Fred.So don't bother with my method, since yours only does one dllcall. Mine does, well, one call to get size,then one call on each ACE, then, one memory allocation to get the sid, then one sid reverse.I wonder why I didn't find the _GetObjectStringSecurityDescriptor to get the info needed. For now I've no time to post the code as it, since it need more cleaning.I'll post it tomorrow, but I think the function inside are more superseed functions than real fonctions with plusvalueI post an extract ( replace mergedacl inside code ) but not $aPerm generated for now. Easy to add but, no time.expandcollapse popup$tACLSIZE = DllStructCreate("DWORD AceCount;DWORD AclBytesInUse;DWORD AclBytesFree") Local $tBuffer = DllStructCreate("int[4]") Local $aCall = DllCall($h__Advapi32Dll, 'DWORD', 'GetAclInformation', 'ptr', $Dacl, 'ptr', DllStructGetPtr($tACLSIZE), 'dword', DllStructGetSize($tACLSIZE), "dword", 2) If $aCall[0] = 0 Then ConsoleWrite("+" & _WinAPI_GetLastError() & @CRLF) Else ConsoleWrite("Size = " & DllStructGetData($tACLSIZE, 1) & @CRLF) EndIf For $ACE = 0 To DllStructGetData($tACLSIZE, 1) - 1 $pace = DllStructCreate("ptr") Local $aCall = DllCall($h__Advapi32Dll, 'int', 'GetAce', 'ptr', $Dacl, 'int', $ACE, 'ptr', DllStructGetPtr($pace)) If $aCall[0] = 0 Then ConsoleWrite("+" & _WinAPI_GetLastErrorMessage() & @CRLF) Else ;$tACE = DllStructCreate("byte AceType;byte AceFlags;word AceSize",DllStructGetData($pace,1)) $tACE = DllStructCreate("byte AceType;byte AceFlags;word AceSize;dword ACCESS_MASK;dword SidStart",DllStructGetData($pace,1)) switch DllStructGetData($tACE,2) case 0 ConsoleWrite ("explicit access" ) case 19 ; $OBJECT_INHERIT_ACE + $CONTAINER_INHERIT_ACE + $INHERITED_ACE ;~ ConsoleWrite ("Inherited and propagate " ) ConsoleWrite ("OBJECT_INHERIT_ACE + CONTAINER_INHERIT_ACE + INHERITED_ACE" & @crlf) case 18 ConsoleWrite("INHERITED_ACE + CONTAINER_INHERIT_ACE" & @crlf) case $OBJECT_INHERIT_ACE ConsoleWrite ("Inherit from " ) case $CONTAINER_INHERIT_ACE ConsoleWrite ("Container Inherit " ) case $NO_PROPAGATE_INHERIT_ACE ConsoleWrite ("This object only " ) case $INHERIT_ONLY_ACE ConsoleWrite ("inherit only " ) case $INHERITED_ACE ConsoleWrite ("inherited " ) case Else ConsoleWrite ("Unknow ace flag " & DllStructGetData($tACE,2)) EndSwitch ; Here we have to get the AceSize to retrieve SID $sSIDLength = DllStructGetData($tACE,3) ; Here we have to get the SIDs - SIDStart ; So I've concatenate it to only one byte value of Lenght - dword (sidstart) - dword ACCESS_MASK ? ; 2 x dword = 8 bytes. $tACE = DllStructCreate("byte AceType;byte AceFlags;word AceSize;dword ACCESS_MASK;byte["& _ $sSIDLength -8 & "]",DllStructGetData($pace,1)) ;~ ConsoleWrite("+" & DllStructGetData($tACE, 1) & "|" & DllStructGetData($tACE, 2) & "|" & _ ;~ DllStructGetData($tACE, 3) & "|" & DllStructGetData($tACE, 4) & "|" & DllStructGetData($tACE, 5) & @CRLF) ;~ _Security__SidToStringSid( ;ConsoleWrite("+" & DllStructGetData($tACE, 1) & "|" & DllStructGetData($tACE, 2) & "|" & _ ;DllStructGetData($tACE, 3) & "|" & @CRLF) ;~ _Security__GetLengthSid( ;~ _Security__IsValidSid( ;ConsoleWrite("!0x010500000000000515000000239D90439519480CBF939CF64F080000"& @CRLF) ;~ ConsoleWrite(">" & DllStructGetData($tACE, 5) & DllStructGetData($tACE, 6) & @CRLF) ;~ ConsoleWrite(">" & _Security__IsValidSid(DllStructGetData($tACE, 5)) & @CRLF) ; Now : reverse SID ! ;~ $tSID = DllStructCreate("byte[" & $sSIDLength & "]",DllStructGetPtr($tACE,5)) ;~ DllStructSetData($tSID,1,DllStructGetData($tACE, 5)) $aLookup = _Security__LookupAccountSid(DllStructGetPtr($tACE,5)) ConsoleWrite("Name : " & $aLookup[0] & @crlf) ConsoleWrite("Domain : " & $aLookup[1] & @crlf) ConsoleWrite("Type : " & $aLookup[2] & @crlf) EndIf Next Edited December 22, 2011 by arcker -- Arck System _ Soon -- Ideas make everything "La critique est facile, l'art est difficile" Projects :[list] [*]Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here [/list]
Mathias Posted January 6, 2012 Posted January 6, 2012 Fred, I would first like to say thank you very much for your posting. It is very helpful. The only problem I have is that I also use some other of the included UDF's on occasion, and many of the constants you define are already used in various UDF's under the AutoIt Include folder. A great way to reproduce this issue is to add #include <Security.au3> to the beginning of a script that also uses the Perissions.au3 include. I found this out needing to use the _LookupAccountSid function in Security.au3. When trying to run it bombs out due to many conflicting constants in all of the includes. I can think of a couple ways to potentially allow this to co-exist. One would be for the Permissions.au3 to include the other UDF's rather than redefining existing constants. This may be difficult though should you need a constant not yet in the standard UDFs, if newer AutoIt versions then incorporated. The other way, that may have less potential for future conflict (at least with the packaged UDFs), would be to prefix all of the items in Permissions.au3 with your own unique prefix. I know the values may not exactly match the MSDN definitions this way, although functionally it may not matter. Thanks again and keep up the great work!
FredAI Posted January 7, 2012 Author Posted January 7, 2012 @Mathias Yes I noticed that a few days ago, too. I'll rename the constants that conflict for the next update. The thing is, I stopped including UDF's a few months ago, when I realized that most of them highly increase the memory usage of the script. That's the reason why I hadn't noticed it before. My UDFs: SetAcl permissions | System restore Examples: File version info editor | GetIp() improved Programs: UVK - Ultra virus killer | ExeFixer | Recent file seeker | SHIcon | Quick_Any2Ico
intime69 Posted January 12, 2012 Posted January 12, 2012 (edited) This seems like a highly complexe UDF. Very impressive!You mentioned in your first post to ask if someone needed a registry example. Well, I do. Here are the registry keys that need to be modified in order to hide the 'Network' item in the Windows 7 Explorer Navigation pane:RegWrite('HKCRCLSID{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}ShellFolder',"Attributes","REG_DWORD",0xb0040064); Hide Network in Explorer Navigation Pane (Windows 32/64bit) RegWrite('HKLMSoftwareWow6432NodeClassesCLSID{F02C1A0D-BE21-4350-88B0-7367FC96EF3C}ShellFolder',"Attributes","REG_DWORD",0xb0040064); Hide Network in 'Save As' and 'Open' dialogs (Windows 64 bit only)Both of these lines require 'Full Control' Permissions. How can I use your UDF to gain permission. Can you please post an example using the above code.More info regarding hidding the 'Network' item can be found here:http://www.askvg.com/how-to-remove-network-from-windows-7-explorers-navigation-pane/Any help would be greatly appreciated!Ian Edited January 17, 2012 by intime69 Developer and Co-OwnerInTime Applicaitons Inc.
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