Security Identifiers (SIDs) and Object Permissions in Windows [Part 1]

Welcome to Part 1 of a planned four-part series!

Part 3: Converting Azure Object IDs in Azure into Security Identifiers (SIDs) 
Part 4: Security Identifiers (SIDs) and User Rights Management 

So on to Part 1!

"How does Windows know what a user is allowed to do?" I imagine you asking for the purpose of writing this blog post? 

Well, it grants permissions to files or folders. The same permissions affect and grants (or denies) access to system registry keys. 

"But how does Windows know what permissions to grant?" You, my imaginary conversational partner, continue to ask. 

Oh! You want the long answer! OK then. 

"And why do I, an Azure cloud native, care?" Woah, woah. Slow down there. First we'll go over what SIDs are, how they are used and why you (the cloud native) should care. 

Windows uses an objects' Security Identifier (SIDs) which are unique identifiers that represent created objects either locally or in an Active Directory domain i.e.  

  • Users
  • Groups
  • Computers
  • Security Objects 
Not every object in Windows is represented by a SID (e.g. printers, contacts, custom classes do not get a SID) however all security principals DO hence SIDs being called Security Identifiers. 

So SIDs are used instead of "friendly names" (i.e. a username) to control access to resources e.g.

  • Network shared folders
  • Registry keys
  • File system objects (NTFS permissions)
  • Printers
  • Etc.

You can think of SIDs as Active Directory object attributes stored in the ntds.dit database whereas local object SIDS in the local Security Account Manager (SAM) database in the HKEY_LOCAL_MACHINE\SAM\SAM registry key. 

For obvious security reasons, you can't simply view the contents of the SAM key however it's not impossible to dump the contents and might be a fun write-up for a future post!

As an aside, if you try looking up a friendly name and instead can only find the SID, that means your Domain Controller can't resolve the SID due to the corresponding object having been deleted. It's like the opposite of the "It's always DNS" meme i.e. its not the resolving the record that's wrong, it's the actual source of the record that's missing. 

How and Where to Find SIDs

While in an elevated CMD or Powershell prompt, here is what I tend to use

  • whoami - which queries the domain
  • wmic useraccount get name,sid - if you just want the device level SIDs
  • Get-WmiObject if you just want the device level SIDs
  • Get-CimInstance - if you just want the device level SIDs

Start by opening up an elevated CMD prompt: 

The first query we're going to try running is to find the current logged in domain user

whoami /user

Once it has been executed, the system will show us the SID of the user running the command:

In order to get a list of the local device SIDs, in the same session, we run wmic useraccount get name,sid and we get: 

"But wait!" you anxiously blurt out, in order to point out that wmic useraccount get name,sid isn't part of the two bulletpoint list at the top of this segment! That's right! And with that said, CMD is so last century and there's essentially nothing you can't do in powershell that you can't do in a CMD prompt

So I suggest we open an elevated powershell instead and do the following:

To get a list of all device user SIDs, simply query 

Get-WmiObject win32_useraccount | Select name,sid

You'll notice that the results from both queries are different. Remember that whoami /user shows the current user which is an AzureAD joined member where as we are using Windows Management Instrumentation Command (WMIC) when running wmic useraccount get name,sid which returns local user results (unless you specify a target remote node). 

The same goes for device groups if you run Get-WmiObject win32_group | Select name,sid

"BUT WAIT" you literally scream out due to annoyance and a sense of come up'ance! "That cmdlet is ALSO struck out! Why are you wasting my time??"

Because it's my blog and I choose to. But really it's so that you, dear reader, get a bit more out of reading my ramblings rather than blindly following a step-by-step guide. I want you to understand the whys behind all of the different answers you'll encounter through your googles. Because even if the above works today it might not work tomorrow

Just like wmic, Get-WmiObject is deprecated. And has been since Powershell version 3. As time of writing, the latest stable release of Powershell is 7.2.1.

Whereas the Powershell version 5.1.x is still the release that comes packages with standard Windows 10 Pro/Enterprise packages.

If your sysadmin experience extends past just Windows and into *nix, then you know the headache and pain of things just... break. After an update. Dependencies, etc. Microsoft tries their damndest to avoid this and a huge part of their business model relies on supporting legacy. The pros and cons of which is worthy of a post of its own - albeit less technical and more personal opinion. 

So instead, use Get-CimInstance -ClassName Win32_useraccount -Property *

You get the same output as before but with more details in a more human readable table output - albeit not as concise. Note the red box in the above screenshot where it says "Degraded". Remember that I'm mainly a cloud guy and, as such, my test environments tend to be AzureAD joined rather than on-prem or HAADJ. The basic principles are the same but I felt the need to point that out as IT is rarely 1:1 between environments so a bit of grey matter utilization is still necessary.

So what does "Degraded" mean? It means the local accounts aren't being used in my cloud-only environment. But take a look at the next screenshot, for the LocalUser account. This is a, guess what, local user account I applied to the device using a custom profile via Intune that I made as part of another blog post I'm working on - the link to which I'll include HERE (when I get around to writing it, that is..) when it's published. 

Why does Windows use SIDs rather than friendly names? And why you should too!

A common low-hanging fruit method for "enhancing" security through obfuscation is renaming BUILTIN administrator users and groups e.g. renaming Administrators to ImportantUsers. Or whatever. I'm not a huge fan of security through obfuscation as the actors you're trying to make things harder for already know about stuff like this. 

But this serves as a good example of my next point. Even if you rename a principal, the SID will stay the same. It is a constant that you can not alter or change without having to really, really want to put in the effort. And even then you'll be limited to the underlying pattern. So rename away! Windows will still know what you're trying to call!  

But let's say you've made a group policy that references the friendly name and not the SID. For example, granting local administrator device privileges to a particular security group. What then? Well, in this case your Domain Controller may not be able to resolve the friendly name because it doesn't exist!

Also because of localization!

That's right, my anglophile friends. As weird as it is (and trust me, it IS for me also!) some users prefer having localized versions of Windows installed which means things like friendly names are translated (read: "localized") into their filthy non-ISO languages. Note: I do not speak on behalf of ISO standards. As filthy as they may be.

Take a look at this fresh Danish Windows VM I just spun up for this purpose. The standardly friendly named "Remote Desktop Users" group has been bastardized into "Brugere af Fjerneskrivbord".

And completely ignoring what I wrote above regarding depreceated cmdlets. I've chosen to run wmic group get name,sid purely because I prefer the output. But the point still stands... notice that the SIDs are the same but the friendly names are not!

This is important if you work in an multinational with regional offices spread all over the place and especially important if your multinational is the sort of organization that prefers to buy up local competitors that may, or may not, buy off-the-shelf devices and run cracked versions of Windows that results in a glorious clusterfuck of thousands of shadow IT devices!

I've seen it more than once. Sadly. But hey, that's the life of an IT tech. 

But so, hey, like, man. What do all of these numbers mean? Don't worry!. We'll be getting to that shortly!