Skip to content
KitploitKITPLOIT
StrumentiBlog
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2025-21298 — Prova di concetto e dettagli per CVE-2025-21298 | Kitploit
Strumenti/GitHubGitHub/ynwarcs/cve-2025-21298
Memory ForensicsAnalisi delle VulnerabilitàExploitReverse EngineeringAnalisi di Binari
GitHubynwarcs/cve-2025-21298

CVE-2025-21298

Prova di concetto e dettagli per CVE-2025-21298

Vedi Repository
197491 anno faRevisionato da Kitploit

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

contenuto

Questa è una proof-of-concept per CVE-2025-21298 - Vulnerabilità di esecuzione remota di codice in Windows OLE (CVSS 9.8). Questa è una PoC di corruzione della memoria, non un exploit.

Diff completo della patch tramite ghidriff: LINK

vulnerabilità

La vulnerabilità si trova in ole32.dll!UtOlePresStmToContentsStm. Lo scopo della funzione è convertire i dati in un flusso "OlePres" all'interno di un archivio OLE in dati formattati opportunamente e inserirli nel flusso "CONTENTS" dello stesso archivio. Riceve un puntatore IStorage a un oggetto di archiviazione e tre argomenti piuttosto irrilevanti.

Di seguito possiamo vedere l'implementazione della funzione con un diff della patch di gennaio 2025:

root@kitploit:~
__int64 __fastcall UtOlePresStmToContentsStm(IStorage *pstg, wchar_t *puiStatus, __int64 a3, unsigned int *lpszPresStm)
{
  struct IStorageVtbl *lpVtbl; // rax
  int v7; // r14d
+ bool IsEnabled; // al
  IStream *v10; // rcx
  bool v11; // zf
  struct IStorageVtbl *v12; // rax
  int v13; // ebx
  HRESULT v14; // eax
  const wchar_t *v15; // rdx
  IStream *pstmContents; // [rsp+40h] [rbp-19h] BYREF
  IStream *pstmOlePres; // [rsp+48h] [rbp-11h] BYREF
  tagFORMATETC foretc; // [rsp+50h] [rbp-9h] BYREF
  tagHDIBFILEHDR hdfh; // [rsp+70h] [rbp+17h] BYREF

  *lpszPresStm = 0;
  lpVtbl = pstg->lpVtbl;
  pstmContents = 0LL;
  v7 = 1;
  // Create a "CONTENTS" stream in the storage and store it into pstmContents
  if ( (lpVtbl->CreateStream)(pstg, L"CONTENTS", 18LL, 0LL, 0, &pstmContents) )
    return 0LL;
  // Immediately release pstmContents, we're not going to be using it right now
  (pstmContents->lpVtbl->Release)(pstmContents);
+ IsEnabled = wil::details::FeatureImpl<__WilFeatureTraits_Feature_3047977275>::__private_IsEnabled(&`wil::Feature<__WilFeatureTraits_Feature_3047977275>::GetImpl'::`2'::impl);
+ v10 = pstmContents;
+ v11 = !IsEnabled;
  v12 = pstg->lpVtbl;
+ if ( !v11 )
+   v10 = 0LL;
+ pstmContents = v10;
  (v12->DestroyElement)(pstg, L"CONTENTS");
  v13 = (pstg->lpVtbl->OpenStream)(pstg, &OlePres, 0LL, 16LL, 0, &pstmOlePres);// 2nd option to fail -> no OlePres stream
  if ( v13 )
  {
    *lpszPresStm |= 1u;
    if ( (pstg->lpVtbl->OpenStream)(pstg, L"CONTENTS", 0LL, 16LL, 0, &pstmContents) )
    {
      *lpszPresStm |= 2u;
    }
    else
    {
      (pstmContents->lpVtbl->Release)(pstmContents);
+     wil::details::FeatureImpl<__WilFeatureTraits_Feature_3047977275>::__private_IsEnabled(&`wil::Feature<__WilFeatureTraits_Feature_3047977275>::GetImpl'::`2'::impl);
    }
    return v13;
  }
  foretc.ptd = 0LL;
  v13 = UtReadOlePresStmHeader(pstmOlePres, &foretc, 0LL, 0LL);
  if ( v13 >= 0 )
  {
    v13 = (pstmOlePres->lpVtbl->Read)(pstmOlePres, &hdfh, 16LL);
    if ( v13 >= 0 )
    {
      v13 = OpenOrCreateStream(pstg, L"CONTENTS", &pstmContents);
      if ( v13 < 0 )
      {
        *lpszPresStm |= 2u;
        goto $errRtn_197;
      }
      if ( foretc.dwAspect == 4 )
      {
        *lpszPresStm |= 4u;
        v7 = 0;
        v13 = 0;
        goto $errRtn_197;
      }
      if ( foretc.cfFormat == 8 )
      {
        v14 = UtDIBStmToDIBFileStm(pstmOlePres, hdfh.dwSize, pstmContents);
LABEL_19:
        v13 = v14;
        goto $errRtn_197;
      }
      if ( foretc.cfFormat == 3 )
      {
        v14 = UtMFStmToPlaceableMFStm(pstmOlePres, hdfh.dwSize, hdfh.dwWidth, hdfh.dwHeight, pstmContents);
        goto LABEL_19;
      }
      v13 = -2147221398;
    }
  }
$errRtn_197:
  if ( pstmOlePres )
    (pstmOlePres->lpVtbl->Release)(pstmOlePres);
  // Release pstmContents if it still exists, we need to clean up
  if ( pstmContents )
    (pstmContents->lpVtbl->Release)(pstmContents);
  if ( foretc.ptd )
    CoTaskMemFree(foretc.ptd);
  if ( v13 )
  {
    v15 = L"CONTENTS";
    goto LABEL_31;
  }
  if ( v7 )
  {
    v15 = &OlePres;
LABEL_31:
    (pstg->lpVtbl->DestroyElement)(pstg, v15);
  }
  return v13;
}

Il problema sta nella variabile pstmContents. Inizialmente viene usata per memorizzare il puntatore all'oggetto flusso "CONTENTS" creato all'inizio della funzione. Il flusso viene immediatamente distrutto dopo essere stato creato e il puntatore memorizzato in pstmContents viene rilasciato (il che lo dealloca in coml2.dll!ExposedStream::~ExposedStream). Tuttavia, la variabile contiene ancora il puntatore deallocato. Più avanti nella funzione, la variabile può essere riutilizzata per memorizzare di nuovo il puntatore al flusso "CONTENTS" - per questo motivo, alla fine della funzione c'è un codice di pulizia che rilascia il puntatore nel caso sia memorizzato nella variabile. Il codice non tiene conto del fatto che UtReadOlePresStmHeader potrebbe fallire - se ciò accade, pstmContents punterà ancora al puntatore deallocato e si arriverà al codice di pulizia, che rilascerà di nuovo il puntatore. Di conseguenza, si verifica una situazione di double-free.

Come si può vedere nel diff della patch, Microsoft ha risolto il problema impostando pstmContents a zero dopo che il puntatore che contiene inizialmente viene rilasciato.

Riproduzione

Nel repository è presente un file rtf che riproduce la vulnerabilità. Ho testato aprendo il file in MS Word, ma puoi testarlo anche con altre applicazioni che analizzano dati RTF (ad esempio outlook). Lo sfruttamento tramite altri formati che incorporano oggetti OLE potrebbe essere possibile; non ci ho provato.

Video:

poc.webm

Dettagli

Pubblicherò i dettagli più avanti.

Scarica lo strumento