예제 #1
0
def find_alpc_endpoints(targetiid,
                        version=(1, 0),
                        nb_response=1,
                        sid=gdef.WinLocalSystemSid):
    """Ask the EPMapper for ALPC endpoints of ``targetiid:version`` (maximum of ``nb_response``)

        :param str targetiid: The IID of the requested interface
        :param (int,int) version: The version requested interface
        :param int nb_response: The maximum number of response
        :param WELL_KNOWN_SID_TYPE sid: The SID used to request the EPMapper

        :returns: [:class:`~windows.rpc.epmapper.UnpackTower`] -- A list of :class:`~windows.rpc.epmapper.UnpackTower`
    """

    if isinstance(targetiid, basestring):
        targetiid = gdef.IID.from_string(targetiid)
    # Connect to epmapper
    client = windows.rpc.RPCClient(r"\RPC Control\epmapper")
    epmapperiid = client.bind("e1af8308-5d1f-11c9-91a4-08002b14a0fa",
                              version=(3, 0))

    # Compute request tower
    ## object
    rpc_object = gdef.RPC_IF_ID(targetiid, *version)
    ## Syntax
    syntax_iid = gdef.IID.from_string("8a885d04-1ceb-11c9-9fe8-08002b104860")
    rpc_syntax = gdef.RPC_IF_ID(syntax_iid, 2, 0)
    ## Forge tower
    tower_array_size, towerarray = construct_alpc_tower(
        rpc_object, rpc_syntax, "ncalrpc", b"", None)

    # parameters
    local_system_psid = windows.utils.get_known_sid(sid)
    context = (0, 0, 0, 0, 0)

    # Pack request
    fullreq = EptMapAuthParameters.pack([
        bytearray(targetiid), (tower_array_size, towerarray),
        local_system_psid, context, nb_response
    ])
    # RPC Call
    response = client.call(epmapperiid, 7, fullreq)
    # Unpack response
    stream = ndr.NdrStream(response)
    unpacked = EptMapAuthResults.unpack(stream)
    # Looks like there is a memory leak here (in stream.data) if nb_response > len(unpacked[2])
    # Parse towers
    return [explode_alpc_tower(obj) for obj in unpacked[2]]
예제 #2
0
def test_rpc_uac_call():
    client = windows.rpc.find_alpc_endpoint_and_connect(UAC_UIID)
    iid = client.bind(UAC_UIID)

    python_path = sys.executable
    python_name = os.path.basename(python_path)

    # Marshalling parameters.
    parameters = UACParameters.pack([
        python_path + "\x00",  # Application Path
        python_path + "\x00",  # Commandline
        0,  # UAC-Request Flag
        gdef.CREATE_UNICODE_ENVIRONMENT,  # dwCreationFlags
        "\x00",  # StartDirectory
        "WinSta0\\Default\x00",  # Station
        # Startup Info
        (
            None,  # Title
            0,  # dwX
            0,  # dwY
            0,  # dwXSize
            0,  # dwYSize
            0,  # dwXCountChars
            0,  # dwYCountChars
            0,  # dwFillAttribute
            0,  # dwFlags
            5,  # wShowWindow
            # Point structure: Use MonitorFromPoint to setup StartupInfo.hStdOutput
            (0, 0)),
        0,  # Window-Handle to know if UAC can steal focus
        0xffffffff
    ])  # UAC Timeout

    result = client.call(iid, 0, parameters)
    stream = ndr.NdrStream(result)

    ph, th, pid, tid = NdrProcessInformation.unpack(stream)
    return_value = ndr.NdrLong.unpack(stream)
    assert ph
    assert pid
    assert th
    assert tid
    windows.winproxy.CloseHandle(th)  # NoLeak
    proc = windows.WinProcess(handle=ph)
    assert proc.name == python_name
    assert proc.pid == pid
    proc.exit(0)
예제 #3
0
def explode_alpc_tower(tower):
    stream = ndr.NdrStream(bytearray(tower))
    size = stream.partial_unpack("<I")[0]
    if size != len(stream.data):
        raise ValueError(
            "Invalid tower size: indicate {0}, tower size {1}".format(
                size, len(stream.data)))
    floor_count = stream.partial_unpack("<H")[0]
    if floor_count != 4:
        raise ValueError(
            "ALPC Tower are expected to have 4 floors ({0} instead)".format(
                floor_count))

    # Floor 0
    lhs, rhs = parse_floor(stream)
    if not (lhs[0] == 0xd):
        raise ValueError("Floor 0: IID expected")
    iid = gdef.IID.from_buffer_copy(lhs[1:17])
    object = gdef.RPC_IF_ID(iid, lhs[17], lhs[18])

    # Floor 1
    lhs, rhs = parse_floor(stream)
    if not (lhs[0] == 0xd):
        raise ValueError("Floor 0: IID expected")
    iid = gdef.IID.from_buffer_copy(lhs[1:17])
    syntax = gdef.RPC_IF_ID(iid, lhs[17], lhs[18])

    # Floor 2
    lhs, rhs = parse_floor(stream)
    if (len(lhs) != 1 or lhs[0] != 0x0c):
        raise ValueError(
            "Alpc Tower expects 0xc as Floor2 LHS (got {0:#x})".format(lhs[0]))

    lhs, rhs = parse_floor(stream)
    if not (rhs[-1] == 0):
        rhs = rhs[:rhs.find("\x00")]
        # raise ValueError("ALPC Port name doest not end by \\x00")
    return UnpackTower("ncalrpc", bytes(rhs[:-1]), None, object, syntax)
예제 #4
0
    params.uacflags, # UAC-Request Flag
    params.creationflags, # dwCreationFlags
    "", # StartDirectory
    "WinSta0\\Default", # Station
        # Startup Info
        (None, # Title
        0, # dwX
        0, # dwY
        0, # dwXSize
        0, # dwYSize
        0, # dwXCountChars
        0, # dwYCountChars
        0, # dwFillAttribute
        0, # dwFlags
        5, # wShowWindow
        # Point structure: Use MonitorFromPoint to setup StartupInfo.hStdOutput
        (0, 0)),
    0, # Window-Handle to know if UAC can steal focus
    0xffffffff]) # UAC Timeout

result = client.call(iid, 0, parameters)
stream = ndr.NdrStream(result)

ph, th, pid, tid = NdrProcessInformation.unpack(stream)
return_value = ndr.NdrLong.unpack(stream)
print("Return value = {0:#x}".format(return_value))
target = windows.winobject.process.WinProcess(handle=ph)
print("Created process is {0}".format(target))
print(" * bitness is {0}".format(target.bitness))
print(" * integrity: {0}".format(target.token.integrity))
print(" * elevated: {0}".format(target.token.is_elevated))
예제 #5
0
                x.append(luid)
        # unpack pointed strings
        result = []
        for luid in x:
            name = ndr.NdrWcharConformantVaryingArrays.unpack(stream)
            result.append((luid, name))
        return result


# Actual code

## LSASS alpc endpoints is fixed, no need for the epmapper
client = windows.rpc.RPCClient(r"\RPC Control\lsasspirpc")
## Bind to the desired interface
iid = client.bind('12345778-1234-abcd-ef00-0123456789ab', version=(0, 0))

## Craft parameters and call 'LsarOpenPolicy2'
params = LsarOpenPolicy2Parameter.pack(
    [None, (0, None, None, 0, None, None), 0x20000000])
res = client.call(iid, 44, params)
## Unpack the resulting handle
handle = NdrContext.unpack(ndr.NdrStream(res))

## Craft parameters and call 'LsarEnumeratePrivileges'
x = LsarEnumeratePrivilegesParameter.pack([handle, 0, 10000])
res = client.call(iid, 2, x)

## Unpack the resulting 'LSAPR_PRIVILEGE_ENUM_BUFFER'
priviledges = LSAPR_PRIVILEGE_ENUM_BUFFER.unpack(ndr.NdrStream(res))
for priv in priviledges:
    print priv