RDP-seanss vajab kliendi aadressi ja ilmsed allikad ei ole ühel meelel. CLIENTNAME annab arvuti nime, register hoiab teiste seansside väärtusi ning soketi vastaspool võib olla lüüsi või NAT-i aadress, mitte klient. Windows pakub tõepoolest seansi kohta teatatud kliendi aadressi, kuid te peate küsima õige seansi järele ja vastuse õigesti dekodeerima.

Ankurdage otsing ühele seansile

Alustage seansist, mitte inimesest. Windowsi RDP-host võib kanda ühe konto jaoks mitut seanssi ja enne taasühendust nähtud aadress ei pruugi enam elava ühendusega sobida. Kirjutage seansi-ID, kasutaja ja vaatlusaeg koos üles. Seansi-ID on võti, mida API ootab, ja just see väärtus hoiab ära kahe seansi segimineku.

Hostis loetlevad paigaldatud seansitööriistad olemasolevat; kasutage haldusvaadet ainult siis, kui teil on sellele õigus. Kinnitage valitud ID vahetult enne päringut, sest ringlusse lastud ID tagastab teise seansi andmed.

qwinsta

Kutsuge selle ID jaoks välja WTSQuerySessionInformationW

Terminal Services API vastab küsimusele info klassiga 14, WTSClientAddress. Väike ctypes-ümbris on Windowsis piisav ja see väldib teise kasutaja hive lugemist. Allpool olev kood võtab selgesõnalise seansi-ID ja küsib kohalikku hosti.

import ctypes
import ipaddress
import socket
from ctypes import wintypes

class WTS_CLIENT_ADDRESS(ctypes.Structure):
    _fields_ = [("AddressFamily", wintypes.DWORD),
                ("Address", ctypes.c_ubyte * 20)]

wts = ctypes.WinDLL("Wtsapi32", use_last_error=True)
query = wts.WTSQuerySessionInformationW
query.argtypes = [wintypes.HANDLE, wintypes.DWORD, ctypes.c_int,
                  ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(wintypes.DWORD)]
query.restype = wintypes.BOOL
free = wts.WTSFreeMemory
free.argtypes = [ctypes.c_void_p]

def client_address(session_id):
    buf = ctypes.c_void_p()
    size = wintypes.DWORD()
    if not query(None, session_id, 14, ctypes.byref(buf), ctypes.byref(size)):
        raise ctypes.WinError(ctypes.get_last_error())
    try:
        if size.value < ctypes.sizeof(WTS_CLIENT_ADDRESS):
            raise RuntimeError("short WTS buffer")
        value = ctypes.cast(buf, ctypes.POINTER(WTS_CLIENT_ADDRESS)).contents
        raw = bytes(value.Address)
        if value.AddressFamily == socket.AF_INET:
            addr = ipaddress.ip_address(raw[2:6])
        elif value.AddressFamily == socket.AF_INET6:
            addr = ipaddress.ip_address(raw[:16])
        else:
            return None
        return None if addr.is_unspecified else str(addr)
    finally:
        free(buf)

Edastage äsja kontrollitud täisarvuline seansi-ID ja hoidke kohaliku masina jaoks null-serveri pideme. Käsitlege ebaõnnestunud kutset veana, mitte puuduva aadressina, sest need kaks viivad erinevate järeldusteni. Teise kasutaja seansi pärimine nõuab asjakohast Query Information luba, seega käivitage tööriist konto all, millele see on antud, mitte eskaleerige ad hoc. Tagastatud puhver kuulub API-le ja tuleb vabastada ka siis, kui dekodeerimine ebaõnnestub.

Dekodeerige perekond ja vabastage seejärel puhver

Struktuur ei ole IP-string. Selle perekonna väli otsustab, kuidas kahtekümmet aadressibaiti lugeda: IPv4 algab nihkelt kaks, IPv6 aga nihkelt null. Määramata aadress tähendab, et klient ei teatanud ühtegi, mis ei ole sama asi kui tühi string. Remote Desktop Gateway ühendused on dokumenteeritud juhuna, kus aadress ei ole saadaval, seega lüüsi kaudu toimuv seanss ei teata kliendi tegeliku aadressi kohta midagi kasulikku. Seejärel peab korrelatsioon liikuma lüüsi enda kirjetesse.

Silumise ajal printige perekond aadressi kõrvale, sest nende kahe lahknevus on tavaline usutava, kuid vale väärtuse põhjus. Vabastage puhver käsuga WTSFreeMemory finally-plokis, et erand seda ei lekitaks.

Eraldage teatatud aadress tõendist

Teatatud kliendi aadress on kliendi esitatud väide, mitte usaldusväärne vaatlus. See ei ole TCP vastaspool, mitte VPN-lüüsi renditabel ja mitte kliendi avalik aadress. Kui tegelik küsimus on, milline VPN-rendileping kuulub ühele inimesele, korreleerige samal ajal VPN-serveri autenditud seansikirjega. Kui küsimus on, milline allikas jõudis kuulajani, lugege ühenduste tabelit või lubatud serveripoolseid logisid.

Hoidke neid väärtusi igas tugitööriistas eraldi märgistatuna. Puuduv WTS-tulemus peaks jääma puuduvaks, selle asemel et langeda tagasi teise seansi suvalisele registriväärtusele. Logige seansi-ID aadressi kõrvale, sest sama kasutaja võib uuesti ühenduda ja saada uue väärtuse. Ei kliendi nimi ega teatatud aadress ei ole piisav tõend juurdepääsu andmiseks.

Seotud artiklid