8

I have the objectSid attribute as returned by the ldapsearch command, how can I generate SID from it in human readable format?

ldapsearch command:

ldapsearch -LLL -H ldap://dc.example.com:389 -b dc=example,dc=lk -D example\administrator -w adminPassword "(sAMAccountName=bob)" | grep -i "objectSid::" | cut -d ":" -f3 | xargs

This command returns objectSid of the AD user "bob". Let's say it returned objectSid as:

AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA==

I want to generate its SID in the following format:

S-1-5-21-1270179133-2928470170-2248674342-4324

Is it possible to do this in Linux?

Reference: Get an object by its objectGUID using ldapsearch

HBruijn
  • 72,524
  • 21
  • 127
  • 192
Yasitha Bogamuwa
  • 403
  • 1
  • 3
  • 12

4 Answers4

15

Finally I managed to construct SID from the ObjectSid. Here's the complete shell script if anyone interested.

#!/bin/bash

# Base-64 encoded objectSid
OBJECT_ID="AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA=="

# Decode it, hex-dump it and store it in an array
G=($(echo -n $OBJECT_ID | base64 -d -i | hexdump -v -e '1/1 " %02X"'))

# SID in HEX
# SID_HEX=${G[0]}-${G[1]}-${G[2]}${G[3]}${G[4]}${G[5]}${G[6]}${G[7]}-${G[8]}${G[9]}${G[10]}${G[11]}-${G[12]}${G[13]}${G[14]}${G[15]}-${G[16]}${G[17]}${G[18]}${G[19]}-${G[20]}${G[21]}${G[22]}${G[23]}-${G[24]}${G[25]}${G[26]}${G[27]}${G[28]}

# SID Structure: https://technet.microsoft.com/en-us/library/cc962011.aspx
# LESA = Little Endian Sub Authority
# BESA = Big Endian Sub Authority
# LERID = Little Endian Relative ID
# BERID = Big Endian Relative ID

BESA2=${G[8]}${G[9]}${G[10]}${G[11]}
BESA3=${G[12]}${G[13]}${G[14]}${G[15]}
BESA4=${G[16]}${G[17]}${G[18]}${G[19]}
BESA5=${G[20]}${G[21]}${G[22]}${G[23]}
BERID=${G[24]}${G[25]}${G[26]}${G[27]}${G[28]}

LESA1=${G[2]}${G[3]}${G[4]}${G[5]}${G[6]}${G[7]}
LESA2=${BESA2:6:2}${BESA2:4:2}${BESA2:2:2}${BESA2:0:2}
LESA3=${BESA3:6:2}${BESA3:4:2}${BESA3:2:2}${BESA3:0:2}
LESA4=${BESA4:6:2}${BESA4:4:2}${BESA4:2:2}${BESA4:0:2}
LESA5=${BESA5:6:2}${BESA5:4:2}${BESA5:2:2}${BESA5:0:2}
LERID=${BERID:6:2}${BERID:4:2}${BERID:2:2}${BERID:0:2}

LE_SID_HEX=${LESA1}-${LESA2}-${LESA3}-${LESA4}-${LESA5}-${LERID}

# Initial SID value which is used to construct actual SID
SID="S-1"

# Convert LE_SID_HEX to decimal values and append it to SID as a string
IFS='-' read -ra ADDR <<< "${LE_SID_HEX}"
for OBJECT in "${ADDR[@]}"; do
  SID=${SID}-$((16#${OBJECT}))
done

echo ${SID}
Yasitha Bogamuwa
  • 403
  • 1
  • 3
  • 12
1

This worked for me: perl -MNet::LDAP::SID -E 'my $binary=qx(echo AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA== | base64 --decode); my $sid = Net::LDAP::SID->new($binary); say $sid->as_string'

Could be done in perl only, but as an example is sufficient I guess.

mestia
  • 139
  • 4
1

First you can restrict the answer set an ldapsearch query returns by including the attributes you want after the filter, that should be a fair bit quicker when you aim for more than one result.

 ldapsearch -LLL -H ldap://dc.example.com:389 -b dc=example,dc=lk -D example\administrator -w adminPassword "(sAMAccountName=bob)" ObjectSID

Second when an attribute is separated from its value by a double colon :: that is an indication that the value is base64 encoded. ldapsearch is not schema aware, it doesn't know if such a base64 encoded attributed is an unicode text string that could be displayed as text in a unicode capable terminal or for instance jpegPhoto or something other data that can't easily be displayed in a terminal and will not decode such values for you.

echo   AQUAAAAAAAUVAAAAPWW1S5rojK4mDAiG5BAAAA== | base64 --decode

should do the trick. AFAIK base64 should be in the coreutils package.


The problem is that the objectSid after base64 decoding is still a binary value that needs further conversion to before you can display that in the conventional security identifier format of S-1-5-21-1270179133-2928470170-2248674342-4324.

You'll need to write a conversion routine in your scripting/programming language of choice, as for instance others have already done for instance in perl or php.

HBruijn
  • 72,524
  • 21
  • 127
  • 192
  • Thank you for the quick reply. Actually I tried to decoding the returning value. But it gives some unicode characters instead of SID. Please refer this snapshot: http://take.ms/Pu0RR – Yasitha Bogamuwa May 24 '17 at 01:18
  • Since the [objectSid](https://msdn.microsoft.com/en-us/library/ms679024(v=vs.85).aspx) seems to be a **binary value** simply decoding it is not sufficient then. – HBruijn May 24 '17 at 05:25
  • I'm trying to use it in a shell script. Do you think it is possible without using python or perl? – Yasitha Bogamuwa May 24 '17 at 17:13
  • Anything is possible But trying to do so most certainly won't be easier or quicker I recon – HBruijn May 24 '17 at 19:17
  • I managed to construct SID from ObjectSid. Will publish the script soon. Thanks! – Yasitha Bogamuwa May 25 '17 at 14:45
0

There are a couple of minor issues in the script given in YasithaB's answer to his own question:

It uses ${G[28]}, which treats one of the IDs as being 5 bytes long. I think this is wrong, and the SID is typically only 28 bytes of binary, numbered 0-27

It assumes the SID has 5 sub-ids, when it could/should use ${G[1]} to find the number of IDs.

The end bit seems very complicated - creating $LE_SID_HEX, then chopping it back up again and converting to decimal. A one liner of:

printf "S-1-%u-%u-%u-%u-%u-%u\n" $(( 16#$LESA1 )) $(( 16#$LESA2 )) $(( 16#$LESA3 )) $(( 16#$LESA4 )) $(( 16#$LESA5 )) $(( 16#$LERID ))

Will give the same result as the last 12 lines of the script.

Michael Firth
  • 131
  • 1
  • 8