Monday, November 28, 2011

Windows Security Descriptor Binary (a Perl parser)

Some days ago I was messing up with RegRipper plugins, and in particular I was using the "shares.pl" plugin on one of my cases. This plugin parses the content of the registry key "SYSTEM\CurrentControlSet\Services\LanManServer" (please ignore case) and returns the values of the subkey "Shares", which are the explicit shares (Microsoft File and Printers Sharing) created by a user.

Under "Shares" there should be a subkey called "Security" and under it as many REG_BINARY values as shares (I found a case with two shares and only a security value related to one share: I did not go in deep with it, another todo added...). I gugled around but I was unable to get useful stuffs (like tools) or documentation about the nature of that binary values. What I found was a post in the great win4n6 mailing list but with few interesting points. From there I posed to myself the following question.

A Windows Security Descriptor?
I tried to figure out a reliable way to check if those bytes were (or not) a Security Descriptor and, what I found really useful, was PowerShell: I must admit my poor practice with it, since it seems quite powerful (another todo...). I used PowerShell to get as quickly as possible an "official api" (aka Microsoft) to get such information. Thanks to Microsoft Technet I was able to write the following few lines of code:

$wmisdh = new-object system.management.ManagementClass Win32_SecurityDescriptorHelper
[Byte[]] $sdbin = get-content -encoding byte -path $args[0]
$sddl = $wmisdh.BinarySDToSDDL( $sdbin )
 
$sddl['SDDL']

My "hello world security descriptor" script takes a binary file as input, which should contain a Security Descriptor, and outputs the relative SDDL (Security Descriptor Definition Language). Using the unsurpassed Mitec Windows Registry Recovery (aka WRR) I dumped the REG_BINARY values from the registry to files.

Extracting the Security Descriptor from registry (credits to WRR)

Then, I used the previous PS script to get the SDDL: yes, it's "definitely" a Security Descriptor!

PS > D:\bin\ps\sdl.ps1 .\ftki.bin
O:S-1-5-21-776561741-789336058-725345543-500G:S-1-5-21-776561741-789336058-725345543-513D:
(A;;0x1200a9;;;WD)

After few minutes I was able to read (with a reference opened in the second monitor) that SDDL but since I'm lazy I searched for a tool to get a more human-readable output. I found this "sddlparse" executable, and that's the output (here using the classic cmd shell...):

>sddlparse.exe O:S-1-5-21-776561741-789336058-725345543-500G:S1-5-21-776561741-789336058-725345543-513D:(A;;0x1200a9;;;WD)
Ace count: 1
**** ACE 1 of 1 ****
ACE Type: ACCESS_ALLOWED_ACE_TYPE
Trustee: Everyone
AccessMask:
  ADS_RIGHT_READ_CONTROL
  ADS_RIGHT_DS_CREATE_CHILD
  ADS_RIGHT_DS_SELF
  ADS_RIGHT_DS_WRITE_PROP
  ADS_RIGHT_DS_LIST_OBJECT
Inheritance flags: 0

So until here I know what it's that REG_BINARY value and how to get a human-readable output from a Security Descriptor in its binary form. Next?


A library-free SD script.
Having become addicted to RegRipper and Perl scripting (note: I'm not a Perl coder, really...) I felt the necessity to create such script, library-free in the sense it does not use any explicit external dependencies. With those requirements the script could be used everywhere without so many problems, for example from inside the "shares.pl" plugin. It's not so difficult to write a rustic script that parses a binary file: the problem is the format. Fortunately Microsoft gives us many details about the binary format and fields significance. So I wrote it, and the following shows the script in action on the same Security Descriptor already analyzed.

>sdbp.pl ftki.bin
sdbp.pl 0.1
A tool to parse binary Windows Security Descriptors
Copyright 2011 F.Picasso

------- SECURITY DESCRIPTOR -------
STRUCTURE -------------------------
Revision         = 1
Padding16        = 0
Control          = 32772
Owner            = 48
Group            = 76
SACL             = 0
DACL             = 20
OWNER SID        = S-1-5-21-776561741-789336058-725345543-500
GROUP SID        = S-1-5-21-776561741-789336058-725345543-513
SACL ------------------------------
no SACL
DACL ------------------------------
Revision         = 2
Padding16        = 0
Size             = 28
AceCount         = 1
Padding32        = 0
ACE number       : 1  -------------
ACCESS ALLOWED   ( no inheritance )
TRUSTEE SID      = S-1-1-0  [ Everyone ]
Standard rights
  SYNCHRONIZE
  READ CONTROL
Specific rights
No OBJECT specified, printing FILE and DIRECTORIES rights
  FILE READ DATA
  FILE READ ATTRIBUTES
  FILE EXECUTE
  FILE READ EA (PROPERTIES)
  DIR FILE LIST
  DIR READ ATTRIBUTES
  DIR TRAVERSE
  DIR READ EA (PROPERTIES)
MASK is 0x001200A9 (specific 0x00A9, standard 0x12, generic 0x0)

Great! Fantastic! I will use it everywhere! Wait...
... a moment: I'm happy if someone could think that, but be calm. A careful reader should point out the differences between sddlparse and my sdbp.pl script. Apart semantic differences, there are some discrepancies: for example the SYNCHRONIZE bit reported by my script it's not reported by the executable. By gugling I guess that Guy Teverovsky (sddlparse tool writer) used the "ADS_RIGHTS_ENUM enumeration" bitmasks to generate output, while I used a mixed of WINNT.H header file and "Parts of the Access Control Model" Microsoft documentation. Being said that, in ADS enum specification there is the key "ADS_RIGHT_SYNCHRONIZE" (which  has the same value of my "SYNCHRONIZE") that is not reported: but the mask value are the same, 0x1200a9. The point is: please help to verify the output of my script (instructions following). I wrote to Guy Teverovsky asking him about my findings, so stay tuned (warning! commercial advertisement!) on this blog.


Hem, I can't find "download" button...
Actually there is not such button. I created a project on the Google Code site with the name hotoloti: http://code.google.com/p/hotoloti/. There you will find a sort of repository of scripts, documents and whatever related to Zena Forensics blog (or even unrelated). I encourage you to open here/there(better) coding issues.
 

Generating binary Security Descriptors.
As I anticipated, here are some steps to create fast&furious binary Security Descriptors (you could automate those steps in a single script). Let's extract the ACL for a folder like "C:\Windows\System32":

PS C:\Windows> $acl = Get-Acl .\System32

Then get the SDDL (here you could use the sddlparse tool):

PS C:\Windows> $acl.sddl
O:S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464
G:S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464
D:PAI(A;OICIIO;GA;;;CO)(A;OICIIO;GA;;;SY)(A;;0x1301bf;;;SY)(A;OICIIO;GA;;;BA)(A;;0x1301bf;;;BA)(A;OICIIO;GXGR;;;BU)(A;;0x1200a9;;;BU)
(A;CIIO;GA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464)
(A;;FA;;;S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464)

Ok, now let's get a binary representation of the SDDL:

PS C:\Windows> $bac = ([wmiclass]"Win32_SecurityDescriptorHelper").SDDLToBinarySD($acl.sddl)

Finally, create a binary file able to get parsed by the Perl script:

PS C:\Windows> set-content -encoding byte -value $bac.BinarySD -path D:\ztmp\sd.bin
Please report your findings to make me improve (myself and) the script.


What about dd images?
Hum, interesting topic. To the best of my knowledge the Sleuthkit does not support ACL details reporting, and (forensics) commercial tools are not so "verbose" and "accurate" (please provide counterchecks). I'll try to deepen this possibility, stay tuned (again!).

No comments:

Post a Comment