In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-02 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly introduces "what is the cause of the remote code execution vulnerability of the CVE-2021-24093 Windows graphics component". In the daily operation, I believe that many people have doubts about the cause of the remote code execution vulnerability of the CVE-2021-24093 Windows graphics component. The editor consulted all kinds of materials and sorted out a simple and useful operation method. I hope it will be helpful to answer the question of "what is the cause of the remote code execution vulnerability of the CVE-2021-24093 Windows graphics component?" Next, please follow the editor to study!
I. Preface
Windows graphics component DWrite library is a user-mode dynamic library for high-quality text rendering, DWrite inventory in remote code execution vulnerabilities. At present, there is a POC,POC that can write anything at any address.
Based on this analysis, we know that when there is error data in the "maxp" table in the font library file, the DWrite library uses this data to calculate the memory needed for fonts, resulting in too small allocated memory. The program reads the data in the font library to write to the array and crosses the boundary to write to another data structure. Subsequently, the data in the structure is used as a pointer to operate the contents, and the writing data and pointers can be controlled. Through the analysis of the patch, the patch scheme is to take out another field of the "maxp" table and add 4 to compare the previous malformed data to get a larger value, so as to calculate the amount of memory that needs to be allocated.
The article contains the following contents:
Locate the rendering process of the chrome engine
Dynamic debugging Analysis of breakpoints using conditional recording
Compare static analysis using IDA patches
Second, vulnerability information 1. Brief description of loophole
Vulnerability name: (Windows graphics component remote code execution vulnerability)
Vulnerability number: (CVE-2021-24093)
Vulnerability type: (array out of bounds write)
Vulnerability impact: (remote code execution)
CVSS score: 8.8
Difficulty of use: not easy to use
Basic permissions: users are required to access the web page
two。 Overview of components
Microsoft DirectWrite is a modern Windows API for high-quality text rendering. Most of its code is in the DWrite.dll user mode library. It is used as a font rasterizer for a variety of widely used desktop programs such as chrome,Firefox and Edge on Windows.
3. Vulnerability exploitation
Using a chrome browser to access the Web page, the rendering engine process is abnormal, causing the chorme page to crash.
4. Vulnerability impact
The vulnerability mainly affects some versions of Win10 and Windows Server 2016, 2019, 2004, 20H2 and other systems.
Third, loophole recurrence 1. Environment building
Target environment: Windows 1909 Professional Edition x64, chrome 86.0.4240.193 (64 bit)
The poc.html is on the local machine, and the vulnerability environment is also on the local machine.
two。 Recurrence process
Place the POC file in the same directory as the poc.ttf and use chrome to open the poc.html file.
two。 The page opens and click the OK button to load the ttf file.
3. Browser rendering engine process crashes
4. Locate the location of the process crash
(1) multiple chrome processes are started when the Html page is opened. First of all, you need to locate which is the rendering engine process.
(2) close the chrome browser first (otherwise it will affect the positioning result), use tinderswords to locate the rendering engine process, empty the Tencent Jian to record the content, enable monitoring, set action filtering including process startup and process exit, click OK, and then enable monitoring, as shown below:
(3) Open poc.html using chrome, click OK on the pop-up box, and then the rendering engine crashes. Close the monitoring, view the monitored content, and filter the monitored content. You only need to include the record of chrome.exe, as shown below:
(4) you can see that the last process exits, the ID of the process is 4228, and the rendering engine crashes, and the process should also exit. Suppose the last process is the rendering engine process, which is the seventh from top to bottom. Try again and repeat the process (2-3). Do not click the OK button after opening the poc.html this time. Check the records of the velvet sword as follows:
Navigate to the seventh process, the process ID is 4948, and use Windbg x64 to attach this process. (if the chrome browser switches to the background, for example, if I click back to the desktop, chrome will automatically click the OK button, causing the rendering process to exit. You can open windbg first, you don't have to switch back to the desktop and then open windbg, or you can use dual screens.)
After the attachment is successful, enter g to continue, then go back to the browser, click the OK button, and the windbg is cut off, as follows:
You can see that a wrong memory address is referenced and an exception occurs, which indicates that the correct rendering process has been located. R8 is 0x0000414100004141, there are a large number of 41414141 data in the poc.ttf downloaded on the Internet. After the author modifies the poc.ttf, the address here is slightly different, which can be seen in the follow-up.
Fourth, loophole analysis 1. Basic information
Vulnerability file: DWrite.dll
Vulnerability function: fsg_ExecuteGlyph
Vulnerability object: "maxp" table in TrueType fonts
two。 Background knowledge
TrueType fonts are usually contained in a single TrueType font file with the suffix .TTF. All data in TrueType is encoded in big-endian, and the TTF file contains the version number of the font and several tables, each table has a TableEntry structure item, and the TableEntry structure contains resource tags, checksums, offsets, and the size of each table. The following is the C language definition of the TrueType font directory:
Typedef sturct
{
Char tag [4]
ULONG checkSum
ULONG offset
ULONG length
} TableEntry
Typedef struct
{
Fixed sfntversion; / / 0x00010000 for version 1.0
USHORT numTables
USHORT searchRange
USHORT entrySelector
USHORT rangeShift
TableEntry entries [1]; / / variable number of TableEntry
} TableDirectory
The file begins with a TableDirectory structure, and the last field of the TableDirectory structure is an array of variable-length TableEntry structures, each corresponding to a table. Each table in the TrueType font holds different logical information, where the function of the "maxp" table is to describe the summary data of the memory allocation required in the font. The specific structure of the "maxp" table is as follows:
Typedef struct
{
Fixed version;// 0x00010000 for version 1.0
USHORT numGlyphs
The maximum point in USHORT maxPoints;// non-compound glyphs
USHORT maxContours
The maximum point in the USHORT maxCompositePoints;// compound glyph
USHORT maxCompositeContours
USHORT maxZones
USHORT maxTwilightPoints
USHORT maxStorage
USHORT maxFunctionDefs
USHORT maxInstructionDefs
USHORT maxStackElements
USHORT maxSizeOfInstructions
The maximum number of components referenced by any compound glyph at the "top level" of USHORT maxComponentElements;//
USHORT maxComponentDepth
}
3. Detailed analysis 1. Basic analysis
Data in poc.ttf:
The data pointed by arrow 1 in the figure is the TableEntry structure of the "maxp" table, and the Offset field is 00000158 where the arrow 2 points to, which is the specific structure of the content of the "maxp" table. The value of the maxPoints field is 0 (offset 0x6 from arrow 2), and the maxCompositePoints field is 3 (offset from arrow 2).
The x and y increments in the table entry of the AE glyph are overwritten to another data structure at run time, as shown in TTF:
When the exception is triggered, the instruction is add word ptr [r8x56h], ax,ax is 0x9E9F (marked in figure 1), R8 is the address of 0x00007A7B00007879 (marked in figure 2), and 7879 7A7B is all data in TTF. The reason for filling 0 is that memset initialization memory space is called on x array and y array before the exception instruction.
The poc.html is as follows:
Normally, the value of the maxPoints field in the ttf file is 0x168. The value of the maxCompositePoins field is 0x2352. In the poc.ttf file, the value of the maxPoints field in the "maxp" structure is changed to 0 and the maxCompositePoins value is changed to 3. When loading and rasterizing the data of the corrupted "maxp" table, the heap allocation buffer is too small, and the call stack is as follows:
When the compound glyph (AE,HTML entity & # 198th 00C6 U + Glyph) is rasterized, the function DWriteGraph fsgExecuteGlyph crashes, and the call stack is as follows:
The fsg_ExecuteGlyph function operates on two integer arrays (corresponding to x and y coordinates) inside the heap block, calling memset with the length of 0x148 to initialize the two arrays, but the length of the array is less than 0x148, and a pointer following the array is set to 0.
If the font is a variable and an axis value is specified, it will also call TrueTypeRasterizer:: Implementation::ApplyOutlineVariation- > GlyphOutlineVariationInterpolator:: ApplyVariation to get the data from TTF and assign it to the members of the array, but the array is small, so the pointer behind the array is set to the data in TTF. Data is then written to the address pointed to by the pointer, resulting in an exception.
The version of the vulnerability library is as follows:
two。 Static analysis
Fsg_ExecuteGlyph analysis of crash function
In the large heap chunk, two blocks of memory are used for x array and y array, respectively. Memset initialization is called, and then call cs:off_7FFF41C70D10 is called. DWritewriter TrueTypeRasterizerVariation is called inside the function to assign values to x array and y array. Addr1 points to memory that is not as large as 0x148 bytes, so it will be written to other data objects. Next, the overwritten data will be referenced as a pointer to write data:
The data in rsi+8 is modified when it is assigned by the array, and the data in TTF is used to overwrite the data in [rsi+8]. The instruction add [r8room56], ax called at the 0x00007FFF41B341F6 address, in which the data in ax can also be controlled.
1. Function call chain
The function call chain that calculates the memory size is
The TrueTypeRasterizer::Implementation::Initialize- > fs_NewSfnt-> fsg_WorkSpaceSetOffsets function fsg_WorkSpaceSetOffsets calculates the amount of memory that needs to be applied internally and sends the result to fs_NewSfnt.
Fs_NewSfnt gets the amount of memory that needs to be applied for, and then calls calloc to request memory.
You can see that after the call to fs_NewSfnt is completed in the figure, the contents of the v39 memory block are fetched as the size of the requested memory in the following loop.
The fs_NewSfnt function is as follows:
V2 is the second parameter a2DWORD * ((_ DWORD *) v2 + 3), which is consistent with fetching the memory size region in fs_NewSfnt (* (_ DWORD *) (v14 + 4i64 * j), j is 3).
two。 Patch Diff
The fsg_WorkSpaceSetOffsets function has been modified before and after the patch.
The pseudo-C code of the fsg_WorkSpaceSetOffsets function before the patch is as follows:
Parameter v3 points to the specific content of the "maxp" table.
You can see that the figure takes a larger value from the maxCompositePoints and maxPoints fields, and compares it with the constant 1 to get a value of 3, and then add 8 to get 0xb, which is passed into fsg_GetOutlineSizeAndOffsets as the first parameter. The name of this function should be to get the size and offset value of the outline.
There is something wrong with the pseudo-C code of the fsg_WorkSpaceSetOffsets function after the patch, so the assembly code is posted below:
After patching, the program first takes a larger value from the maxCompositePoints and maxPoints fields, gets 3, compares it with 1 and gets 0xb, and then takes out the maxComponentElements field in the maxp table. The value in POC is 0x0062, and the offset from the "maxp" table is 0x1C.
0x62+4=0x66, compare 0x66 with 0xb and get a larger value as the first parameter passed into the fsg_GetOutlineSizeAndOffsets function.
The function fsg_GetOutlineSizeAndOffsets does not change, but the final result is different because the first parameter passed in is different.
two。 Loophole function analysis
The fsg_ExecuteGlyph function operates on the two integer arrays inside the heap block, corresponding to the x and y coordinates. In fact, the array is smaller, fsg_ExecuteGlyph function calls memset twice to zero the array, if the font is a variable and specifies the axis value, it will also call TrueTypeRasterizer::Implementation::ApplyOutlineVariation- > GlyphOutlineVariationInterpolator::ApplyVariation to assign the data in the font to the coordinate array, which will destroy the subsequent structure members.
3. Dynamic analysis
The process of calculating the required memory can be debugged by conditional breakpoints, and after being attached to the debugger, you can set the following breakpoint commands
Bp DWritesian TrueTypeRasterizerVuImplementationWidrized TrueTypeRasterizerVlImplementationFunctionalize "r $t0characters\" .printf\ "Initialize times:%d\ n\", @ $t0tt.echotencgc "
You can see that the crash occurs after the 13th call to the TrueTypeRasterizer::Implementation::Initialize function.
Restart, lower breakpoint:
Bp DWritesTrueTypeRasterizerVlImplementationWidrized TrueTypeRasterizerVlImplementationParticipate "r $t0destroy Initialize times:%d\ n\", @ $t0it.echotra.if (@ $t0 = = 0x0D) {} .else gc} "
If you run, you can see:
Before calling fs_NewSfnt, enter the breakpoint to view the contents of the passed parameters:
Step by step, look at the memory again, and you can see that the memory size that needs to be applied for is 0x6fa4.
Continue to run down:
You can see that the memory address of the request is 0x00000196bc484b60.
At the breakpoint in the crash function, run:
The starting address of the heap block is the 0x00000196bc484b60 of the above application, the size used to call memset is 0x148, and the above is the memory block 1dyne addr1 for 0x00000196bc4850fc.
Check the size of the heap and the offset of the addr1 from the starting address of the heap as follows:
Finally, the instruction add [r8x56h] at fsg_ExecuteGlyph+ 0x772 is called. When ax, A8 comes from [rsi+8].
View the offset of rsi+8 from the heap block
Rsi+8 offsets 0x6c8 relative to the starting address of the heap, while addr1 offsets 0x59creco0x148room0x6E4 > 0x6C8 relative to the starting address of the heap, so manipulating the data in addr1 will overwrite the data at rsi+8. As you can see in the figure, the data in rsi+8 is initialized to 0 after calling memset.
After calling the ApplyOutlineVariation function, the data at rsi+8 is modified to the data in the ttf file. (restart, memory address is not the same as above)
Continue to run as follows:
You can see that ax is 0x9e9fjournal R8 is 0x00007a7b00007879, and both data are in the poc.ttf file, so the pointer data can be controlled (where) and the content to be written (what) can also be controlled.
After patching, check that the ESI function remains unchanged. Debugging shows that the size of the entire heap becomes larger. The size of the x array and y array is still 0x148 bytes, and the distance between the ESI object and the starting address of the heap block becomes larger, so the Glyph object is not overwritten during the assignment process of the x array and y array, as follows:
You can see that the heap size is 0x7d24, which was previously 0x6fa4.
The end address of addr1 is 0x0000015fd070427c
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.