Okay, George, I figured it out.
The SIDs for Local built-in groups do not contain
a host or domain SID component. They are "well-known" SIDs. For
example, the SID for a user account with a RID of 1007 may look something like
S-1-5-21-1277933745-1127690641-2306662984-1007
(with everything between 21 and 1007 belonging to the host or domain SID),
while the SID for the built-in group Backup Operators (RID 551) will
always be S-1-5-32-551 on every
host.
Obviously, joining the host SID to the group
RID and then looking it up with
LsaLookupSid will not work for local built-in
groups.
The revision (1): 01
The number of dashes
(4) minus two (2): 02
Six-byte big-endian
hex value for 5: 000000000005
Four-byte
little-endian hex value for 32: 20000000
Four-byte
little-endian hex value for the RID: 27020000
Which becomes:
01020000000000052000000027020000
Calling my getObjectName on this
value does, indeed, produce "Backup Operators."
The range of well-known RIDS for built-in local
groups is 544 through 561, so modifying my getObjectSid
function as follows produces a correct raw object SID value regardless of the
object type:
function getObjectSid ( hostSid,
objRid ) {
local_var objSid;
if(
objRid >= 544 && objRid <= 561 )
{
objSid =
raw_string(0x01,0x02,0x00,0x00,0x00,0x00,0x00,0x05 )
+
raw_dword( 32 ) + raw_dword( objRid
);
} else {
hostSid = hex2raw2( s: hostSid );
objSid =
hostSid[0] + raw_byte( b: ord( hostSid[1] ) +1 )
+
substr( hostSid, 2, strlen(
hostSid ) -1 ) + raw_dword( d: objRid );
}
return objSid;
}
Passing this to my getObjectName
function produces the correct object name - again, regardless of object
type:
function getObjectName (
lsaHandle, objSid ) {
local_var objSids, objNames,
objInfo;
objSids = NULL; objSids[0] =
objSid;
objNames = LsaLookupSid( handle: lsaHandle,
sid_array: objSids );
if( !isnull( objNames ) ) objInfo
= parse_lsalookupsid( data: objNames[0] );
return
objInfo[2];
}
Thanks again for the tips, George.
Regards,
John
Scherff
Sr.
IT Security Engineer
24 Hour Fitness