Skip to content
KitploitKITPLOIT
ツールブログ
提出
ツールブログ
提出

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

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

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

ツールディレクトリ

カテゴリ

すべてのカテゴリを見る
Loading categories
CVE-2024-20698 — 脆弱性の分析 | Kitploit
ツール/GitHubGitHub/romanrybachek/cve-2024-20698
脆弱性分析コード分析エクスプロイトリバースエンジニアリングバイナリ解析
GitHubromanrybachek/cve-2024-20698

CVE-2024-20698

脆弱性の分析

リポジトリを見る
51732年前Kitploit レビュー済み

人気

すべて見る →

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

すべてのツールを探索

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

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

CVE-2024-20698

この脆弱性について: https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-20698

パッチの分析

ntoskrnl.exe には、パッチが適用された2つの関数があります: sub_1406AE224 と WbAddLookupEntryEx。脆弱な関数は WbAddLookupEntryEx です。この関数へのパス:

drawing

この関数を呼び出すには、最初の引数 0xb9 を指定して NtQuerySystemInformation を呼び出す必要があります。ユーザーが2番目の引数として提供するバッファの最初のバイトが、このスイッチのオプションです:

root@kitploit:~
switch ( first_byte_in_usermod_buf )
{
    case 1:
      status_1 = WbDecryptEncryptionSegment(item, copy_of_usermod_buf, NumberOfBytes_1);
      goto set_status_and_return;
    case 2:
      status_1 = WbReEncryptEncryptionSegment(item, copy_of_usermod_buf, NumberOfBytes_1);
      goto set_status_and_return;
    case 3:
      status_1 = WbHeapExecuteCall(item, copy_of_usermod_buf, usermod_buffer, NumberOfBytes_1);
      goto set_status_and_return;
    case 4:
      if ( !copy_of_usermod_buf )
      {
        status_1 = patched_case4_no_user_buffer(item, another_item);
set_status_and_return:
        status = status_1;
        goto return;
      }
      break;
    case 5:
    case 6:
      status = usermod_buffer != 0i64 ? STATUS_NOT_IMPLEMENTED : STATUS_INVALID_PARAMETER;
      goto return;
    case 7:
      status_1 = WbRemoveWarbirdProcess(item->proc_handle);
      goto set_status_and_return;
    case 8:
      status_1 = WbProcessStartup(item, copy_of_usermod_buf, NumberOfBytes_1);
      goto set_status_and_return;
    case 9:
      status_1 = WbProcessModuleUnload(item, copy_of_usermod_buf, NumberOfBytes_1);
      goto set_status_and_return;
}
ツールをダウンロード

引数0xb9で NtQuerySystemInformation を使用する各プロセスに対して、プロセスが終了するまでメモリに保存される構造体が作成されます。この構造体を item_instance と呼びます。まず、関数 sub_1406AF294 が他のそのような構造体の中からプロセスの構造体を探そうとします。これらの構造体へのポインタは、プロセスIDの順にメモリに保存されます。構造体が見つからない場合は、WbCreateWarbirdProcess によって作成されます。次に、この構造体へのポインタが脆弱な WbAddLookupEntryEx を使用して配列に追加されます。
パッチ適用前の WbAddLookupEntryEx のコード:

root@kitploit:~
NTSTATUS WbAddLookupEntryEx(
        items_info *items_info,
        __int64 new_item_pointer,
        __int64 not_used,
        unsigned int new_item_index)
{
  unsigned int last_item_index;
  NTSTATUS status;
  unsigned int old_items_count;
  unsigned int size_of_item;

  last_item_index = items_info->last_item_index;
  status = 0;
  old_items_count = items_info->old_items_count;

  if ( last_item_index + 1 >= old_items_count )
  {
    status = WbReAlloc(
               items_info->vuln_buffer,
               old_items_count * items_info->size_of_item,
               items_info->size_of_item * (old_items_count + items_info->count_of_new_items),
               &items_info->vuln_buffer);

    if ( status < 0 )
      return status;

    items_info->old_items_count += items_info->count_of_new_items;
    old_items_count = items_info->old_items_count;
    last_item_index = items_info->last_item_index;
  }

  if ( new_item_index > last_item_index || !old_items_count )
    return STATUS_INVALID_PARAMETER;
  memmove(
    (char *)items_info->vuln_buffer + (new_item_index + 1) * items_info->size_of_item,
    (char *)items_info->vuln_buffer + new_item_index * items_info->size_of_item,
    items_info->size_of_item * (last_item_index - new_item_index));

  size_of_item = items_info->size_of_item;
  ++items_info->last_item_index;
  *(_QWORD *)((char *)items_info->vuln_buffer + new_item_index * size_of_item) = new_item_pointer;
  return status;
}

これはポインタの配列を再割り当てし、新しいポインタを挿入します。

パッチでは次のセキュリティチェックが追加されています:

root@kitploit:~
status = RtlULongMult(old_items_count, items_info->size_of_item, &size_of_old_items);
if ( status < 0 )
  return status;
status = RtlULongAdd(old_items_count, items_info->count_of_new_items, &sum_result);
if ( status < 0 )
  return status;
status = RtlULongMult(sum_result, mb_item_size, result_size_8byte);
if ( status < 0 )
  return status;

これにより、加算と乗算の操作がオーバーフローに対して安全になります。そのため、パッチ未適用バージョンでは、次の場合に整数オーバーフローが発生する可能性があります:

  • old_items_count * size_of_item > 0xffffffff
  • old_items_count + count_of_new_items > 0xffffffff
  • (old_items_count + count_of_new_items) * size_of_item > 0xffffffff

整数オーバーフローの後、ポインタの配列は再割り当てされますが、サイズは小さくなります。そして、memmove は新しい要素のためのスペースを作るために要素をシフトしようとします。そのため、新しく割り当てられたチャンクの後に続くチャンクが破壊されます。 整数オーバーフローをトリガーするには、0xffffffff / size_of_item + 1 個の構造体を作成する必要があります。size_of_item は常に8です。したがって、0x20000001 個の構造体を作成する必要があります。各構造体はプロセスを表します。つまり、0x20000001 (536870913) 個の同時プロセスが必要です。私の仮想マシンでは12492個の同時プロセスしか作成できませんでしたが、ホストマシンでは39652個作成できました。