Akú adresu hlási Windows pre reláciu RDP?
Rozhranie WTS API vracia hlásenú adresu klienta pre jednu reláciu RDP, register nie. Pýtajte sa na správne ID relácie a správne dekódujte IPv4 alebo IPv6.
Relácia RDP potrebuje adresu klienta a zrejmé zdroje sa nezhodujú. CLIENTNAME dáva názov počítača, register drží hodnoty z iných relácií a protiľahlá strana socketu môže byť adresa brány alebo NAT, nie klienta. Windows síce zverejňuje hlásenú adresu klienta pre každú reláciu, ale treba sa opýtať správnej relácie a odpoveď správne dekódovať.
Ukotvite hľadanie k jednej relácii
Začnite reláciou, nie osobou. Hostiteľ RDP v systéme Windows môže niesť viac relácií pre jeden účet a adresa videná pred opätovným pripojením už nemusí zodpovedať živému spojeniu. Zaznamenajte ID relácie, používateľa a čas pozorovania spolu. ID relácie je kľúč, ktorý API očakáva, a je to hodnota, ktorá bráni zámene dvoch relácií.
Na hostiteľovi nainštalované nástroje relácií vypisujú, čo existuje; administratívne zobrazenie používajte len vtedy, keď naň máte nárok. Potvrďte zvolené ID tesne pred dotazom, pretože recyklované ID vracia údaje inej relácie.
qwinsta
Zavolajte WTSQuerySessionInformationW pre toto ID
API Služieb terminálu odpovedá na otázku informačnou triedou 14, WTSClientAddress. Malý obal ctypes na Windows stačí a vyhne sa čítaniu hive iného používateľa. Kód nižšie preberá explicitné ID relácie a pýta sa miestneho hostiteľa.
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)
Odovzdajte celočíselné ID relácie, ktoré ste práve overili, a ponechajte nulový handle servera pre miestny stroj. Neúspešné volanie berte ako chybu, nie ako chýbajúcu adresu, pretože obe vedú k rôznym záverom. Dotaz na reláciu iného používateľa vyžaduje príslušné oprávnenie Query Information, preto nástroj spúšťajte pod účtom, ktorému bolo udelené, namiesto ad hoc eskalácie. Vrátený buffer patrí API a musí sa uvoľniť aj vtedy, keď dekódovanie zlyhá.
Dekódujte rodinu a potom uvoľnite buffer
Štruktúra nie je IP reťazec. Jej pole rodiny rozhoduje, ako sa číta dvadsať bajtov adresy: IPv4 začína na offsete dva, zatiaľ čo IPv6 na offsete nula. Nezadaná adresa znamená, že ju klient nenahlásil, čo nie je to isté ako prázdny reťazec. Pripojenia cez Remote Desktop Gateway sú dokumentované ako prípad, keď adresa nie je dostupná, takže relácia cez bránu nehlási nič užitočné o skutočnej adrese klienta. Korelácia sa potom musí presunúť do vlastných záznamov brány.
Počas ladenia tlačte rodinu vedľa adresy, pretože nezhoda medzi oboma je obvyklou príčinou vierohodnej, ale nesprávnej hodnoty. Uvoľnite buffer pomocou WTSFreeMemory v bloku finally, aby ho výnimka nepresiakla.
Oddeľte hlásenú adresu od dôkazu
Hlásená adresa klienta je tvrdenie, ktoré poskytol klient, nie dôveryhodné pozorovanie. Nie je to protiľahlá strana TCP, nie je to tabuľka prenájmov brány VPN a nie je to verejná adresa klienta. Keď je skutočnou otázkou, ktorý prenájom VPN patrí nejakej osobe, korelujte v tom istom čase overený záznam relácie servera VPN. Keď je otázkou, ktorý zdroj dosiahol poslucháča, čítajte tabuľku spojení alebo povolené záznamy na strane servera.
Tieto hodnoty držte v každom podpornom nástroji označené oddelene. Chýbajúci výsledok WTS má zostať chýbajúci, namiesto toho aby sa nahradil ľubovoľnou hodnotou registra z inej relácie. Zaznamenajte ID relácie vedľa adresy, pretože ten istý používateľ sa môže znova pripojiť a dostať novú hodnotu. Ani meno klienta, ani hlásená adresa nie sú dostatočným dôkazom na udelenie prístupu.