Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2024-20698 — Analyse de la vulnérabilité | Kitploit
Outils/GitHubGitHub/romanrybachek/cve-2024-20698
Analyse des VulnérabilitésAnalyse de CodeExploitationRétro-ingénierieAnalyse de Binaires
GitHubromanrybachek/cve-2024-20698

CVE-2024-20698

Analyse de la vulnérabilité

Voir le dépôt
5173il y a 2 ansVérifié par Kitploit

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

CVE-2024-20698

À propos de cette vulnérabilité : https://msrc.microsoft.com/update-guide/vulnerability/CVE-2024-20698

Analyse du correctif

Dans ntoskrnl.exe, nous avons deux fonctions corrigées : sub_1406AE224 et WbAddLookupEntryEx. La fonction vulnérable est WbAddLookupEntryEx. Chemins vers cette fonction :

schéma

Pour appeler cette fonction, nous devons appeler NtQuerySystemInformation avec le premier argument 0xb9. Le premier octet du tampon fourni par l'utilisateur comme deuxième argument est une option pour ce commutateur :

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;
}
Télécharger l’outil

Pour chaque processus qui utilise NtQuerySystemInformation avec l'argument 0xb9, une structure sera créée et stockée en mémoire jusqu'à la fin du processus. J'ai appelé cette structure item_instance. D'abord, la fonction sub_1406AF294 essaie de trouver la structure du processus parmi d'autres structures similaires. Les pointeurs vers ces structures sont stockés en mémoire dans l'ordre des ID de processus. Si la structure n'est pas trouvée, elle sera créée par WbCreateWarbirdProcess. Ensuite, un pointeur vers cette structure sera ajouté au tableau en utilisant WbAddLookupEntryEx qui est vulnérable.
Le code de WbAddLookupEntryEx avant le correctif :

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

Il réalloue le tableau de pointeurs et insère un nouveau pointeur.

Le correctif ajoute ces vérifications de sécurité :

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;

Cela sécurise les opérations d'addition et de multiplication contre les débordements. Ainsi, dans la version non corrigée, nous pouvons obtenir un débordement d'entier dans ces cas :

  • 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

Après le débordement d'entier, le tableau de pointeurs sera réalloué, mais avec une taille plus petite. Ensuite, memmove tentera de décaler les éléments pour faire de la place au nouvel élément. Ainsi, il corrompra les blocs situés après le nouveau bloc alloué. Pour déclencher un débordement d'entier, nous devons créer 0xffffffff / size_of_item + 1 structures. size_of_item est toujours 8. Donc, nous devons créer 0x20000001 structures. Chaque structure représente un processus. Nous devons donc avoir 0x20000001 (536870913) processus concurrents. Sur ma machine virtuelle, je n'ai pu créer que 12492 processus concurrents et 39652 sur ma machine hôte.