Home > Enterprise >  Access violation inside ctype imported windows function RtlDeriveCapabilitySidsFromName
Access violation inside ctype imported windows function RtlDeriveCapabilitySidsFromName

Time:09-27

I am importing ntdll.dll RtlDeriveCapabilitySidsFromName function and having access violation inside it. But can't figure what i am doing wrong.

import win32file, win32api
import os
import ctypes
import sys
from ctypes import *
from struct import calcsize
from ctypes.wintypes import BOOL, LPCVOID, LPCWSTR


prototype = WINFUNCTYPE(BOOL, LPCWSTR, LPCVOID, LPCVOID, LPCVOID, LPCVOID, use_last_error=True)
cap_group_sids = create_string_buffer(b"", 1024)
sid = create_unicode_buffer(u"S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646")

print(f'sid ', sid.value, f' cap_group_sids @ ', cap_group_sids)
param_flags = (1, "sid", sid), (1, "CapabilityGroupSids", cap_group_sids), (1, "CapabilityGroupSidCount", cap_group_sids), \
              (1, "CapabilitySids", cap_group_sids), (1, "CapabilitySidCount", cap_group_sids)
print(f'param_flags: {param_flags}')

RtlDeriveCapabilitySidsFromName = prototype(("RtlDeriveCapabilitySidsFromName", windll.ntdll), param_flags)

try:
    RtlDeriveCapabilitySidsFromName(sid=sid, CapabilityGroupSids=cap_group_sids, CapabilityGroupSidCount=cap_group_sids,
                                    CapabilitySids=cap_group_sids, CapabilitySidCount=cap_group_sids)
    print(f'cap {cap_group_sids}')
except Exception as e:
    print(f"Error: {WinError()} RtlDeriveCapabilitySidsFromName exception: ", e)

Output:

C:\ProgramData\Anaconda3\envs\first-py\python.exe E:/projects/first-py/py-sec-tools/sid.py 
sid  S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646  cap_group_sids @  <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>
param_flags: ((1, 'sid', <ctypes.c_wchar_Array_99 object at 0x0000020A2E24FF40>), (1, 'CapabilityGroupSids', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>), (1, 'CapabilityGroupSidCount', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>), (1, 'CapabilitySids', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>), (1, 'CapabilitySidCount', <ctypes.c_char_Array_1024 object at 0x0000020A2B824140>))
Error: [WinError 0] The operation completed successfully. RtlDeriveCapabilitySidsFromName exception:  exception: access violation reading 0xFFFFFFFFFFFFFFFF

Process finished with exit code 0

CodePudding user response:

The Rtl function is undocumented and what I found online about it indicates it doesn't have the same function signature. I found and got DeriveCapabilitySidsFromName to work as shown below. The documentation indicates it is in kernel32.dll but it was not found there. I found it in kernelbase.dll:

import ctypes as ct
from ctypes import wintypes as w

PSID = w.LPVOID

kb = ct.WinDLL('kernelbase') # documented as kernel32.dll but found in kernelbase.dll instead.
kb.DeriveCapabilitySidsFromName.argtypes = w.LPCWSTR, ct.POINTER(ct.POINTER(PSID)), ct.POINTER(w.DWORD), ct.POINTER(ct.POINTER(PSID)), ct.POINTER(w.DWORD)
kb.DeriveCapabilitySidsFromName.restype = w.BOOL

k32 = ct.WinDLL('kernel32')
k32.LocalFree.argtypes = w.HLOCAL,
k32.LocalFree.restype = w.HLOCAL

cap_name = ct.create_unicode_buffer('S-1-15-3-1024-3424233489-972189580-2057154623-747635277-1604371224-316187997-3786583170-1043257646')

cap_group_sids = ct.POINTER(PSID)()
cap_group_sid_count = w.DWORD()
cap_sids = ct.POINTER(PSID)()
cap_sid_count = w.DWORD()

result = kb.DeriveCapabilitySidsFromName(cap_name, ct.byref(cap_group_sids), ct.byref(cap_group_sid_count),
                                          ct.byref(cap_sids), ct.byref(cap_sid_count))
if result:
    print(cap_group_sid_count.value)
    print(cap_group_sids[:cap_group_sid_count.value])
    print(cap_sid_count.value)
    print(cap_sids[:cap_sid_count.value])

    # These all print 'None' if free succeeds.
    for h in cap_group_sids[:cap_group_sid_count.value]:
        print(k32.LocalFree(h))
    for h in cap_sids[:cap_sid_count.value]:
        print(k32.LocalFree(h))
    print(k32.LocalFree(cap_group_sids))
    print(k32.LocalFree(cap_sids))

Output:

1
[2568639690416]
1
[2568639690480]
None
None
None
None
  • Related