How do I convert a SID between binary and string forms?

Date:March 15, 2004 / year-entry #97
Tags:other
Orig Link:https://blogs.msdn.microsoft.com/oldnewthing/20040315-00/?p=40253
Comments:    9
Summary:Of course, if you want to do this programmatically, you would use ConvertSidToStringSid and ConvertStringSidtoSid, but often you're studying a memory dump or otherwise need to do the conversion manually. If you have a SID like S-a-b-c-d-e-f-g-... Then the bytes are a (revision) N (number of dashes minus two) bbbbbb (six bytes of "b" treated...

Of course, if you want to do this programmatically, you would use ConvertSidToStringSid and ConvertStringSidtoSid, but often you're studying a memory dump or otherwise need to do the conversion manually.

If you have a SID like S-a-b-c-d-e-f-g-...

Then the bytes are

a (revision)
N (number of dashes minus two)
bbbbbb (six bytes of "b" treated as a 48-bit number in big-endian format)
cccc (four bytes of "c" treated as a 32-bit number in little-endian format)
dddd (four bytes of "d" treated as a 32-bit number in little-endian format)
eeee (four bytes of "e" treated as a 32-bit number in little-endian format)
ffff (four bytes of "f" treated as a 32-bit number in little-endian format)
etc.

So for example, if your SID is S-1-5-21-2127521184-1604012920-1887927527-72713, then your raw hex SID is

010500000000000515000000A065CF7E784B9B5FE77C8770091C0100

This breaks down as follows:

01 S-1
05 (seven dashes, seven minus two = 5)
000000000005 (5 = 0x000000000005, big-endian)
15000000 (21 = 0x00000015, little-endian)
A065CF7E (2127521184 = 0x7ECF65A0, little-endian)
784B9B5F (1604012920 = 0x5F9B4B78, little-endian)
E77C8770 (1887927527 = 0X70877CE7, little-endian)
091C0100 (72713 = 0x00011c09, little-endian)

Yeah, that's great, Raymond, but what do all those numbers mean?

S-1- version number (SID_REVISION)
-5- SECURITY_NT_AUTHORITY
-21- SECURITY_NT_NON_UNIQUE
-...-...-...- these identify the machine that issued the SID
72713 unique user id on the machine

Each machine generates a unique ID that it uses to stamp all the SIDs it creates (-...-...-...-). The last number is a "relative id (RID)" that represents a user created by that machine. There are a bunch of predefined RIDs; you can see them in the header file ntseapi.h, which is also where I got these names from. The system reserves RIDs up to 999, so the first non-builtin account gets assigned ID number 1000. The number 72713 means that this particular SID is the 71714th SID created by the issuer. (The machine that issued this SID is clearly a domain controller, responsible for creating the accounts of tens of thousands of users.)

(Actually, I lied above when I said that this is the 71714th SID created by the issuer. Large servers can delegate SID creation to helpers, in which case SID issuance is no longer strictly consecutive.)

Security isn't my area of expertise, so it's entirely possibly (perhaps even likely) that I got something wrong up above. But it's mostly correct, I think.


Comments (9)
  1. So what are the security issues with giving out ones SID?

  2. Larry Osterman says:

    As far as I know, there aren’t any issues with giving out the SID – except for one minor issue.

    The -…-…-…- actually identify the domain that issued the SID, and that means that it’s possible to corrolate the domain on which a user account is created.

    That means that if you know one account on a domain that has a weak security policy, you can know if other accounts are also created on the same domain.

    It’s a small bit of information disclosure, but in the scheme of things…

    If you think about it, the SID of all the users in an ACL are included in the security descriptor for objects, and the security descriptor contents are semi-public information (you need READ_CONTROL access rights to the object).

    But I’m also not a security guy (although I’ve done a LOT of security work).

  3. Adrian Oney says:

    Same boat as Raymond – not a security guy, but I’ve done a good amount of security work.

    I personally found the information on SIDs in the SDK and even Howard & LeBlanc’s excellent "Writing Secure Code" book somewhat lacking in organization. When I had to put things together for the DDK, I organized the list of SIDs this way (from wdmsec.h):

    Each SID is listed in the form EnglishName ("SDDL Abbreviation", FullSID, Authority:SubAuthorities)

    The following SIDs represent *accounts* on the local machine:

    ————————————————————-

    System ("SY", S-1-5-18, SECURITY_NT_AUTHORITY:SECURITY_LOCAL_SYSTEM_RID)

    The OS itself (including its user mode components.)

    Local Service ("LS", S-1-5-19, SECURITY_NT_AUTHORITY:SECURITY_LOCAL_SERVICE_RID)

    A predefined account for services that presents user credentials for local

    resources and annonymous credentials for network access.

    Available on XP and later.

    Network Service ("NS", S-1-5-20, SECURITY_NT_AUTHORITY:SECURITY_NETWORK_SERVICE_RID)

    A predefined account for services that presents user credentials for local

    resources and the machine ID for network access.

    Available on XP and later.

    (A local *account* for a guest and a default administrator also exist, but

    the corresponding SDDL abbreviations are not supported by this library.

    Use the corresponding group SIDs instead.)

    The following SIDs represent *groups* on the local machine:

    ———————————————————–

    Administrators ("BA", S-1-5-32-544, SECURITY_NT_AUTHORITY:SECURITY_BUILTIN_DOMAIN_RID:DOMAIN_ALIAS_RID_ADMINS)

    The builtin administrators group on the machine. This is not the same

    as the builtin Administrator *account*.

    Builtin users group ("BU", S-1-5-32-545, SECURITY_NT_AUTHORITY:SECURITY_BUILTIN_DOMAIN_RID:DOMAIN_ALIAS_RID_USERS)

    Group covering all local user accounts, and users on the domain.

    Builtin guests group ("BG", S-1-5-32-546, SECURITY_NT_AUTHORITY:SECURITY_BUILTIN_DOMAIN_RID:DOMAIN_ALIAS_RID_GUESTS)

    Group covering users logging in using the local or domain guest account.

    This is not the same as the builtin Guest *account*.

    The below SIDs describe the authenticity of the user’s identity:

    —————————————————————-

    Authenticated Users ("AU", S-1-5-11, SECURITY_NT_AUTHORITY:SECURITY_AUTHENTICATED_USER_RID)

    Any user recognized by the local machine or by a domain. Note that

    users logged in using the Builtin Guest account are not authenticated.

    However, members of the Guests group with individual accounts on the

    machine or domain are authenticated.

    Anonymous Logged-on User ("AN", S-1-5-7, SECURITY_NT_AUTHORITY:SECURITY_ANONYMOUS_LOGON_RID)

    Any user logged on without an identity, for instance via an anonymous

    network session. Note that users logged in using the Builtin Guest

    account are neither authenticated nor anonymous. Available on XP and

    later.

    World ("WD", S-1-1-0, SECURITY_WORLD_SID_AUTHORITY:SECURITY_WORLD_RID)

    Prior to Windows XP, this SID covers every session: authenticated,

    anonymous, and the Builtin Guest account.

    For Windows XP and later, this SID does not cover anonymous logon

    sessions – only authenticated and the Builtin Guest account.

    Note that untrusted or "restricted" code is also not covered by the

    World SID. See the Restricted Code SID description for more

    information.

    The below SIDs describe how the user logged into the machine:

    ————————————————————-

    Interactive Users ("IU", S-1-5-4, SECURITY_NT_AUTHORITY:SECURITY_INTERACTIVE_RID)

    Users who initally logged onto the machine "interactively", such as

    local logons and Remote Desktops logons.

    Network Logon User ("NU", S-1-5-2, SECURITY_NT_AUTHORITY:SECURITY_NETWORK_RID)

    Users accessing the machine remotely, without interactive desktop

    access (ie, file sharing or RPC calls).

    Terminal Server Users (—, S-1-5-14, SECURITY_NT_AUTHORITY:SECURITY_TERMINAL_SERVER_RID)

    Interactive Users who *initially* logged onto the machine specifically

    via Terminal Services or Remote Desktop.

    (NOTE: There is currently no SDDL token for this SID. Furthermore, the

    presence of the SID doesn’t take into account fast user switching

    either.)

    The below SID deserves special mention:

    —————————————

    Restricted Code ("RC", S-1-5-12, SECURITY_NT_AUTHORITY:SECURITY_RESTRICTED_CODE_RID)

    This SID is used to control access by untrusted code.

    ACL validation against tokens with RC go through *two* checks, one

    against the token’s normal list of SIDs (containing WD for instance),

    and one against a second list (typically containing RC and a subset of

    the original token SIDs). Only if both tests pass is access granted.

    As such, RC actually works in *combination* with other SIDs.

    When RC is paired with WD in an ACL, a *superset* of Everyone

    _including_ untrusted code is described. RC is thus rarely seen in

    ACL’s without the WD token.

  4. Pavel Lebedinsky says:

    If you’re looking at a memory dump then you can also use !sid debugger extension:

    c:debuggers> cdb notepad

    0:000> dc RPCRT4!AnonymousSid

    78073fc8 00000101 05000000 00000007

    0:000> !sid RPCRT4!AnonymousSid 1

    SID is: S-1-5-7 (Well Known Group: NT AUTHORITYANONYMOUS LOGON)

  5. Florian W. says:

    My greatest highlight inside the security-API-documentation on MSDN is the article: "Windows NT Security in Theory and Practice". This article has a nice line: ‘First, you should definitely read Robert Reichel’s two-part article "Inside Windows NT Security," which appeared in the April 1993 and May 1993 issues of the Windows/DOS Developer’s Journal’.

    Unfortunatly, that article is *not* part of MSDN:-(

  6. Norman Diamond says:

    I found one article by Robert Reichel on windows security. He’s a real estate agent, and he recommended that windows on and near the ground floor should be locked.

    As for that other Robert Reichel, it seems his articles would likely be included in a CD that was made by the original publisher, but the CD is sold out. CMP has more recent archives posted on their web site. Anyone know if they could be persuaded to do the same with older ones?

Comments are closed.


*DISCLAIMER: I DO NOT OWN THIS CONTENT. If you are the owner and would like it removed, please contact me. The content herein is an archived reproduction of entries from Raymond Chen's "Old New Thing" Blog (most recent link is here). It may have slight formatting modifications for consistency and to improve readability.

WHY DID I DUPLICATE THIS CONTENT HERE? Let me first say this site has never had anything to sell and has never shown ads of any kind. I have nothing monetarily to gain by duplicating content here. Because I had made my own local copy of this content throughout the years, for ease of using tools like grep, I decided to put it online after I discovered some of the original content previously and publicly available, had disappeared approximately early to mid 2019. At the same time, I present the content in an easily accessible theme-agnostic way.

The information provided by Raymond's blog is, for all practical purposes, more authoritative on Windows Development than Microsoft's own MSDN documentation and should be considered supplemental reading to that documentation. The wealth of missing details provided by this blog that Microsoft could not or did not document about Windows over the years is vital enough, many would agree an online "backup" of these details is a necessary endeavor. Specifics include:

<-- Back to Old New Thing Archive Index