RDP сессиясына клиент мекенжайы қажет, ал айқын дереккөздер келіспейді. CLIENTNAME компьютер атауын береді, тіркелім басқа сессиялардың мәндерін сақтайды, ал сокеттің қарсы жағы клиент емес, шлюз немесе NAT мекенжайы болуы мүмкін. Windows әр сессия үшін хабарланған клиент мекенжайын шынымен ұсынады, бірақ дұрыс сессияны сұрап, жауапты дұрыс декодтау керек.

Іздеуді бір сессияға байлаңыз

Адамнан емес, сессиядан бастаңыз. Windows RDP хосты бір тіркелгі үшін бірнеше сессияны ұстай алады, ал қайта қосылу алдында көрінген мекенжай белсенді байланысқа енді сәйкес келмеуі мүмкін. Сессия ID-ін, пайдаланушыны және бақылау уақытын бірге жазып алыңыз. Сессия ID-і API күтетін кілт және екі сессияны шатастырмайтын мән де сол.

Хостта орнатылған сессия құралдары барды тізімдейді; әкімшілік көріністі оған құқығыңыз болғанда ғана қолданыңыз. Таңдалған ID-ді сұраудан бірден бұрын растаңыз, өйткені қайта пайдаланылған ID басқа сессияның деректерін қайтарады.

qwinsta

Сол ID үшін WTSQuerySessionInformationW шақырыңыз

Terminal Services API сұраққа 14-ақпарат класымен жауап береді, WTSClientAddress. Windows-та шағын ctypes қаптамасы жеткілікті және ол басқа пайдаланушының hive-ін оқудан сақтайды. Төмендегі код айқын сессия ID-ін қабылдап, жергілікті хосттан сұрайды.

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)

Жаңа ғана тексерген бүтін санды сессия ID-ін беріңіз және жергілікті машина үшін нөлдік сервер дескрипторын сақтаңыз. Сәтсіз шақыруды жоқ мекенжай ретінде емес, қате ретінде қабылдаңыз, өйткені екеуі әртүрлі қорытындыға әкеледі. Басқа пайдаланушының сессиясын сұрау тиісті Query Information рұқсатын талап етеді, сондықтан құралды ad hoc құқық көтерудің орнына сол рұқсат берілген тіркелгімен іске қосыңыз. Қайтарылған буфер API-ге тиесілі және декодтау сәтсіз болса да босатылуы керек.

Отбасын декодтаңыз, содан кейін буферді босатыңыз

Құрылым IP жолы емес. Оның отбасы өрісі жиырма мекенжай байтының қалай оқылатынын анықтайды: IPv4 екі ығысудан басталады, ал IPv6 нөл ығысудан басталады. Анықталмаған мекенжай клиент оны хабарламағанын білдіреді, бұл бос жолмен бірдей емес. Remote Desktop Gateway қосылымдары мекенжай қолжетімсіз болатын жағдай ретінде құжатталған, сондықтан шлюз арқылы өтетін сессия клиенттің нақты мекенжайы туралы пайдалы ештеңе хабарламайды. Содан кейін корреляция шлюздің өз жазбаларына ауысуы керек.

Жөндеу кезінде отбасын мекенжайдың қасында басып шығарыңыз, өйткені екеуі арасындағы сәйкессіздік сенімді болып көрінетін, бірақ қате мәннің әдеттегі себебі. Буферді finally блогында WTSFreeMemory арқылы босатыңыз, сонда ерекшелік оны ағызбайды.

Хабарланған мекенжайды дәлелден ажыратыңыз

Хабарланған клиент мекенжайы — клиент ұсынған мәлімдеме, сенімді бақылау емес. Ол TCP-нің қарсы жағы емес, VPN шлюзінің жалдау кестесі емес және клиенттің ашық мекенжайы емес. Нақты сұрақ қандай VPN жалдауы адамға тиесілі екенін білу болса, сол уақытта VPN серверінің аутентификацияланған сессия жазбасын корреляциялаңыз. Сұрақ қай дереккөз тыңдаушыға жеткенін білу болса, қосылым кестесін немесе рұқсат етілген сервер жақ журналдарын оқыңыз.

Бұл мәндерді кез келген қолдау құралында бөлек белгіленген күйде ұстаңыз. Жоқ WTS нәтижесі басқа сессиядан алынған кездейсоқ тіркелім мәніне оралмай, жоқ күйінде қалуы керек. Сессия ID-ін мекенжайдың қасында журналға жазыңыз, өйткені сол пайдаланушы қайта қосылып, жаңа мән ала алады. Клиент атауы да, хабарланған мекенжай да кіру беру үшін жеткілікті дәлел емес.

Қатысты мақалалар