Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2025-47810 — PunkBuster LPI to NT AUTHORITY\SYSTEM | Kitploit
Tools/GitHubGitHub/ptrstr/cve-2025-47810
Privilege EscalationVulnerability AnalysisExploitationLateral MovementBinary Analysis
GitHubptrstr/cve-2025-47810

CVE-2025-47810

PunkBuster LPI to NT AUTHORITY\SYSTEM

Repository anzeigen
vor 11 MonatenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

PunkBuster LPI (CVE-2025-47810)

Screenshot

Hintergrund

PunkBuster installiert sich selbst als zwei Dienste und einen optionalen? Kernel-Treiber.

  • PnkBstrA: Dienst, der ständig im Hintergrund läuft und für die allgemeine Verwaltung von PunkBuster zuständig ist
  • PnkBstrB: Dienst, der startet, wenn ein geschütztes Spiel gestartet wird. Bietet mehr Funktionalität als sein Gegenstück A.

Beide Dienste sind ähnlich aufgebaut und hören auf UDP auf localhost auf einem Port im Bereich [44301, 44400]. Sobald ein Port gefunden wurde, wird er im Port-Wert unter HKLM:\SOFTWARE\Even Balance\PnkBstrA oder HKLM:\SOFTWARE\WOW6432Node\Even Balance\PnkBstrA geschrieben.

Jede Anfrage wird in einem globalen Puffer mit einer Länge von 1500 Bytes gespeichert (es werden jedoch nur 1499 Bytes empfangen, um einen NUL-Terminator unterzubringen).

Es gibt keine Standardstruktur für die Anfragedaten, aber hier ist ihre übliche Struktur:

  • erstes Byte (normalerweise ein Buchstabe), das angibt, welche Funktionalität aufgerufen werden soll
  • Argumente für die Funktionalität, normalerweise durch Leerzeichen getrennt, falls mehrere benötigt werden

Die Anfragearten in PnkBstrA sind wie folgt:

  • l: Load: Startet und aktualisiert PnkBstrB
    • Nimmt ein (optionales) Argument, den Pfad zur aktualisierten PnkBstrB-Executable
  • u: Unload: Stoppt PnkBstrB
  • v: Version: Gibt einfach die Version zurück
  • m: Monitor: Nimmt eine PID und prüft, ob die PunkBuster-Client-DLL (pbcl.dll) im Prozess vorhanden ist, und gibt bei Bedarf dessen Speicher aus.

Schwachstelle

Der Load-Handler (l) enthält eine Schwachstelle im TOCTOU-Stil, die zu einer lokalen Privilegienausweitung als NT AUTHORITY\SYSTEM führt.

Der Ablauf des Handlers ist etwa wie folgt:

  1. Den PnkBstrB-Dienst löschen
  2. Den MD5 der Datei im Argument berechnen, falls vorhanden
  3. Authenticode und Zertifikate der ausführbaren Datei im Argument validieren, falls vorhanden
    • Unter anderem prüfen, ob der Betreff des Zertifikats Even Balance, Inc. lautet
  4. Zwischen 750 ms und 2,25 s pausieren, ohne Dateihandles, während versucht wird, die Datei im Argument nach C:\Windows\SysWOW64\PnkBstrB.exe oder C:\Windows\System32\PnkBstrB.exe (je nach Plattform) zu kopieren
  5. Den MD5 der in das Systemverzeichnis kopierten Datei berechnen
  6. Prüfen, ob beide MD5-Hashes übereinstimmen
    • Falls ja, den PnkBstrB-Dienst erstellen und starten, der als LocalSystem mit der neu kopierten Datei läuft.

Das Problem hier ist, dass die Datei, die PnkBstrA manipuliert, für jeden Vorgang mehrmals geöffnet wird, was zu einer Situation führt, in der ein Angreifer die Datei zwischen den Vorgängen ändern könnte.

Dies kann zu einem Problem führen, bei dem die Datei nach der Zertifikatsvalidierung ausgetauscht wird und eine schädliche Datei als ausführbare Datei des PnkBstrB-Dienstes landet. Diese ausführbare Datei würde es einem nicht privilegierten Benutzer ermöglichen, auf NT AUTHORITY\SYSTEM zu eskalieren.

Die relevante Dekompilierung ist hier dargestellt:

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);

    ...
}

Eine einfache Lösung wäre, die Datei zuerst an einen sicheren, aber temporären Speicherort zu kopieren (z.B. PnkBstrB.exe.tmp) und von dort aus den MD5 und die Prüfungen zu berechnen. Auf diese Weise kann die Datei nicht von einem böswilligen Akteur bearbeitet werden. Dies würde auch sicherstellen, dass nur eine Kopie der Datei geöffnet ist, was die SMB-Ausnutzung verhindert.

Ausnutzung

Ansatz 1

Ein Angriffsszenario könnte darin bestehen, eine schädliche Datei bereitzustellen, auf die Berechnung des MD5 zu warten, die Datei durch die originale PnkBstrB.exe zu ersetzen, damit die WinVerifyTrust- und Zertifikatsprüfungen bestehen, und sie dann erneut durch die schädliche Datei zu ersetzen, damit der zweite MD5 besteht und die Datei kopiert und ausgeführt wird.

Dieses Szenario ist jedoch sehr schwer auszuführen, da das Ersetzen der Datei schwierig ist und eine Änderung, während sie von PnkBstrA geöffnet ist, die Änderungen nicht zu übernehmen scheint. Das liegt daran, dass es schwierig ist, unseren Code im INJECTION POINT 1 wie im Code gezeigt zu planen. Es ist wahrscheinlich möglich, indem man viele zeitkritische Prioritäts-Threads verwendet, von denen einige ständig versuchen, die Datei zu ersetzen, und andere gleichzeitige Kerne in Busy-Waits blockieren.

Ansatz 2

Ein anderer Ansatz wäre, eine MD5-Kollision zwischen PnkBstrB und der schädlichen Datei zu erzwingen. Dies würde funktionieren, indem zuerst die legitime Datei als Kandidat für den ersten MD5 verwendet und auf das Zertifikat geprüft wird. Danach haben wir jedoch ein gutes Zeitfenster von 750 Millisekunden oder mehr, um die Datei durch unsere eigene zu ersetzen. Dann würde der zweite MD5 bestehen und unsere Datei würde eingeschleust. Während der Entwicklung war ich jedoch zu faul, auf eine Kollision zu warten, und entschied mich für einen anderen Ansatz.

Ansatz 3

Dieser Code ist Windows-abhängig und verwendet fopen, was auf Windows' eigene I/O-Funktionen abgebildet wird. Per Definition würde dies bedeuten, dass SMB-Freigaben zugänglich wären. Darüber hinaus erwähnt MSDN, dass dieses Verhalten unterstützt wird:

fopen akzeptiert UNC-Pfade und Pfade, die gemappte Netzlaufwerke betreffen, solange das System, das den Code ausführt, zum Zeitpunkt der Ausführung Zugriff auf die Freigabe oder das gemappte Laufwerk hat.

Das bedeutet, dass wir unseren ersten Ansatz verwenden könnten, aber da der Code von unserer SMB-Freigabe abhängig wäre, senden wir je nach Anzahl der Dateianfragen verschiedene Dateien.

Durch Modifikation von Impackets smbserver ist es möglich, dieses Verhalten zu erreichen. Die vollständige .patch-Datei ist hier zu finden. Die wichtigsten Änderungen sind:

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'

Wie Sie sehen können, senden wir dem Client die schädliche Datei, wenn es das erste Mal ist, dass wir die Datei öffnen (erster MD5) oder mindestens das achte Mal (Dateikopie und danach), während wir in anderen Fällen die Originaldatei senden.

Der Code der schädlichen Datei ist hier zu finden, ein einfacher Hello-World-Dienst mit einer Reverse Shell.

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

Offenlegung

EvenBalance wurde seit dem 15.02.2025 mehrfach auf verschiedenen Wegen kontaktiert, hat aber nicht geantwortet.

Diese Problem wurde am 10.05.2025 vollständig offengelegt.

Tool herunterladen