RDP seansi mijoz manzilini talab qiladi va ko'rinib turgan manbalar bir-biriga mos kelmaydi. CLIENTNAME kompyuter nomini beradi, ro'yxatga olish kitobi boshqa seanslarning qiymatlarini saqlaydi, soketning qarama-qarshi tomoni esa mijoz emas, shlyuz yoki NAT manzili bo'lishi mumkin. Windows har bir seans uchun xabar qilingan mijoz manzilini haqiqatan taqdim etadi, lekin to'g'ri seansni so'rash va javobni to'g'ri dekodlash kerak.

Qidiruvni bitta seansga bog'lang

Odamdan emas, seansdan boshlang. Windows RDP xosti bitta hisob uchun bir nechta seansni olib yurishi mumkin va qayta ulanishdan oldin ko'rilgan manzil endi faol ulanishga mos kelmasligi mumkin. Seans ID sini, foydalanuvchini va kuzatuv vaqtini birga yozib oling. Seans ID si API kutgan kalit va aynan shu qiymat ikki seansning chalkashishini oldini oladi.

Xostda o'rnatilgan seans vositalari nima borligini sanab o'tadi; ma'muriy ko'rinishdan faqat unga haqli bo'lganda foydalaning. Tanlangan ID ni so'rovdan darhol oldin tasdiqlang, chunki qayta ishlatilgan ID boshqa seansning ma'lumotlarini qaytaradi.

qwinsta

O'sha ID uchun WTSQuerySessionInformationW ni chaqiring

Terminal Services API savolga 14-ma'lumot sinfi bilan javob beradi, WTSClientAddress. Windows da kichik ctypes o'rami yetarli va u boshqa foydalanuvchining hive ini o'qishdan saqlaydi. Quyidagi kod aniq seans ID sini oladi va mahalliy xostdan so'raydi.

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)

Hozir tekshirgan butun sonli seans ID sini uzating va mahalliy mashina uchun nol server tutqichini saqlang. Muvaffaqiyatsiz chaqiruvni yo'q manzil emas, xato deb qabul qiling, chunki ikkisi turli xulosalarga olib keladi. Boshqa foydalanuvchining seansini so'rash tegishli Query Information ruxsatini talab qiladi, shuning uchun vositani ad hoc imtiyozlarni oshirish o'rniga shu ruxsat berilgan hisob ostida ishga tushiring. Qaytarilgan bufer API ga tegishli va dekodlash muvaffaqiyatsiz bo'lsa ham bo'shatilishi kerak.

Oilani dekodlang, so'ng buferni bo'shating

Tuzilma IP satri emas. Uning oila maydoni yigirma manzil baytini qanday o'qishni belgilaydi: IPv4 ikkinci ofsetdan boshlanadi, IPv6 esa nol ofsetdan boshlanadi. Aniqlanmagan manzil mijoz hech qanday manzil xabar qilmaganini bildiradi, bu bo'sh satr bilan bir xil emas. Remote Desktop Gateway ulanishlari manzil mavjud bo'lmagan holat sifatida hujjatlashtirilgan, shuning uchun shlyuz orqali o'tadigan seans mijozning haqiqiy manzili haqida foydali hech narsa xabar qilmaydi. Keyin korrelyatsiya shlyuzning o'z yozuvlariga o'tishi kerak.

Nosozliklarni tuzatishda oilani manzil yonida chop eting, chunki ikkisi orasidagi nomuvofiqlik ishonchli ko'rinadigan, ammo noto'g'ri qiymatning odatiy sababi. Buferni finally blokida WTSFreeMemory bilan bo'shating, shunda istisno uni oqizib yubormaydi.

Xabar qilingan manzilni dalildan ajrating

Xabar qilingan mijoz manzili mijoz taqdim etgan bayonot, ishonchli kuzatuv emas. Bu TCP ning qarama-qarshi tomoni emas, VPN shlyuzining ijara jadvali emas va mijozning ommaviy manzili emas. Haqiqiy savol qaysi VPN ijara qaysi shaxsga tegishli ekani bo'lsa, ayni vaqtda VPN serverining autentifikatsiya qilingan seans yozuvini korrelyatsiya qiling. Savol qaysi manba tinglovchiga yetib kelgani bo'lsa, ulanish jadvalini yoki ruxsat etilgan server tomonidagi jurnallarni o'qing.

Bu qiymatlarni har qanday yordam vositasida alohida belgilangan holda saqlang. Yo'q WTS natijasi boshqa seansdan olingan ixtiyoriy ro'yxatga olish kitobi qiymatiga qaytish o'rniga yo'q bo'lib qolishi kerak. Seans ID sini manzil yonida jurnalga yozing, chunki o'sha foydalanuvchi qayta ulanib yangi qiymat olishi mumkin. Mijoz nomi ham, xabar qilingan manzil ham kirish berish uchun yetarli dalil emas.

O'xshash maqolalar