تحتاج جلسة RDP إلى عنوان عميل، والمصادر الواضحة تختلف. يمنح CLIENTNAME اسم حاسوب، ويحتفظ السجل بقيم من جلسات أخرى، وقد يكون نظير المقبس عنوان بوابة أو NAT بدلًا من العميل. يكشف Windows بالفعل عن عنوان عميل مُبلَّغ عنه لكل جلسة، لكن عليك أن تطلب الجلسة الصحيحة وأن تفك ترميز الرد بشكل صحيح.

ثبّت البحث على جلسة واحدة

ابدأ بالجلسة، لا بالشخص. يمكن لمضيف RDP يعمل بنظام Windows أن يحمل عدة جلسات لحساب واحد، وقد لا يطابق عنوان رُصد قبل إعادة الاتصال الرابط الحالي بعد الآن. سجّل معرّف الجلسة والمستخدم ووقت الرصد معًا. معرّف الجلسة هو المفتاح الذي تتوقعه الواجهة، وهو القيمة التي تمنع الخلط بين جلستين.

على المضيف، تسرد أدوات الجلسات المثبّتة ما هو موجود؛ استخدم العرض الإداري فقط عندما تكون مخوّلًا به. أكّد المعرّف المختار فورًا قبل الاستعلام، لأن المعرّف المُعاد استخدامه يعيد بيانات جلسة مختلفة.

qwinsta

استدعِ WTSQuerySessionInformationW لهذا المعرّف

تجيب واجهة خدمات الطرفية على السؤال بفئة المعلومات 14، WTSClientAddress. غلاف ctypes صغير يكفي على Windows، ويتجنب قراءة خلية مستخدم آخر. يأخذ الكود أدناه معرّف جلسة صريحًا ويسأل المضيف المحلي.

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)

مرّر معرّف الجلسة الصحيح الذي تحققت منه للتو، واحتفظ بمقبض الخادم الفارغ للجهاز المحلي. عامل الاستدعاء الفاشل كخطأ لا كعنوان غائب، لأن الاثنين يؤديان إلى استنتاجات مختلفة. يتطلب الاستعلام عن جلسة مستخدم آخر إذن Query Information المناسب، فشغّل الأداة بحساب مُنح ذلك الإذن بدلًا من التصعيد العشوائي. المخزن المؤقت المُعاد يخص الواجهة ويجب تحريره حتى عندما يفشل فك الترميز.

فك ترميز العائلة ثم حرّر المخزن المؤقت

البنية ليست سلسلة IP. يحدد حقل العائلة كيف تُقرأ بايتات العنوان العشرين: يبدأ IPv4 عند الإزاحة اثنين، بينما يبدأ IPv6 عند الإزاحة صفر. العنوان غير المحدد يعني أن العميل لم يبلّغ عن عنوان، وهذا ليس نفس السلسلة الفارغة. اتصالات بوابة سطح المكتب البعيد موثّقة كحالة لا يتوفر فيها العنوان، لذا لا تبلّغ جلسة تمر عبر بوابة عن أي شيء مفيد للعنوان الحقيقي للعميل. عندئذ يجب أن ينتقل الربط إلى سجلات البوابة نفسها.

اطبع العائلة إلى جانب العنوان أثناء التصحيح، لأن عدم التطابق بينهما هو السبب المعتاد لقيمة معقولة لكنها خاطئة. حرّر المخزن المؤقت باستخدام WTSFreeMemory داخل كتلة finally حتى لا يسرّبه استثناء.

افصل العنوان المُبلَّغ عنه عن البرهان

العنوان المُبلَّغ عنه للعميل عبارة يقدّمها العميل، وليس رصدًا موثوقًا. إنه ليس نظير TCP، ولا جدول إيجارات بوابة VPN، ولا العنوان العام للعميل. عندما يكون السؤال الحقيقي أي إيجار VPN يخص شخصًا ما، اربط سجل الجلسة الموثّق لخادم VPN في الوقت نفسه. وعندما يكون السؤال أي مصدر وصل إلى المستمع، اقرأ جدول الاتصالات أو السجلات المسموح بها على جانب الخادم.

أبقِ هذه القيم موسومة بشكل منفصل في أي أداة دعم. يجب أن تبقى نتيجة WTS المفقودة مفقودة بدلًا من الرجوع إلى قيمة سجل عشوائية من جلسة أخرى. سجّل معرّف الجلسة بجوار العنوان، لأن المستخدم نفسه يمكنه إعادة الاتصال والحصول على قيمة جديدة. لا اسم العميل ولا العنوان المُبلَّغ عنه دليل كافٍ لمنح الوصول.

مقالات ذات صلة