Skip to content

Instantly share code, notes, and snippets.

@ikuamike
Forked from mprahl/sid2str.py
Created June 16, 2020 22:13
Show Gist options
  • Save ikuamike/5747e29888c29233a960893b89e53ca8 to your computer and use it in GitHub Desktop.
Save ikuamike/5747e29888c29233a960893b89e53ca8 to your computer and use it in GitHub Desktop.
Python 2.7/3.5 function to convert an Active Directory binary SID to string format (sid_to_str)
import sys
import struct
def sid_to_str(sid):
""" Converts a hexadecimal string returned from the LDAP query to a
string version of the SID in format of S-1-5-21-1270288957-3800934213-3019856503-500
This function was based from: http://www.gossamer-threads.com/lists/apache/bugs/386930
"""
# The revision level (typically 1)
if sys.version_info.major < 3:
revision = ord(sid[0])
else:
revision = sid[0]
# The number of dashes minus 2
if sys.version_info.major < 3:
number_of_sub_ids = ord(sid[1])
else:
number_of_sub_ids = sid[1]
# Identifier Authority Value (typically a value of 5 representing "NT Authority")
# ">Q" is the format string. ">" specifies that the bytes are big-endian.
# The "Q" specifies "unsigned long long" because 8 bytes are being decoded.
# Since the actual SID section being decoded is only 6 bytes, we must precede it with 2 empty bytes.
iav = struct.unpack('>Q', b'\x00\x00' + sid[2:8])[0]
# The sub-ids include the Domain SID and the RID representing the object
# '<I' is the format string. "<" specifies that the bytes are little-endian. "I" specifies "unsigned int".
# This decodes in 4 byte chunks starting from the 8th byte until the last byte
sub_ids = [struct.unpack('<I', sid[8 + 4 * i:12 + 4 * i])[0]
for i in range(number_of_sub_ids)]
return 'S-{0}-{1}-{2}'.format(revision, iav, '-'.join([str(sub_id) for sub_id in sub_ids]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment