{"id":5027,"date":"2025-01-29T09:33:07","date_gmt":"2025-01-29T08:33:07","guid":{"rendered":"https:\/\/security.humanativaspa.it\/?p=5027"},"modified":"2025-09-23T16:58:34","modified_gmt":"2025-09-23T16:58:34","slug":"cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2","status":"publish","type":"post","link":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/","title":{"rendered":"CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis &#8211; Part 2"},"content":{"rendered":"<p>In the <a href=\"https:\/\/hnsecurity.it\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-1\">previous article<\/a>, we discussed a vulnerability in the <em>LoadContainerQ()<\/em> function inside clfs.sys. The root cause of the vulnerability was <em>LoadContainerQ() <\/em>using a <em>CLFS_CONTAINER_CONTEXT.pContainer<\/em> without checking if <em>FlushImage()<\/em> invalidated the General Metadata Block.<\/p>\r\n<p>The previous article mentioned that it was possible to <strong>develop another exploit leveraging the patched vulnerability in <em>WriteMetadataBlock()<\/em><\/strong>. The aim of this article is to analyze the vulnerability in <em>WriteMetadataBlock()\u00a0<\/em>and develop another proof of concept exploit.<\/p>\r\n<p>The <em>Vulnerability Analysis<\/em> section describes the vulnerability and the <em>Exploitation <\/em>section describes how to exploit the vulnerability to obtain arbitrary read\/write in ring 0 and elevate privileges to system. <em>Limitations and Improvements <\/em>highlights some limitations of the existing PoC and provides some hints to improve it, while the <em>Patch Analysis <\/em>section briefly describes the patch applied by Microsoft. Finally, the <em>Detection<\/em> section provides some recommendations to <strong>detect exploitation of both vulnerabilities<\/strong>.<\/p>\r\n<p>As previously, the analysis was conducted on a <strong>Windows 11 23H2<\/strong> machine with the following hashes for ntoskrnl.exe and clfs.sys:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\" data-enlighter-theme=\"monokai\">PS C:\\Windows\\System32\\drivers&gt; Get-FileHash .\\clfs.sys\r\n\r\nAlgorithm       Hash                                                                   Path\r\n---------       ----                                                                   ----\r\nSHA256          B138C28F72E8510F9612D07D5109D73065CED6CBBF8079A663A1E0601FE0FBAA       C:\\Windows\\System32\\drivers\\c...\r\n\r\n\r\nPS C:\\Windows\\System32\\drivers&gt;<\/pre>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"powershell\" data-enlighter-theme=\"monokai\">PS C:\\Windows\\System32&gt; Get-FileHash .\\ntoskrnl.exe\r\n\r\nAlgorithm       Hash                                                                   Path\r\n---------       ----                                                                   ----\r\nSHA256          0CE15480462E9CD3F7CBF2D44D2E393CF5674EE1D69A3459ADFA0E913A7A2AEB       C:\\Windows\\System32\\ntoskrnl.exe\r\n\r\n\r\nPS C:\\Windows\\System32&gt;<\/pre>\r\n<p><em>Note: All code snippets provided here come from reverse engineering and may not be entirely accurate.<\/em><\/p>\r\n<h2>Vulnerability Analysis<\/h2>\r\n<p>The following screenshot shows the various CLFS_METADATA_BLOCK structures in <em>_CClfsBaseFilePersisted.m_rgBlocks:<\/em><\/p>\r\n<figure id=\"attachment_5068\" aria-describedby=\"caption-attachment-5068\" style=\"width: 1901px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5068 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-15_13_34-Clipboard-1.png\" alt=\"\" width=\"1901\" height=\"889\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-15_13_34-Clipboard-1.png 1901w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-15_13_34-Clipboard-1-300x140.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-15_13_34-Clipboard-1-1024x479.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-15_13_34-Clipboard-1-768x359.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-15_13_34-Clipboard-1-1536x718.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-15_13_34-Clipboard-1-350x164.png 350w\" sizes=\"(max-width: 1901px) 100vw, 1901px\" \/><figcaption id=\"caption-attachment-5068\" class=\"wp-caption-text\">General Metadata Block and Shadow in memory and reference counts<\/figcaption><\/figure>\r\n<p>It is important to notice that the <strong><em>pbImage\u00a0<\/em>of the original block and the one of the shadow block point to the same memory location<\/strong>. However, the <strong>reference count of a shadow block is<\/strong> <strong>always 0<\/strong> while the reference count of the original block is always higher than 1 and can increase.<\/p>\r\n<p>In fact, the screenshot shows that the General Metadata Block was loaded in memory at address 0xffffd400ef9a000 and the same address was set also for the corresponding shadow block. However, the reference count of the General Metadata Block is set to 1 while the reference count of General Metadata Block Shadow is set to 0.\u00a0<\/p>\r\n<h3>AddSymbol()<\/h3>\r\n<p>The <em>CClfsBaseFilePersisted::AddContainer()<\/em> function is responsible for adding a new container and is triggered through the user-space API <em><a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/clfsw32\/nf-clfsw32-addlogcontainer\">AddLogContainer()<\/a>:<\/em><\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">__int64 __fastcall CClfsBaseFilePersisted::AddContainer(\r\n        _CClfsBaseFilePersisted *this,\r\n        struct _UNICODE_STRING *container_name,\r\n        ULONGLONG *a3,\r\n        char a4,\r\n        unsigned __int8 arg20,\r\n        unsigned __int8 arg28,\r\n        struct _CLFS_CONTAINER_CONTEXT *a2)\r\n{\r\n[...]<br \/> a2-&gt;cidNode.cType = -1;<br \/>v11 = ExAcquireResourceExclusiveLite((PERESOURCE)this-&gt;m_presImage, 1u);<br \/>if ( !CClfsBaseFile::GetBaseLogRecord(this) )<br \/>goto LABEL_13;<br \/>if ( !RtlNumberOfClearBits(&amp;this-&gt;bitmap) )<br \/>{<br \/>ret = -1072037870;<br \/>goto LABEL_15;<br \/>}<br \/>ExReleaseResourceForThreadLite((PERESOURCE)this-&gt;m_presImage, (ERESOURCE_THREAD)KeGetCurrentThread());<br \/>ret = CClfsBaseFilePersisted::AddSymbol(<br \/>this,<br \/>container_name,<br \/>&amp;this-&gt;m_symtblContainer,<br \/>0x30,<br \/>&amp;hashsym_container,<br \/>(unsigned __int64 *)offset_hashsymcontainer);<br \/>ret_1 = ret;<br \/>[...]\r\n}<\/pre>\r\n<p>Internally it calls <em>CClfsBaseFilePersisted::AddSymbol()\u00a0<\/em>to add the container (client and containers are symbols in CLFS) to the General Metadata Block:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">__int64 __fastcall CClfsBaseFilePersisted::AddSymbol(\r\n        _CClfsBaseFilePersisted *this,\r\n        struct _UNICODE_STRING *symbol,\r\n        struct _CLFSHASHTBL *hashtable,\r\n        int symsize,\r\n        struct _CLFSHASHSYM **phashsym,\r\n        unsigned __int64 *poffset)\r\n{\r\n[...]\r\n  while ( 1 )\r\n  {\r\n    ret_1 = CClfsBaseFile::FindSymbol(symbol, hashtable, 1, symsize, phashsym);\r\n    if ( ret_1 &gt;= 0 )\r\n    {\r\n      *poffset = *(_DWORD *)phashsym - (unsigned int)CClfsBaseFile::GetBaseLogRecord(this);\r\n      goto ret;\r\n    }\r\n    if ( ret_1 != 0xC0000023 )\r\n      goto ret1;\r\n    container_size = 0LL;\r\n    ret = CClfsContainer::GetContainerSize((_CClfsContainer *)this-&gt;pCclfsContainer, &amp;container_size);\r\n    if ( ret &lt; 0 )\r\n      break;\r\n    ExReleaseResourceForThreadLite((PERESOURCE)this-&gt;m_presImage, (ERESOURCE_THREAD)KeGetCurrentThread());\r\n    ret_2 = CClfsBaseFilePersisted::ExtendMetadataBlock(this, ClfsMetaBlockGeneral, (unsigned int)container_size &gt;&gt; 1);\r\n    v11 = ExAcquireResourceExclusiveLite((PERESOURCE)this-&gt;m_presImage, 1u);\r\n[...]\r\n  return (unsigned int)ret_1;\r\n}<\/pre>\r\n<p>Notice that it calls <em>CClfsBaseFile::FindSymbol()\u00a0<\/em>to add the symbol. If it <strong>fails<\/strong>, it calls <em>ExtendMetadataBlock()<\/em>.<\/p>\r\n<h3>FindSymbol()<\/h3>\r\n<p><em>FindSymbol()<\/em> internally calls <em>AllocSymbol():<\/em><\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">__int64 __fastcall CClfsBaseFile::FindSymbol(\r\n        struct _UNICODE_STRING *string,\r\n        struct _CLFSHASHTBL *hashTable,\r\n        char flag,\r\n        int symbolsize,\r\n        struct _CLFSHASHSYM **pphashsym)\r\n{\r\n[...]\r\n  v14 = (_CClfsBaseFilePersisted *)*p_pBaseFile;\r\n  v15 = (_DWORD)poffset - (unsigned int)CClfsBaseFile::GetBaseLogRecord(v14);\r\n  v35 = (symbolsize + 7) &amp; 0xFFFFFFF8;\r\n  v16 = ((__int64 (__fastcall *)(_CClfsBaseFilePersisted *, _QWORD, struct _CLFSHASHSYM **))v14-&gt;vftbl_0_00000001C0014000-&gt;CClfsBaseFilePersisted::AllocSymbol(ulong,void * *))(\r\n          v14,\r\n          v10 + v35 + 0x30,\r\n          &amp;v36);\r\n if ( v16 &lt; 0 )\r\n  {\r\nLABEL_29:\r\n    *pphashsym = 0LL;\r\n    return (unsigned int)v16;\r\n[...]\r\n}<\/pre>\r\n<p><em>AllocSymbol()\u00a0<\/em>fails when <em><strong>cbSymbolZone<\/strong> <\/em>points to a location that is <strong>too close to the signatures array<\/strong>. This means that the General Metadata block must be extended:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">NTSTATUS __fastcall CClfsBaseFilePersisted::AllocSymbol(_CClfsBaseFilePersisted *this, unsigned int size, void **ppout)\r\n{\r\n[...]\r\n  logBlockHeader = (CLFS_LOG_BLOCK_HEADER *)this_1-&gt;m_rgBlocks[ClfsMetaBlockGeneral].pbImage;\r\n  *ppout = 0LL;\r\n  cbSymbolZone = BaseLogRecord-&gt;cbSymbolZone;\r\n  if ( (char *)&amp;BaseLogRecord[1] + cbSymbolZone + size_1 &gt; (char *)(&amp;logBlockHeader-&gt;MajorVersion\r\n                                                                  + logBlockHeader-&gt;SignaturesOffset) )\r\n    return 0xC0000023;\r\n[...]\r\n}<\/pre>\r\n<p>Therefore, <em>FindSymbol()<\/em> returns the error caused by <em>AllocSymbol()\u00a0<\/em>and causes <em>AddSymbol()\u00a0<\/em>to call <em>CClfsBaseFilePersisted::ExtendMetadataBlock()<\/em>.<\/p>\r\n<h3>ExtendMetadataBlock()<\/h3>\r\n<p>The <em>ExtendMetadataBlock()\u00a0<\/em>routine first loops over all the blocks starting from <em>blockType, <\/em>that corresponds to ClfsMetaBlockGeneral=2 when called by <em>CClfsBaseFilePersisted::AddSymbol()<\/em>, and calls <em>AcquireMetadataBlock()\u00a0<\/em>on each of them:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">__int64 __fastcall CClfsBaseFilePersisted::ExtendMetadataBlock(\r\n        _CClfsBaseFilePersisted *this,\r\n        __int64 blockType,\r\n        __int64 extendedSectors)\r\n{\r\n[...]\r\n  for ( j = blockType_1; j &lt; this-&gt;m_cBlocks; j += 2 )\r\n  {\r\n    res = CClfsBaseFile::AcquireMetadataBlock(this, (enum _CLFS_METADATA_BLOCK_TYPE)j);\r\n    res_1 = res;\r\n    if ( res &lt; 0 )\r\n      goto exit1;\r\n  }\r\n  res = CClfsBaseFile::GetControlRecord(this, &amp;controlRecord, 0);\r\n  res_1 = res;\r\n  if ( res &lt; 0 )\r\n    goto exit1;\r\n  controlRecord_1 = controlRecord;\r\n  eExtendState = controlRecord-&gt;eExtendState;\r\n  if ( eExtendState )\r\n  {\r\n    v14 = (CClfsBaseFilePersisted *)(unsigned int)(eExtendState - 1);\r\n    if ( (_DWORD)v14 )\r\n    {\r\n      if ( (_DWORD)v14 == 1 )\r\n        goto clfsExtendStateFlusingBlock;\r\n      goto exit;\r\n    }\r\n    goto clfsExtendStateExtendingFsd;\r\n  }\r\n  for ( i = 0; ; ++i )\r\n  {\r\n    i_1 = i;\r\n    if ( i &gt;= this-&gt;m_cBlocks )\r\n      break;\r\n    res = CClfsBaseFilePersisted::WriteMetadataBlock(this, (enum _CLFS_METADATA_BLOCK_TYPE)i, 0);\r\n    res_1 = res;\r\n    if ( res &lt; 0 )\r\n      goto exit;\r\n  }\r\n[...]\r\nexit:\r\n  while ( (unsigned int)blockType_1 &lt; j )\r\n  {\r\n    CClfsBaseFile::ReleaseMetadataBlock(this, (enum _CLFS_METADATA_BLOCK_TYPE)blockType_1);\r\n    LODWORD(blockType_1) = blockType_1 + 2;\r\n  }\r\n  if ( res &lt; 0 )\r\n[...]\r\nreturn (unsigned int)res;\r\n}<\/pre>\r\n<p><em>AcquireMetadataBlock()<\/em> increases the reference count in m_rgcBlockReferences[blockType] or load the block in memory with <em>ReadMetadataBlock()\u00a0<\/em>and sets the reference count to 1 in m_rgcBlockReferences[blockType]. Notice the <em>AcquireMetadataBlock()<\/em> is <strong>not<\/strong> <strong>called on shadow blocks<\/strong>.<\/p>\r\n<p>After that, the function retrieves the <em>CLFS_CONTROL_RECORD,<\/em> calling <em>CClfsBaseFile::GetControlRecord()<\/em>, and checks <em>CLFS_CONTROL_RECORD.eExtendState\u00a0<\/em>field.<\/p>\r\n<p>If <em>eExtendState\u00a0<\/em>is <strong><em>ClfsExtendStateNone<\/em><\/strong>, i.e., it is 0, it will loop over all the blocks and for each of them call <em>CClfsBaseFilePersisted::WriteMetadataBlock()<\/em>. Notice in this case it calls <em>WriteMetadataBlock()\u00a0<\/em><strong>also on the shadow blocks<\/strong>.<\/p>\r\n<h3>Vulnerable Scenario<\/h3>\r\n<p>Let&#8217;s suppose the following scenario:<\/p>\r\n<ul>\r\n<li>The execution path follows <em>AddContainer() &gt; AddSymbol() &gt; ExtendMetadataBlock().<\/em><\/li>\r\n<li><em>ExtendMetadataBlock() <\/em>first increases the reference count of the General Metadata Block and then starts looping over all the Blocks and for each of them calls <em>WriteMetadataBlock().<\/em><\/li>\r\n<li>In the loop it will call <em>WriteMetadataBlock()\u00a0<\/em>on the <strong>General Metadata Block Shadow<\/strong>.<\/li>\r\n<li><em>WriteMetadataBlock()\u00a0<\/em>calls <em>ClfsEncodeBlock()\u00a0<\/em>and <em>ClfsEncodeBlock()\u00a0<\/em>creates an <strong>invalid General Metadata Block<\/strong>. This can be triggered using the same trick used by the <a href=\"https:\/\/hnsecurity.it\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-1\">previous exploit<\/a>, <strong>overlapping the signatures array with a sector signature<\/strong> and forcing the <em><strong>ullDumpCount <\/strong><\/em>to be<strong> even\u00a0<\/strong>when <em>WriteMetadataBlock() <\/em>is invoked.\u00a0<\/li>\r\n<li><em>WriteMetadataBlock()\u00a0<\/em>then calls <em>ClfsDecodeBlock()\u00a0<\/em>that <strong>fails<\/strong>, since the block was invalidated, and triggers a call to <em>ClfsReleaseMetadataBlock().<\/em><\/li>\r\n<li><em>ClfsReleaseMetadataBlock()\u00a0<\/em>reads the reference count of the <strong>General Metadata Block Shadow<\/strong>. Since the reference count is <strong>0 <\/strong>(shadow blocks always have the reference count set to 0), it simply returns (the pseudocode of <em>ClfsReleaseMetadataBlock()\u00a0<\/em>can be found <a href=\"https:\/\/hnsecurity.it\/cve-2024-49138-clfs-heap-based-buffer-overflow-analysis-part-1\">here<\/a>).<\/li>\r\n<li>Then <em>WriteMetadataBlock()\u00a0<\/em>fails and causes <em>ExtendMetadataBlock()<\/em> to fail.<\/li>\r\n<\/ul>\r\n<p>The effect is that <em>ExtendMetadataBlock()\u00a0<\/em>fails and returns, but the <strong>reference count<\/strong> of <strong>General Metadata Block\u00a0<\/strong>is larger than <strong>1<\/strong>. So, the <strong>General Metadata Block<\/strong> is <strong>not freed<\/strong>,\u00a0is <strong>invalid<\/strong> and <strong>in memory<\/strong>. This means that the subsequent API calls will use an <strong>invalid General Metadata Block<\/strong>. Using the trick employed for the previous exploit, the invalid General Metadata Block has a <strong><em>pContainer<\/em> equal to a controllable user-space address<\/strong>.<\/p>\r\n<h3>Triggering the Vulnerability<\/h3>\r\n<p>As previously, in\u00a0order to trigger the vulnerability the PoC first calls <em>CreateLogFile()<\/em> and <em>AddContainer()<\/em> to create both files on disk.<\/p>\r\n<p>After that, it <strong>overwrites the generated base log file with a malicious base log file<\/strong> (embedded as resource file in the exploit and retrieved through <em>FindResource()\/LoadResource()\/LockResource())<\/em> with the following characteristics:<\/p>\r\n<figure id=\"attachment_5074\" aria-describedby=\"caption-attachment-5074\" style=\"width: 547px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5074 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/characteristsics_geenral_secondpoc-1.png\" alt=\"\" width=\"547\" height=\"457\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/characteristsics_geenral_secondpoc-1.png 547w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/characteristsics_geenral_secondpoc-1-300x251.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/characteristsics_geenral_secondpoc-1-350x292.png 350w\" sizes=\"(max-width: 547px) 100vw, 547px\" \/><figcaption id=\"caption-attachment-5074\" class=\"wp-caption-text\">Malicious BLF. Start of General Metadata Block (ImHex)<\/figcaption><\/figure>\r\n<figure id=\"attachment_5075\" aria-describedby=\"caption-attachment-5075\" style=\"width: 497px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5075 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/cbsymzone-1.png\" alt=\"\" width=\"497\" height=\"396\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/cbsymzone-1.png 497w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/cbsymzone-1-300x239.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/cbsymzone-1-350x279.png 350w\" sizes=\"(max-width: 497px) 100vw, 497px\" \/><figcaption id=\"caption-attachment-5075\" class=\"wp-caption-text\">Malicious BLF. cbSymbolZone of General Metadata Block (ImHex)<\/figcaption><\/figure>\r\n<figure id=\"attachment_5078\" aria-describedby=\"caption-attachment-5078\" style=\"width: 575px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5078 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/secondexpoit_cahractetrsisc-1-1.png\" alt=\"\" width=\"575\" height=\"526\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/secondexpoit_cahractetrsisc-1-1.png 575w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/secondexpoit_cahractetrsisc-1-1-300x274.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/secondexpoit_cahractetrsisc-1-1-350x320.png 350w\" sizes=\"(max-width: 575px) 100vw, 575px\" \/><figcaption id=\"caption-attachment-5078\" class=\"wp-caption-text\">Malicious BLF. CLFS_CONTAINER_CONTEXT and signatures array<\/figcaption><\/figure>\r\n<p><em>Usn<\/em> is set to 1 and <em>ullDumpCount<\/em> is set to 1, an <strong>odd value<\/strong>. This is done for the reason explained below.<\/p>\r\n<p><em>ExtendMetadataBlock(),\u00a0<\/em>in a loop, calls <em>WriteMetadataBlock()\u00a0<\/em>first on the General Metadata Block and then on the General Metadata Block Shadow. To trigger the vulnerable scenario, <strong><em>WriteMetadataBlock()\u00a0<\/em>must fail on the General Metadata Block Shadow<\/strong>. Setting the <em>ullDumpCount<\/em> to an odd value, the first <em>WriteMetadataBlock()\u00a0<\/em>on the General Metadata Block <strong>just increases the <em>ullDumpCount<\/em><\/strong> and <strong>not the <em>Usn<\/em><\/strong><em>.\u00a0<\/em>The next <em>WriteMetadataBlock()\u00a0<\/em>on the General Metadata Block Shadow has an <strong>even<\/strong> <em><strong>ullDumpCount <\/strong><\/em>that consequently <strong>changes the <em>Usn<\/em><\/strong>, by <strong>incrementing it<\/strong>, and causes the <i>ClfsDecodeBlock() <\/i>to <strong>fail\u00a0<\/strong>(it works in the same way as for the previous <a href=\"https:\/\/hnsecurity.it\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-1\">exploit<\/a>).<\/p>\r\n<p>Similarly to the previous exploit, the <em>signaturesOffset<\/em> is changed so that the signatures array overlaps one of the sector signatures (the red area at the bottom in the diagram above) and the <em>CLFS_CONTAINER_CONTEXT<\/em> is shifted in a way that the <em><strong>pContainer<\/strong> <\/em>field <strong>overlaps<\/strong> with another <strong>sector signature<\/strong>.<\/p>\r\n<p>In addition, <em>cbSymbolZone<\/em> was modified so that it points to the same location of the signatures array. This is done to force <em>AddSymbol() <\/em>to call <em>ExtendMetadataBlock()\u00a0<\/em>by making <em>FindSymbol()<\/em> <strong>fail<\/strong>.<\/p>\r\n<p>Finally, it was necessary to update also all the other offsets such as:<\/p>\r\n<ul>\r\n<li>The offset in the <em>rgContainer\u00a0<\/em>array.<\/li>\r\n<li>The offset in the <em>rgContainerSymTbl <\/em>array.<\/li>\r\n<\/ul>\r\n<p>It was also necessary to overwrite all the signatures to match the <em>Usn\u00a0<\/em>and recompute the <strong>checksum<\/strong>.<\/p>\r\n<p>This Python script can be useful to compute the checksum (created by ChatGPT, same as previous exploit):<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"python\" data-enlighter-theme=\"monokai\">import binascii\r\n\r\ndef calculate_crc32(input_file):\r\n    \"\"\"\r\n    Reads a file containing hexadecimal numbers, calculates the CRC32 checksum\r\n    using the polynomial 0x04C11DB7, prints the buffer length in hexadecimal,\r\n    and displays the CRC32 checksum in both big-endian and little-endian formats.\r\n    \"\"\"\r\n    try:\r\n        # Read the input file\r\n        with open(input_file, \"r\") as file:\r\n            hex_data = file.read().strip()\r\n\r\n        # Convert hex string to bytes\r\n        hex_numbers = hex_data.split()\r\n        byte_array = bytes(int(num, 16) for num in hex_numbers)\r\n\r\n        # Calculate CRC32 using binascii\r\n        crc32_checksum = binascii.crc32(byte_array) &amp; 0xFFFFFFFF\r\n\r\n        # Calculate buffer length in hexadecimal\r\n        buffer_length = len(byte_array)\r\n\r\n        # Convert checksum to little-endian hex sequence\r\n        little_endian_hex = ' '.join(f\"{b:02X}\" for b in crc32_checksum.to_bytes(4, 'little'))\r\n\r\n        # Print the results\r\n        print(f\"Buffer Length (hex): 0x{buffer_length:02X}\")\r\n        print(f\"CRC32 Checksum (big-endian): 0x{crc32_checksum:08X}\")\r\n        print(f\"CRC32 Checksum (little-endian as hex sequence): {little_endian_hex}\")\r\n    except Exception as e:\r\n        print(f\"Error: {e}\")\r\n\r\n# Example usage\r\nif __name__ == \"__main__\":\r\n    input_file = \"hex_numbers.txt\"  # Replace with your input file path\r\n    calculate_crc32(input_file)\r\n<\/pre>\r\n<p>The PoC, after replacing the BLF on disk with the malicious one, calls again <em>CreateLogFile()\u00a0<\/em>and after that calls <em>AddLogContainer()<\/em>. The execution in kernel follows the path: <em>CClfsBaseFilePersisted::AddContainer() &gt; CClfsBaseFilePersisted::AddSymbol() &gt; CClfsBaseFilePersisted::ExtendMetadataBlock(). <\/em>It starts looping over the blocks and for each them calls <em>WriteMetadataBlock():<\/em><\/p>\r\n<figure id=\"attachment_5081\" aria-describedby=\"caption-attachment-5081\" style=\"width: 1980px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5081 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_32_20-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png\" alt=\"\" width=\"1980\" height=\"853\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_32_20-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png 1980w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_32_20-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-300x129.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_32_20-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-1024x441.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_32_20-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-768x331.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_32_20-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-1536x662.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_32_20-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-350x151.png 350w\" sizes=\"(max-width: 1980px) 100vw, 1980px\" \/><figcaption id=\"caption-attachment-5081\" class=\"wp-caption-text\">Execution before the call to WriteMetadataBlock() on General Metadata Block Shadow<\/figcaption><\/figure>\r\n<p>The screenshot above shows the execution flow right <strong>before<\/strong> calling <em>WriteMetadataBlock()\u00a0<\/em>on the <em>General Metadata Block Shadow<\/em> (RDX=0x3). The reference count of the General Metadata Block is 2 while the reference count of the General Metadata Block Shadow is 0 and both of them have <em>pbImage<\/em> pointing to the same memory location (the block is the same):<\/p>\r\n<figure id=\"attachment_5082\" aria-describedby=\"caption-attachment-5082\" style=\"width: 1996px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5082 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_38_17-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png\" alt=\"\" width=\"1996\" height=\"849\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_38_17-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png 1996w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_38_17-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-300x128.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_38_17-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-1024x436.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_38_17-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-768x327.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_38_17-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-1536x653.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_38_17-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-350x149.png 350w\" sizes=\"(max-width: 1996px) 100vw, 1996px\" \/><figcaption id=\"caption-attachment-5082\" class=\"wp-caption-text\">Execution after the call to WriteMetadataBlock() on General Metadata Block Shadow<\/figcaption><\/figure>\r\n<p>The screenshot above shows the execution right <strong>after<\/strong> calling <em>WriteMetadataBlock()<\/em>. <em>WriteMetadataBlock()<\/em> failed with error 0xc01a0002 (stored in RAX), the reference count is still set to 2, and <strong>pContainer\u00a0<\/strong>now corresponds to <strong>0x0000000002100000<\/strong>:<\/p>\r\n<figure id=\"attachment_5085\" aria-describedby=\"caption-attachment-5085\" style=\"width: 1989px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5085 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_47_04-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png\" alt=\"\" width=\"1989\" height=\"833\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_47_04-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png 1989w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_47_04-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-300x126.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_47_04-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-1024x429.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_47_04-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-768x322.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_47_04-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-1536x643.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-23-17_47_04-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-350x147.png 350w\" sizes=\"(max-width: 1989px) 100vw, 1989px\" \/><figcaption id=\"caption-attachment-5085\" class=\"wp-caption-text\">Execution when returning from ExtendMetadataBlock. General Metadata Block is tampered and reference count is larger than 0<\/figcaption><\/figure>\r\n<p>The screenshot above shows the execution flow right after <em>ExtendMetadataBlock()<\/em>. The reference count of the General Metadata Block is still set to <strong>1<\/strong> (<strong>larger than 0<\/strong>) and <em>pbImage\u00a0<\/em>points to a tampered General Metadata Block with <strong>pContainer=0x0000000002100000<\/strong>.<\/p>\r\n<p>This means that subsequent API calls to the opened BLF will use the tampered General Metadata Block and the tampered <strong>pContainer<\/strong>.<\/p>\r\n<h2>Exploitation<\/h2>\r\n<p>To exploit the vulnerability it is first necessary to find APIs that cause the kernel to manipulate the General Metadata Block and dereference <strong>pContainer<\/strong>. The exploit uses the API <a href=\"https:\/\/learn.microsoft.com\/en-us\/windows\/win32\/api\/clfsw32\/nf-clfsw32-createlogcontainerscancontext\"><em>CreateLogContainerScanContext()<\/em><\/a>. This API triggers a kernel call to <em>CClfsBaseFile::ScanContainerInfo()<\/em>.<\/p>\r\n<h3>CClfsBaseFile::ScanContainerInfo()<\/h3>\r\n<p><em>CClfsBaseFile::ScanContainerInfo()\u00a0<\/em>first retrieves the <em>_CLFS_BASE_RECORD_HEADER\u00a0<\/em>calling <em>GetBaseLogRecord()<\/em>. After that, it cycles over <em>CLFS_CONTAINER_CONTEXT<\/em> in a while loop and for each calls <em>CClfsContainer::QueryContainerInfo()\u00a0<\/em>passing <strong>pContainer<\/strong>:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">__int64 __fastcall CClfsBaseFile::ScanContainerInfo(\r\n        _CClfsBaseFilePersisted *this,\r\n        const unsigned int *const a2,\r\n        const union _CLS_LSN *a3,\r\n        const union _CLS_LSN *a4,\r\n        CLFS_LSN *a5,\r\n        unsigned int a6,\r\n        char a7,\r\n        struct _CLS_CONTAINER_INFORMATION *a8,\r\n        char a9,\r\n        unsigned int *a10,\r\n        unsigned int *a11)\r\n{\r\n[...]\r\n  BaseLogRecord = CClfsBaseFile::GetBaseLogRecord(this);\r\n  v43 = BaseLogRecord;\r\n  if ( !BaseLogRecord )\r\n  {\r\n    ret = 0xC01A000D;\r\n    v35 = 0xC01A000D;\r\n    goto LABEL_53;\r\n  }\r\n[...]\r\nwhile ( v16 &lt; containerCount )\r\n    {\r\n      if ( v19 &gt;= v14 )\r\n        break;\r\n      if ( v16 &gt;= 1024 )\r\n        break;\r\n      v20 = a2[((_WORD)v19 + (_WORD)a6) &amp; 0x3FF];\r\n      if ( (_DWORD)v20 == -1 )\r\n        break;\r\n      v21 = BaseLogRecord-&gt;rgContainers[v20];\r\n      if ( (_DWORD)v21 )\r\n      {\r\n        ret = CClfsBaseFile::GetSymbol(this, v21, v20, (UCHAR **)&amp;v41);\r\n        v35 = ret;\r\n        if ( ret &lt; 0 )\r\n          goto LABEL_52;\r\n        v22 = v41;\r\n        eState = v41-&gt;eState;\r\n[...]\r\n          CClfsContainer::QueryContainerInfo(v22-&gt;pContainer, v24);\r\n          ret = CClfsBaseFile::GetContainerName(this, v20, &amp;v40);\r\n[...]\r\n}<\/pre>\r\n<h3>CClfsContainer::QueryContainerInfo()<\/h3>\r\n<p><em>CClfsContainer::QueryContainerInfo()\u00a0<\/em>calls <em>CClfsContainer::QueryInformation()\u00a0<\/em>passing again <strong>pContainer\u00a0<\/strong>(the <strong>this\u00a0<\/strong>variable corresponds to <strong>pContainer<\/strong>):<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">NTSTATUS __fastcall CClfsContainer::QueryContainerInfo(_CClfsContainer *this, struct _CLS_CONTAINER_INFORMATION *a2)\r\n{\r\n[...]\r\n  v6 = 0LL;\r\n  v7 = 0LL;\r\n  v8 = 0LL;\r\n  result = CClfsContainer::QueryInformation(this, &amp;v5, (struct _IRP *)&amp;v6, 0x28u, 4u);\r\n  if ( result &gt;= 0 )\r\n  {\r\n    a2-&gt;ContainerSize = this-&gt;container_size;\r\n    *(_OWORD *)&amp;a2-&gt;CreationTime = v6;\r\n    a2-&gt;LastWriteTime = v7;\r\n    a2-&gt;FileAttributes = v8;\r\n  }\r\n  return result;\r\n}<\/pre>\r\n<h3>CClfsContainer::QueryInformation()<\/h3>\r\n<p><em>CClfsContainer::QueryInformation()\u00a0<\/em>calls <em>IoGetRelatedDeviceObject()\u00a0<\/em>on <em>this-&gt;fileObject<\/em> and saves the result in <em>RelatedDeviceObject<\/em>. After that, it calls <em>IofCallDriver()\u00a0<\/em>passing <em>RelatedDeviceObject<\/em>:<\/p>\r\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"monokai\">__int64 __fastcall CClfsContainer::QueryInformation(\r\n        _CClfsContainer *this,\r\n        struct _IO_STATUS_BLOCK *a2,\r\n        struct _IRP *a3,\r\n        ULONG a4,\r\n        ULONG a5)\r\n{\r\n[...]\r\n  v19 = 0uLL;\r\n  Object = 0LL;\r\n  RelatedDeviceObject = IoGetRelatedDeviceObject(this-&gt;fileObject);\r\n  LOBYTE(v10) = RelatedDeviceObject-&gt;StackSize;\r\n  Irp = (IRP *)IoAllocateIrpEx(RelatedDeviceObject, v10, 0LL);\r\n  if ( !Irp )\r\n    return 0xC000009ALL;\r\n  v13 = ClfsCreateEventObject(v11, &amp;Object);\r\n  if ( v13 &gt;= 0 )\r\n  {\r\n    Irp-&gt;Tail.Overlay.Thread = KeGetCurrentThread();\r\n    Irp-&gt;UserIosb = (PIO_STATUS_BLOCK)&amp;v19;\r\n    stackLocation = Irp-&gt;Tail.Overlay.CurrentStackLocation;\r\n    stackLocation[-1].FileObject = this-&gt;fileObject;\r\n    stackLocation[-1].MajorFunction = IRP_MJ_QUERY_INFORMATION;\r\n[...]\r\n    CurrentStackLocation[-1].CompletionRoutine = (PIO_COMPLETION_ROUTINE)CClfsContainer::CompleteFsdRequest;\r\n    v17 = Object;\r\n    CurrentStackLocation[-1].Context = Object;\r\n[...]\r\n    IofCallDriver(RelatedDeviceObject, Irp);\r\n    KeWaitForSingleObject(v17, Executive, 0, 0, 0LL);\r\n[...]\r\n   }\r\n IoFreeIrp(Irp);\r\n  if ( Object )\r\n    ObfDereferenceObject(Object);\r\n  return (unsigned int)v13;\r\n}<\/pre>\r\n<p>Since <strong><em>this<\/em> corresponds to <em>pContainer<\/em><\/strong>, <em>RelatedDeviceObject\u00a0<\/em>is controllable. Therefore, it is possible to pass a<strong> controllable address to <em>IofCallDriver()<\/em><\/strong><em>. <\/em>Passing a controllable address to <em>IofCallDriver()<\/em> is an exploitable scenario already encountered <a href=\"https:\/\/hnsecurity.it\/exploiting-amd-atdcm64a-sys-arbitrary-pointer-dereference-part-1\/\">here<\/a>.<\/p>\r\n<p>The <strong>general idea<\/strong> is the following:<\/p>\r\n<ol>\r\n<li>Allocate user-space memory at <em><strong>pContainer\u00a0<\/strong>(that is <strong>0x0000000002100000<\/strong>).<\/em><\/li>\r\n<li>Create a FILE_OBJECT structure at <em>pContainer-&gt;fileObject\u00a0<\/em>so that <em>IoGetRelatedDeviceObject()\u00a0<\/em>succeed and returns another user-space address for <em>RelatedDeviceObject.<\/em><\/li>\r\n<li>Create a DEVICE_OBJECT structure at <em>RelatedDeviceObject.<\/em><\/li>\r\n<li>When <em>IofCallDriver()\u00a0<\/em>is invoked, it calls <em>RelatedDeviceObject-&gt;DriverObject-&gt;MajorFunction[IRP_MJ_QUERY_INFORMATION](),\u00a0<\/em>an arbitrary function that can set <em>_KTHREAD.PreviousMode<\/em> of a thread to 0.<\/li>\r\n<\/ol>\r\n<h3>Proof of Concept Exploit<\/h3>\r\n<p>To summarize, here are the steps performed by the proof of concept exploit available <a href=\"https:\/\/github.com\/MrAle98\/CVE-2024-49138-POC\/tree\/second\">here<\/a> (<em>second\u00a0<\/em>branch):<\/p>\r\n<ol>\r\n<li>Call <em>CreateLogFile()\u00a0<\/em>and <em>AddLogContainer()\u00a0<\/em>to create the .BLF and the container files under <em>C:\\temp\\testlog.<\/em><\/li>\r\n<li>Fetch the malicious .BLF from the resources and overwrite the original .BLF with the malicious .BLF.<\/li>\r\n<li>Create a thread X with <em>CreateThread().<\/em><\/li>\r\n<li>Allocate memory at address <em><strong>0x0000000002100000<\/strong> (<\/em>stored in the variable <em>pcclfscontainer<\/em>).<\/li>\r\n<li>Create in the allocated memory space a <em>FILE_OBJECT, DEVICE_OBJECT, DRIVER_OBJECT.<\/em><\/li>\r\n<li>Link <em>FILE_OBJECT <\/em>to <em>pcclfscontainer, DEVICE_OBJECT <\/em>to <em>FILE_OBJECT<\/em> and <em>DRIVER_OBJECT <\/em>to <em>DEVICE_OBJECT.<\/em><\/li>\r\n<li>Set <em>DRIVER_OBJECT.MajorFunction[IRP_MJ_QUERY_INFORMATION] <\/em>to be <em>nt!DbgkpTriageDumpRestoreState. S<\/em>ets the <em>_KTHREAD.PreviousMode <\/em>address of thread X in <em>DEVICE_OBJECT<\/em> (the where of the write-what-where) and the value to write to that address in <em>DEVICE_OBJECT <\/em>(the what of the write-what-where).<\/li>\r\n<li>Call again <em>CreateLogFile()\u00a0<\/em>and <em>AddLogContainer()\u00a0<\/em>to trigger the vulnerability. Now, the next function calls using the opened BLF handle will use the corrupted <em>General Metadata Block<\/em> having a <em><strong>pContainer<\/strong> <\/em>with value <em><strong>0x0000000002100000<\/strong>).<\/em><\/li>\r\n<li>Call <em>CreateLogContainerScanContext().\u00a0<\/em><\/li>\r\n<\/ol>\r\n<p>After the last API call, the main thread, in kernel mode, follows the path <em>CClfsBaseFile::ScanContainerInfo() &gt; CClfsContainer::QueryContainerInfo()\u00a0<\/em>passing as first parameter the controllable <em><strong>pContainer<\/strong>:<\/em><\/p>\r\n<figure id=\"attachment_5094\" aria-describedby=\"caption-attachment-5094\" style=\"width: 1458px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5094 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-24-13_29_48-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png\" alt=\"\" width=\"1458\" height=\"720\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-24-13_29_48-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1.png 1458w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-24-13_29_48-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-300x148.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-24-13_29_48-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-1024x506.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-24-13_29_48-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-768x379.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/2025-01-24-13_29_48-IDA-clfs.sys_.i64-clfs.sys-C__CVE-2024-49138_clfs.sys_.i64-1-350x173.png 350w\" sizes=\"(max-width: 1458px) 100vw, 1458px\" \/><figcaption id=\"caption-attachment-5094\" class=\"wp-caption-text\">Calling QueryContainerInfo() with controllable pContainer<\/figcaption><\/figure>\r\n<p>The execution continues following the path <em>CClfsContainer::QueryContainerInfo() &gt; CClfsContainer::QueryInformation() &gt; IofCallDriver() &gt; nt!DbgkpTriageDumpRestoreState()\u00a0<\/em>and overwrites with 0 the <em>_KTHREAD.PreviousMode<\/em> field of thread X.<\/p>\r\n<p>At this point the <strong>main thread<\/strong> is stuck <strong>waiting indefinitely<\/strong>\u00a0on <em>KeWaitForSingleObject()\u00a0<\/em>inside <em>CClfsContainer::QueryInformation()\u00a0<\/em>after returning from <em>IofCallDriver().<\/em><\/p>\r\n<p>Then, <strong>thread X kicks in<\/strong> and uses <em>NtReadVirtualMemory()\/NtWriteVirtualMemory() <\/em>to overwrite the <em>_EPROCESS.Token\u00a0<\/em>to elevate privileges, restores<em> _KTHREAD.PreviousMode<\/em> to 1 and spawns a new cmd as system.<\/p>\r\n<figure id=\"attachment_5091\" aria-describedby=\"caption-attachment-5091\" style=\"width: 1515px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5091 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/systemshell_second-1.gif\" alt=\"\" width=\"1515\" height=\"873\" \/><figcaption id=\"caption-attachment-5091\" class=\"wp-caption-text\">Running second poc<\/figcaption><\/figure>\r\n<h2>Limitations and Improvements<\/h2>\r\n<p>The exploit retrieves the kernel address of <em>_KTHREAD\u00a0<\/em>using <em>NtQuerySystemInformation().<\/em> Starting from Windows 11 24h2, to access this API <strong>the user must have have the SeDebugPrivilege<\/strong> (meaning they must be an Administrator). It could be possible to user alternative APIs manipulating the General Metadata Block that allow to obtain an info leak.<\/p>\r\n<p>The <em>PreviousMode<\/em> technique was mitigated by Microsoft starting from Windows 11 24h2. Attackers can still use other techniques to grant themselves read\/write in kernel-land (<a href=\"https:\/\/windows-internals.com\/one-i-o-ring-to-rule-them-all-a-full-read-write-exploit-primitive-on-windows-11\/\">I\/O Ring<\/a> for example).<\/p>\r\n<p>Hardcoded offsets should be replaced with hash-based search in ntoskrnl.exe for n<em>t!DbgkpTriageDumpRestoreState.\u00a0<\/em>Otherwise, offsets to functions and inside data structures may be fetched by PDB symbol server passing as input the ntoskrnl.exe file hash.<\/p>\r\n<p>After the vulnerability is exploited, it is recommended to <strong>clean up the state in memory<\/strong> (a thread is stuck indefinitely) and then delete the container and the BLF file. For this purpose, the <a href=\"https:\/\/github.com\/Cr4sh\/KernelForge\">KernelForge<\/a> project may be useful to call arbitrary APIs in kernel mode from user mode having an arbitrary read\/write.<\/p>\r\n<h2>Patch Analysis<\/h2>\r\n<p>The screenshot below highlights the patch applied by Microsoft to <em><strong>WriteMetadataBlock()<\/strong>:<\/em><\/p>\r\n<figure id=\"attachment_5144\" aria-describedby=\"caption-attachment-5144\" style=\"width: 1801px\" class=\"wp-caption aligncenter\"><img decoding=\"async\" class=\"wp-image-5144 size-full\" src=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/patch_writemeta-1.png\" alt=\"\" width=\"1801\" height=\"721\" srcset=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/patch_writemeta-1.png 1801w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/patch_writemeta-1-300x120.png 300w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/patch_writemeta-1-1024x410.png 1024w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/patch_writemeta-1-768x307.png 768w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/patch_writemeta-1-1536x615.png 1536w, https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/01\/patch_writemeta-1-350x140.png 350w\" sizes=\"(max-width: 1801px) 100vw, 1801px\" \/><figcaption id=\"caption-attachment-5144\" class=\"wp-caption-text\">WriteMetadataBlock() before and after the patch<\/figcaption><\/figure>\r\n<p>The patch, before calling <em>ReleaseMetadataBlock()<\/em>, checks if the block is a shadow block. In this case, it calls <em>ReleaseMetadataBlock()\u00a0<\/em><strong>not on the shadow but on the original one<\/strong> by decrementing blockType by 1. The effect is that it <strong>decrements<\/strong> the <strong>reference count<\/strong> of the <strong>original block<\/strong>.<\/p>\r\n<h2>Detection<\/h2>\r\n<p>Both presented exploits provided in the <a href=\"https:\/\/github.com\/MrAle98\/CVE-2024-49138-POC\">repository<\/a> require to open the BLF with <em>CreateLogFile()\u00a0<\/em>after it was tampered by directly writing to it.<\/p>\r\n<p>I recommend <strong>monitoring for <em>CreateLogFile()<\/em>, <em>CreateFile()<\/em>, <\/strong><em><strong>WriteFile()<\/strong>. <\/em>A <em>CreateFile()\/WriteFile() <\/em>on file X followed by a <em>CreateLogFile() <\/em>on the same file X could be a reliable indicator of exploitation.<\/p>\r\n<p>Regular users are not supposed to directly interact with a BLF file using <em>WriteFile()<\/em> or <em>CreateFile(),<\/em> but only with the APIs offered by CLFS. So, <strong>detecting such unusual activity could be a red flag<\/strong>.<\/p>\r\n<h2>Conclusions<\/h2>\r\n<p>The article first analyzed the <strong>vulnerability<\/strong> in <em>WriteMetadataBlock()<\/em> and described how to <strong>exploit<\/strong> it in a Windows 11 23H2 environment.<\/p>\r\n<p>It highlighted limitations and proposed improvements to the PoC and later analyzed the patch applied by Microsoft.<\/p>\r\n<p>Finally, it proposed a <strong>strategy for detecting (and preventing) exploitation attempts<\/strong> of these and other vulnerabilities based on tampering with a Base Log File.<\/p>\r\n<h2>References<\/h2>\r\n<ul>\r\n<li><a href=\"https:\/\/github.com\/ionescu007\/clfs-docs\">https:\/\/github.com\/ionescu007\/clfs-docs<\/a><\/li>\r\n<li><a href=\"https:\/\/securelist.com\/windows-clfs-exploits-ransomware\/111560\/\">https:\/\/securelist.com\/windows-clfs-exploits-ransomware\/111560\/<\/a><\/li>\r\n<li><a href=\"https:\/\/blog.exodusintel.com\/2022\/03\/10\/exploiting-a-use-after-free-in-windows-common-logging-file-system-clfs\/\">https:\/\/blog.exodusintel.com\/2022\/03\/10\/exploiting-a-use-after-free-in-windows-common-logging-file-system-clfs\/<\/a><\/li>\r\n<\/ul>\r\n<h2>Contacts<\/h2>\r\n<p>If you have any questions, feel free to reach out at:<\/p>\r\n<ul>\r\n<li><a href=\"https:\/\/x.com\/MrAle_98\">X<\/a><\/li>\r\n<li><a href=\"https:\/\/www.linkedin.com\/in\/alessandro-iandoli-86a19b211\/\">Linkedin<\/a><\/li>\r\n<\/ul>\r\n","protected":false},"excerpt":{"rendered":"<p>In the previous article, we discussed a vulnerability in the LoadContainerQ() function inside clfs.sys. The root cause of the vulnerability [&hellip;]<\/p>\n","protected":false},"author":12,"featured_media":159961,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[78,81],"tags":[77,82,135,191,210,218,219],"class_list":["post-5027","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-exploits","category-vulnerabilities","tag-exploit","tag-vulnerability-research","tag-windows","tag-red-teaming","tag-exploit-development","tag-clfs","tag-cve-2024-49138"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>HN Security - CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis - Part 2 -<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"it_IT\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"HN Security - CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis - Part 2 -\" \/>\n<meta property=\"og:description\" content=\"In the previous article, we discussed a vulnerability in the LoadContainerQ() function inside clfs.sys. The root cause of the vulnerability [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"HN Security\" \/>\n<meta property=\"article:published_time\" content=\"2025-01-29T08:33:07+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-09-23T16:58:34+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/WIN.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1600\" \/>\n\t<meta property=\"og:image:height\" content=\"836\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Alessandro Iandoli\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@hnsec\" \/>\n<meta name=\"twitter:site\" content=\"@hnsec\" \/>\n<meta name=\"twitter:label1\" content=\"Scritto da\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alessandro Iandoli\" \/>\n\t<meta name=\"twitter:label2\" content=\"Tempo di lettura stimato\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minuti\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/\"},\"author\":{\"name\":\"Alessandro Iandoli\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#\\\/schema\\\/person\\\/7883a9c36dac7694ca101137125d5fff\"},\"headline\":\"CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis &#8211; Part 2\",\"datePublished\":\"2025-01-29T08:33:07+00:00\",\"dateModified\":\"2025-09-23T16:58:34+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/\"},\"wordCount\":2316,\"publisher\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hnsecurity.it\\\/wp-content\\\/uploads\\\/2025\\\/09\\\/WIN.jpg\",\"keywords\":[\"exploit\",\"vulnerability research\",\"windows\",\"red teaming\",\"exploit development\",\"clfs\",\"cve-2024-49138\"],\"articleSection\":[\"Exploits\",\"Vulnerabilities\"],\"inLanguage\":\"it-IT\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/\",\"url\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/\",\"name\":\"HN Security - CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis - Part 2 -\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/hnsecurity.it\\\/wp-content\\\/uploads\\\/2025\\\/09\\\/WIN.jpg\",\"datePublished\":\"2025-01-29T08:33:07+00:00\",\"dateModified\":\"2025-09-23T16:58:34+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/#breadcrumb\"},\"inLanguage\":\"it-IT\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/#primaryimage\",\"url\":\"https:\\\/\\\/hnsecurity.it\\\/wp-content\\\/uploads\\\/2025\\\/09\\\/WIN.jpg\",\"contentUrl\":\"https:\\\/\\\/hnsecurity.it\\\/wp-content\\\/uploads\\\/2025\\\/09\\\/WIN.jpg\",\"width\":1600,\"height\":836,\"caption\":\"Microsoft logo\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis &#8211; Part 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#website\",\"url\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/\",\"name\":\"HN Security\",\"description\":\"Offensive Security Specialists\",\"publisher\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"it-IT\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#organization\",\"name\":\"HN Security\",\"url\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/hnsecurity.it\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/hn-libellula.jpg\",\"contentUrl\":\"https:\\\/\\\/hnsecurity.it\\\/wp-content\\\/uploads\\\/2026\\\/01\\\/hn-libellula.jpg\",\"width\":696,\"height\":696,\"caption\":\"HN Security\"},\"image\":{\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/hnsec\",\"https:\\\/\\\/www.linkedin.com\\\/company\\\/hnsecurity\\\/\",\"https:\\\/\\\/github.com\\\/hnsecurity\",\"https:\\\/\\\/infosec.exchange\\\/@hnsec\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/#\\\/schema\\\/person\\\/7883a9c36dac7694ca101137125d5fff\",\"name\":\"Alessandro Iandoli\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"it-IT\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g\",\"caption\":\"Alessandro Iandoli\"},\"url\":\"https:\\\/\\\/hnsecurity.it\\\/it\\\/blog\\\/author\\\/ale98\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"HN Security - CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis - Part 2 -","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/","og_locale":"it_IT","og_type":"article","og_title":"HN Security - CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis - Part 2 -","og_description":"In the previous article, we discussed a vulnerability in the LoadContainerQ() function inside clfs.sys. The root cause of the vulnerability [&hellip;]","og_url":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/","og_site_name":"HN Security","article_published_time":"2025-01-29T08:33:07+00:00","article_modified_time":"2025-09-23T16:58:34+00:00","og_image":[{"width":1600,"height":836,"url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/WIN.jpg","type":"image\/jpeg"}],"author":"Alessandro Iandoli","twitter_card":"summary_large_image","twitter_creator":"@hnsec","twitter_site":"@hnsec","twitter_misc":{"Scritto da":"Alessandro Iandoli","Tempo di lettura stimato":"12 minuti"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/#article","isPartOf":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/"},"author":{"name":"Alessandro Iandoli","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/7883a9c36dac7694ca101137125d5fff"},"headline":"CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis &#8211; Part 2","datePublished":"2025-01-29T08:33:07+00:00","dateModified":"2025-09-23T16:58:34+00:00","mainEntityOfPage":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/"},"wordCount":2316,"publisher":{"@id":"https:\/\/hnsecurity.it\/it\/#organization"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/WIN.jpg","keywords":["exploit","vulnerability research","windows","red teaming","exploit development","clfs","cve-2024-49138"],"articleSection":["Exploits","Vulnerabilities"],"inLanguage":"it-IT"},{"@type":"WebPage","@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/","url":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/","name":"HN Security - CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis - Part 2 -","isPartOf":{"@id":"https:\/\/hnsecurity.it\/it\/#website"},"primaryImageOfPage":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/#primaryimage"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/WIN.jpg","datePublished":"2025-01-29T08:33:07+00:00","dateModified":"2025-09-23T16:58:34+00:00","breadcrumb":{"@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/#breadcrumb"},"inLanguage":"it-IT","potentialAction":[{"@type":"ReadAction","target":["https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/"]}]},{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/#primaryimage","url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/WIN.jpg","contentUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/WIN.jpg","width":1600,"height":836,"caption":"Microsoft logo"},{"@type":"BreadcrumbList","@id":"https:\/\/hnsecurity.it\/it\/blog\/cve-2024-49138-windows-clfs-heap-based-buffer-overflow-analysis-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/hnsecurity.it\/it\/"},{"@type":"ListItem","position":2,"name":"CVE-2024-49138 Windows CLFS heap-based buffer overflow analysis &#8211; Part 2"}]},{"@type":"WebSite","@id":"https:\/\/hnsecurity.it\/it\/#website","url":"https:\/\/hnsecurity.it\/it\/","name":"HN Security","description":"Offensive Security Specialists","publisher":{"@id":"https:\/\/hnsecurity.it\/it\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/hnsecurity.it\/it\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"it-IT"},{"@type":"Organization","@id":"https:\/\/hnsecurity.it\/it\/#organization","name":"HN Security","url":"https:\/\/hnsecurity.it\/it\/","logo":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/","url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg","contentUrl":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2026\/01\/hn-libellula.jpg","width":696,"height":696,"caption":"HN Security"},"image":{"@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/hnsec","https:\/\/www.linkedin.com\/company\/hnsecurity\/","https:\/\/github.com\/hnsecurity","https:\/\/infosec.exchange\/@hnsec"]},{"@type":"Person","@id":"https:\/\/hnsecurity.it\/it\/#\/schema\/person\/7883a9c36dac7694ca101137125d5fff","name":"Alessandro Iandoli","image":{"@type":"ImageObject","inLanguage":"it-IT","@id":"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/644822f5d8329ca419a50c1f39c97de5ccd163d1932e4cdc60a6cc8cb64ed29e?s=96&d=mm&r=g","caption":"Alessandro Iandoli"},"url":"https:\/\/hnsecurity.it\/it\/blog\/author\/ale98\/"}]}},"jetpack_featured_media_url":"https:\/\/hnsecurity.it\/wp-content\/uploads\/2025\/09\/WIN.jpg","_links":{"self":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/5027","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/users\/12"}],"replies":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/comments?post=5027"}],"version-history":[{"count":2,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/5027\/revisions"}],"predecessor-version":[{"id":160880,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/posts\/5027\/revisions\/160880"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/media\/159961"}],"wp:attachment":[{"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/media?parent=5027"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/categories?post=5027"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hnsecurity.it\/it\/wp-json\/wp\/v2\/tags?post=5027"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}