How Do You Get A Service SID From A Service Name

Recently I have been trying to better understand Windows Service Security.

Starting with Windows Vista, Windows Services were able to have a SID Associated with the service so you could have Service Isolation and reduce the required privileges needed and to still have the ability to access the required registry and files it needed to, and also have the ability of restricting other SID’s to it’s resources.

So I was wondering, how do you get a SID for a service you create ?

The only built in tool I could find was the SC.Exe utility console application and use the command “sc.exe showsid ServiceName”

I then got wondering how does that program get the SID for the service ? Has it already been created and its just getting it from some location ?

After some internet searching I ran across a Wikipedia page for  Security Identifier and it said the the SID is created using the service name in uppercase and running it thru the SHA-1 Hash function.

So I created a small application that did that but it was not producing the same output as the SC.Exe utility. So I was still missing something.

I then started cmd.exe with a debugger, then ran the command “sc.exe showsid ServiceName” , that gave me a little bit of information but not enough to solve my problem of outputting the wrong results.

Next I turned to a Utility named EXE Explorer to view what the imports were for the Sc.exe utility and found that it imported a function from ntdll.dll named  RtlCreateServiceSid. That function Is undocumented.

Next I copied the ntdll.dll to another folder and opened it with a program named PEBrowser64 Professional. Then found and  decompiled that function and seen it was in fact using the Sha1 has function.

Next I Looked at the RFC 3174 SHA1 specification to see if they were doing anything different.(They were not,best I could tell)

Going back to PEBrowser64 Professional and after tracing that function thru several other functions you can get the basic steps required to output a Service SID from the input service name.

Basic Steps

1: Input service same.

2: Convert service name to upper case.

3: Get the Unicode bytes()  from the upper case service name.

4: Run bytes() thru the sha1 hash function.

5: Reverse the byte() string  returned from the SHA1 hash function (on Little Endian systems Not tested on Big Endian systems)

6: Split the reversed string into 5 blocks of 4 bytes each.

7: Convert each block of hex bytes() to Decimal

8: Reverse the Position of the blocks

9: Create the first part of the SID “S-1-5-80-“

10: Tack on each block of Decimal strings with a “-“ in between each block that was converted and reversed.

11: Finally out put the complete SID for the service.

This is not the exact order that the API call used but the order I used in my test application.

Here is what the final test application looks like.

CnvtSvcName

This test application currently only takes input from the combo box that is filled with the service names it found.

The next problem was to figure out why I was getting a Different result so I broke down an Existing SID to Hex to be able to compare and to help figure this out.

S-1-5-80-391397178-1713532359-3388783719-1671243502-2983178441

S
0x01
0x00000005
0x50

391397178   = 0x17543F3A ,Reverse Order = 0x3A3F5417
1713532359 = 0x66226DC7 ,Reverse Order = 0xC76D2266
3388783719 = 0xC9FCBC67 ,Reverse Order = 0x67BCFCC9
1671243502 = 0x639D26EE ,Reverse Order = 0xEE269D63
2983178441 = 0xB1CFB0C9 ,Reverse Order = 0xC9B0CFB1

My initial output looked like.

MSMPSVC 
94-85-C3-CD-A1-BC-E8-E0-CF-28-2C-D4-EC-EA-20-D7-6C-12-87-CC
9485C3CDA1BCE8E0CF282CD4ECEA20D76C1287CC

Decimal:
148,133,195,205,161,188,232,224,207,40,44,212,236,234,32,215,108,18,135,204,

Wrong results, But it agreed with all SHA1 Utility’s I tried.

After some more internet searching I ran across a question on Stack Overflow named Unicode, UTF, ASCII, ANSI format differences down at the bottom there was a link to another article named Joel on Software: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

After reading that I then searched on Code project for “RFC 3174” and ended up with this article http://www.codeproject.com/Articles/2463/CSHA1-A-C-Class-Implementation-of-the-SHA-1-Hash-A

I Read the article, downloaded the sample project and built it, and then ran it inputting the uppercase service name and it returned,

Enter the string to hash:
MSMPSVC

Hash of the ANSI representation of the string:
9485C3CDA1BCE8E0CF282CD4ECEA20D76C1287CC

Hash of the Unicode representation of the string:
3A3F5417C76D226667BCFCC9EE269D63C9B0CFB1

Now looking at that confirmed the the RtlCreateServiceSid function was not doing anything strange with the SHA1 function.

The top one matched what I was outputting in the original version but the bottom was lining up with the SID I had broken down.

So what was the problem of the different results ?

I then went back to my code and took a look and made a change on the Input Decoder from.

Dim encoder As New System.Text.ASCIIEncoding

To

Dim encoder As New System.Text.UnicodeEncoding

After that I was getting the results of .

MSMPSVC
3A-3F-54-17-C7-6D-22-66-67-BC-FC-C9-EE-26-9D-63-C9-B0-CF-B1
3A3F5417C76D226667BCFCC9EE269D63C9B0CFB1

Now I knew I was onto something and the rest was a matter of following the steps mentioned above.

Lets take a closer look to understand why I was getting the wrong results.

A while back I created a utility that input a string and output as hex string encoded with various Unicode encoders.

GetBytes5

As you can see from the screenshot above that using the ASCII encoder output as :
4D 53 4D 50 53 56 43   And the Unicode output as 4D 0 53 0 4D 0 50 0 53 0 56 0 43 0

The first is 7 bytes long but the second one is padded with zeros and is 14 bytes long.
Looking thru the RFC 3174 you find that the whole thing starts with the length of the “message” in binary bits and using a different format will drastically change the outcome of the hash function due to the different lengths..

Another thing you may notice in this application is the BigEndianUnicode.

GetBytes6

If you will take a close look of that, the bytes are going the same direction but the lead and trailing Zeros are on opposite ends.That would lead me to believe that the “Plain” Unicode is considered Little Endian byte order. Correct me if I am wrong.

The last part of the puzzle is after you create a SID how do you associate it with the service name ?

The answer can be found on Service Changes for Windows Vista under the sub section “Service Isolation”.

The last part reads : “To set the service SID, call ChangeServiceConfig2 with SERVICE_CONFIG_SERVICE_SID_INFO.”

In order to have your service have a SID set automatically you must set a value for “SERVICE_SID_INFO structure” to either “SERVICE_SID_TYPE_RESTRICTED” or “SERVICE_SID_TYPE_UNRESTRICTED” if you set it as “SERVICE_SID_TYPE_NONE” then it will not automatically be set and available for use by your service to aid in securing it.

Just being able to create a SID using this tool does not enable you to be able to use that SID without setting the required parameters above, It would only show you the same SID that the “sc.exe showsid ServiceName” does.

For instance If I was to run a service name like “mySuperService” thru the SC.exe utility it returns.

NAME: mySuperService
SERVICE SID: S-1-5-80-1956725871-603941828-2318551034-3950094706-3826225633

But that does not mean the service is installed on the system or the SID could be used.

It is just the SID created from the name.

Although it may help to know what it will be after being set or while building a Security Descriptor and setting the rights.

I have not found a command using the SC.Exe utility to set the service SID yet.

It may need to be done thru your service installer or a controller application.

The “Sc config servicename” does not seem to have the setting in it for setting the Service SID Type. I’m still looking into it.

That’s it for now I’m still working on a more overall service security article mainly aimed towards understanding why my program stopped working for shutting down Microsoft Security Essentials. Windows 8.1 has something new for Anti-Malware programs.

Advertisements

About pcsxcetrasupport3

My part time Business, I mainly do system building and system repair. Over the last several years I have been building system utility's in vb script , HTA applications and VB.Net to be able to better find the information I need to better understand the systems problems in order to get the systems repaired and back to my customers quicker.
This entry was posted in RootAdmin and tagged . Bookmark the permalink.