Jump to content

This site uses cookies. By continuing to browse the site you are agreeing to our use of cookies. Find out more here. X
X


Photo

Set Acl permissions UDF


  • Please log in to reply
97 replies to this topic

#41 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 13 December 2011 - 11:49 PM

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.







#42 superg

superg

    Seeker

  • Active Members
  • 8 posts

Posted 13 December 2011 - 11:59 PM

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 by superg, 14 December 2011 - 12:10 AM.


#43 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 14 December 2011 - 12:07 AM

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.

#44 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 16 December 2011 - 10:19 PM

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.

#45 superg

superg

    Seeker

  • Active Members
  • 8 posts

Posted 17 December 2011 - 11:12 PM

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! :)

#46 arcker

arcker

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 581 posts

Posted 21 December 2011 - 02:37 PM

Hi FredAl

First : 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 step
what 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 :

  • Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here

#47 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 21 December 2011 - 09:30 PM

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.

#48 arcker

arcker

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 581 posts

Posted 22 December 2011 - 08:49 AM

Hi Fred,

Yeah totally

I'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 :

  • Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here

#49 arcker

arcker

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 581 posts

Posted 22 December 2011 - 11:33 AM

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 :

  • Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here

#50 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 22 December 2011 - 11:35 AM

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.

AutoIt         
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 by FredAI, 22 December 2011 - 11:53 AM.


#51 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 22 December 2011 - 11:40 AM

I guess our posts got crossed :)

#52 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 22 December 2011 - 11:45 AM

Can you post the code you used to get the inherited aces?

#53 arcker

arcker

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 581 posts

Posted 22 December 2011 - 01:16 PM

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 :

  • Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here

#54 arcker

arcker

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 581 posts

Posted 22 December 2011 - 01:30 PM

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 :

  • Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here

#55 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 22 December 2011 - 02:49 PM

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_ALL


The 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 by FredAI, 22 December 2011 - 02:50 PM.


#56 arcker

arcker

    Universalist

  • Active Members
  • PipPipPipPipPipPip
  • 581 posts

Posted 22 December 2011 - 04:03 PM

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 plusvalue
I post an extract ( replace mergedacl inside code ) but not $aPerm generated for now. Easy to add but, no time.

AutoIt         
$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 by arcker, 22 December 2011 - 04:06 PM.

-- Arck System _ Soon -- Ideas make everything

"La critique est facile, l'art est difficile"

 

Projects :

  • Au3Service : Run your exe as service V3 / Updated 29/07/2013 Get it Here

#57 Mathias

Mathias

    Seeker

  • Normal Members
  • 2 posts

Posted 06 January 2012 - 03:20 AM

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!

#58 FredAI

FredAI

    Wayfarer

  • Active Members
  • Pip
  • 81 posts

Posted 07 January 2012 - 02:59 PM

@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.

#59 intime69

intime69

    Seeker

  • Active Members
  • 35 posts

Posted 12 January 2012 - 05:09 PM

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 by intime69, 17 January 2012 - 07:29 PM.

Developer and Co-OwnerInTime Applicaitons Inc.

#60 ter-pierre

ter-pierre

    Wayfarer

  • Active Members
  • Pip
  • 85 posts

Posted 13 January 2012 - 04:35 PM

Hey FredAl
Very nice job!!!




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users