Një sesion RDP ka nevojë për një adresë klienti, dhe burimet e dukshme nuk pajtohen. CLIENTNAME jep një emër kompjuteri, regjistri mban vlera nga sesione të tjera, dhe pala tjetër e socket-it mund të jetë një adresë gateway ose NAT në vend të klientit. Windows vërtet ekspozon një adresë klienti të raportuar për çdo sesion, por duhet të kërkoni sesionin e saktë dhe ta dekodoni përgjigjen saktë.

Ankoroni kërkimin në një sesion të vetëm

Filloni me sesionin, jo me personin. Një host RDP i Windows mund të mbajë disa sesione për një llogari, dhe një adresë e parë përpara një rilidhjeje mund të mos përputhet më me lidhjen aktive. Shënoni bashkë ID-në e sesionit, përdoruesin dhe momentin e vëzhgimit. ID-ja e sesionit është çelësi që pret API-ja, dhe është vlera që pengon ngatërrimin e dy sesioneve.

Në host, mjetet e instaluara të sesioneve rendisin çfarë ekziston; përdorni pamjen administrative vetëm kur keni të drejtë për të. Konfirmoni ID-në e zgjedhur menjëherë përpara kërkesës, sepse një ID e ricikluar kthen të dhënat e një sesioni tjetër.

qwinsta

Thirrni WTSQuerySessionInformationW për atë ID

API e Terminal Services përgjigjet pyetjes me klasën e informacionit 14, WTSClientAddress. Një mbështjellës i vogël ctypes mjafton në Windows, dhe shmang leximin e hive-it të një përdoruesi tjetër. Kodi më poshtë merr një ID sesioni të qartë dhe pyet hostin lokal.

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)

Kaloni ID-në e sesionit si numër i plotë që sapo verifikuat, dhe mbani dorezën nule të serverit për makinën lokale. Trajtoni një thirrje të dështuar si gabim dhe jo si adresë që mungon, sepse të dyja çojnë në përfundime të ndryshme. Kërkimi për sesionin e një përdoruesi tjetër kërkon lejen përkatëse Query Information, prandaj ekzekutoni mjetin nën një llogari që e ka marrë atë, në vend që të rrisni privilegjet ad hoc. Buferi i kthyer i përket API-së dhe duhet të lirohet edhe kur dekodimi dështon.

Dekodoni familjen, pastaj lironi buferin

Struktura nuk është një varg IP. Fusha e familjes vendos si lexohen njëzet bajtët e adresës: IPv4 fillon në offsetin dy, ndërsa IPv6 fillon në offsetin zero. Adresa e pacaktuar do të thotë që klienti nuk raportoi asnjë, gjë që nuk është e njëjtë me një varg bosh. Lidhjet përmes Remote Desktop Gateway janë dokumentuar si një rast ku adresa nuk është e disponueshme, prandaj një sesion i ndërmjetësuar nga gateway nuk raporton asgjë të dobishme për adresën reale të klientit. Atëherë korrelacioni duhet të kalojë te regjistrat e vetë gateway-it.

Printo familjen pranë adresës gjatë korrigjimit, sepse mospërputhja midis të dyjave është shkaku i zakonshëm i një vlere të besueshme por të gabuar. Lironi buferin me WTSFreeMemory në një bllok finally, që një përjashtim të mos e rrjedhë.

Ndani adresën e raportuar nga prova

Një adresë klienti e raportuar është një deklaratë që jep klienti, jo një vëzhgim i besueshëm. Nuk është pala tjetër e TCP-së, nuk është tabela e qirasë e gateway-it VPN dhe nuk është adresa publike e klientit. Kur pyetja e vërtetë është cila qira VPN i takon një personi, korreloni në të njëjtën kohë regjistrin e autentifikuar të sesionit të serverit VPN. Kur pyetja është cili burim arriti te dëgjuesi, lexoni tabelën e lidhjeve ose regjistrat e lejuar në anën e serverit.

Mbani këto vlera të etiketuara veçmas në çdo mjet mbështetjeje. Një rezultat WTS që mungon duhet të mbetet i mangët në vend që të bjerë mbrapsht në një vlerë arbitrare regjistri nga një sesion tjetër. Regjistroni ID-në e sesionit pranë adresës, sepse i njëjti përdorues mund të rilidhet dhe të marrë një vlerë të re. As emri i klientit dhe as adresa e raportuar nuk janë provë e mjaftueshme për të dhënë akses.

Artikuj të ngjashëm