Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to analyze remote Command execution vulnerability CVE-2020-0729 in LNK File

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)05/31 Report--

Today, I will talk to you about how to analyze the remote command execution vulnerability CVE-2020-0729 in the LNK file, which may not be well understood by many people. In order to make you understand better, the editor summarizes the following content for you. I hope you can get something according to this article.

The following is an excerpt from the CVE-2020-0729 section with some minor modifications.

Microsoft released 99 CVE security patches on Patch Tuesday in February 2020, and it's hard to believe that so many vulnerabilities have been fixed in a month. Because of the widespread use, many people are concerned about the Scripting Engine vulnerability, but there is also a "high risk" vulnerability that is also very important-CVE-2020-0729, which is a RCE vulnerability in an Windows LNK file (that is, shortcuts). This vulnerability is remarkable in part because vulnerabilities in LNK files were often used to spread malware, such as the famous Stuxnet, and in most cases, simply browsing to the folder containing the malicious LNK file was sufficient to trigger the vulnerability, whether locally or on a network share. So the question becomes, can this RCE vulnerability be triggered in the same way as previous LNK file vulnerabilities? Because the LNK file is in binary format and contains only some top-level structural information, more research is needed to answer this question.

Start the analysis

For us research teams, Microsoft's "Tuesday patch day" means we need to start studying vulnerabilities, generally unpacking the security only patch pack for a given Windows platform, and trying to locate the vulnerability-related files in the patch based on Microsoft's suggested information. The February fix pack does not include updates to commonly used DLL files related to working with LNK files, such as shell32.dll and windows.storage.dll, which makes it difficult to find out what the problem is. However, after a close examination of the file list, we found a special DLL file: StructuredQuery.dll. This DLL file is special in part because we have seen formal vulnerabilities involving StructuredQuery, such as CVE-2018-0825, but there is no similar recommendation in this Tuesday patch. So what is the relationship between LNK files and StructuredQuery? We searched StructuredQuery in Microsoft's developer Center and found a document about the header file structuredquery.h, which mentioned that the header file was used for Windows Search, which is the connection between the LNK file and StructuredQuery.

Many functions of LNK files

It is well known that LNK files contain binary structures that create shortcuts to files or folders, but few people know that LNK files can also contain search results directly. Typically, when users search for files in Windows 10, a "Search" tab appears on the Explorer ribbon, where users can optimize the search function, set advanced search options, and save the current search results for later use. The search result is a XML file with the extension ".search-ms", and there is only a simple documentation for files in this format.

In addition to saving search results in this way, if you drag the search results icon on the address bar in the following image to another folder, a LNK file is created that contains the serialized results of the data in the "search-ms" XML file.

Now that we know how to do this, let's take a look at the changes in StructuredQuery in the patch using BinDiff.

As you can see, only one function has changed-- StructuredQuery1::ReadPROPVARIANT (). Since the similarity is only 81%, the change of the function can be said to be quite large, which can be confirmed by comparing the flow charts of the two:

So what does this function do in the LNK file? This requires an in-depth study of the search-ms file structure in the LNK file mentioned above.

According to the Shell Link (.LNK) binary file format specification, the Windows shell link file contains several necessary components and several optional components, and each shell link file must contain at least one Shell Link Header in the following format:

Unless otherwise noted, all multibyte fields are represented in small-end mode.

The LinkFlags field is used to set whether there is an optional structure and various other options, such as whether strings in the shell link file use Unicode encoding. The following is the structural distribution of the LinkFlags field:

One flag is set in most cases-- HasLinkTargetIDList, which is represented by the position "A" in the figure, which is the least significant bit of the first byte in the LinkFlags field. If this flag is set, the Shell Link Header must be followed by a LinkTargetIDList structure that defines the target of the link and has the following structure:

Where the IDList structure contains a list of item ID.

The function of ItemIDList is similar to that of a file path, where each ItemID corresponds to an item in the path structure and can represent a real folder in the file system, or a virtual folder such as "Control Panel" or "saved search", or other forms of embedded data, to perform specific functions as "shortcuts". For more information about ItemID and ItemIDList, see Microsoft's Common Explorer Concepts). What is important for this vulnerability is the structure of ItemIDList and ItemID in the LNK file that contains the search results.

When a user creates a shortcut that holds search results, the shortcut contains an IDList structure that starts with Delegate Folder ItemID, followed by a search-related User Property View ItemID. Generally speaking, ItemID begins with the following structure:

The two bytes starting with the offset 0x0004 are used in conjunction with ItemSize and ItemType to determine the type of ItemID. For example, if ItemSize is 0x14dyItemType is 0x1F, and the two bytes at the offset 0x0004 are greater than ItemSize, you can think of the rest of ItemID as a 16-byte globally unique identifier (GUID), which is usually the structure of the first ItemID in the LNK file, pointing to a file or folder. If the ItemSize is greater than the size required to contain the GUID, but less than the two bytes at the offset 0x0004, the remaining data after the GUID is called ExtraDataBlock, and the first two bytes of this data is a size field that defines the number of bytes of the subsequent data.

For Delegate Folder ItemID, this location also has a 2-byte size field, which represents the number of bytes in the remaining structure. It has the following structure:

All the GUID in the LNK file is stored in the form of RPC IDL, that is, in the first three fields of GUID, each field is stored as a whole in small-end mode (it can be thought of as a DWORD followed by two WORD), and each byte in the last two fields is independent. For example, GUID {01234567-1234-ABCD-9876-0123456789AB} can be represented in the following binary:

\ x67\ x45\ x23\ X01\ x34\ x12\ xCD\ xAB\ x98\ x76\ X01\ x23\ x45\ x67\ x89\ xAB

The specific purpose of Delegate Folder ItemID is not documented, but the class specified in the Item GUID field in this item is likely to be used to handle the next ItemID, so the root namespace of the entire path structure is the class specified by Item GUID. If the LNK file contains search results, the Item GUID is {04731B67-D933-450A-90E6-4ACD2E9408FE}, which represents CLSID_SearchFolder and is a reference to the Windows.Storage.Search.dll file.

User Property View ItemID follows Delegate Folder ItemID, and its structure is similar to Delegate Folder ItemID:

The PropertyStoreList field is important and contains one or more serialized PropertyStore entries, each with the following structure:

The Property Store Data field consists of a series of properties, all of which belong to the class specified in the Property Format GUID field, each identified by a numeric ID, the property ID or PID. The combination of PID and Property Format GUID is the property key, or PKEY. If the Property Format GUID field is equal to {D5CDD505-2E9C-101B-9397-08002B2CF9AE}, the PKEY is determined slightly differently, and each property becomes part of the "Property Bag" with the following structure:

Some elements in the property package have Name fields in the format Key:FMTID or Key:PID, and these elements determine the PKEY of the remaining elements, in which case the other elements in the property package must be arranged in order for them to take effect.

If the Property Format GUID field is not equal to the guid value we mentioned above ({D5CDD505-2E9C-101B-9397-08002B2CF9AE}), then each attribute is identified by the integer value PID, which has the following structure:

The TypedPropertyValue field represents the type value of an attribute in the property set. For more information, please see the summary of Microsoft Object Linking and Embedding (OLE) Property Set Data Structures specification 2.15.

Many different PKEY are defined in the header file of Windows SDK, but many PKEY are not recorded and can only be identified by checking the references in the debug symbols of the relevant library files. For the LNK file that contains the search results, the Property Format GUID field in the first PropertyStore in the User Property View ItemID is {1E3EE840-BC2B-476C-8237-2ACD1A839B22}, containing an attribute with an ID value of 2, corresponding to PKEY_FilterInfo.

In the TypedPropertyValue structure in PKEY_FilterInfo, there is a VT_STREAM in the optional value of the type field, which means that the TypedPropertyValue structure consists of a type value of 0x0042, two padding bytes, and an IndirectPropertyName. IndirectPropertyName refers to the name of an optional stream data that may contain PropertySetStream packages for simple property set storage or "CONTENTS" stream elements for non-simple property set storage, as specified in Microsoft documentation. IndirectPropertyName starts with the wide string "prop", followed by a decimal string, which is an attribute identifier in the PropertySet package, because the LNK file uses properties of serialized VT_STREAM type, so when you look at IndirectPropertyName, just check to see if it starts with "prop", and the following values are ignored. In this case, the structure of TypedPropertyValue is as follows:

The content of the Stream Data field depends on the PKEY value of the stream attribute. For PKEY_FilterInfo, Stream Data contains a PropertyStoreList and more serialized PropertyStore, which is structured as follows:

The PropertyStoreList in PKEY_FilterInfo is the serialization result of the "conditions" tag in the. search-ms file, and the structure of the "conditions" tag is as follows:

The exact function of the attribute tag is not documented, but the attribute tag contains a GUID for the CONDITION_HISTORY and a CLSID for the CConditionHistory class in the StructuredQuery, which means that this nested condition and attribute structure may represent the history of search results, while the chs attribute in the attribute tag indicates whether any other history exists. Serialize the above structure and express it as a PropertyStore, which is put into the PropertyStoreList of the PKEY_FilterInfo, and the PropertyStoreList becomes a property package, where the Property Format GUID of the property is the {D5CDD505-2E9C-101B-9397-08002B2CF9AE} mentioned above. More specifically, the serialized Conditions structure is contained in a property of type VT_STREAM that is identified by the "Condition" of the name field. To sum up, we get a PropertyStore term with the following structure:

Where Condition object is usually a "Leaf Condition" or a "Compound Condition" containing multiple nested objects, where the nested objects can be one or more Leaf Condition or other Compound Condition. Both condition object begin with the following structure:

Where the Condition GUID of Leaf Condition is {52F15C89-5A17-48E1-BBCD-46A3F89C7CC2} and the Condition GUID of Compound Condition is {116F8D13-101E-4FA5-84D4-FF8279381935}. The Attributes field consists of attribute structures, and the number of attribute structures is determined by the Number of Attributes field. Each attribute structure corresponds to an attribute tag in the. search-ms file, starting with the following structure:

The remaining structure of Attribute is determined by AttributeID and Attribute CLSID. If it is the CONDITION_HISTORY attribute mentioned above, then the AttributeID field is set to {9554087B-CEB6-45AB-99FF-50E8428E860D}, the Attribute CLSID field is set to {C64B9B66-E53D-4C56-B9AE-FEDE4EE95DB1}, and the remaining structure is a ConditionHistory object with the following structure. Note that the field name is the same as the attribute name of the attribute tag in XML:

If the value of the field has_nested_condition is greater than 0, then CONDITION_HISTORY attribute has a nested Conditon object, and the Conditon object itself may have a nested Conditon object.

After reading the top-level Attributes and all its nested structures, the structure of Compound Condition and Leaf Condition begins to be different, and the remaining structure of Compound Condition is as follows, where offset is the offset from the end of the Attributes field:

The numFixedObjects field determines how much condition (usually Leaf Condition) is followed.

The remaining structure of Leaf Condition is as follows, where offset is the offset from the end of the Attributes field:

Whether the TokenInformationComplete field appears depends on whether the corresponding TokenInformationComplete flag above is set. If it is not set, the field does not exist, followed by the next TokenInformationComplete flag. If so, the structure is as follows:

To sum up, the following figure shows the possible simplest structure of a LNK file with search results. For simplicity, all irrelevant structures have been deleted:

Search results that contain only one Leaf Condition have the simplest structure described above, but in most cases, the LNK file that contains the search results will have a Compound Condition and many nested structures that contain Leaf Condition.

Loopholes

Now that we know the core structure of the LNK file that holds the search results, we can now focus on the vulnerability itself, which lies in how to handle the PropertyVariant field of Leaf Condition.

The PropertyVariant field of Leaf Condition is basically a PROPVARIANT structure, which consists of a 2-byte type and data belonging to that particular type. It is important to note that the PROPVARIANT structure in StructuredQuery is somewhat different and usually does not have the padding bytes defined in the Microsoft specification.

It is also important to note that if the 2-byte type value is a combination of 0x1000 (VT_VECTOR) and another type value, there will be multiple values of that particular type in the structure.

The parsing of the PropertyVariant field is done by the problematic function StructuredQuery1::ReadPROPVARIANT () that we mentioned earlier. This function first reads in a 2-byte type value to check whether the VT_ARRAY bit (0x2000) is set in the value, because StructuredQuery does not support this option:

The function then checks to see if the type is VT_UI4 (0x0013), and if not, enters the switch statement to handle all other types.

The vulnerability lies in how to handle PropertyVariant of type VT_VARIANT (0x000C). The VT_VARIANT type is usually used with VT_VECTOR to form a series of PropertyVariant structures. In other words, this type is like an array, and each element in the array can be any data type.

If the type of PropertyVariant is set to VT_VARIANT (0x000C), the type check checks whether the VT_VECTOR bit is set.

If the VT_VECTOR bit is not set, the ReadPROPVARIANT () function allocates a 24-byte buffer by calling CoTaskMemAlloc (), which is passed to the recursive call to ReadPROPVARIANT () in order to populate the buffer with the attribute immediately after the VT_VARIANT field. But the buffer is not initialized (for example, filling it with null bytes) before it is passed to ReadPROPVARIANT ().

If the above nested property type is VT_CF (0X0047), which contains a pointer to the clipboard data, ReadPROPVARIANT () also checks the VT_VECTOR bit, and if it is not set, the function attempts to write to the next four bytes in the stream, specified by an 8-byte value in the previously allocated 24-byte buffer.

Because the buffer is not initialized, data is written to an undefined area of memory, which can lead to arbitrary code execution. In the following figure, the exception displayed by WinDBG (with Page Heap enabled) and the stack trace indicate that the program is attempting to write data:

If an attacker can correctly manipulate the memory distribution so that the uninitialized buffer contains a value controlled by the attacker, they can write any 4 bytes of data at once to the area of memory that the value points to.

The vulnerability analysis of the solution is incomplete, and for this vulnerability, the solution is simple: initialize the allocated 24-byte buffer to null bytes to ensure that the attacker cannot use the data left before the memory location as the contents of the buffer. Microsoft released their patch in February, and it should be noted that Microsoft fixed another LNK vulnerability in March, but this vulnerability in March has nothing to do with this vulnerability.

After reading the above, do you have any further understanding of how to analyze the remote command execution vulnerability CVE-2020-0729 in the LNK file? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

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.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report