Reading view

There are new articles available, click to refresh the page.

Pwn2Own Returns to Miami Beach for 2023

¡Bienvenidos de nuevo a Miami!

Even as we make our final preparations for our consumer-focused contest in Toronto, we’re already looking ahead to warmer climes and returning to the S4 Conference in Miami for our ICS/SCADA-themed event. Pwn2Own returns to South Beach on February 14-16, 2023, and for this year’s event, we’ve refined our target list to include the latest trends in the ICS world. As we did last year, we’ll have contestants both in person and around the world demonstrating the latest exploits on OPC Unified Architecture (OPC UA) Servers, OPC UA Clients, Data Gateways, and Edge systems.

Our inaugural Pwn2Own Miami was held back in January 2020 at the S4 Conference, and we had a fantastic time as we awarded over $280,000 USD in cash and prizes for 24 unique 0-day vulnerabilities. Last year, we awarded $400,000 for 26 unique 0-days (plus a few bug collisions). At that event, we crowned Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) Master of Pwn for their multiple successful exploits. We’ll see if they return in 2023 to defend their crown.

This contest is not possible without the participation and help of our partners within the ICS community, and we would like to especially thank the folks at the OPC Foundation and AVEVA for their expertise and guidance. The cooperation of those within the ICS/SCADA community is essential in ensuring we have the right categories and targets. Pwn2Own Miami seeks to harden these platforms by revealing vulnerabilities and providing that research to the vendors. The goal is always to get these bugs fixed before they’re actively exploited by attackers. ICS vendors have been instrumental in making that goal a reality.

The 2023 edition of Pwn2Own Miami has four categories:

·      OPC Unified Architecture (OPC UA) Server
·      OPC Unified Architecture (OPC UA) Client
·      Data Gateway
·      Edge systems

You’ll notice these are different categories from previous years. These differences reflect the changing state of the ICS industry and better reflect current threats to SCADA systems. Let’s look at the details of each category.

OPC UA Server Category

The OPC Unified Architecture (UA) is a platform-independent, service-oriented architecture that integrates all the functionality of the individual OPC Classic specifications into one extensible framework. OPC UA serves as the universal translator protocol in the ICS world. It is used by almost all ICS products to send data between disparate vendor systems. While we’ve had OPC UA targets in the past, for this event, we’ve set up distinct Server and Client categories.

An attempt in this category must be launched against the target’s exposed network services from the contestant’s laptop within the contest network. An entry in the category must result in either a denial-of-service condition, arbitrary code execution, credential theft, or a bypass of the trusted application check.

The Credential Theft target should prove interesting. For this scenario, the contestant must create a session with a trusted certificate but use credentials acquired by either decrypting a password from an ongoing session or by abusing a vulnerability that allows for the retrieval of the stored password from the server. The server will be configured with an ‘admin’ account with a random password that is 12-16 characters long. A successful entry must log in using a legitimate client after the password is retrieved by some means. Brute force attacks won’t be allowed.

For the “bypass trusted application check” scenario, the contestant must bypass the trusted application check that occurs after the creation of a secure channel. Entries that bypass the check by manipulating the server security configuration are out of scope. There are additional requirements for this target, so definitely read the rules carefully if you want to enter.

Here is the full list of targets for the OPC UA Server category:

OPC UA Client Category

Similar to the Server category, we’ll have specific OPA UA Clients available to target. Again, the “bypass trusted application check” scenario must meet specific criteria, so you should check out the rules for a full description.

Here is the full list of targets for the OPC US Client category:

Data Gateway Category

This category focuses on devices that connect other devices of varying protocols. There are two products in this category. The first is the Triangle Microworks SCADA Data Gateway product. Triangle Microworks makes the most widely used DNP3 protocol stack.  The other is the Softing Secure Integration Server. According to their website, “Secure Integration Server covers the full range of OPC UA security features and enables the implementation of state-of-the-art security solutions.” We’ll see if that holds true throughout the contest.

A successful entry in this category must result in arbitrary code execution.

Edge Category

This category is new for 2023 and reflects how edge devices are often used in ICS/SCADA networks to manage and maintain systems. For this year’s event, we’ll have the AVEVA Edge Data Store as our sole target in this category. Edge Data Store collects, stores, and provides data from remote and uncrewed assets. This is an exciting addition to the contest, and we look forward to seeing what exploits researchers demonstrate against this target.

A successful entry in this category must result in arbitrary code execution.

Master of Pwn

No Pwn2Own contest would be complete without crowning a Master of Pwn, and Pwn2Own Miami is no exception. Earning the title comes with a slick trophy and  65,000 ZDI reward points (instant Platinum status in 2024, which includes a one-time bonus estimated at $25,000).

For those not familiar with how it works, Master of Pwn points are accumulated for each successful attempt. While only the first demonstration in a category wins the full cash award, each successful entry claims the full number of Master of Pwn points. Since the order of attempts is determined by a random draw, those who receive later slots can still claim the Master of Pwn title – even if they earn a lower cash payout.

To add to the excitement, there are penalties for withdrawing from an attempt once you register for it. If a contestant decides to withdraw from the registered attempt before the actual attempt, the Master of Pwn points for that attempt will be divided by 2 and deducted from the contestant's point total for the contest. Since Pwn2Own is now often a team competition, along with the initial deduction of points, the same number of Master of Pwn points will also be deducted from all contestant teams from the same company.

The Complete Details

The full set of rules for Pwn2Own Miami 2023 can be found here. They may be changed at any time without notice. Anyone thinking about participating should read the rules thoroughly and completely.

Registration is required to ensure we have sufficient resources on hand at the event. Please contact ZDI at [email protected] to begin the registration process. (Email only, please; queries via Twitter, blog post, or other means will not be acknowledged or answered.) If we receive more than one registration for any category, we’ll hold a random drawing to determine the order of attempts. Contest registration closes at 5:00 p.m. Eastern Standard Time on February 9, 2023.

The Results

We’ll be live blogging results throughout the competition. Be sure to keep an eye on the blog for the latest results. We’ll also be posting results and videos to Twitter, YouTube, Mastodon, LinkedIn, and Instagram, so follow us on your favorite flavor of social media for the latest news from the event.

We look forward to seeing everyone again in Miami, and we look forward to seeing what new exploits and attack techniques they bring with them.

 

 

©2022 Trend Micro Incorporated. All rights reserved. PWN2OWN, ZERO DAY INITIATIVE, ZDI, and Trend Micro are trademarks or registered trademarks of Trend Micro Incorporated. All other trademarks and trade names are the property of their respective owners.

Pwn2Own Returns to Miami Beach for 2023

CVE-2022-40300: SQL Injection in ManageEngine Privileged Access Management

In this excerpt of a Trend Micro Vulnerability Research Service vulnerability report, Justin Hung and Dusan Stevanovic of the Trend Micro Research Team detail a recently patched SQL injection vulnerability in Zoho ManageEngine products. The bug is due to improper validation of resource types in the AutoLogonHelperUtil class. Successful exploitation of this vulnerability could lead to arbitrary SQL code execution in the security context of the database service, which runs with SYSTEM privileges. The following is a portion of their write-up covering CVE-2022-3236, with a few minimal modifications.


ManageEngine recently patched a SQL injection vulnerability bug in their Password Manager Pro, PAM360, and Access Manager Plus products. The vulnerability is due to improper validation of resource types in the AutoLogonHelperUtil class. A remote attacker can exploit the vulnerability by sending a crafted request to the target server. Successful exploitation could lead to arbitrary SQL code execution in the security context of the database service, which runs with SYSTEM privileges.

The Vulnerability

Password Manager Pro is a secure vault for storing and managing shared sensitive information such as passwords, documents, and digital identities of enterprises. The product is also included in other two similar ManageEngine products: PAM360 and Access Manager Plus. A user can access the web console on these products through HTTPS requests via the following ports:

The HTTP request body may contain data of various types. The data type is indicated in the Content-Type header field. One of the standardized types is multipart, which contains various subtypes that share a common syntax. The most widely used subtype of multipart type is multipart/form-data. Multipart/form-data is made up of multiple parts, each of which contains a Content-Disposition header. Each part is separated by a string of characters. The string of characters separating the parts is defined by the boundary keyword found in the Content-Type header line. The Content-Disposition header contains parameters in “name=value” format. Additional header lines may be present in each part; each header line is separated by a CRLF sequence. The last header line is terminated by two consecutive CRLFs sequences and the form element’s data follows. The filename parameter in a ContentDisposition header provides a suggested file name to be used if the element's data is detached and stored in a separate file.

A user with admin privileges can add/edit a resource type via Password Manager Pro web interface by clicking the menu “Resources” -> “Resource Types” -> “Add” (or “Edit”) and a HTTP multipart/form-data request will be submitted to the “AddResourceType.ve” endpoint, as an example shown below:

where several form-data parts are transferred in the request, like “TYPEID”, “dnsname_label”, “resLabChkName__1”, etc. The data carried in the multipart/form-data part with a name parameter value of “resourceType” represents the name of the resource type, which is relevant to the vulnerability in this report.

An SQL injection vulnerability exists in Password Manager Pro. The vulnerability is due to a lack of sanitization of the name of the resource type in the Java class AutoLogonHelperUtil. The AutoLogonHelperUtil class is used by several controller classes, like AutologonController and PasswordViewController, to construct a partial SQL statement related to the query for existing resource types. For example, if a user clicks the menu “Connections” on the web admin interface, a request will be sent to “AutoLogonPasswords.ec” endpoint, and the includeView() method of ViewProcessorServlet class is called. The includeView() method will use AutologonController class to handle the request. The AutologonController class is derived from the SqlViewController class and its updateViewModel() method is called to process the request. The updateViewModel() method will first call the initializeSQL() method to get an SQL statement. It then calls the getAsTableModel() method of the SQLQueryAPI class to execute the SQL statement.

In the initializeSQL() method, it will call the getSQLString() method of the AutologonController class to get the SQL statement, which will invoke the getFilledString() method of the TemplateAPI class. In the getFilledString() method, it will call the getVariableValue() method of the AutologonController. The getVariableValue() method will use the getOSTypeCriteriaForView() method of the AutoLogonHelperUtil class to construct a partial SQL statement. The getOSTypeCriteriaForView() will call the getOSTypeCriteria() method, which uses getOSTypeList() to read all resource types from the database. It then uses these resource types to build a partial SQL statement as below:

PTRX_OSTYPE in ( <resource type 1>, <resource type 2>, ..., <resource type n> )

where <resource type n> represents a resource type name queried from a database by the getOSTypeList() method. Then, this partial SQL statement will be returned to getOSTypeCriteriaForView() and then be returned to the getFilledString(). The getFilledString() will use this partial SQL statement to generate the final complete SQL statement and return it back to getSQLString().

However, the getOSTypeCriteria() method of the AutoLogonHelperUtil class does not sanitize the name of the resource type (returned from getOSTypeList()) for SQL injection characters before using it to create a partial SQL statement. An attacker can therefore first add a new resource type (or edit an existing resource type) with a crafted resource type name containing a malicious SQL command, and then click a menu such as “Connections” to invoke the methods of the AutoLogonHelperUtil class which will use the malicious resource type name to construct a SQL statement. This could trigger the execution of the injected SQL command.

A remote authenticated attacker can exploit the vulnerability by sending a crafted request to the target server. Successful exploitation could lead to arbitrary SQL code execution in the security context of the database service, which runs with SYSTEM privileges.

Detection Guidance

To detect an attack exploiting this vulnerability, the detection device must monitor and parse traffic on the ports listed above. Note that the traffic is encrypted via HTTPS and should be decrypted before performing the following steps.

The detection device must inspect HTTP POST requests to a Request-URI containing the following string:

        /AddResourceType.ve

If found, the detection device must inspect each part of the multipart/form-data parts in the body of the request. In each part, the detection device must search for the Content-Disposition header and its name parameter to see if its value is “resourceType”. If found, the detection device must continue to inspect the data carried in this multipart/ form-data part to see if it contains the single-quote character “' (\x27)”. If found, the traffic should be considered malicious and an attack exploiting this vulnerability is likely underway. An example of malicious requests is shown below:

Additional notes:

• The string matching for the Request-URI and “POST” should be performed in a case-sensitive manner, while other string matching like “name”, “resourceType” and “Content-Disposition” should be performed in a case-insensitive manner.
• The Request-URI may be URL encoded and should be decoded before applying the detection guidance.
• It is possible that the single quote “' (\x27)” is naturally found in the resource type name resulting in false positives. However, in normal cases, the possibility should be low.

Conclusion

ManageEngine patched this and other SQL injections in September. Interestingly, the patch for PAM360 came a day after the patches for Password Manager Pro and Access Manager Plus. The vendor offers no other workarounds. Applying these updates is the only way to fully protect yourself from these bugs.

Special thanks to Justin Hung and Dusan Stevanovic of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit http://go.trendmicro.com/tis/.

The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the team on Twitter, Mastodon, LinkedIn, or Instagram for the latest in exploit techniques and security patches.

CVE-2022-40300: SQL Injection in ManageEngine Privileged Access Management

Control Your Types or Get Pwned: Remote Code Execution in Exchange PowerShell Backend

By now you have likely already heard about the in-the-wild exploitation of Exchange Server, chaining CVE-2022-41040 and CVE-2022-41082. It was originally submitted to the ZDI program by the researcher known as “DA-0x43-Dx4-DA-Hx2-Tx2-TP-S-Q from GTSC”. After successful validation, it was immediately submitted to Microsoft. They patched both bugs along with several other Exchange vulnerabilities in the November Patch Tuesday release.

It is a beautiful chain, with an ingenious vector for gaining remote code execution. The tricky part is that it can be exploited in multiple ways, making both mitigation and detection harder. This blog post is divided into two main parts:

·       Part 1 – where we review details of the good old ProxyShell Path Confusion vulnerability (CVE-2021-34473), and we show that it can still be abused by a low-privileged user.
·       Part 2 – where we present the novel RCE vector in the Exchange PowerShell backend.

 Here’s a quick demonstration of the bugs in action:

Part 1: The ProxyShell Path Confusion for Every User (CVE-2022-41040)

There is a great chance that you are already familiar with the original ProxyShell Path Confusion vulnerability (CVE-2021-34473), which allowed Orange Tsai to access the Exchange PowerShell backend during Pwn2Own Vancouver 2021. If you are not, I encourage you to read the details in this blog post.

Microsoft patched this vulnerability in July of 2021. However, it turned out that the patch did not address the root cause of the vulnerability. Post-patch, unauthenticated attackers are no longer able to exploit it due to the implemented access restrictions, but the root cause remains.

First, let’s see what happens if we try to exploit it without authentication.

HTTP Request

HTTP Response

As expected, a 401 Unauthorized error was returned. However, can you spot something interesting in the response? The server says that we can try to authenticate with either Basic or NTLM authentication. Let’s give it a shot.

HTTP Request

HTTP Response

Exchange says that it is cool now! This shows us that:

·       The ProxyShell Path Confusion still exists, as we can reach the PowerShell backend through the autodiscover endpoints.
·       As the autodiscover endpoints allow the use of legacy authentication (NTLM and Basic authentication) by default, we can access those endpoints by providing valid credentials. After successful authentication, our request will be redirected to the selected backend service.

Legacy authentication in Exchange is described by Microsoft here. The following screenshot presents a fragment of the table included in the previously mentioned webpage.

Figure 1 - Legacy authentication in Exchange services, source: https://learn.microsoft.com/

According to the documentation and some manual testing, it seems that an Exchange instance was protected against this vulnerability if:

·       A custom protection mechanism was deployed that blocks the Autodiscover SSRF vector (for example, on the basis of the URL), or
·       If legacy authentication was blocked for the Autodiscover service. This can be done with a single command (though an Exchange Server restart is probably required):

Set-AuthenticationPolicy -BlockLegacyAuthAutodiscover:$true

So far, we have discovered that an authenticated user can access the Exchange PowerShell backend. We will now proceed to the second part of this blog post to discuss how this can be exploited for remote code execution.

Part 2: PowerShell Remoting Objects Conversions – Be Careful or Be Pwned (CVE-2022-41082)

In this part, we will focus on the remote code execution vulnerability in the Exchange PowerShell backend. It is a particularly interesting vulnerability, and is based on two aspects:

·       PowerShell Remoting conversions and instantiations.
·       Exchange custom converters.

It has been a very long ride for me to understand this vulnerability fully and I find that I am still learning more about PowerShell Remoting. The PowerShell Remoting Protocol has a very extensive specifications and there are some hidden treasures in there. You may want to look at the official documentation, although I will try to guide you through the most important aspects. The discussion here should be enough to understand the vulnerability.

PowerShell Remoting Conversions Basics and Exchange Converters

There are several ways in which serialized objects can be passed to a PowerShell Remoting instance. We can divide those objects into two main categories:

·       Primitive type objects
·       Complex objects

Primitive types are not always what you would think of as “primitive”. We have some basic types here such as strings and byte arrays, but “primitive types” also include types such as URI, XMLDocument and ScriptBlock (the last of which is blocked by default in Exchange). Primitive type objects can usually be specified with a single XML tag, for example:

Complex objects have a completely different representation. Let’s take a quick look at the example from the documentation:

First, we can see that the object is specified with the “Obj” tag. Then, we use the “TN” and “T” tags to specify the object type. Here, we have the System.Drawing.Point type, which inherits from System.ValueType.

An object can be constructed in multiple ways. Shown here is probably the simplest case: direct specification of properties. The “Props” tag defines the properties of the object. You can verify this by comparing the presented serialized object and the class documentation.

One may ask: How does PowerShell Remoting deserialize objects? Sadly, there is no single, easy answer here. PowerShell Remoting implements multiple object deserialization (or conversion) mechanisms, including quite complex logic and as well as some validation. I will focus on two main aspects, which are crucial for our vulnerability.

a)     Verifying if the specified type can be deserialized
b)     Converting (deserializing) the object

Which Types Can Be Deserialized?

PowerShell Remoting will not deserialize all .NET types. By default, it allows those types related to the remoting protocol itself. However, the list of allowed types can be extended. Exchange does that through two files:

·       Exchange.types.ps1xml
·       Exchange.partial.types.ps1xml

 An example entry included in those files will be presented soon.

In general, the type specified in the payload that can be deserialized is referenced as the “Target Type For Deserialization”. Let’s move to the second part.

How Is Conversion Performed?

In general, conversion is done in the following way.

·       Retrieve properties/member sets, deserializing complex values if necessary.
·       Verify that this type is allowed to be deserialized.
·       If yes, perform the conversion.

Now the most important part. PowerShell Remoting implements multiple conversion routines. In order to decide which converter should be used, the System.Management.Automation.LanguagePrimitives.FigureConversion(Type, Type) method is used. It accepts two input arguments:

·       Type fromType – the type from which the object will be obtained (for example, string or byte array).
·       Type toType – the target type for deserialization.

The FigureConversion method contains logic to find a proper converter. If it is not able to find any converter, it will throw an exception.

As already mentioned, multiple converters are available. However, the most interesting for us are:

·       ConvertViaParseMethod – invokes Parse(String) method on the target type. In this case, we control the string argument.
·       ConvertViaConstructor – invokes the single-argument constructor that accepts an argument of type fromType. In this case, we can control the argument, but limitations apply.
·       ConvertViaCast – invokes the proper cast operator, which could be an implicit or explicit cast.
·       ConvertViaNoArgumentConstructor – invokes the no-argument constructor and sets the public properties using reflection.
·       CustomConverter – there are also some custom converters specified.

As we can see, these conversions are very powerful and provide a strong reflection primitive. In fact, some of them were already mentioned in the well-known Friday the 13th JSON Attacks Black Hat paper. As we have mentioned, though, the toType is validated and we are not able to use these converters to instantiate objects of arbitrary type. That would certainly be a major security hole.

SerializationTypeConverter – Exchange Custom Converter

Let’s have a look at one particular item specified in the Exchange.types.ps1xml file:

There are several basic things that we can learn from this XML fragment:

·       Microsoft.Exchange.Data.IPvxAddress class is included in the list of the allowed target types.
·       The TargetTypeForDeserialization member gives the full class name.
·       A custom type converter is defined: Microsoft.Exchange.Data.SerializationTypeConverter

The SerializationTypeConverter wraps the BinaryFormatter serializer with ExchangeBinaryFormatterFactory. That way, the BinaryFormatter instance created will make use of the allow and block lists. 

To sum up, some of our types (or members) can be retrieved through BinaryFormatter deserialization. Those types must be included in the SerializationTypeConverter allowlist, though. Moreover, custom converters are last-resort converters. Before they are used, PowerShell Remoting will try to retrieve the object through a constructor or a Parse method.

RCE Payload Walkthrough

It is high time to show you the RCE payload and see what happens during the conversion.

This XML fragment presents the specification of the “-Identity” argument of the “Get-Mailbox” Exchange Powershell cmdlet. We have divided the payload into three sections: Object type, Properties, and Payload.

·       Object type section – specifies that there will be an object of type System.ServiceProcess.ServiceController.
·       Properties section – specifies the properties of the object. One thing that should catch your attention here is the property with the name TargetTypeForDeserialization. You should also notice the byte array with the name SerializationData. (Note that Powershell Remoting accepts an array of bytes in the form of a base64 encoded string).
·       Payload section – contains XML in the form of a string. The XML is a XAML deserialization gadget based on ObjectDataProvider.

Getting Control over TargetTypeForDeserialization

In the first step, we are going to focus on the Properties section of the RCE payload. Before we do that, let’s quickly look at some fragments of the deserialization code. The majority of the deserialization routines are implemented in the System.Management.Automation.InternalDeserializer class.

Let’s begin with this fragment of the ReadOneObject(out string) method:

At [1], it invokes the ReadOneDeserializedObject method, which may return an object.

At [2], the code flow continues, provided an object has been returned. We will focus on this part later.

Let’s quickly look at the ReadOneDeserializedObject method. It goes through the XML tags and executes appropriate actions, depending on the tag. However, only one line is particularly interesting for us.

At [1], it calls ReadPSObject. This happens when the tag name is equal to “Obj”.

Finally, we analyze a fragment of the ReadPSObject function.

At [1], the code retrieves the type names (strings) from the <TN> tag.

At [2], the code retrieves the properties from the <Props> tag.

At [3], the code retrieves the member set from the <MS> tag.

At [4], the code tries to read the primary type (such as string or byte array).

At [5], the code initializes a new deserialization procedure, provided that the tag is an <Obj> tag.

 

So far, we have seen how InternalDeserializer parses the Powershell Remoting XML. As shown earlier, the Properties section of the payload contains a <Props> tag. It seems that we must look at the ReadProperties method.

At [1], the adaptedMembers property of the PSObject object is set to some PowerShell-related collection.

At [2], the property name is obtained (from the N attribute).

At [3], the code again invokes ReadOneObject in order to deserialize the nested object.

At [4], it instantiates a PSProperty object, based on the deserialized value and the property name.

Finally, at [5], it extends adaptedMembers by adding the new PSProperty. This is a crucial step, pay close attention to this.

Let’s again look at the Payload section of our RCE payload:

We have two properties defined here:

·       The Name property, which is of type string and whose value is the string “Type”.

·       The TargetTypeForDeserialization property, whose value is a complex object specified as follows:

o   The type (TN tag) is System.Exception.
o   There is a value stored as a base64 encoded string, representing a byte array.

We have already seen that nested objects (defined with the Obj tag) are also deserialized with the ReadOneObject method. We have already looked at its first part (object retrieval). Now, let’s see what happens further:

At [1], the code retrieves the Type targetTypeForDeserialization through the GetTargetTypeForDeserialization method.

At [2], the code tries to retrieve a new object through the LanguagePrimitives.ConvertTo method (if GetTargetTypeForDeserialization returned anything). The targetTypeForDeserialization is one of the inputs. Another input is the object obtained with the already analyzed ReadOneDeserializedObject method.

As we have specified the object of the System.Exception type (TN tag), the GetTargetTypeForDeserialization method will return the System.Exception type. Why does the exploit use Exception? For two reasons:

·       It is included in the allowlist exchange.partial.types.ps1xml.
·       It has a custom converter registered: Microsoft.Exchange.Data.SerializationTypeConverter.

 These two conditions are important because they allow the object to be retrieved using the SerializationTypeConverter, which was discussed above as a wrapper for BinaryFormatter. Note that there are also various other types available besides System.Exception that meet the two conditions mentioned here, and those types could be used as an alternative to System.Exception.

 Have you ever tried to serialize an object of type Type? If yes, you probably know that it is serialized as an instance of System.UnitySerializationHolder. If you base64-decode the string provided in the Properties part of our payload, you will quickly realize that it is a System.UnitySerializationHolder with the following properties:

·       m_unityType = 0x04,
·       m_assemblyName = "PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35",
·       m_data = "System.Windows.Markup.XamlReader".

To sum up, our byte array holds the object, which constructs a XamlReader type upon deserialization! That is why we want to use the SerializationTypeConverter – it allows us to retrieve an object of type Type. An immediate difficulty is apparent here, though, because Exchange’s BinaryFormatter is limited to types on the allowlist. Hence, it’s not clear why the deserialization of this byte array should succeed. Amazingly, though, System.UnitySerializationHolder is included in the SerializationTypeConverter’s list of allowed types!

Let’s see how it looks in the debugger:

Figure 2 - Deserialization leading to the retrieval of the XamlReader Type

Even though the targetTypeForDeserialization is Exception, LanguagePrimitives.ConvertTo returned the Type object for XamlReader (see variable obj2). This happens because the final type of the retrieved object is not verified. Finally, this Type object will be added to the adaptedMembers collection (see the ReadProperties method).

Getting Code Execution Through XamlReader, or Any Other Class

We have already deserialized the TargetTypeForDeserialization property, which is a Type object for the XamlReader type. Perfect! As you might expect, allowing users to obtain an arbitrary Type object through deserialization is not the best idea. But we still need to understand: why does PowerShell Remoting respect such a user-defined property? To begin answering this, let’s consider what the code should do next:

·       It should deserialize the <S> tag defined after the <Props> tag (payload section of the input XML). This is a primitive string type, thus it retrieves the string.
·       It should take the type of the main object, which is defined in the <TN> tag (here: System.ServiceProcess.ServiceController).
·       It should try to create the System.ServiceProcess.ServiceController instance from the provided string.

Our goal is to switch types here. We want to perform a conversion so that the System.Windows.Markup.XamlReader type is retrieved from the string. Let’s analyze the GetTargetTypeForDeserialization function to see how this can be achieved.

At [1], it tries to retrieve an object of the PSMemberInfo type using the GetPSStandardMember method. It passes two parameters: backupTypeTable (this contains the Powershell Remoting allowed types/converters) and the hardcoded string “TargetTypeForDeserialization”.

At [2], the code retrieves the Value member from the obtained object and tries to cast it to Type. When successful, the Type object will be returned. If not, null will be returned.

GetPSStandardMember method is not easy to understand, especially when you are not familiar with the classes and methods used here. However, I will try to summarize it for you in two points:

At [1], the PSMemberSet object is retrieved through the TypeTableGetMemberDelegate method. It takes our specified type (here, System.ServiceProcess.ServiceController) and compares it against the list of allowed types. If the provided type is allowed, it will extract its properties and create the new member set.

The following screenshot presents the PSMemberSet retrieved for the System.ServiceProcess.ServiceController type:

Figure 3 - PSMemberSet retrieved for the System.ServiceProcess.ServiceController type

At [2], the collection of members is created from multiple sources. If a member is not included in the basic member set (obtained from the list of allowed types), it will try to find such a member in a different source. This collection includes the adapted members, which contain the deserialized properties obtained through the Props tag.

Finally, it will try to retrieve the TargetTypeForDeserialization member from the final collection.

Let’s have a quick look at the specification of the System.ServiceProcess.ServiceController in the list of allowed types. It is defined in the default Powershell Remoting types list, located in C:\Windows\System32\WindowsPowerShell\v1.0\types.ps1xml.

As you can see, this type does not have the TargetTypeForDeserialization member specified. Only the DefaultDisplayPropertySet member is defined. According to that, the targetTypeForDeserialization will be retrieved from adaptedMembers. As the Exchange SerializationTypeConverter converter allows us to retrieve a Type through deserialization, we can provide a new conversion type to adaptedMembers!

Following screenshot presents the obtained psmemberinfo, which defines the XamlReader type:

Figure 4 - Retrieved XamlReader type

Success! GetTargetTypeForDeserialization returned the XamlReader type. You probably remember that PowerShell Remoting contains several converters. One of them allows calling the Parse(String) method. According to that, we can call the XamlReader.Parse(String) method, where the input will be equal to the string provided in the <S> tag. Let’s quickly verify it with the debugger.

The following screenshot presents the debugging of the LanguagePrimitive.ConvertTo method. The resultType is indeed equal to the XamlReader:

Figure 5 - Debugging of the ConvertTo method - resultType

The next screenshot presents the valueToConvert argument. It includes the string (XAML gadget) included in our payload:

Figure 6 - Debugging of the ConvertTo method - valueToConvert

We will soon reach the LanguagePrimitives.FigureParseConversion method. The following screenshot illustrates debugging this method. One can see that:

·       fromType is equal to String.
·       toType is equal to XamlReader.
· methodInfo contains the XamlReader.Parse(String string) method.

Figure 7 – Debugging the LanguagePrimitives.FigureParseConversion method

Yes! We have been able to get the XamlReader.Parse(String string) method through reflection! We also fully control the input that will be passed to this function. Finally, it will be invoked through the System.Management.Automation.LanguagePrimitives.ConvertViaParseMethod.ConvertWithoutCulture method, as presented in the following screenshot:

Figure 8 - Execution of the XamlReader.Parse method

As you may be aware, XamlReader allows us to achieve code execution through loading XAML (see ysoserial.net). When we continue the process, our command gets executed.

Figure 9 - Remote Code Execution through the Exchange PowerShell backend

There are also plenty of other classes besides XamlReader that could be abused in a similar way. For example, you can call the single-argument constructor of any type, so you can be creative here!

TL;DR – Summary

Getting to understand this vulnerability has been a long and complicated process. I hope that I have provided enough details for you to understand this issue. I would like to summarize the whole Microsoft Exchange chain in several points:

·       The path confusion in the Autodiscover service (CVE-2021-34473) was not fixed, but rather it was restricted to unauthenticated users. Authenticated users can still easily abuse it using Basic or NTLM authentication.

·       PowerShell Remoting allows us to perform object deserialization/conversion operations.

·       PowerShell Remoting includes several powerful converters, which can:

o   Call the public single-argument constructor of the provided type.
o   Call the public Parse(String) method of the provided type.
o   Retrieve an object through reflection.
o   Call custom converters.
o   Other conversions may be possible as well.

·       PowerShell Remoting implements a list of allowed types, so an attacker cannot (directly) invoke converters to instantiate arbitrary types.

·       However, the Exchange custom converter named SerializationTypeConverter allows us to obtain an arbitrary object of type Type.

·       This can be leveraged to fully control the type that will be retrieved through a conversion.

·       The attacker can abuse this behavior to call the Parse(String) method or the public single-argument constructor of almost any class while controlling the input argument.

·       This behavior easily leads to remote code execution. This blog post illustrates exploitation using the System.Windows.Markup.XamlReader.Parse(String) method.

It was not clear to us how Microsoft was going to approach fixing this vulnerability. Direct removal of the System.UnitySerializationHolder from the SerializationTypeConverter allowlist might cause breakage to Exchange functionality. One potential option was to restrict the returned types, for example, by restricting them to the types in the “Microsoft.Exchange.*” namespace. Accordingly, I started looking for Exchange-internal exploitation gadgets. I found more than 20 of them and reported them to Microsoft to help them with their mitigation efforts. That effort appears to have paid off. Microsoft patched the vulnerability by restricting the types that can be returned through the deserialization of System.UnitySerializationHolder according to a general allowlist, and then restricting them further according to a specific denylist. It seems that the gadgets I reported had an influence on that allowlist. I will probably detail some of those gadgets in a future blog post. Stay tuned for more…

Summary

I must admit that I was impressed with this vulnerability. The researcher clearly invested a good amount of time to fully understand the details of PowerShell Remoting, analyze Exchange custom converters, and find a way to abuse them. I had to take my analysis to another level to fully understand this bug chain and look for potential variants and alternate gadgets.

Microsoft patched these bugs in the November release. They also published a blog with additional workarounds you can employ while you test and deploy the patches. You should also make sure you have the September 2021 Cumulative Update (CU) installed. This adds the Exchange Emergency Mitigation service. This automatically installs available mitigations and sends diagnostic data to Microsoft. Still, the best method to prevent exploitation is to apply the most current security updates as they are released. We expect more Exchange patches in the coming months.

In a future blog post, I will describe some internal Exchange gadgets that can be abused to gain remote code execution, arbitrary file reads, or denial-of-service conditions. These have been reported to Microsoft, but we are still waiting for these bug reports to be addressed with patches.   Until then, you can follow me @chudypb and follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

Control Your Types or Get Pwned: Remote Code Execution in Exchange PowerShell Backend

The November 2022 Security Update Review

Welcome to the penultimate Patch Tuesday of 2021. As expected, Adobe and Microsoft have released their latest security updates and fixes to the world. Take a break from your regularly scheduled activities and join us as we review the details of their latest security offerings.

Adobe Patches for November 2022

For November, Adobe released no patches at all. They’ve released as few as one in the past, but this is the first month in the last six years where they had no fixes at all. Perhaps the U.S. elections play a factor, as Patch Tuesday hasn’t fallen on Election Day since 2016. Whatever the cause, enjoy a month of no Adobe updates.

Microsoft Patches for November 2022

This month, Microsoft released 64 new patches addressing CVEs in Microsoft Windows and Windows Components; Azure and Azure Real Time Operating System; Microsoft Dynamics; Exchange Server; Office and Office Components; SysInternals; Visual Studio; SharePoint Server; Network Policy Server (NPS); Windows BitLocker; and Linux Kernel and Open Source Software. This is in addition to five other CVEs from third parties being integrated into Microsoft products bringing the total number of fixes to 69. Eight of these CVEs were submitted through the ZDI program.

Of the 64 new patches released today, 11 are rated Critical and 53 are rated Important in severity. This volume is similar to previous November releases. It also pushes Microsoft over the number of fixes they released in 2021 and makes this year their second busiest ever for patches.

One of the new CVEs released this month is listed as publicly known and six others are listed as being in the wild at the time of release, which includes the two Exchange bugs listed as under active attack since September. Let’s take a closer look at some of the more interesting updates for this month, starting with those Exchange fixes we’ve been waiting for:

-       CVE-2022-41082 – Microsoft Exchange Server Remote Code Execution Vulnerability
-       CVE-2022-41040 – Microsoft Exchange Server Elevation of Privilege Vulnerability
These patches address the recent Exchange bugs that are currently being used in active attacks. They were expected last month, but they are finally here (along with several other Exchange fixes). These bugs were purchased by the ZDI at the beginning of September and reported to Microsoft at the time. At some point later, they were detected in the wild. Microsoft has released several different mitigation recommendations, but the best advice is to test and deploy these fixes. There were some who doubted these patches would release this month, so it’s good to see them here.

-       CVE-2022-41128 – Windows Scripting Languages Remote Code Execution Vulnerability
This bug in JScript is also listed as being exploited in the wild. An attack would need to lure a user to either a specially crafted website or server share. In doing so, they would get their code to execute on an affected system at the level of the logged-on user. Microsoft provides no insight into how widespread this may be but considering it’s a browse-and-own type of scenario, I expect this will be a popular bug to include in exploit kits.

-       CVE-2022-41091 – Windows Mark of the Web Security Feature Bypass Vulnerability
If you follow Will Dormann on Twitter, you probably have already read quite a bit about these types of bugs. Mark of the Web (MoW) is meant to be applied to files downloaded from the Internet. These files should be treated differently and receive security warning dialogs when accessing them. This vulnerability is also listed as being under active attack, but again, Microsoft provides no information on how widespread these attacks may be.

-       CVE-2022-41073 – Windows Print Spooler Elevation of Privilege Vulnerability
The legacy of PrintNightmare continues as threat actors continue to mine the vast attack surface that is the Windows Print Spooler. While we’ve seen plenty of other patches since PrintNightmare, this one is listed as being in the wild. While not specifically called out, disabling the print spooler should be an effective workaround. Of course, that breaks printing, but if you’re in a situation where patching isn’t feasible, it is an option.

-       CVE-2022-41125 – Windows CNG Key Isolation Service Elevation of Privilege Vulnerability
The final bug listed under active attack for November is this privilege escalation in the “Cryptography Application Programming Interface - Next Generation” (CNG) Key Isolation Service. An attacker can abuse this bug to run their code at SYSTEM. They would need to be authenticated, which is why bugs like these are often paired with some form of remote code execution exploit. As with all the other in-the-wild exploits, there’s no indication of how widely this is being used, but it’s likely somewhat targeted at this point. Still, test and deploy the updates quickly.

Here’s the full list of CVEs released by Microsoft for November 2022:

CVE Title Severity CVSS Public Exploited Type
CVE-2022-41091 Windows Mark of the Web Security Feature Bypass Vulnerability Important 5.4 Yes Yes SFB
CVE-2022-41040 Microsoft Exchange Server Elevation of Privilege Vulnerability Critical 8.8 No Yes EoP
CVE-2022-41082 Microsoft Exchange Server Remote Code Execution Vulnerability Critical 8.8 No Yes RCE
CVE-2022-41128 Windows Scripting Languages Remote Code Execution Vulnerability Critical 8.8 No Yes RCE
CVE-2022-41125 Windows CNG Key Isolation Service Elevation of Privilege Vulnerability Important 7.8 No Yes EoP
CVE-2022-41073 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.8 No Yes EoP
CVE-2022-39327 * GitHub: CVE-2022-39327 Improper Control of Generation of Code ('Code Injection') in Azure CLI Critical N/A No No RCE
CVE-2022-41080 Microsoft Exchange Server Elevation of Privilege Vulnerability Critical 8.8 No No EoP
CVE-2022-38015 Windows Hyper-V Denial of Service Vulnerability Critical 6.5 No No DoS
CVE-2022-37967 Windows Kerberos Elevation of Privilege Vulnerability Critical 7.2 No No EoP
CVE-2022-37966 Windows Kerberos RC4-HMAC Elevation of Privilege Vulnerability Critical 8.1 No No EoP
CVE-2022-41039 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-41088 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-41044 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-41118 Windows Scripting Languages Remote Code Execution Vulnerability Critical 7.5 No No RCE
CVE-2022-3602 * OpenSSL: CVE-2022-3602 X.509 certificate verification buffer overrun High 7.5 No No RCE
CVE-2022-3786 * OpenSSL: CVE-2022-3786 X.509 certificate verification buffer overrun High 7.5 No No DoS
CVE-2022-41064 .NET Framework Information Disclosure Vulnerability Important 5.8 No No Info
CVE-2022-23824 * AMD: CVE-2022-23824 IBPB and Return Address Predictor Interactions Important Unknown No No Info
CVE-2022-41085 Azure CycleCloud Elevation of Privilege Vulnerability Important 7.4 No No EoP
CVE-2022-41051 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-41099 BitLocker Security Feature Bypass Vulnerability Important 4.6 No No SFB
CVE-2022-39253 * GitHub: CVE-2022-39253 Local clone optimization dereferences symbolic links by default Important 5.5 No No Info
CVE-2022-41066 Microsoft Business Central Information Disclosure Vulnerability Important 4.4 No No Info
CVE-2022-41096 Microsoft DWM Core Library Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41105 Microsoft Excel Information Disclosure Vulnerability Important 7.8 No No Info
CVE-2022-41106 Microsoft Excel Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-41063 Microsoft Excel Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-41104 Microsoft Excel Security Feature Bypass Vulnerability Important 5.5 No No SFB
CVE-2022-41123 Microsoft Exchange Server Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41078 Microsoft Exchange Server Spoofing Vulnerability Important 8 No No Spoofing
CVE-2022-41079 Microsoft Exchange Server Spoofing Vulnerability Important 8 No No Spoofing
CVE-2022-41047 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-41048 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-41107 Microsoft Office Graphics Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-41062 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-41122 Microsoft SharePoint Server Spoofing Vulnerability Important 6.5 No No Spoofing
CVE-2022-41120 Microsoft Windows Sysmon Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41060 Microsoft Word Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-41103 Microsoft Word Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-41061 Microsoft Word Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-38023 Netlogon RPC Elevation of Privilege Vulnerability Important 8.1 No No EoP
CVE-2022-41056 Network Policy Server (NPS) RADIUS Protocol Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-41097 Network Policy Server (NPS) RADIUS Protocol Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-41119 Visual Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-41100 Windows Advanced Local Procedure Call (ALPC) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41045 Windows Advanced Local Procedure Call (ALPC) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41093 Windows Advanced Local Procedure Call (ALPC) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41114 Windows Bind Filter Driver Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-41095 Windows Digital Media Receiver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41050 Windows Extensible File Allocation Table Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41098 Windows GDI+ Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-41052 Windows Graphics Component Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-41086 Windows Group Policy Elevation of Privilege Vulnerability Important 6.4 No No EoP
CVE-2022-37992 Windows Group Policy Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41057 Windows HTTP.sys Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41055 Windows Human Interface Device Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-41053 Windows Kerberos Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-41049 Windows Mark of the Web Security Feature Bypass Vulnerability Important 5.4 No No SFB
CVE-2022-41058 Windows Network Address Translation (NAT) Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-41101 Windows Overlay Filter Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41102 Windows Overlay Filter Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41090 Windows Point-to-Point Tunneling Protocol Denial of Service Vulnerability Important 5.9 No No DoS
CVE-2022-41116 Windows Point-to-Point Tunneling Protocol Denial of Service Vulnerability Important 5.9 No No DoS
CVE-2022-41054 Windows Resilient File System (ReFS) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38014 Windows Subsystem for Linux (WSL2) Kernel Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-41113 Windows Win32 Kernel Subsystem Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41109 Windows Win32k Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41092 Windows Win32k Elevation of Privilege Vulnerability Important 7.8 No No EoP

* Indicates this CVE had previously been assigned by a 3rd-party and is now being incorporated into Microsoft products.

There are four additional bugs in Exchange Server receiving fixes this month, and three of those were reported by ZDI Vulnerability Researcher Piotr Bazydło. Most notably, the privilege escalation bug is due to Exchange having a hardcoded path to a file on the “D:” drive. If a “D:” exists and an attacker puts a DLL in the specified folder, Exchange will load the DLL. By default, low-privileged users have write access to the “D:” drive (assuming it exists). Another vector would be if the low-privileged attacker can insert an optical disk or attach an external drive that will be assigned the letter “D:”. Hard to believe a hard-coded path still exists within Exchange, but here we are. The two spoofing bugs would allow an authenticated attacker to obtain the NTLMv2 challenge and eventually perform further NTLM Relaying attacks. I have a strong premonition many Exchange administrators have a long weekend in front of them.

Looking at the remaining Critical-rated fixes, the two privilege escalation bugs in Kerberos stand out. You’ll need to take additional actions beyond just applying the patch. Specifically, you’ll need to review KB5020805 and KB5021131 to see the changes made and next steps. Microsoft notes this is a phased rollout of fixes, so look for additional updates to further impact the Kerberos functionality. There’s another patch for Scripting Languages. In this case, it’s JScript and Chakra, and this one is not listed as under active attack. There are three Critical-rated fixes for Point-to-Point Tunneling Protocol (PPTP). This seems to be a continuing trend of researchers looking for (and finding) bugs in older protocols. If you rely on PPTP, you should really consider upgrading to something more modern. There’s a Critical-rated denial-of-service (DoS) bug in Hyper-V, which is pretty unusual to see. DoS bugs rarely get the Critical tag, but Microsoft states, “Successful exploitation of this vulnerability could allow a Hyper-V guest to affect the functionality of the Hyper-V host.” I guess that’s severe enough to earn a Critical rating despite the 6.5 CVSS score. The fix for the Azure CLI was actually released a couple of weeks ago, and it’s getting documented now.

In addition to the fixes we’ve already discussed, there are 11 other patches for remote code execution vulnerabilities, including a memory corruption bug in the Windows Graphics Component reported by ZDI Vulnerability Researcher Hossein Lotfi. There are also multiple RCE bugs in various Office components, including one from ZDI Vulnerability Researchers Mat Powell and Michael DePlante. For these cases, user interaction would be required – the Preview Pane isn’t an exploit vector. There’s an authenticated SharePoint RCE, but a default user has the needed permissions to take over a SharePoint server. The vulnerability in Azure RTOS would require a user to run specially crafted code, so a level of social engineering would likely be needed to exploit this bug. The final two RCE bugs are in the ODBC driver, and these would require some social engineering to exploit as well. An attacker would need to convince someone to connect to their SQL server via ODBC. If they can do that to an affected system, they could execute code remotely on the client.

A total of 26 bugs in this release are Elevation of Privilege (EoP) bugs, including those already mentioned. The majority of these require an authenticated user to run specially crafted code on an affected system, but there are a few that stand out. The first is the fix for Netlogon that reads similar to the aforementioned Kerberos fixes. Microsoft is rolling out updates in phases and admins should review KB5021130 for additional steps. The bug in Azure CloudCycle has a brute force component, which definitely makes exploitation more difficult. Still. If you are using CloudCycle to manage your HPC environments on Azure, ensure you get it updated. The fixes for ALPC note the bugs could be used to escape a contained execution environment. While certainly not the first bugs to do so, I don’t recall Microsoft documenting this before now. Finally, there’s an EoP in SysInternals services. These tools are often used by incident responders, so definitely make sure you have an updated version before heading out to recover a compromised system. 

The November release includes eight new fixes for information disclosure bugs. Most of the info disclosure vulnerabilities only result in leaks consisting of unspecified memory contents. There is one notable exception. The vulnerability in Business Central requires admin credentials but could lead to the disclosure of integration secrets that are owned by a different partner. Presumably, you would be able to impersonate the other client with this info.

Four total Security Feature Bypass bugs are getting fixed this month, including the patch for the MoW bug being actively exploited. There’s another fix for a MoW bug, but this one is not listed as under active attack. The fix for Excel addresses a bug that would bypass the content check in the INDIRECT function. More notably, the bug in BitLocker could allow an attacker with physical access to bypass the Device Encryption feature and access the encrypted data. Preventing this is pretty much the “one job” of Device Encryption, so regardless of exploitability, this is a significant bypass.

Today’s release also includes fixes for five additional DoS bugs. Four of these impact network protocols: PPTP, RADIUS, and Network Address Translation (NAT). A successful attack on one of these protocols would cause the service to stop responding. The same is true of the bug in Kerberos, which could impact logging on and other functionality that relies on the Kerberos service.

There is one spoofing bug in SharePoint server, but beyond the authentication requirement, there’s no information regarding the exploit scenario.

Finally, you may have heard of some OpenSSL bugs that had everyone abuzz before their release. To say they fizzled out is a bit of an understatement. Still, the fixes for Microsoft products are included in this release.

There is one new advisory this month adding defense-in-depth functionality to Microsoft Office. The new feature provides hardening around IRM-protected documents to ensure the trust-of-certificate chain. The latest servicing stack updates can be found in the revised ADV990001.

Looking Ahead

The final Patch Tuesday of 2022 will be on December 13, and we’ll return with details and patch analysis then. Be sure to catch the Patch Report webcast on our YouTube channel. It should be posted in just a few hours. Until then, stay safe, happy patching, and may all your reboots be smooth and clean!

The November 2022 Security Update Review

Vulnerabilities in Apache Batik Default Security Controls – SSRF and RCE Through Remote Class Loading

Introduction

I stumbled upon the Apache Batik library while researching other Java-based products. It immediately caught my attention, as this library parses Scalable Vector Graphics (SVG) files and transforms them into different raster graphics formats (i.e., PNG, PDF, or JPEG). I was even more encouraged when I looked at the Batik documentation. It was obvious that such a library could be prone to Server-Side Request Forgery (SSRF) issues (e.g., loading of images from remote resources). However, the documentation shows that Batik can also:

·      Execute JavaScript through the Rhino interpreter.
·      Load and execute remote Java classes.

Those are some neat features! On the other hand, Apache Batik protects its users from both SSRF and remote code execution (RCE) vulnerabilities through the various security modes it offers. In this blog post, I am going to show you:

·      How I bypassed the default security modes: DefaultScriptSecurity (CVE-2022-40146) and DefaultExternalResourceSecurity (CVE-2022-38398).
·      How to abuse the SSRF in the default Batik Transcoder to make arbitrary HTTP GET requests or to trigger an NTLM challenge.
·      What configurations are vulnerable to the RCE through remote class loading.
·      What configurations are vulnerable to the RCE through the Rhino interpreter and JavaScript execution.

Before we get into the details, here’s a quick video demonstrating a remote code execution vulnerability exploited through remote JAR loading.

Sample Web Application Endpoint

Apache Batik can be used in different ways. There is a pretty good chance that you have already seen it in web applications during the conversion of SVG to PDF/PNG/JPEG. Let’s define a sample endpoint that performs such a conversion:

```

This endpoint performs the following actions:

·      Retrieves and decodes the base64-encoded SVG file.
·      Creates the Apache Batik JPEG Transcoder.
·      Converts the SVG to JPEG.

This is a common usage of Apache Batik. Note that there is a risk of an easy SSRF if the SVG loads an image from an external resource. Batik tries to protect against such a scenario with its external resource controls, although some of these have existing bypasses with their own CVEs assigned. Let’s quickly review those resource controls.

Apache Batik External Resource Controls

Apache Batik resource controls can be divided into two main categories:

·      Script execution
·      External resources controls (like images). 

Let’s take a brief look at the scripting controls. They control whether script provided within an SVG will be executed. The external resource controls are similar to the scripting controls but apply to the fetching of resources such as images. For a full description of security controls, you can access the documentation here. Here’s a quick overview of the available ScriptSecurity implementations:

·      NoLoadScriptSecurity – scripts are completely blocked.
·      EmbededScriptSecurity [sic] scripts embedded in the document can be executed when properly referenced.
·      DefaultScriptSecurity Embedded external scripts (as above) plus scripts coming from the same origin as the document referencing them are allowed.
·      RelaxedScriptSecurity scripts from any location can be loaded.

In my research so far, I have focused only on the default security controls.

Note that the default security control has a concept of “origin”, but what exactly does this mean? It means that the resource or script will be loaded only if it originates from the same “host” as the SVG file. For example:

·      If we load a local SVG file, we can also load local scripts or resources.
·      If we load a local SVG file, we cannot load scripts or resources from remote origins (e.g., through HTTP or SMB).
·      If we load an SVG file through the HTTP protocol, we can load remote scripts from the same host through either HTTP or any other supported protocol, such as SMB.

In order to avoid any confusion, let’s quickly describe what “loading an SVG through the HTTP protocol” means in Batik. It specifically means that the HTTP URL is directly provided to the Batik TranscoderInput.

This does not look like a particularly common scenario, because the attacker would need to control the URL from which the SVG file is (directly) loaded into Batik.

Accordingly, the default security controls seem to be appropriate. When a local SVG file is loaded, or an SVG is provided as an InputStream, the default controls should block the loading of any remote resources.

Now let’s see how we can bypass those security checks.

DefaultScriptSecurity and DefaultExternalResourceSecurity vs URL.getHost

To start, let’s dig into the DefaultScriptSecurity constructor, which is responsible for our security check. Please note that the code of DefaultExternalResourceSecurity is almost identical, thus it will not be presented.

At [1], the scriptURL and docURL of ParsedURL type are provided. For the sake of simplicity, let’s say that ParsedURL wraps the Java URL class.

At [2] and [3], the respective host strings are retrieved with the getHost method. Under the hood, it retrieves the output of the Java URL.getHost.

At [4], hosts obtained in points [2] and [3] are compared. If they are the same, the code flow continues, and the exception will not be thrown.

At [5], a SecurityException is thrown if the security check is not successful.

If the document host and the script host are the same, the exception will not be thrown, and the script or resource will be loaded. Next, let’s look at how the Java URL.getHost behaves for different protocols:

It’s pretty simple. The host for a local file will be equal to null, whereas for the remote files shown here (referenced by either UNC path or HTTP) it will be equal to evil.com. If the Apache Batik TranscoderInput is created with the InputStream, the getHost method will also return null.

It seems that the default security routines work properly, and we will not be able to load remote resources during processing of SVGs coming from local files or input streams.

Unfortunately, a trivial bypass exists, and honestly, Java itself is the likely culprit. Let’s see the output of the getHost getter for the JAR protocol:

What? It seems that the host for the JAR protocol is also null. In order to properly retrieve the host from the JAR URL, the following cumbersome code can be used. We retrieve the file member from the URL and then use it to create a new URL, from which we can get the host.

In this way, the security check can be easily bypassed with the JAR protocol. Let’s have a look at a sample SVG that leads to SSRF through the image tag.

This SVG will bypass the DefaultExternalResourceSecurity control and will make an HTTP GET request to the attacker’s server. Please note that we can also use the syntax “jar:file://…”, in order to get an NTLMv2 challenge-response in a Windows environment and potentially perform an NTLM relaying attack.

Now that we have shown how to bypass the default external resources controls to get an easy SSRF through the image tag, let’s see how to get remote code execution. This has been fixed in Batik 1.15.

Apache Batik Remote Class Loading Feature

While digging through the Apache Batik documentation, I found an intriguing feature: “Referencing Java Code From a Document”.

Batik implements the Java bindings for SVG, and thus allows Java code to be referenced from script elements…
In order to use this extension, the type attribute of a script element must be set to application/java-archive. In addition, the xlink:href attribute must be the URI of a jar file that contains the code to run.

It seems that we can provide a script of type application/java-archive referencing a properly structured JAR file. We already know that we can bypass the DefaultScriptSecurity check and load files from remote locations, thus it looks like a win!

Luckily, the script execution is not enabled by default in the Apache Batik transcoder and some configuration modifications must be applied:

1)    Enable script execution

Script execution can be enabled in the transcoder with the following line of code:

Please note that the Apache Batik is a “do it yourself” library and often requires a lot of customization. There is a chance that you will see such a configuration in the wild. Also, Batik defines some methods that allow dynamic verification of whether the SVG file contains scripts or not. This method can be used to automatically enable script execution if needed. 

2)    Fix the logical flaw to allow execution of scripts of type “application/java-archive”.

It seems that Apache Batik’s definition of default-allowed script types contains an unintended error. Let’s have a quick look:

You can clearly see that the script types are separated with a comma followed by a space. Now, let’s look at the method that retrieves the list of allowed types:

The list is created with StringTokenizer, where the delimiter is set to a comma without a space! According to that, all the allowed types other than the first one (ECMASCRIPT) will contain a leading space. For example, the allowed type will be “ application/java-archive” instead of “application/java-archive”.

The code will compare the script type declared in the SVG against the type specified in the list. You may think that this is not a problem, since we can declare a script type in the SVG that also includes a space:

<script type=” application/java-archive”>

This will not work, though. The type check for remote JAR loading is performed twice. The second check verifies if the script type is equal to “application/java-archive”, without a leading space. As a result, we will not be able to pass both checks. To enable remote class loading, we must manually modify the list of allowed script types by making an API call as follows:

Now, let’s look at how to perform remote JAR loading in Batik. To begin, we must create a class that implements the EventListenerInitializer interface. Then, we must define the initializeEventListeners method. This method will be executed after the JAR is loaded. Here’s an example of a malicious class:

The MANIFEST.MF file included in the JAR needs to specify SVG-Handler-Class. The following snippet presents an exemplary manifest:

Finally, we specify a malicious SVG that loads such a JAR and bypasses the security policies:

The following screenshot presents a proof of concept where the JAR was loaded through the HTTP protocol and the code was executed, spawning a curl process and making a request to our HTTP server.

Figure 1 - Code Execution through remote JAR loading

Success! We were able to bypass the restrictions defined in DefaultScriptSecurity, load the JAR file from the remote location, and achieve remote code execution.

Scripts Enabled with Remote JAR Loading Disallowed

Due to the logical flaw described in the previous section, it’s likely that you will encounter the following configuration:

·      Scripts enabled.
·      The setting for allowed script types is untouched, so that, in practice, only ECMAScript is enabled.

Luckily, you can still get an easy RCE. ECMAScript is interpreted with Mozilla Rhino, an open-source implementation of JavaScript written in Java. This code execution vector has been already presented by the researcher known as pyn3rd.

The following snippet presents an SVG file with an ugly looking script that will execute the attacker’s command.

The following screenshot demonstrates the achieved code execution:

Figure 2 - Code Execution through ECMAScript

Execution of ECMAScript is a well-documented feature of Apache Batik and this behavior will not be fixed. The official security guide recommends securing your application with the Java SecurityManager when scripting is enabled. I’m taking a guess, but I think that we will never see a completely secure implementation of SecurityManager within Batik. It would likely break too much functionality and make the application unusable. This is still merely speculation on my part. It should also be noted that running scripts is disabled by
default and must be explicitly enabled.

UPDATE: Apache Batik 1.16 has been recently released. It introduces a hardening to Rhino script execution mechanisms. However, it’s hard to call this hardening a strong one. You are still able to call almost any class whose full name starts with “org.”. Saying that, you can still easily abuse many methods included in Apache libraries. This security check can be found here.

Summary

To wrap things up, the security checks implemented in the default external resource controllers of Apache Batik could be bypassed prior to Batik 1.15, in order to:

·      Perform SSRF through the JAR protocol, producing either an HTTP GET request or NTLM relaying via an UNC path.
·      Potentially achieve RCE through remote JAR loading, provided that a non-default configuration was applied.

The bugs discussed here in DefaultScriptSecurity and DefaultExternalResourceSecurity were fixed in version 1.15. Still, Apache Batik may allow the execution of arbitrary Java code when script execution is enabled, even in the latest version 1.16.

If you are using Batik or are interested in finding additional bugs, here are some things to consider:

·      Developers – do not allow scripts to execute through Batik. Apply the strictest controls possible.
·      Pentesters/Bug Hunters – when you test functionality that accepts SVG, try to use the SVG files presented in this blog post.
·      Vulnerability researchers – when your target uses Apache Batik for SVG parsing or conversions, analyze its configuration carefully. You might have an easy win over there.

Thanks for reading, and I hope you’ve enjoyed this post. You can follow me @chudypb and follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

Vulnerabilities in Apache Batik Default Security Controls – SSRF and RCE Through Remote Class Loading

CVE-2022-3236: Sophos Firewall User Portal and Web Admin Code Injection

In this excerpt of a Trend Micro Vulnerability Research Service vulnerability report, Guy Lederfein and Dusan Stevanovic of the Trend Micro Research Team detail a recently patched code injection vulnerability in the Sophos Firewall. The bug is due to improper validation of JSON keys submitted in the “JSON” parameter sent to the Controller endpoint. Successful exploitation of this vulnerability could result in remote code execution with the privileges of the root user. The following is a portion of their write-up covering CVE-2022-3236, with a few minimal modifications.


Sophos recently patched a code injection vulnerability in Sophos Firewall v19.0 MR1 (19.0.1) and previous. This vulnerability is due to improper validation of JSON keys submitted in the “json” parameter sent to the Controller endpoint. A remote, unauthenticated attacker could exploit this vulnerability by sending a specially crafted request to an affected server. Successfully exploiting this vulnerability could result in remote code execution with the privileges of the root user.

The Vulnerability

Sophos Firewall is a network security solution, which can be deployed on purpose-built devices, on a cloud network (AWS/Azure), on a virtual device, or as a software appliance on x86 Intel hardware. The firewall application supports multiple network security features, including application-aware routing, TLS inspection, deep packet inspection, remote access VPN, logging, and reporting. Sophos Firewall exposes a web admin console for managing the device’s configuration via HTTPS on TCP port 4444. In addition, Sophos Firewall exposes a user portal for updating a user’s details or downloading authentication clients via HTTPS on TCP port 443.

HTTP is a request/response protocol described in RFCs 7230 - 7237 and other RFCs. A request is sent by a client to a server, which in turn sends a response back to the client. An HTTP request consists of a request line, various headers, an empty line, and an optional message body:

where CRLF represents the new line sequence Carriage Return (CR) followed by Line Feed (LF) and SP represents a space character. Parameters can be passed from the client to the server as name-value pairs in either the Request-URI or in the message-body, depending on the Method used and the Content-Type header. For example, a simple HTTP request passing a parameter named “param” with value “1”, using the GET method might look like this:

A corresponding HTTP request using the POST method might look like this:

JavaScript Object Notation (JSON) is a data-interchange format used for creating machine parseable, human-readable output. A JSON object has the following syntax:

• An object is enclosed in curly braces {}.
• An object is comprised of zero or more items delimited by a comma (“,”) character.
• An item is comprised of a key and a value. A key is delimited from its value by a colon (“:”) character.
• A key must be a string enclosed in quotes.
• A value must be a valid type. JSON defines seven value types: string, number, object, array, true, false, and null.
• An array is an object enclosed in square braces [].
• An array is comprised of zero or more strings, numbers, JSON objects, arrays, boolean, or null type-objects delimited by a comma (“,”) character.

An example JSON object is as follows:

      {“name”:”bob”, “age”:30}

The web admin and user portal web interfaces exposed by Sophos Firewall both run on a Jetty server behind an Apache httpd server. Configuration and diagnostic requests issued through these interfaces are submitted via requests to the Controller servlet. This servlet retrieves the appropriate EventBean object based on the mode HTTP request parameter. For example, if the mode HTTP request parameter is set to 151 or 451, the WebAdminAuth or UserPortalAuth classes are called to process the request, respectively. In each of these classes, the generateAndSendAjaxEvent() method of the CSCClient class is called. This method parses the json HTTP request parameter and modifies specific fields from the parsed object. The send() method is then called, which in turn calls _send(), which adds the mode JSON parameter according to the mode of the associated EventBean object. It then sends the created JSON object as a string, including appropriate headers, to the local CSC server over TCP or UDP port 299.

When the CSC server receives the JSON object submitted by the Jetty server, it validates the JSON object submitted via the validateJSON() method in the Perl script CyberAPIArch.pm. If the JSON object contains a key named _discriminator, the getValidationHash() method is called. This method iterates over each key of the _discriminator Perl hash, representing field names. Each field name is associated with a JSON object describing the mapping between field values and object names. Some Perl objects resolved when parsing the JSON object received (natrule, securitypolicy, hotspot, etc.) contain a template with a _discriminator key containing such a mapping for specific field names between field values and their associated objects. The method iterates over the field values to check whether the submitted JSON object contains a field with the referenced name and value. If so, it retrieves the associated object name and attempts to resolve it to an object using the eval function.

A code injection vulnerability has been reported for Sophos Firewall. This vulnerability is due to improper validation of JSON keys submitted in the “json” parameter sent to the Controller endpoint. Specifically, the _discriminator key can be set in the HTTP request. This JSON object is sent, after some modification, to the CSC server. However, the _discriminator key set is sent unmodified. Once the validateJSON() method of the Perl script CyberAPIArch.pm is called, it will detect this key and call getValidationHash(). The Perl method iterates over the $hashObj hash object, which contains a key named _discriminator whose value is a nested hash with a value key set with the value set for the _discriminator key in the original request sent. This value key is treated as a nested hash containing field values mapped to object names. Therefore, if the originally submitted JSON object contains a key named value with its value set to one of the values in this nested hash, the associated object name will be resolved using the eval function. Since the _discriminator key in the original request can be set to a JSON object with an arbitrary mapping between values and object names, a malicious object can be submitted to be concatenated into the eval function, resulting in code injection.

Sophos attempts to perform input validation on request parameters, including the JSON object, using the RequestCheckFilter Java object. This filter detects request parameters and JSON keys with non-ASCII printable characters. However, arbitrary request parameters and JSON keys containing ASCII printable characters can still be submitted, including the _discriminator key.

A remote, unauthenticated attacker could exploit this vulnerability by sending a crafted request to the target server. Successfully exploiting this vulnerability could result in arbitrary Perl commands being run on the server, resulting in remote code execution with the privileges of the root user.

Source Code Walkthrough

The following code snippet was taken from Sophos Firewall version 19.0.1 with additional comments added by Trend Micro.

From the decompiled Java class cyberoam.sessionmanagement.RequestCheckFilter:

From the Perl script CyberAPIArch.pm:

Detecting Attacks

To detect an attack attempting to exploit this vulnerability, the detection device must monitor and parse traffic on ports 443/TCP and 4444/TCP. Note that the traffic is encrypted with SSL/TLS. The detection device must decrypt the traffic before proceeding through the next steps.

Based on the TCP ports monitored, the detection device must inspect HTTP GET and POST requests to a Request- URI containing the following string:

Requests to the Webadmin Controller endpoint (TCP port 4444) can use the multipart/form-data encoding.

Multipart/form-data is made up of multiple parts, each of which contains a Content-Disposition header. Each part is separated by a string of characters. The string of characters separating the parts is defined by the boundary keyword found on the Content-Type header line, which is set to “multipart/form-data”. The Content-Disposition header contains a name parameter describing the form element being returned. Additional header lines may be present in each part. Each line is separated by a new line sequence. The header is terminated by two consecutive new lines. The form element's data follows. The filename parameter provides a suggested filename to be used if the entity is detached and stored in a separate file. The following is a sample Content-Disposition header for a file item, where the boundary keyword is “TMSR”:

If a request to one of the above endpoints is found, the detection device must parse its parameters according to the encoding described in the Content-Type header and search for the json parameter. If found, the detection device must inspect the json parameter value using any suitable methods below.

Method 1: If the detection device is capable of parsing JSON, it must parse the json parameter as a JSON object. The detection device must parse any items (potentially nested) whose key is the string “_discriminator”. If found, the traffic should be considered malicious as an attack exploiting this vulnerability is likely underway.

Method 2: If the detection device is not capable of parsing JSON, it must inspect the json parameter as a string and check if it contains the string “_discriminator”. If found, the traffic should be considered malicious as an attack exploiting this vulnerability is likely underway.

Additional things to note:

• Parameter names and values may be URL-encoded and must be decoded before applying the above detection guidance.
• String matching for the URI and parameter names (“json”) and values (“_discriminator”) must be performed in a case-sensitive manner.
• String matching for HTTP header names (i.e., “Content-Type”) and values (i.e., “multipart/form-data”) must be performed in a case-insensitive manner.

Conclusion

There are reports that this vulnerability is being used to target a small group of organizations and that Sophos has “informed each of these [affected] organizations directly.” This bug is also similar to a previous vulnerability, CVE-2022-1040, that that Volexity and The Record claim was used by a Chinese APT crew in March 2022. Regardless, this bug has a CVSS base score of 9.8 and should be remediated immediately. Sohpos users who don’t have hotfixes enabled or are on legacy versions should patch immediately as outlined in Sophos’s advisory. You should also consider blocking the affected ports from external network access if it is not required.

Special thanks to Guy Lederfein and Dusan Stevanovic of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit http://go.trendmicro.com/tis/.

 

The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

CVE-2022-3236: Sophos Firewall User Portal and Web Admin Code Injection

The October 2022 Security Update Review

Another Patch Tuesday is here, and Adobe and Microsoft have released their latest crop of new security updates and fixes. Take a break from your regularly scheduled activities and join us as we review the details of their latest security offerings.

Adobe Patches for October 2022

For October, Adobe released four patches addressing 29 vulnerabilities in Adobe Acrobat and Reader, ColdFusion, Commerce and Magento, and Adobe Dimension. A total of 22 of these bugs were reported through the ZDI program. The fix for ColdFusion seems to be the most critical, with multiple CVSS 9.8 code execution bugs being addressed. There’s also a fix for a bug in the Admin Component service. The service uses a hard-coded password for the administrator user. An attacker can leverage this vulnerability to bypass authentication on the system. Hard to imagine hard-coded credentials have existed in the product for so long without being discovered.

The Commerce and Magento update addresses only one bug, but it’s a CVSS 10. If you’re using either of these products, ensure you test and deploy this quickly to fix the stored cross-site scripting (XSS) bug. The patch for Acrobat and Reader fixes six bugs, with the most severe being stack-based buffer overflows that could lead to code execution. A threat actor would need to trick someone into opening a specially crafted PDF to get arbitrary code exec. The fix for Dimension corrects nine bugs, eight of which are rated critical. Most of these are file parsing bugs and would require user interaction to exploit.  

None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release. Adobe categorizes these updates as a deployment priority rating of 3.

Microsoft Patches for October 2022

This month, Microsoft released 85 new patches addressing CVEs in Microsoft Windows and Windows Components; Azure, Azure Arc, and Azure DevOps; Microsoft Edge (Chromium-based); Office and Office Components; Visual Studio Code; Active Directory Domain Services and Active Directory Certificate Services; Nu Get Client; Hyper-V; and the Windows Resilient File System (ReFS). This is in addition to the 11 CVEs patched in Microsoft Edge (Chromium-based) and one patch for side-channel speculation in Arm processors. That brings the total number of CVEs to 96. Six of these CVEs were submitted through the ZDI program.

What may be more interesting is what isn’t included in this month’s release. There are no updates for Exchange Server, despite two Exchange bugs being actively exploited for at least two weeks. These bugs were purchased by the ZDI at the beginning of September and reported to Microsoft at the time. With no updates available to fully address these bugs, the best administrators can do is ensure the September 2021 Cumulative Update (CU) is installed. This adds the Exchange Emergency Mitigation service. This automatically installs available mitigations and sends diagnostic data to Microsoft. Otherwise, follow this post from Microsoft with the latest information. Their mitigation advice has changed multiple times, so you’ll need to make sure you check it often for updates.

Of the 85 new patches released today, 15 are rated Critical, 69 are rated Important, and one is rated Moderate in severity. This volume is somewhat in line with what we’ve seen in previous October releases, but it does put Microsoft on track to exceed its 2021 total. If that happens, 2022 would the second busiest year for Microsoft CVEs. One of the new CVEs released this month is listed as publicly known and one other is listed as being in the wild at the time of release. Let’s take a closer look at some of the more interesting updates for this month, starting with the bug under active attack:

-       CVE-2022-41033 – Windows COM+ Event System Service Elevation of Privilege Vulnerability
This patch fixes a bug that Microsoft lists as being used in active attacks, although they specify how broad these attacks may be. Since this is a privilege escalation bug, it is likely paired with other code execution exploits designed to take over a system. These types of attacks often involve some form of social engineering, such as enticing a user to open an attachment or browse to a malicious website. Despite near-constant anti-phishing training, especially during “Cyber Security Awareness Month”, people tend to click everything, so test and deploy this fix quickly.

-       CVE-2022-37987/CVE-2022-37989 – Windows Client Server Run-time Subsystem (CSRSS) Elevation of Privilege Vulnerability
These bugs were reported by ZDI Sr. Vulnerability Researcher Simon Zuckerbraun and pertain to the behavior of the CSRSS process when it searches for dependencies. CVS-2022-37989 is a failed patch for CVE-2022-22047, an earlier bug that saw some in-the-wild exploitation. This vulnerability results from CSRSS being too lenient in accepting input from untrusted processes. By contrast, CVE-2022-37987 is a new attack that works by deceiving CSRSS into loading dependency information from an unsecured location. We’ll publish additional details about these bugs on our blog in the future.

-       CVE-2022-37968 – Azure Arc-enabled Kubernetes cluster Connect Elevation of Privilege Vulnerability
This vulnerability could allow an attacker to gain administrative control over Azure Arc-enabled Kubernetes clusters. Azure Stack Edge devices may also be impacted by this bug. To exploit this remotely, the attacker would need to know the randomly generated DNS endpoint for an Azure Arc-enabled Kubernetes cluster. Still, this bug receives the rare CVSS 10 rating – the highest severity rating the system allows. If you’re running these types of containers, make sure you either have auto-upgrade enabled or manually update to the latest version by running the appropriate commands in the Azure CLI.

-       CVE-2022-38048 – Microsoft Office Remote Code Execution Vulnerability
This bug was reported to the ZDI by the researcher known as “hades_kito” and represents a rare Critical-rated Office bug. Most Office vulnerabilities are rated Important since they involve user interaction – typically opening a file. An exception to that is when the Preview Pane is an attack vector, however, Microsoft states that isn’t the case here. Likely the rating results from the lack of warning dialogs when opening a specially crafted file. Either way, this is a UAF that could lead to passing an arbitrary pointer to a free call which makes further memory corruption possible.

Here’s the full list of CVEs released by Microsoft for October 2022:

CVE Title Severity CVSS Public Exploited Type
CVE-2022-41033 Windows COM+ Event System Service Elevation of Privilege Vulnerability Important 7.8 No Yes EoP
CVE-2022-41043 Microsoft Office Information Disclosure Vulnerability Important 4 Yes No Info
CVE-2022-37976 Active Directory Certificate Services Elevation of Privilege Vulnerability Critical 8.8 No No EoP
CVE-2022-37968 Azure Arc-enabled Kubernetes cluster Connect Elevation of Privilege Vulnerability Critical 10 No No EoP
CVE-2022-38049 Microsoft Office Graphics Remote Code Execution Vulnerability Critical 7.8 No No RCE
CVE-2022-38048 Microsoft Office Remote Code Execution Vulnerability Critical 7.8 No No RCE
CVE-2022-41038 Microsoft SharePoint Server Remote Code Execution Vulnerability Critical 8.8 No No RCE
CVE-2022-34689 Windows CryptoAPI Spoofing Vulnerability Critical 7.5 No No Spoofing
CVE-2022-41031 Microsoft Word Remote Code Execution Vulnerability Critical 7.8 No No RCE
CVE-2022-37979 Windows Hyper-V Elevation of Privilege Vulnerability Critical 7.8 No No EoP
CVE-2022-30198 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-24504 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-33634 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-22035 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-38047 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-38000 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-41081 Windows Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-38042 Active Directory Domain Services Elevation of Privilege Vulnerability Important 7.1 No No EoP
CVE-2022-38021 Connected User Experiences and Telemetry Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-38036 Internet Key Exchange (IKE) Protocol Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-37977 Local Security Authority Subsystem Service (LSASS) Denial of Service Vulnerability Important 6.5 No No DoS
CVE-2022-37983 Microsoft DWM Core Library Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38040 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-38001 Microsoft Office Spoofing Vulnerability Important 6.5 No No Spoofing
CVE-2022-41036 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-41037 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-38053 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-37982 Microsoft WDAC OLE DB provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-38031 Microsoft WDAC OLE DB provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-37971 Microsoft Windows Defender Elevation of Privilege Vulnerability Important 7.1 No No EoP
CVE-2022-41032 NuGet Client Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38045 Server Service Remote Protocol Elevation of Privilege Vulnerability Important 8.8 No No EoP
CVE-2022-35829 Service Fabric Explorer Spoofing Vulnerability Important 6.2 No No Spoofing
CVE-2022-38017 StorSimple 8000 Series Elevation of Privilege Vulnerability Important 6.8 No No EoP
CVE-2022-41083 Visual Studio Code Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-41042 Visual Studio Code Information Disclosure Vulnerability Important 7.4 No No Info
CVE-2022-41034 Visual Studio Code Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-38046 Web Account Manager Information Disclosure Vulnerability Important 6.2 No No Info
CVE-2022-38050 Win32k Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37978 Windows Active Directory Certificate Services Security Feature Bypass Important 7.5 No No SFB
CVE-2022-38029 Windows ALPC Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-38044 Windows CD-ROM File System Driver Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-37989 Windows Client Server Run-time Subsystem (CSRSS) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37987 Windows Client Server Run-time Subsystem (CSRSS) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37980 Windows DHCP Client Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38026 Windows DHCP Client Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-38025 Windows Distributed File System (DFS) Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-37970 Windows DWM Core Library Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37981 Windows Event Logging Service Denial of Service Vulnerability Important 4.3 No No DoS
CVE-2022-33635 Windows GDI+ Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-38051 Windows Graphics Component Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37997 Windows Graphics Component Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37985 Windows Graphics Component Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-37975 Windows Group Policy Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37999 Windows Group Policy Preference Client Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37993 Windows Group Policy Preference Client Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37994 Windows Group Policy Preference Client Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37995 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37988 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38037 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38038 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37990 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38039 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37991 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38022 Windows Kernel Elevation of Privilege Vulnerability Important 2.5 No No EoP
CVE-2022-37996 Windows Kernel Memory Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-38016 Windows Local Security Authority (LSA) Elevation of Privilege Vulnerability Important 8.8 No No EoP
CVE-2022-37998 Windows Local Session Manager (LSM) Denial of Service Vulnerability Important 7.7 No No DoS
CVE-2022-37973 Windows Local Session Manager (LSM) Denial of Service Vulnerability Important 7.7 No No DoS
CVE-2022-37974 Windows Mixed Reality Developer Tools Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-35770 Windows NTLM Spoofing Vulnerability Important 6.5 No No Spoofing
CVE-2022-37965 Windows Point-to-Point Tunneling Protocol Denial of Service Vulnerability Important 5.9 No No DoS
CVE-2022-38032 Windows Portable Device Enumerator Service Security Feature Bypass Vulnerability Important 5.9 No No SFB
CVE-2022-38028 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38003 Windows Resilient File System Elevation of Privilege Important 7.8 No No EoP
CVE-2022-38041 Windows Secure Channel Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-38043 Windows Security Support Provider Interface Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-38033 Windows Server Remotely Accessible Registry Keys Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-38027 Windows Storage Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-33645 Windows TCP/IP Driver Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-38030 Windows USB Serial Driver Information Disclosure Vulnerability Important 4.3 No No Info
CVE-2022-37986 Windows Win32k Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37984 Windows WLAN Service Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38034 Windows Workstation Service Elevation of Privilege Vulnerability Important 4.3 No No EoP
CVE-2022-41035 Microsoft Edge (Chromium-based) Spoofing Vulnerability Moderate 8.3 No No Spoofing
CVE-2022-3304 * Chromium: CVE-2022-3304 Use after free in CSS High N/A No No RCE
CVE-2022-3307 * Chromium: CVE-2022-3307 Use after free in Media High N/A No No RCE
CVE-2022-3370 * Chromium: CVE-2022-3370 Use after free in Custom Elements High N/A No No RCE
CVE-2022-3373 * Chromium: CVE-2022-3373 Out of bounds write in V8 High N/A No No RCE
CVE-2022-3308 * Chromium: CVE-2022-3308 Insufficient policy enforcement in Developer Tools Medium N/A No No SFB
CVE-2022-3310 * Chromium: CVE-2022-3310 Insufficient policy enforcement in Custom Tabs Medium N/A No No SFB
CVE-2022-3311 * Chromium: CVE-2022-3311 Use after free in Import Medium N/A No No RCE
CVE-2022-3313 * Chromium: CVE-2022-3313 Incorrect security UI in Full Screen Medium N/A No No SFB
CVE-2022-3315 * Chromium: CVE-2022-3315 Type confusion in Blink Medium N/A No No RCE
CVE-2022-3316 * Chromium: CVE-2022-3316 Insufficient validation of untrusted input in Safe Browsing Low N/A No No Spoofing
CVE-2022-3317 * Chromium: CVE-2022-3317 Insufficient validation of untrusted input in Intents Low N/A No No Spoofing

* Indicates this CVE had previously been assigned by a 3rd-party and is now being incorporated into Microsoft products.

Looking at the rest of the Critical-rated patches, the update for Active Directory Certificate Services (ADCS) stands out the most as successful exploitations would provide the attacker domain administrative privileges. However, exploiting this would be tricky. A malicious DCOM client would need to trick a DCOM server to authenticate to it through ADCS and then use the credential to launch a cross-protocol attack. There are seven Critical-rated fixes for the Point-to-Point Tunneling Protocol (PPTP). If you’re still using this, consider migrating to a more modern (and secure) solution. There’s a fix for a guest-to-host escape in Hyper-V that could result in the attacker executing code on the root OS. In addition to the one mentioned above, there are two other Critical-rated bugs impacting Office components. Neither have a Preview Pane attacker vector, so it’s not clear why the Critical rating applies. Speaking of confusing, there’s a Critical fix for SharePoint that reads identical to the Important-rated SharePoint fixes. Microsoft offers no clarity on why this bug is different.

There are only nine other fixes for remote code execution vulnerabilities, including three for SharePoint that have the same description as the Critical-rated SharePoint bugs already mentioned. There are two patches for the WDAC OLE DB provider for SQL Server and one for the ODBC Driver itself. There’s a fix for an RCE in Visual Studio Code, but no details are provided on what the attack scenario would be. That’s not the case for the GDI+ bug. An attacker would need to convince a user to browse to a malicious website or open a specially crafted file to get code execution. Finally, former Pwn2Own winner Bien Pham from Team Orca of Sea Security reported a code execution bug in the CD-ROM driver through the ZDI program. It’s an integer overflow that could lead to an out-of-bound write on kernel heap memory. In this case, an attacker would need to convince someone to open a malicious .iso file, which does seem a bit unlikely.

A total of 39 bugs in this release are Elevation of Privilege (EoP) bugs, including those mentioned above. The majority of these require an authenticated user to run specially crafted code on an affected system, but there are a few that stand out. The first is the patch for the print spooler. While we’re certainly used to spooler updates by now, this one was reported by the National Security Agency (NSA). The EoP in the Workstation service requires privileges, but it can be reached remotely. An attacker could execute RPC functions that are normally restricted to the local client. You would also need to be authenticated to send malicious RPC calls to the DHCP service to escalate to SYSTEM. The bug in Active Directory Domain Services could allow an attacker to get domain administrator privileges, but Microsoft offers no details on how that would occur. The NuGet package manager for .NET receives a fix impacting multiple NuGet versions. The fix for Visual Studio Code contains an …uh… interesting workaround:

“Create a folder C:\ProgramData\jupyter\kernels\ and configure it to be writable only by the current user.”

It’s not clear why this prevents the attack, but Microsoft claims it will. Lastly, the EoP in the Local Security Authority (LSA) could lead to a sandbox escape.

The October release includes fixes for 11 information disclosure bugs, including one in Office that’s listed as publicly known. Most of the other info disclosure vulnerabilities only result in leaks consisting of unspecified memory contents. There are a couple of notable exceptions. The bug in the Web Account Manager could allow an attacker to view unbound refresh tokens issued by one cloud on a different cloud. The patches for Visual Studio Code and the Mixed Reality Developer Tools fix disclosure bugs that could allow reading from the file system. The final info disclosure bug fixed this month could allow reading from the HKLM hive of the registry which you normally would not have access to.

There are two patches for Security Features Bypass (SFB) vulnerabilities this month, and the first requires physical access. On systems with outdated USB controller hardware, a Group Policy might have silently failed, which would leave the Windows Portable Device Enumerator Service open to attacks that rely on inserting a USB storage device. The SFB bug in Active Directory Certificate Services requires a Man-in-the-Middle (MiTM) and applies to Windows Challenge/Response (NTLM) authentication.

Eight different DoS vulnerabilities are patched this month. Probably the most interesting is the DoS in TCP/IP, which could be exploited by remote, unauthenticated attackers and does not require user interaction. Microsoft states systems with IPv6 disabled aren’t affected, but IPv6 comes enabled by default on most systems these days. Microsoft provides no further details about the seven other DoS patches.

The October release is rounded out by five spoofing bugs, including the lone Moderate-rated fix, which addresses a spoofing vulnerability in Microsoft Edge (Chromium-based). The most interesting is the Critical-rated fix for the Windows CryptoAPI. This bug could allow an attacker to spoof an existing public x.509 certificate to authenticate or sign code as the targeted certificate. I’m sure malware authors will definitely try to use this one in the near future. There’s also a store cross-site scripting (XSS) bug in the Service Fabric Explorer. If you’re using this, you need to ensure you are on the latest version by following these instructions. No additional details are provided about the spoofing bugs in Office or NTLM.

No new advisories were released this month. The latest servicing stack updates can be found in the revised ADV990001.

Looking Ahead

The next Patch Tuesday falls on November 8, and we’ll return with details and patch analysis then. Be sure to catch the Patch Report webcast on our YouTube channel. It should be posted in just a few hours. Until then, stay safe, happy patching, and may all your reboots be smooth and clean!

The October 2022 Security Update Review

MindShaRE: Analyzing BSD Kernels for Uninitialized Memory Disclosures using Binary Ninja

Disclosure of uninitialized memory is one of the common problems faced when copying data across trust boundaries. This can happen between the hypervisor and guest OS, kernel and user space, or across the network. The most common bug pattern noticed among these cases is where a structure or union is allocated in memory, and some of the fields or padding bytes are not initialized before copying it across trust boundaries. The question is, is it possible to perform variant analysis of such bugs?

The idea here is to perform a control flow insensitive analysis to track all memory store operations statically. Any memory region never written to is identified as uninitialized when the data from it is copied across trust boundaries.

Generalizing the code pattern for analysis

Consider the case of CVE-2018-17155, a FreeBSD kernel memory disclosure in the getcontext() and swapcontext() system calls due to a lack of structure initialization. Shown below is the patch for sys_getcontext(). The listing on the left shows the patched code. sys_swapcontext() was patched in a similar fashion.

Figure 1 - Patch for sys_getcontext() information disclosure. Vulnerable code appears on the right.

The vulnerable code declared a ucontext_t structure on the stack, wrote to some but not all fields, and finally used copyout() to copy UC_COPY_SIZE bytes of data from the structure to userland. The problem here is that not all fields are initialized, so any data occupying the uninitialized parts of the structure memory region are disclosed. To solve the problem, the patched code zeroes out the entire structure using the bzero() function.

The generalization of the above code pattern looks like this:

• A memory region (structure, union, etc.) is declared on the stack or allocated on the heap, which could be the source of uninitialized memory.
• The memory region may get fully or partially written.
• There is an API that transfers data across trust boundaries. This could be the sink for uninitialized memory.
• The API generally takes at least 3 parameters: source buffer, destination buffer, and size. In this case, the source of the memory is a stack offset, and the size of the transfer is a constant value. A constant size of transfer means the value is either the entire size of the memory region (using sizeof operator) or a part of it until an offset.
• The memory region may be zeroed out before usage using functions like memset() or bzero().

The sink function is application-specific. To mention a few of the more likely sinks: copy_to_user() in case of Linux kernel, copyout() in case of BSD kernels, send() or sendto() for network transfers or any wrappers around them. The definitions of these functions are either documented, or else understood by reverse engineering if the target is closed source.

Searching the code pattern for analysis

Once the sink function and its definition are known, we can query for calls to the sink function with a constant size argument and source buffer pointing to a stack offset or heap memory. Querying for a pointer to stack memory is straightforward, whereas detecting heap pointers requires visiting the definition site of source variables. Consider the definition of copyout() function in BSD:

         copyout(const void *kaddr, void *uaddr, size_t len)

When looking for stack memory disclosures, search for cross-references to the copyout() function where kaddr is pointing to a stack offset and the len parameter is a constant.

Binary Ninja has a static data flow feature that propagates known values within a function, including stack frame offsets and type information. Using this feature, it is possible to narrow down calls to copyout() that satisfy our search criteria. To understand this better, let’s inspect the arguments passed to copyout() from sys_getcontext().

Figure 2 - sys_getcontext() invoking copyout(kaddr, uaddr, len)

The kaddr parameter, or params[0], holds a kernel stack pointer, is shown as the stack frame offset -0x398. The value for the len parameter, or params[1], is shown as the constant 0x330. Since Binary Ninja has no information regarding uaddr, this is shown as <undetermined>. With this register type information for kaddr and len, the following query fetches all instances of calls to copyout() with a kernel stack pointer and constant size:

Statically tracking memory stores

The core idea of the analysis is to track all the memory store operations using Binary Ninja’s static data flow capability and propagate pointers manually using Single Static Assignment (SSA) form whenever necessary. For tracking stack memory stores in local function scope, we rely on Low-Level IL (LLIL), because Medium Level IL (MLIL) abstracts stack access and might eliminate some of the memory stores. For tracking inter-procedure store operations where the address is passed to another function, we rely on the MLIL SSA form to propagate the pointers. The visitor class implemented to handle IL instructions is based on Josh Watson’s Emilator.

Tracking stack memory stores with LLIL

In LLIL, any instruction writing to memory is represented as an LLIL_STORE operation. It has a source and destination parameter. The idea is to linearly visit each LLIL instruction in a function and check if it is an LLIL_STORE operation having a stack frame offset as its destination. When a memory store writing to stack is identified, we will log the source offset of the write and its size. Consider a simple 8-byte memory move operation and its corresponding LLIL information provided by Binary Ninja:

Figure 3 - LLIL_STORE operation in freebsd32_sigtimedwait()

The StackFrameOffset value is the offset from the base of the stack and the size property gives the size of the store operation. Using this information, it is possible to know which memory address are being written. In this case, the addresses from stack base offset -116 to -109 (8 bytes) are being initialized.

Static function hooks and memory writing APIs

While memory store instructions are one way to initialize memory, functions like memset() and bzero() are frequently used to initialize a memory region with NULLs. Similarly, functions such as memcpy(), memmove(), bcopy(), strncpy(), and strlcpy() are also used to write to a memory region. All these functions have something in common: there is a destination memory pointer and a size to write. If the destination and size values are known, it is possible to know the memory region being written to. Consider the case of bzero(), which is used to clear stack memory in the patched sys_getcontext():

Figure 4 - Clearing stack memory using bzero()

By querying the destination pointer and size parameters, it is possible to know their respective values and hence the target memory region.

Now let us consider how the analyzer can handle CALL operations. Static hooks are handlers to functions which we intend to handle differently compared to other functions. For any CALL instruction with a known destination i.e., MLIL_CONST_PTR, the symbol is fetched to check for static hooks.

A JSON configuration with the function names as well their positional parameters (destination buffer and size) is provided to the analyzer for static hooking:

The copyin() function is specific to BSD kernels. It is used to initialize kernel buffers with data from user space. Any target-specific functions to hook can be added to the JSON config and handled in visit_function_hooks() as per necessity.

Handling x86 REP optimization

Many times compilers optimize memory writing functions into REP instructions or a series of store operations. While store operations introduced due to optimization can be handled like any other store operation, REP instructions requires special handling. Static function hooks are not useful in detecting memory writes due to REP. So how do we handle such optimizations and avoid missing those memory writes? First, let’s look at how Binary Ninja translates the REP instruction in LLIL or MLIL.

Figure 5 - memcpy() optimized to REP instruction

Figure 6 - REP instruction translation in MLIL

The REP instruction repeats the string operation until RCX is 0. The direction of copy operation depends on the Direction Flag (DF), hence the branching where one branch increments the source (RSI) and destination (RDI) pointers and the other decrements them. In general, it is reasonably safe to assume that DF will be 0, and that pointers are incremented.

When linearly walking through the ILs, the translated REP instruction will look no different from other instructions. The idea is to check for GOTO instruction, and for every GOTO instruction in IL, fetch the disassembly at the same address. If the disassembly is REP instruction, then fetch the destination pointer as well as size arguments and mark the memory region as initialized.

The LLIL has a get_possible_reg_values() API to read values of registers statically. The MLIL provides couple of APIs, get_var_for_reg() and get_ssa_var_version(), to map architecture registers to SSA variables. This is very useful when propagating values manually using SSA variables in the absence of RegisterValueType information (i.e. RegisterValueType.UndeterminedValue). Similar APIs are currently missing in LLIL and tracked as a feature request: API to get SSARegister for a register at a given LLIL instruction.

Tracking Inter-procedure memory stores with MLIL

At this point we can track memory store operations, CALL operations such as bzero(), memset(), and also deal with REP optimization. The next task is to track memory writes across function calls, as when a caller passes a memory address to a callee. The interesting challenge here is that once a stack pointer has been passed into another function, it can no longer be tracked using the register value type information (StackFrameOffset) as we did within the local function scope using LLIL (see above).

To solve this problem, we propagate the pointers within the callee function using MLIL SSA variables, just like propagating taint information. Whenever a MLIL_STORE_SSA instruction is encountered, we log the offset of the write operation and size values whenever the destination of the memory write operation is resolved manually based on values of SSA variables. The set_function_args() function shown below iterates through MLIL variables and assigns the value (pointer) passed by the caller:

Once the initial SSA variables are set, we visit all the instructions linearly to propagate the pointer and log memory writes. While doing this, the most common operation performed on the pointer is addition. Therefore, it is necessary to emulate MLIL_ADD instruction to handle pointer arithmetic operations. Additionally, it is also important to emulate instructions such as MLIL_SUB, MLIL_LSR and MLIL_AND to handle certain pointer-aligning operations in case of optimizations. Here is an example of how these MLIL SSA expressions are resolved to log a memory store operation:

Considering the SSA variable rax_43#65 as a manually propagated pointer value, it is possible to resolve the destination of the store operation as well as the size of the write. But when the value of the SSA variable rax_43#65 is not available, this memory is not associated with the pointer that was propagated by the caller and therefore not logged.

Handling pointer-aligning optimizations

When performing inter-procedure analysis, further optimizations were noticed in addition to the REP optimization as seen in the “Handling x86 REP optimization” section above. A variable allocated on the stack will usually be aligned to meet the needs of upcoming operations. Let’s say a stack pointer is passed to memset() and the compiler inlines the call as a REP instruction. In this case, it is very likely the memory will be allocated at an aligned address such that the fastest instructions can be used during REP operation.

However, when a pointer is received as an argument by a callee or as a return value of an allocator function, the compiler may have to generate pointer and size alignment opcodes which could rely on branching decisions before reaching REP instruction. Here is an example of such an optimization commonly found in the NetBSD kernel used for analysis:

Figure 7 - An example memset() optimization from NetBSD

When such branching decisions are involved, the pointer, as well as the size, can take multiple possible values (from the perspective of static analysis) at the point of REP instruction. This is different from what we observed in the “Handling x86 REP optimization" section where there is only one possible value for pointer and size. Our goal here is to find the actual value of the pointer and size in the absence of pointer-aligning computations. To achieve this, a couple of SSA expressions were identified that can be used to resolve the original value:

• Search for an expression involving (ADDRESS & BYTESIZE). This could be the first use of ADDRESS before taking any conditional branches.
• Search for an expression involving (SIZE >> 3). This is where the adjusted size is passed to a REP instruction.

I had a couple of ideas in mind to track back the above expressions from the point of REP instruction, one relying entirely on SSA and the other based on dominators:

• Use get_ssa_var_definition() and get_ssa_var_uses() APIs to get a variable’s definition site and its uses.
• Alternatively, get the dominators of the basic block containing the REP instruction and visit the instructions in the dominator blocks.

The function resolve_optimization() shown below uses dominators to get the basic blocks to perform the search operation. Since the pointer is manually passed by the caller, the value is fetched from the SSA variables.

In the case of a possible constant size value, we fetch the maximum from the list of available size values. Once both pointer and size values are available, we log the memory region as initialized.

Tracking memory stores in dynamic memory allocations

So far, all our analyses were concentrated on stack memory as the source buffer for information disclosure. This is largely due to the prevalence of stack memory disclosure bugs, as described in KLEAK: Practical Kernel Memory Disclosure Detection (PDF). What about other memory regions such as the heap? Can we model some of the heap memory disclosures too?

When looking for heap memory disclosures, the idea remains the same. We are still looking for calls to sink functions with known size value. But instead of the source pointer being RegisterValueType.StackFrameOffset, we check for RegisterValueType.UndeterminedValue. Consider the code for sys_statfs():

Figure 8 - Dynamic memory allocation in sys_statfs()

Here the kernel pointer rdi_1#2 in copyout() is undetermined because Binary Ninja does not know what the allocator function returns. However, by using the SSA form, we can manually track back whether rdi_1#2 is holding the return value of malloc(). For example, follow the highlighted instructions in Figure 8. - the variables are assigned as rax_1#1->r15#1->rdi_1#2. This information can be obtained programmatically using the MLIL get_ssa_var_definition() API. Once the definition site of an SSA variable is obtained, we can check whether the variable is initialized using a CALL operation as demonstrated below:

How does the analyzer know the definition of allocator functions? We can take the same approach used for providing information regarding static function hooks (see the “Static function hooks and memory writing APIs” section above). A JSON configuration with a list of allocator functions and an index of size parameters is provided to the analyzer. For any CALL instruction with a known destination (i.e., MLIL_CONST_PTR), the symbol is fetched to check for known allocator functions. Here is a sample JSON configuration used for analysis:

Once we have established the connection between the source pointer and allocator call, the next question is, what pointer value will be assigned as the return value of the allocator call? The stack pointers as tracked as negative offsets in Binary Ninja as seen below:

To have a generalized representation between the stack and heap pointers, I decided to set the return value of a heap allocator calls as a negative value of the size of the allocation. For the malloc() call in sys_statfs(), rax_1#1 is set to -0x1d8 as the starting address. Therefore, the memory region which needs to be initialized ranges from -0x1d8 to 0 [start + size of allocation]. Even when the allocation size is undetermined, starting address can be set to some arbitrary value such as -0x10000. All that matters here is to know whether the contiguous memory region accessed by copyout() is initialized or not.

Filtering memory stores using dominators and post dominators

A dominator in graph theory provides information on the order of execution of some basic blocks. While we have already used dominators for handling pointer-aligning optimizations in the “Handling pointer aligning optimizations” section, this section details the usage of dominators in detecting control flow-sensitive memory store operations.

To analyze uninitialized memory disclosures, we explore two ideas: dominators and post-dominators. A basic block X is said to dominate another basic block Y if all paths to Y should go through X. A basic block Y is said to post-dominate basic block X if all paths from X to any of the function’s return blocks should go through Y. Consider this example from Wikipedia:

Figure 9 - Graph demonstrating dominators and post dominators

In the provided graph, node B dominates nodes C, D, E, and F because all paths to these nodes must go through node B. By definition, every node dominates itself, so the set of all nodes dominated by node B will be B, C, D, E, and F. Also, node A dominates all the nodes in the graph. Therefore, the dominators of nodes C, D, E, F are A and B.

Similarly, when A is considered as the function entry node, with E and F being exit nodes, node B is the post-dominator of node A. This is because all paths from A to the exit nodes must go through B.

Now, how can dominators and post-dominators help us in this analysis?

We can perform dominator analysis on the callers of the sink function. The idea is to log only memory stores in basic blocks which dominate the basic block calling copyout(), that is, basic blocks which will be executed irrespective of branching decisions. Consider the code below:

Figure 10 - Dominators of basic block calling copyout()

Here the basic block calling copyout() is <mlil block: [email protected]> and there are five dominator blocks in the path from the function entry to copyout(). When performing dominator-based analysis, we will log only memory stores within these five dominator blocks. The memory store operations in other basic blocks might be skipped and not execute. The same is the case with the callee function. We will perform an inter-procedure analysis only when the function is called from a dominator block.

Post-dominator analysis is done on the callee function during an inter-procedure analysis. It is meant to find bugs where a callee can possibly return before initializing the memory region it is supposed to. Consider the callee function do_sys_waitid() from figure 10.

Figure 11 - Post dominators of function entry block in do_sys_waitid()

The function entry block <mlil block: [email protected]> is always executed. The other basic blocks that are executed irrespective of the branching decisions are <mlil block: [email protected]> and <mlil block: [email protected]>. Once again, memory stores and callee analysis are limited only to these three basic blocks.

Dominator- and post-dominator-based analysis tries to fill the gaps in control flow insensitive analysis performed by the analyzer. The general assumption here is that memory is initialized or cleared before performing further operations and therefore dominates other basic blocks. However, this assumption is not always true. For example, there are cases where individual code paths can perform the same operation as done in the dominators. Moreover, when a callee returns due to any error condition, the return value could be validated by the caller before calling copyout(). Consequently, dominator-based analysis as done in this implementation is prone to large numbers of false positives.

Checking for uninitialized memory disclosures

Once all the memory store operations are statically logged with information on offset and size of write, the memory region copied out to user space using copyout() can be evaluated for uninitialized memory disclosure. Consider the call to copyout() shown below:

The source pointer is -0x398 and the size copied is 0x330 bytes. Therefore, the analyzer has to validate if all the bytes in the memory range from -0x398 to (-0x398 + 0x330) are initialized, and if not, flag that as a bug.

False positives and limitations

The analyzer is written with the goal of finding memory regions that never get written to in any possible code paths. False positives occur in cases when it is unable to track a memory store operation. Below are some common false positive conditions and limitations of the implementation:

• The analyzer does not emulate branching instructions. Therefore, false positives are seen in code constructs involving control flow decisions. Consider a memory region such as an array that is initialized in a loop operation. In this case, the store operation would be detected only once because the loop body is visited only once by the analyzer, and not in a loop as it would be during execution.

• Indirect calls are not resolved statically. Consequently, any memory store done during indirect calls is not tracked.

• Optimizations may make it harder to track memory stores. Some common optimizations noticed were tackled in the “Handling x86 REP optimization” and “Handling pointer aligning optimizations” sections.

• Binary Ninja may wrongly detect type information of functions used for static hooking or sink functions like copyout(). Since our analysis relies on RegisterValueType information, any failure to accurately detect the function prototype may lead to false results. Verify the type information before analysis and update if necessary.

• The analyzer looks only for code patterns where the memory source and sink function are within the same function. There is no tracking back of memory source beyond the local function scope.

• Dominator analysis is experimental. You should use it only as a guideline to perform code reviews.

When there is access to source code, some of these false positives can be resolved by changing the optimization flags or by unrolling loops to reduce branching decisions.

Analysis and results

The target kernel executable is loaded in Binary Ninja to generate the BNDB analysis database. Then the analyzer is executed against the database for faster analysis. There are a couple of scripts: one for analyzing stack memory disclosures and another for analyzing sink functions with known size and unknown source pointer. Since the source pointer could be from a heap allocator, provide a JSON configuration with a list of allocator functions as an argument. The dominator analysis is experimental. You need to enable it using an optional argument when needed:

Conclusion

The scripts were tested on Binary Ninja version 2.4.2846 against FreeBSD 11.4, NetBSD 9.2, and OpenBSD 6.9 kernels. Amongst the results, code paths that are possibly reachable for an unprivileged user were evaluated. The OpenBSD bugs were found in sysctls related to multicast routing in IPv4 as well as IPv6, which are tracked as ZDI-22-073 and ZDI-22-012 respectively.

The four vulnerabilities (ZDI-22-075, ZDI-22-1036, ZDI-22-1037, ZDI-22-1067) found in NetBSD are related to syscalls supporting backward compatibility for older NetBSD releases ZDI-22-075 and ZDI-22-1036 are information disclosures in VFS syscalls for NetBSD 3.0 and NetBSD 5.0 respectively. Details regarding the fixes can be found here. Next, ZDI-22-1037 is an information disclosure in getkerneinfo syscall for NetBSD 4.3. This bug was fixed with many other potential issues as seen here. Finally, ZDI-22-1067 is another information disclosure related to VFS syscalls but in NetBSD 2.0 compatibility. Details regarding the fix can be found here.

The FreeBSD bug found in version 11.4 was also related to compatibility, which in this case for supporting 32-bit binaries. However, this bug was fixed without a disclosure during a large change done for the 64-bit inode. The uninitialized structure fields were cleared in the copy_stat function as part of the 64-bit inode project. Though this commit was in May 2017, it was tagged to release 12.0 and above. Therefore, the bug remained unfixed in release 11.4 until it reached EOL in September 2021, soon after our bug report.

Putting it together, most of the bugs were found in BSD’s compatibility layers. Additionally, all these bugs are stack memory disclosures. For anyone interested, the source code for the project can be found here.

 You can find me on Twitter @RenoRobertr, and follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

 

Acknowledgments and references

— Various blog posts from Trail of Bits on Binary Ninja
— Josh Watson for various projects using Binary Ninja. The visitor class implementation is based on emilator
— Jordan for all the code snippets and the Binary Ninja slack community for answering various questions
KLEAK: Practical Kernel Memory Disclosure Detection by Thomas Barabosch and Maxime Villard
Solving Uninitialized Stack Memory on Windows by Joe Bialek
Building Faster AMD64 Memset Routines by Joe Bialek

MindShaRE: Analyzing BSD Kernels for Uninitialized Memory Disclosures using Binary Ninja

The September 2022 Security Update Review

Another Patch Tuesday is upon us, and Adobe and Microsoft have released a bevy of new security updates. Take a break from your regularly scheduled activities and join us as we review the details of their latest security offerings.

Adobe Patches for September 2022

For September, Adobe released seven patches addressing 63 in Adobe Experience Manager, Bridge, InDesign, Photoshop, InCopy, Animate, and Illustrator. A total of 42 of these bugs were reported by ZDI Sr Vulnerability Researcher Mat Powell. The update for InDesign is the largest patch this month, with eight Critical-rated and 10 Important-rated vulnerabilities receiving fixes. The most severe of these could lead to code execution if a specially crafted file is opened on an affected system. The patch for Photoshop fixes 10 CVEs, nine of which are rated Critical. Again, an attacker can get code execution if they can convince a user to open a malicious file. The fix for InCopy fixes five similar code execution bugs and two info disclosure bugs. Adobe Animate also receives patches for two Critical-rated code execution bugs.

The update for Adobe Bridge corrects 10 Critical-rated code execution bugs and two Important-rated info disclosure bugs. One of the three Illustrator vulnerabilities getting patched could also lead to code execution. As with the bugs previously mentioned, a user would need to open a malicious file with an affected software version. Finally, the patch for Adobe Experience Manager addresses 11 Important-rated bugs, primarily of the cross-site scripting (XSS) variety.

None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release. Adobe categorizes these updates as a deployment priority rating of 3.

Apple Patches for September 2022

Yesterday, Apple released updates for iOS, iPadOS, macOS, and Safari. They also released updates for watchOS and tvOS but provided no details on any of the fixes included in these patches. Two of the bugs patched by Apple were identified as being under active exploit. The first is a kernel bug (CVE-2022-32917) resulting from improper bounds checking. It affects iOS 15 and iPadOS 15, macOS Big Sur, and macOS Monterey. Interestingly, this CVE is also listed in the advisory for iOS 16, but it is not called out as being under active exploit for that flavor of the OS. The Big Sur version of macOS also includes a fix for an Out-of-Bounds (OOB) Write bug in the kernel (CVE-2022-32894) that’s also listed as under active attack. One final note: Apple states in its iOS 16 advisory that “Additional CVE entries to be added soon.” It is possible other bugs could also impact this version of the OS. Either way, it’s time to update your Apple devices.

Microsoft Patches for September 2022

This month, Microsoft released 64 new patches addressing CVEs in Microsoft Windows and Windows Components; Azure and Azure Arc; .NET and Visual Studio and .NET Framework; Microsoft Edge (Chromium-based); Office and Office Components; Windows Defender; and Linux Kernel (really). This is in addition to the 15 CVEs patched in Microsoft Edge (Chromium-based) and one patch for side-channel speculation in Arm processors. That brings the total number of CVEs to 79. Five of these CVEs were submitted through the ZDI program.

The volume of fixes released this month is about half of what we saw in August, but it is in line with the volume of patches from previous September releases. For whatever reason, the last quarter of the calendar year tends to have fewer patches released. We’ll see if that trend continues in 2022.

Of the 64 new CVEs released today, five are rated Critical, 57 are rated Important, one is rated Moderate, and one is rated Low in severity. One of these new CVEs is listed as publicly known and under active attack at the time of release. Let’s take a closer look at some of the more interesting updates for this month, starting with the CLFS bug under active attack:

-       CVE-2022-37969 - Windows Common Log File System Driver Elevation of Privilege Vulnerability
This bug in the Common Log File System (CLFS) allows an authenticated attacker to execute code with elevated privileges. Bugs of this nature are often wrapped into some form of social engineering attack, such as convincing someone to open a file or click a link. Once they do, additional code executes with elevated privileges to take over a system. Usually, we get little information on how widespread an exploit may be used. However, Microsoft credits four different agencies reporting this bug, so it’s likely beyond just targeted attacks.

-       CVE-2022-34718 - Windows TCP/IP Remote Code Execution Vulnerability
This Critical-rated bug could allow a remote, unauthenticated attacker to execute code with elevated privileges on affected systems without user interaction. That officially puts it into the “wormable” category and earns it a CVSS rating of 9.8. However, only systems with IPv6 enabled and IPSec configured are vulnerable. While good news for some, if you’re using IPv6 (as many are), you’re probably running IPSec as well. Definitely test and deploy this update quickly.

-       CVE-2022-34724 - Windows DNS Server Denial of Service Vulnerability
This bug is only rated Important since there’s no chance of code execution, but you should probably treat it as Critical due to its potential impact. A remote, unauthenticated attacker could create a denial-of-service (DoS) condition on your DNS server. It’s not clear if the DoS just kills the DNS service or the whole system. Shutting down DNS is always bad, but with so many resources in the cloud, a loss of DNS pointing the way to those resources could be catastrophic for many enterprises.

-       CVE-2022-3075 - Chromium: CVE-2022-3075 Insufficient data validation in Mojo
This patch was released by the Google Chrome team back on September 2, so this is more of an “in case you missed it.” This vulnerability allows code execution on affected Chromium-based browsers (like Edge) and has been detected in the wild. This is the sixth Chrome exploit detected in the wild this year. The trend shows the near-ubiquitous browser platform has become a popular target for attackers. Make sure to update all of your systems based on Chromium.

Here’s the full list of CVEs released by Microsoft for September 2022:

CVE Title Severity CVSS Public Exploited Type
CVE-2022-37969 Windows Common Log File System Driver Elevation of Privilege Vulnerability Important 7.8 Yes Yes EoP
CVE-2022-23960 * Arm: CVE-2022-23960 Cache Speculation Restriction Vulnerability Important N/A Yes No Info
CVE-2022-34700 Microsoft Dynamics 365 (on-premises) Remote Code Execution Vulnerability Critical 8.8 No No RCE
CVE-2022-35805 Microsoft Dynamics 365 (on-premises) Remote Code Execution Vulnerability Critical 8.8 No No RCE
CVE-2022-34721 Windows Internet Key Exchange (IKE) Protocol Extensions Remote Code Execution Vulnerability Critical 9.8 No No RCE
CVE-2022-34722 Windows Internet Key Exchange (IKE) Protocol Extensions Remote Code Execution Vulnerability Critical 9.8 No No RCE
CVE-2022-34718 Windows TCP/IP Remote Code Execution Vulnerability Critical 9.8 No No RCE
CVE-2022-38013 .NET Core and Visual Studio Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-26929 .NET Framework Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-38019 AV1 Video Extension Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-38007 Azure Guest Configuration and Azure Arc-enabled servers Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37954 DirectX Graphics Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35838 HTTP V3 Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-35828 Microsoft Defender for Endpoint for Mac Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34726 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-34727 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-34730 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-34732 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-34734 Microsoft ODBC Driver Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-37963 Microsoft Office Visio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-38010 Microsoft Office Visio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-34731 Microsoft OLE DB Provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-34733 Microsoft OLE DB Provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35834 Microsoft OLE DB Provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35835 Microsoft OLE DB Provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35836 Microsoft OLE DB Provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35840 Microsoft OLE DB Provider for SQL Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-37962 Microsoft PowerPoint Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-35823 Microsoft SharePoint Remote Code Execution Vulnerability Important 8.1 No No RCE
CVE-2022-37961 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-38008 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-38009 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-37959 Network Device Enrollment Service (NDES) Security Feature Bypass Vulnerability Important 6.5 No No SFB
CVE-2022-38011 Raw Image Extension Remote Code Execution Vulnerability Important 7.3 No No RCE
CVE-2022-35830 Remote Procedure Call Runtime Remote Code Execution Vulnerability Important 8.1 No No RCE
CVE-2022-37958 SPNEGO Extended Negotiation (NEGOEX) Security Mechanism Information Disclosure Vulnerability Important 7.5 No No Info
CVE-2022-38020 Visual Studio Code Elevation of Privilege Vulnerability Important 7.3 No No EoP
CVE-2022-34725 Windows ALPC Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-35803 Windows Common Log File System Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30170 Windows Credential Roaming Service Elevation of Privilege Vulnerability Important 7.3 No No EoP
CVE-2022-34719 Windows Distributed File System (DFS) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34724 Windows DNS Server Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-34723 Windows DPAPI (Data Protection Application Programming Interface) Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-35841 Windows Enterprise App Management Service Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35832 Windows Event Tracing Denial of Service Vulnerability Important 5.5 No No DoS
CVE-2022-38004 Windows Fax Service Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-34729 Windows GDI Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-38006 Windows Graphics Component Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-34728 Windows Graphics Component Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-35837 Windows Graphics Component Information Disclosure Vulnerability Important 5 No No Info
CVE-2022-37955 Windows Group Policy Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34720 Windows Internet Key Exchange (IKE) Extension Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-33647 Windows Kerberos Elevation of Privilege Vulnerability Important 8.1 No No EoP
CVE-2022-33679 Windows Kerberos Elevation of Privilege Vulnerability Important 8.1 No No EoP
CVE-2022-37956 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37957 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-37964 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30200 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-26928 Windows Photo Import API Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-38005 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35831 Windows Remote Access Connection Manager Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30196 Windows Secure Channel Denial of Service Vulnerability Important 8.2 No No DoS
CVE-2022-35833 Windows Secure Channel Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-38012 Microsoft Edge (Chromium-based) Remote Code Execution Vulnerability Low 7.7 No No RCE
CVE-2022-3038 * Chromium: CVE-2022-3038 Use after free in Network Service Critical N/A No No RCE
CVE-2022-3075 * Chromium: CVE-2022-3075 Insufficient data validation in Mojo High N/A No Yes RCE
CVE-2022-3039 * Chromium: CVE-2022-3039 Use after free in WebSQL High N/A No No RCE
CVE-2022-3040 * Chromium: CVE-2022-3040 Use after free in Layout High N/A No No RCE
CVE-2022-3041 * Chromium: CVE-2022-3041 Use after free in WebSQL High N/A No No RCE
CVE-2022-3044 * Chromium: CVE-2022-3044 Inappropriate implementation in Site Isolation High N/A No No N/A
CVE-2022-3045 * Chromium: CVE-2022-3045 Insufficient validation of untrusted input in V8 High N/A No No RCE
CVE-2022-3046 * Chromium: CVE-2022-3046 Use after free in Browser Tag High N/A No No RCE
CVE-2022-3047 * Chromium: CVE-2022-3047 Insufficient policy enforcement in Extensions API Medium N/A No No SFB
CVE-2022-3053 * Chromium: CVE-2022-3053 Inappropriate implementation in Pointer Lock Medium N/A No No N/A
CVE-2022-3054 * Chromium: CVE-2022-3054 Insufficient policy enforcement in DevTools Medium N/A No No SFB
CVE-2022-3055 * Chromium: CVE-2022-3055 Use after free in Passwords Medium N/A No No RCE
CVE-2022-3056 * Chromium: CVE-2022-3056 Insufficient policy enforcement in Content Security Policy Low N/A No No SFB
CVE-2022-3057 * Chromium: CVE-2022-3057 Inappropriate implementation in iframe Sandbox Low N/A No No EoP
CVE-2022-3058 * Chromium: CVE-2022-3058 Use after free in Sign-In Flow Low N/A No No RCE

* Indicates this CVE had previously been assigned by a 3rd-party and is now being incorporated into Microsoft products.

Checking the remaining Critical-rated updates, there are two for Windows Internet Key Exchange (IKE) Protocol Extensions that could also be classified as “wormable.” For both bugs, only systems running IPSec are affected. There are also two Critical-rated vulnerabilities in Dynamics 365 (On-Premises) that could allow an authenticated user to perform SQL injection attacks and execute commands as db_owner within their Dynamics 356 database.

Moving on to other code execution bugs, more than half of this month’s release involves some form of remote code execution. Of these, the patches for SharePoint stand out. Microsoft recently detailed how a SharePoint bug was used by Iranian threat actors against the Albanian government, resulting in Albania breaking off diplomatic relations with Iran. Those attacks involved a SharePoint bug we had previously blogged about. These new SharePoint cases do require authentication, but they sound very similar to other SharePoint bugs that came through the ZDI program. There are six RCE bugs in OLE DB Provider for SQL Server, but they require user interaction. A threat actor would need a user on an affected system to connect to a malicious SQL server via OLEDB, which could result in the target server receiving a malicious packet, resulting in code execution. There are five RCE bugs in the ODBC driver that also require user interaction. For these, opening a malicious MDB in Access would get code execution, similar to the other open-and-own bugs in Office components. The bug in LDAP also requires user interaction, but no other information about the exploit scenario is given.

The bug in the Enterprise App Management component requires authentication, but it’s still intriguing. An attacker could use the vulnerability to install arbitrary SYSTEM services that would then run with SYSTEM privileges. I could definitely see this bug being used after an initial breach for lateral movement and to maintain a presence on a target network. The RPC bug also looks interesting, but it’s likely not as practical since an attacker would need to spoof the localhost IP address of the target. There’s an RCE bug in .NET, but no information besides the requirement for user interaction is given. Finally, there are updates for the AV1 video extension and the Raw image extension. Both updates are delivered automatically through the Microsoft store. If you’re in a disconnected environment, you’ll need to apply these updates manually.

There are a total of 19 elevation of privilege (EoP) fixes in this month’s release, including the aforementioned patch for CLFS. Many of these require an authenticated user to run specially crafted code on an affected system. The bug in Windows Defender for Mac fits this description, as do the kernel-related patches. However, there are a couple of interesting bugs that don’t fit this profile. The first of these is a bug in the Credential Roaming Service that could allow attackers to gain remote interactive logon rights on a machine. There are two bugs in Kerberos that could lead to SYSTEM, but both have many caveats, so exploitation is unlikely. The EoP in Azure Guest Configuration and Arc-Enabled servers is fascinating for multiple reasons. A threat actor could use this vulnerability to replace Microsoft-shipped code with their own code, which would then be run as root in the context of a Guest Configuration daemon. On an Azure Arc-enabled server, it could run in the context of the GC Arc Service or Extension Service daemons. While this is interesting on its own, the mere fact that Microsoft is producing patches for the Linux kernel boggles the mind. And, of course, it wouldn’t be a monthly update if it didn’t include a patch for the print spooler.

The September release includes six patches for information disclosure vulnerabilities. For the most part, these only result in leaks consisting of unspecified memory contents. One exception is the bug impacting the Data Protection Application Programming Interface (DPAPI). If you aren’t familiar with it, DPAPI allows you to encrypt data using information from the current user account or computer. The bug patched this month could allow an attacker to view the DPAPI master key. The vulnerability in the Windows graphics component could leak metafile memory values, although it’s not clear what an attacker could do with this information.

Seven different DoS vulnerabilities are patched this month, including the DNS bug previously mentioned above. Two bugs in secure channel would allow an attacker to crash a TLS by sending specially crafted packets. There’s a DoS in IKE, but unlike the code execution bugs listed above, no IPSec requirements are listed here. If you’re running newer OSes with the latest features, don’t miss the fix for an HTTP DoS. The system needs HTTP/3 enabled and the server using buffered I/O to be affected. HTTP/3 is a new feature in Windows Server 2022, so in this rare instance, older is better.

The September release includes a fix for a lone security feature bypass in Network Device Enrollment (NDES) Service. An attacker could bypass the service’s cryptographic service provider.

The Low-rated bug is a sandbox escape in Microsoft Edge (Chromium-based) that requires user interaction. However, the CVSS for this bug is 7.7, which Mitre classifies as “High.” Microsoft claims the user interaction involved justifies the Low rating, but I would still treat this as an important update and not delay the rollout.

No new advisories were released this month. The latest servicing stack updates can be found in the revised ADV990001.

Looking Ahead

The next Patch Tuesday falls on October 11, and we’ll return with details and patch analysis then. Don’t forget - I’ll be premiering the Patch Report webcast tomorrow on our YouTube channel at 9:00 am Central time. I hope you’re able to tune in and check it out. Until then, stay safe, happy patching, and may all your reboots be smooth and clean!

The September 2022 Security Update Review

Riding the InfoRail to Exploit Ivanti Avalanche – Part 2

In my first blog post covering bugs in Ivanti Avalanche, I covered how I reversed the Avalanche custom InfoRail protocol, which allowed me to communicate with multiple services deployed within this product. This allowed me to find multiple vulnerabilities in the popular mobile device management (MDM) tool. If you aren’t familiar with it, Ivanti Avalanche allows enterprises to manage mobile device and supply chain mobility solutions. That’s why the bugs discussed here could be used by threat actors to disrupt centrally managed Android, iOS and Windows devices. To refresh your memory, the following vulnerabilities were presented in the previous post:

 ·       Five XStream insecure deserialization issues, where deserialization was performed on the level of message handling.
·       A race condition leading to authentication bypass, wherein I abused a weakness in the protocol and the communication between services.

This post is a continuation of that research. By understanding the expanded attack surface exposed by the InfoRail protocol, I was able to discover an additional 20 critical and high severity vulnerabilities. This blog post takes a detailed look at three of my favorite vulnerabilities, two of which have a rating of CVSS 9.8:

·       CVE-2022-36971 – Insecure deserialization.
·       CVE-2021-42133 – Arbitrary file write/read through the SMB server.
·       CVE-2022-36981 – Path traversal, delivered with a fun authentication bypass.

Each of these three vulnerabilities leads to remote code execution as SYSTEM.

CVE-2022-36971: A Tricky Insecure Deserialization

I discovered the first vulnerability when I came across an interesting class named JwtTokenUtility, which defines a non-default constructor that could be a potential target:

At [1], the function base64-decodes one of the arguments.

At [2], it checks if the publicOnly argument is true.

If not, it deserializes the base64 decoded argument at [3].

This looks like a possible insecure deserialization sink. In addition, it is invoked from many locations within the codebase. The following screenshot illustrates several instances where it is invoked with the first argument set to false:

Figure 1 - Example invocations of JwtTokenUtility non-default constructor

It turned out that most of these potential vectors require control over the SQL database. The serialized object is retrieved from the database, and I found no direct way to modify this value. Luckily, there are two services with a more direct attack vector: the Printer Device Server and the Smart Device Server. The exploitation of both services is almost identical. We will focus on the Printer Device Server (PDS).

Let’s have a look at the PDS AmcConfigDirector.createAccessTokenGenerator method:

At [1], it uses acctApi.getGlobal to retrieve an object that implements IGlobal.

At [2], it retrieves the pkk string by calling global.getAccessKeyPair.

At [3], it decrypts the pkk string by calling PasswordUtils.decryptPassword. We are not going to analyze this decryption routine. This decryption function implements a fixed algorithm with a hardcoded key, thus the attacker can easily perform the encryption or decryption on their own.

At [4], it invokes the vulnerable JwtTokenUtility constructor, passing the pkk string as an argument.

At this point, we are aware that there is potential for abusing the non-default JwtTokenUtility constructor. However, we are missing two things:

       -- How can we control the pkk string?
       -- How can we reach createAccessTokenGenerator?

Let’s start with the control of the pkk string.

Controlling the value of pkk

To begin, we know that:

       -- The code retrieves an object to assign to the global variable. This object implements IGlobal.
       -- It calls the global.getAccessKeyPair getter to retrieve pkk.

There is a Global class that appears to control the PDS service global settings. It implements the IGlobal interface and both the getter and the setter for the accessKeyPair member, so this is probably the class we’re looking for.

Next, we must look for corresponding setAccessKeyPair setter calls. Such a call can be found in the AmcConfigDirector.processServerProfile method.

At [1], processServerProfile accepts the config argument, which is of type PrinterAgentConfig.

At [2], it retrieves a list of PropertyPayload objects by calling config.getPayload.

At [3], the code iterates over the list of PropertyPayload objects.

At [4], there is a switch statement based on the property.name field.

At [5], the code checks to see if property.name is equal to the string "webfs.ac.ppk".

If so, it calls setAccessKeyPair at [6].

So, the AmcConfigDirector.processServerProfile method can be used to control the pkk value. Finally, we note that this method can be invoked remotely through a ServerConfigHandler InfoRail message:

At [1], we see that this message type can be accessed through the subcategory 1000000 (see first blog post - Message Processing and Subcategories section).

At [2], the main processMessage method is defined. It will be called during message handling.

At [3], the code retrieves the message payload.

At [4], it calls the second processMessage method.

At [5], it deserializes the payload and casts it to the PrinterAgentConfig type.

At [6], it calls processServerProfile and provides the deserialized config object as an argument.

Success! We can now deliver our own configuration through the ServerConfigHandler method of the PDS server. This method can be invoked through the InfoRail protocol. Next, we need to get familiar with the PrinterAgentConfig class to prepare the appropriate serialized object.

It has a member called payload, which is of type List<PropertyPayload>.

PropertyPayload has two members that are interesting for us: name and value. Recall that the processServerProfile method does the following:

       -- Iterates through the list of PropertyPayload objects with a for loop.
       -- Executes switch statement based on PropertyPayload.name.
       -- Sets values based on PropertyPayload.value.

With this in mind, we can understand how to deliver a serialized object and control the pkk variable. We have to prepare an appropriate gadget (we can use the Ysoserial C3P0 or CommonsBeanutils1 gadgets), encrypt it (decryption will be handled by the PasswordUtils.decryptPassword method) and deliver through the InfoRail protocol.

The properties of the InfoRail message should be as follows:

       -- Message subcategory: 1000000.
       -- InfoRail distribution list address: 255.3.5.15 (PDS server).

Here is an example payload:

The first step of the exploitation is completed. Next, we must find a way to call the createAccessTokenGenerator function.

Triggering the Deserialization

Because the full flow that leads to the invocation of createAccessTokenGenerator is extensive, I will omit some of the more tedious details. We will instead focus on the InfoRail message that allows us to trigger the deserialization via the needFullConfigSync function. Be aware that the PDS server frequently performs synchronization operations, but typically does not perform a synchronization of the full configuration. By calling needFullConfigSync, a full synchronization will be performed, leading to execution of doPostDeploymentCleanup:

At [1], the code invokes our target method, createAccessTokenGenerator.

The following snippet presents the NotificationHandler message, which calls the needFullConfigSync method:

At [1], the message subcategory is defined as 2200.

At [2], the main processMessage method is defined.

At [3], the payload is deserialized and casted to the NotifyUpdate type (variable nu).

At [4], the code iterates through the entries of the NotifyUpdateEntry object that was obtained from nu.getEntries.

At [5], [6], and [7], the code checks to see if entry.ObjectType is equal to 61, 64, or 59.

If one of the conditions is true, the code sets the universalDeployment variable to true value at [8], [9], or [10], so that needFullConfigSync will be called at [11].

The last step is to create an appropriate serialized message object. An example payload is presented below. Here, the objectType field is equal to 61.

The attacker must send this payload through a message with the following properties:

-- Message subcategory: 2200.
-- InfoRail distribution list address: 255.3.5.15 (PDS server).

To summarize, we must send two different InfoRail messages to exploit this deserialization issue. The first message is to invoke ServerConfigHandler, which delivers a serialized pkk string. The second message is to invoke NotificationHandler, to trigger the insecure deserialization of the pkk value. The final result is a nice pre-auth remote code execution as SYSTEM.

CVE-2021-42133: One Vuln to Rule Them All - Arbitrary File Read and Write

Ivanti Avalanche has a File Store functionality, which can be used to upload files of various types. This functionality has been already abused in the past, in CVE-2021-42125, where an administrative user could:

-- Use the web application to change the location of the File Storage and point it to the web root.
-- Upload a file of any extension, such as a JSP webshell, through the web-based functionality.
-- Use the webshell to get code execution.

The File Store configuration operations are performed through the Enterprise Server, and they can be invoked through InfoRail messages. I quickly discovered three interesting properties of the File Store:

  1. It supports Samba shares. Therefore, it is possible to connect it to any reachable SMB server. The attacker can set the File Store path pointing to his server by specifying a UNC path.
  2. Whenever the File Store path is changed, Avalanche copies all files from the previous File Store directory to the new one. If a file of the same name already exists in the new location, it will be overwritten.
  3. The File Store path can also be set to any location in the local file system.

These properties allow an attacker to freely exchange files between their SMB server and the Ivanti Avalanche local file system. In order to modify the File Store configuration, the attacker needs to send a SetFileStoreConfig message:

At [1], the subcategory is defined as 1501.

At [2], the standard Enterprise Server processMessage method is defined. The implementation of message processing is a little bit different in the Enterprise Server, although the underlying idea is the same as in previous examples.

At [3] and [4], the method saves the new configuration values.

The only thing that we must know about the saveConfig method is that it overwrites all the properties with the new ones provided in the serialized payload. Moreover, some of the properties, such as the username and password for the SMB share, are encrypted in the same manner as in the previously described deserialization vulnerability.

To sum up this part, we must send an InfoRail message with the following properties:

--Message subcategory: 1501.
--Message distribution list: 255.3.2.5 (Enterprise Server).

Below is a fragment of an example payload, which sets the File Store path to an attacker-controlled SMB server:

Arbitrary File Read Scenario

The whole Arbitrary File Read scenario can be summarized in the following picture:

Figure 2 - Example scenario for the Arbitrary File Read exploitation

  1. The attacker points the File Store to a non-existent SMB share. This step is optional, but makes the exploit cleaner by ensuring that files from the current File Store location will not be copied to the location where the attacker wants to retrieve the files.
  2. The attacker points the File Store to a desired local file system path from which he wants to disclose files.
  3. The attacker points the File Store to his SMB share.
  4. Files from the previous File Store path (local file system) are transferred to the attacker’s SMB share.

The following screenshot presents an example exploitation of this scenario:

Figure 3 - Exploitation of the Arbitrary File Read scenario

As shown, the exploit is targeting the main Ivanti Avalanche directory: C:\Program Files\Wavelink\Avalanche.

The following screenshot presents the exploitation results. Files from the Avalanche main directory were gradually copied to the attacker’s server:

Figure 4 - Exploitation of the Arbitrary File Read scenario - results

Arbitrary File Write Scenario

The following screenshot presents the Arbitrary File Write scenario:

Figure 5 - Example scenario for the Arbitrary File Write scenario

  1. The attacker creates an SMB share that contains the JSP webshell.
  2. The attacker points the File Store to a non-existent SMB share. This step is optional, but makes the exploit cleaner by ensuring that files from the current File Store location will not be copied to the Avalanche webroot.
  3. The attacker points the File Store to the SMB share containing the webshell file.
  4. The attacker points the File Store to the Ivanti Avalanche webroot directory.
  5. Avalanche copies the webshell to the webroot.
  6. The attacker executes code through the webshell.

The following screenshot presents an example exploitation attempt. It uploads a file named poc-upload.jsp to C:\Program Files\Wavelink\Avalanche\Web\webapps\ROOT:

Figure 6 - Exploitation of the Arbitrary File Write scenario

Finally, one can use the uploaded webshell to execute arbitrary commands.

Figure 7 - Executing arbitrary code via the webshell

CVE-2022-36981: Path Traversal in File Upload, Plus Authentication Bypass

We made it to the final vulnerability we will discuss today. This time, we will exploit a path traversal vulnerability in the Avalanche Smart Device Server, which listens on port TCP 8888 by default. However, InfoRail will play a role during the authentication bypass that allows us to reach the vulnerable code.

Path Traversal in File Upload

Our analysis begins with examining the uploadFile method.

At [1], the endpoint path is defined. The path contains two arguments: uuid and targetbasename.

At [2], the doUploadFile method is called.

Let’s start with the second part of the doUploadFile method, as I want to save the authentication analysis for later in this section.

At [1], the uploadPath string is obtained by calling getUploadFilePath. This method accepts two controllable input arguments: uuid and baseFileName.

At [2], the method instantiates a File object based on uploadPath.

At [3], the method invokes writeToFile, passing the attacker-controlled input stream together with the File object.

We will now analyze the crucial getUploadFilePath method, as this is the method that composes the destination path.

At [1], it constructs deviceRoot as an object of type File. The parameters passed to the constructor are the hardcoded path obtained from getCachePath() and the attacker-controllable uuid value. As shown above, uuid is not subjected to any validation, so we can perform path traversal here.

At [2], the code verifies that the deviceRoot directory exists. From here we see that uuid is intended to specify a directory. If the directory does not exist, the code creates it at [3].

At [4], it validates the attacker-controlled baseFileName against a regular expression. If the validation fails, baseFileName is reassigned at [5].

At [6], it creates a new filename fn, based on the current datetime, an integer value, and baseFileName.

At [7], it instantiates a new object of type File. The path for this File object is composed from uuid and fn.

After ensuring that the file does not already exist, the file path is returned at [8].

After analyzing this method, we can draw two conclusions:

       -- The uuid parameter is not validated to guard against path traversal sequences. An attacker can use this to escape to a different directory.
       -- The extension of baseFileName is not validated. An attacker can use this to upload a file with any extension, though the filename will be prepended with a datetime and an integer.

Ultimately, when doUploadFile calls writeToFile, it will create a new file with this name and write the attacker-controlled input stream to the file. This makes it seem that we can exploit this as a path traversal vulnerability and write an arbitrary file to the filesystem. However, there are two major obstacles that will be presented in the next section.

Authentication and Additional UUID Verification

Now that we’ve covered the second part, let’s go back and analyze the first part of the doUploadFile method.

At [1], the code retrieves the mysterious testFlags.

At [2], it validates the length of the uuid, to ensure it is at least 5 characters long.

At [3], it performs an authorization check (perhaps better thought of as an authentication check) by calling isAuthorized. This method accepts uuid, credentials (authorization), and testFlags.

At [4], the code retrieves the deviceId based on the provided uuid.

At [5], the code checks to see if any device was retrieved. If not, it checks for a specific value in testFlags at [6]. If this second check is also not successful, the code raises an exception.

At [7], it calls allowUpload to perform one additional check. However, this final check has nothing to do with validating uuid. It only verifies the amount of available disk space, and this should not pose any difficulties for us.

We can spot two potential roadblocks:

       -- There is an authentication check.
       -- There is a check on the value of uuid, in that it must map to a known deviceId. However, we can bypass this check if we could get control over testFlags. If testFlags & 0x100 is not equal to 0, the exception will not be thrown, and execution will proceed.

Let’s analyze the most important fragments of the isAuthorized method:

At [1], the method retrieves enrollmentId, found within the token submitted by the requester.

At [2], it tries to retrieve the enrollment object from the database, based on enrollmentId.

At [3], it checks to see if enrollment was retrieved.

Supposing that enrollment was not retrieved successfully, the code checks for a particular value in testFlags at [4]. If not, it will return false at [6]. But if the relevant value is found in testFlags, the authentication routine will return true at [5], even though the requester’s authorization token did not contain a valid enrollmentId.

Note that this method also checks an enrollment password, although that part is not important for our purposes.

Here as well, testFlags can also be used to bypass the relevant check. Hence, if we can control testFlags, neither the authentication nor the uuid validation will cause any further trouble for us.

Here is where InfoRail comes into play. It turns out that the Smart Device Server AgentTaskHandler message can be used to modify testFlags:

At [1], it retrieves flagsToSet from the sds.modflags.set property.

At [2], it obtains the Config Directory API interface.

At [3], it uses flagsToSet to calculate the new flags value.

At [4], it saves the new flag value.

To sum up, an attacker can control testFlags, and use this to bypass both the authentication check and the uuid check.

Exploitation

Exploitation includes two steps.

1) Set testFlags to bypass the authentication and the uuid check.

To modify the testFlags, the attacker must send an InfoRail message with the following parameters:

       -- Message subcategory: 2500.
       -- Distribution list: 255.3.2.17 (SDS server).
       -- Payload:

2) Exploit the path Traversal through a web request

The path traversal can be exploited with an HTTP Request, as in the following example:

The response will return the name of the uploaded webshell:

Finally, an attacker can use the uploaded JSP webshell for remote code execution as SYSTEM.

Figure 8 - Remote Code Execution with the uploaded webshell

Conclusion

I really hope that you were able to make it through this blog post, as I was not able to describe those issues with a smaller number of details (believe me, I have tried). As you can see, undiscovered attack surfaces can lead to both cool and dangerous vulnerabilities. It is something that you must look for, especially in products that are responsible for the administration of many other devices.

This blog post is the last in this series of articles on Ivanti Avalanche research. However, I am planning something new, and yes, it concerns Java deserialization. Until then, you can follow me @chudypb and follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

Riding the InfoRail to Exploit Ivanti Avalanche – Part 2

CVE-2022-34715: More Microsoft Windows NFS v4 Remote Code Execution

In this excerpt of a Trend Micro Vulnerability Research Service vulnerability report, Quintin Crist and Dusan Stevanovic of the Trend Micro Research Team detail a recently patched remote code execution vulnerability in the Microsoft Windows operating system, originally discovered and reported by the researcher known as Arimura. The bug is the result of a dynamically allocated buffer created by an NFS function and is present only on Windows Server 2022. An unauthenticated attacker could exploit this bug to execute arbitrary code in the context of SYSTEM. This is the third such NFS vulnerability in as many months. The following is a portion of their write-up covering CVE-2022-34715, with a few minimal modifications.


A remote code execution vulnerability exists in Windows Network File System. The vulnerability is due to incorrect validation of fields within an NFS request. A remote attacker can exploit this vulnerability by sending malicious RPC calls to a target server. Successful exploitation results in arbitrary code execution in the context of SYSTEM. Unsuccessful exploitation may result in a crash of the target system.

The Vulnerability

Microsoft Windows ships with several network features designed to communicate and interact with non-Windows file shares. One of these modules is called Network File System (NFS).

NFS is a protocol originally developed by Sun Microsystems in 1984. Version 2 is documented in RFC 1094. Version 3 is documented in RFC 1813. Version 4 was developed by the IETF and is documented in RFC 3010 (released December 2000) and revised in RFC 3530 (released April 2003) and RFC 7530 (released March 2015). NFS allows users to access remote file shares in the same way that the local file system is accessed. Different access levels and permissions can be set on shares, such as read-write and read-only. Additionally, IP/UID/GID/Kerberos security can be used. NFS uses Open Network Computing (ONC) Remote Procedure Call (RPC) to exchange control messages. ONC RPC was originally developed by Sun Microsystems and can also be referred to as Sun RPC.

When ONC RPC messages are transferred over TCP, they are prepended with a Fragment header structure (as illustrated in the following table) that specifies the length of the message. This allows the receiver to distinguish multiple messages sent over a single TCP session. Other protocols such as UDP do not use this field. Note that all multi-byte values are encoded in big-endian byte order.

The structure of ONC RPC request messages, in general, is as follows:

The Credentials structure in a Sun-RPC message has the following structure:

The Flavor field in the above structure serves as a type identifier of the Contents data. Security flavors have been called authentication flavors for historical reasons. There are multiple security flavors defined in the RPC specification, such as AUTH_NONE(0), AUTH_SYS(1), AUTH_SHORT(2), AUTH_DH(3), and RPCSEC_GSS(6).

The Contents field for the flavor RPCSEC_GSS has the following structure:

There are four types defined for the GSS Procedure field: RPCSEC_GSS_DATA(0), RPCSEC_GSS_INIT(1), RPCSEC_GSS_CONTINUE_INIT(2), and RPCSEC_GSS_DESTROY(3). Also, for the GSS Service field, there are three types: rpc_gss_svc_none(1), rpc_gss_svc_integrity(2), and rpc_gss_svc_privacy(3). When using RPCSEC_GSS to authenticate RPC clients, a security context must be created by using RPCSEC_GSS_INIT and RPCSEC_GSS_CONTINUE_INIT RPC messages. First, the RPC client sends an RPCSEC_GSS_INIT message to start the creation of the context. Then, the RPC server decides whether it needs another token for the creation. If so, the server replies with a GSS_S_CONTINUE_NEEDED message, and the client needs to send an RPCSEC_GSS_CONTINUE_INIT message to continue.

If the GSS Service field is set to 2 (rpc_gss_svc_integrity), the Program-specific data field is prefixed with the following structure:

If the GSS Service field is set to 3 (rpc_gss_svc_privacy), the Program-specific data field is encrypted.

When the Program field is set to 100003 (NFS) and the Procedure field is set to 1 (Compound), the Program-specific data field has the following structure:

In the request data, for each operation in the message:

Operation data for opcode OP_CREATE(6):

Operation data for opcode OP_OPEN(18):

Operation data for opcode OP_SETATTR(34):

Attributes Data (fattr4) has the following format:

Attributes Data for ACL ( Bit12, 0x1000 ):

A buffer overflow vulnerability exists in the Windows implementation of NFS. The vulnerability is due to incorrect validation of the of the ACE_Count field when processing ACL attribute data in Nfs4SrvAclBuildWindowsAclsFromNfsAcl.

This function is only vulnerable when setting ACL attribute data using opcodes 6, 18, 34.

The server allocates a response buffer of size (ACE_Count << 5). This size is stored as a uint64_t in Nfs4SrvAclBuildWindowsAclsFromNfsAcl. A buffer of this size is created using NfsMemMgrBufferAllocate. However, NfsMemMgrBufferAllocate only takes a uint32_t for the buffer size, so the upper 32 bits of the requested size is ignored.

This allows an attacker to specify an ACE_Count such that (ACE_Count << 5) & 0xFFFFFFFF < ACE_Count. This will result in a buffer overflow later in the function when the buffer is used.

In particular, ACE_Count values above 0x8000000 will trigger this vulnerability.

Note that ACE_Count = 0x8000000 itself is not vulnerable since NfsMemMgrBufferAllocate will error when the requested length is zero.

An attacker can use this vulnerability to overflow a heap buffer. Successful exploitation may result in arbitrary code execution in the context of SYSTEM. Unsuccessful exploitation will result in a crash of the target system.

Source Code Walkthrough

The following code snippet was taken from nfssvr.sys version 10.0.20348.825. Comments have been added by Trend Micro researchers.

Detecting Attacks

The detection device needs to check if the Program field in an RPC request message has the value 100003 (NFS), Procedure field has the value 1 (COMPOUND), and Program Version field has the value 4 (NFS4). If found, the device must inspect the Program-specific data in the ONC RPC messages.

The detection device should check for the vulnerable opcodes (6, 18, 34) in each operation. If present the device should check the operation for ACL attribute data. If ACL attribute data is present, the device should check for an ACE_Count field above 0x8000000.

There is no fixed offset into the message that can be used to ignore non-vulnerable opcodes since NFS operations do not consistently contain a length of the operation data. The full message must be processed to determine if there is any ACL attribute data.

If the ACE_Count field is greater than 0x8000000, the traffic should be considered suspicious; an attack exploiting this vulnerability is likely underway.

Conclusion

This bug was patched by Microsoft in August 2022 and assigned CVE-2022-34715. Their advisory lists the vulnerability as not requiring authentication. However, all known exploitation paths require file creation or modification privileges. In their write-up, they also list disabling NFSv4.1 as a method to mitigate attacks. However, this could lead to a loss of functionality. Applying the NFS-related updates is the best method to fully address the multiple NFS bugs patched in recent months.

Special thanks to Quintin Crist and Dusan Stevanovic of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit http://go.trendmicro.com/tis/.

The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

CVE-2022-34715: More Microsoft Windows NFS v4 Remote Code Execution

Announcing Pwn2Own Toronto 2022 and Introducing the SOHO Smashup!

Contest Rule Updates:
September 2: Due to sourcing issues with the original model, we are adding the Lexmark MC3224i printer as a target.
October 21: Due to continued sourcing issues, the Lexmark MC3224adwe printer has been removed from the competition.
November 29: Added Google Nest Audio to the smart speaker category and announced Google as an event sponsor.

If you just want to read the rules, you can find them here.

Our Fall Pwn2Own event has become a bit of a nomad, having gone from Amsterdam to Tokyo to Austin. This year, we’re heading to Toronto to celebrate the 10th anniversary of the contest formerly known as Mobile Pwn2Own. Since 2012, we’ve expanded the contest to include devices beyond phones. This year is no different, with devices typically found in homes and home offices.

Pwn2Own Toronto will be held at our Toronto office on December 6-8, 2022. While this year’s contest isn’t being held in conjunction with a conference, we still want contestants to attend in person. In fact, we want them there so much that we’re going to put our money where our mouth is by reimbursing $3,000 for travel expenses for teams that participate in Toronto. We’re also going to try to have some sort of audience there as well, but we’re not offering cash just to watch. If you are a former Pwn2Own winner and would like more information about this program, you know how to get in touch with us.

If you can’t be in Toronto due to travel restrictions or travel safety concerns, you can opt to compete remotely. You will still need to register before the contest deadline (December 2, 2022) and submit a detailed whitepaper completely explaining your exploit chain and instructions on how to run the entry by December 5, 2022. A member of the ZDI staff in Toronto will run your exploit for you. All attempts will be filmed and available for viewing by the contestant and the vendor. As in the past, we will work with remote contestants to monitor the attempt in real-time via a phone call or video chat. Please note that since you are not in person, changes to exploits/scripts/etc. will not be possible, which could lower your chance of winning should something unexpected occur.

As for the contest itself, we’re pleased to welcome back Synology as a co-sponsor of the competition. We’re also happy to have Google co-sponsor the event. We’re also excited to announce a special challenge for this year’s contest we’re calling the “SOHO Smashup” (as in Small Office/Home Office). This is a real-world scenario of how a threat actor would exploit a home office, so we wanted to include it here, too. It works like this; a contestant picks a router and begins by exploiting the WAN interface. They must then pivot into the LAN to their choice of second target – one of the other devices in the contest. For example, you could pick the TP-Link router and the HP printer. If you compromise both, you’ll win $100,000 and 10 Master of Pwn points.

Beyond that, the contest remains largely the same as in previous years. We will have a random drawing to determine the schedule of attempts on the first day of the contest, and we will proceed from there. Our intention with allowing remote participation is to provide as many people as possible with the benefits of participating in Pwn2Own while still treating all contestants as equally as possible. As always, if you have questions, please contact us at [email protected]. We will be happy to address your issues or concerns directly.

Now on to the specific target categories. We’ll have seven different categories for this year’s event:

- Mobile Phones
- Wireless Routers
- Home Automation Hubs
- Printers
- Smart Speakers
- NAS Devices
- The SOHO Smashup

Let’s take a look at each category in more detail, starting with mobile phones.

The Target Phones

Back when this version of Pwn2Own started in 2012, it was called Mobile Pwn2Own, and phones are still at the heart of our fall event. As always, these phones will be running the latest version of their respective operating systems with all available updates installed. We’ve increased the rewards on these targets to add further incentives to these handsets.

In this category, contestants must compromise the device by browsing to content in the default browser for the target under test or by communicating with the following short-distance protocols: near field communication (NFC), Wi-Fi, or Bluetooth. The awards for this category are:

Mobile Phone Targets

The Google and Apple devices in this category also include an add-on bonus. If your exploit payload executes with kernel-level privileges, you earn an additional $50,000 and 5 more Master of Pwn points. That means a full exploit chain for the iPhone or Pixel that includes kernel-level access will earn $250,000.

Back to top

Routers - Your SOHO Entry Point

You connect to the world through your local wireless router, and the world has the opportunity to reach back to you. In the past, successful demonstrations included some flair by having the LED lights flash in different patterns. In addition to the home office routers, we have some devices typically used by SMBs as well. An attempt in this category must be launched against the target’s exposed network services from the contestant’s device within the contest network.

WiFi Router Targets

Back to top

Home Automation Hubs

As people add smart devices to their homes, they tend to add a hub to centralize control of all of those devices. From lights, to locks, to thermostats, cameras, and more, all can be accessed through a home automation hub. Of course, that means a threat actor could potentially access them as well. Three of the most popular smart hubs are included in this year’s event.

Home Automation Targets

Back to top

The Return of Printers

Exploits involving printing capabilities have made quite a bit of news over the last couple of years, with ransomware gangs incorporating PrintNightmare bugs in their exploit kits. In last year’s contest, one printer was turned into a jukebox playing classic rock. It will be interesting to see what exploits the contestants come up with this year.

Back to top

Smart Speakers

Smart speakers continue to play a large part in our daily interactions with music, news, and more. They also offer an attack surface for threat actors to target. For this event, Pwn2Own Toronto has three targets available in this category.

Back to top

Network Attached Storage (NAS) Devices

NAS devices make their return to Pwn2Own, and both Synology and Western Digital have returned as targets with their latest offerings. Last year’s event exposed some industry-wide Netatalk bugs. Time will tell if this year’s event has a similar impact. An attempt in this category must be launched against the target’s exposed network services from the contestant’s laptop within the contest network. 

Back to top

The SOHO Smashup

With more and more people working from home, many enterprises have found their network perimeter move to the home office as well. Threat actors who exploit home routers and consumer devices can use these as a launch point for lateral movements into enterprise resources. We wanted to demonstrate this during the contest, so we’re introducing the SOHO Smashup category to show how this could happen. Contestants will need to first compromise the WAN port on a selected router. Once they accomplish that, they will need to pivot to one of the other devices and compromise it as well. The contestant is free to select any combination of router and home automation hub, smart speaker, printer, or network attached storage device during the registration process. If they get both devices within 30 minutes, they earn $100,000 and 10 Master of Pwn points. We’re hopeful several contestants will use this category to choose their own (mis)adventure.

Back to top

Master of Pwn

No Pwn2Own contest would be complete without crowning a Master of Pwn, which signifies the overall winner of the competition. Earning the title results in a slick trophy, a different sort of wearable, and brings with it an additional 65,000 ZDI reward points (instant Platinum status in 2023).

For those not familiar with how it works, points are accumulated for each successful attempt. While only the first demonstration in a category wins the full cash award, each successful entry claims the full number of Master of Pwn points. Since the order of attempts is determined by a random draw, those who receive later slots can still claim the Master of Pwn title – even if they earn a lower cash payout. As with previous contests, there are penalties for withdrawing from an attempt once you register for it. If the contestant decides to remove an Add-on Bonus during their attempt, the Master of Pwn points for that Add-on Bonus will be deducted from the final point total for that attempt. For example, someone registers for the Apple iPhone 13 with the Kernel Bonus Add-on. During the attempt, the contestant drops the Kernel Bonus Add-on but completes the attempt. The final point total will be 15 Master of Pwn points.

The Complete Details

The full set of rules for Pwn2Own Toronto 2022 can be found here. They may be changed at any time without notice. We highly encourage potential entrants to read the rules thoroughly and completely should they choose to participate. We also encourage contestants to read this blog covering what to expect when participating in Pwn2Own.

Registration is required to ensure we have sufficient resources on hand at the event. Please contact ZDI at [email protected] to begin the registration process. (Email only, please; queries via Twitter, blog post, or other means will not be acknowledged or answered.) If we receive more than one registration for any category, we’ll hold a random drawing to determine the contest order. Registration closes at 5:00 p.m. Eastern Daylight Time on December 2, 2022.

The Results

We’ll be blogging and tweeting results in real-time throughout the competition. Be sure to keep an eye on the blog for the latest information. Follow us on Twitter at @thezdi and @trendmicro, and keep an eye on the #P2OToronto hashtag for continuing coverage.

We look forward to seeing everyone in Toronto and online, and we look forward to seeing what new exploits and attack techniques they bring with them.

With special thanks to our Pwn2Own Toronto 2022 sponsors, Synology and Google, for providing their assistance and technology.

©2022 Trend Micro Incorporated. All rights reserved. PWN2OWN, ZERO DAY INITIATIVE, ZDI, and Trend Micro are trademarks or registered trademarks of Trend Micro Incorporated. All other trademarks and trade names are the property of their respective owners. The “Synology” logo are trademarks of Synology, Inc., registered in the Republic of China (Taiwan) and other regions.

Announcing Pwn2Own Toronto 2022 and Introducing the SOHO Smashup!

But You Told Me You Were Safe: Attacking the Mozilla Firefox Sandbox (Part 2)

In the first part of this series, we reviewed how Pwn2Own contestant Manfred Paul was able to compromise the Mozilla Firefox renderer process via a prototype pollution vulnerability in the await implementation. In modern browser architecture design, compromising the renderer gets us just half the way there, since the sandbox prevents further damage. In this blog post, we discuss a second prototype pollution vulnerability that allowed the execution of attacker-controlled JavaScript in the privileged parent process, escaping the sandbox. This vulnerability is known as CVE-2022-1529 and is tracked as ZDI-22-798 on the Zero Day Initiative advisory page. Mozilla fixed this vulnerability along with the first one in Firefox 100.0.2 via Mozilla Foundation Security Advisory 2022-19.

Root Cause

As described in the previous post, the exploit compromised the renderer by leveraging a prototype pollution vulnerability in some built-in JavaScript code that executes in the renderer process. For the sandbox escape part of the exploit, the researcher used a second prototype pollution vulnerability. This second vulnerability exists in built-in JavaScript code that runs in the fully privileged parent process, also known as the chrome process (not to be confused with Google’s Chrome browser).

How can the sandboxed renderer process affect JavaScript running in the chrome process? The answer is that the renderer can communicate with the chrome process via various interfaces. In fact, some of these interfaces can be reached directly from JavaScript when running in a “privileged” JavaScript context (not to be confused with any OS-level concept of privilege). As we will see, achieving “privileged” JavaScript execution will be the exploit’s first step.

After achieving privileged JavaScript execution, the exploit can reach out to various endpoints for communication with the chrome process. One of the endpoints is called NotificationDB. It is implemented almost entirely in JavaScript. It processes various messages, which it receives via the content process message manager. In the case of a “Notification:Save” message, a “save” task is queued:

After the “save” task is put on the queue, it is handled in the chrome process, in the “taskSave” function:

At [1], both origin and notification.id are taken directly from the message data sent by the renderer, without any validation. This means we can set either of these to any serializable JavaScript value. More specifically, we can set them to any values supported by the structured clone algorithm, since this is the algorithm used to marshal data from the renderer to the chrome process. If we set origin to the string "__proto__", then this.notifications[origin] will not access a normal data property. Instead, it will access the object’s prototype. This prototype is Object.prototype, since this.notifications is a plain Object. This gives us a prototype pollution primitive. It allows us to write any serializable JavaScript value to any property of Object.prototype with only one restriction: the value we write must have an id property that matches the property name we are writing to.

Using this prototype pollution, we can corrupt the global JavaScript state in the chrome process. This affects all JavaScript that runs in the chrome process, far beyond NotificationDB.jsm itself. Since JavaScript execution contexts are largely shared, all chrome-level JavaScript modules are now exposed to unexpected properties in Object.prototype. The exploit will use this corruption to gain chrome-level XSS during tab restoration, leading to native code execution outside the sandbox.

Now that we have a complete picture of what we want to do, let’s begin.

Achieving Privileged JavaScript Execution

As mentioned above, before we can invoke NotificationDB, we need to access a privileged JavaScript context. In particular, what we need is access to an object called components. This is a different object than a much more limited object confusingly also named Components, which is intended to be exposed to untrusted script.

To gain access to components, the attacker script performs the following steps. Note that all this is made possible because the attacker script has already gained full native code execution within the renderer sandbox, as detailed in part one of this series:

        1 -- Mark the current JavaScript compartment as system by setting the corresponding flag in memory.
        2 -- Patch CanCreateWrapper to always return NS_OK. This prevents further security checks on the calling context.
        3 -- Call the GetComponents method to add the components object to the scope.

Triggering the Prototype Pollution Primitive

Once we have obtained the components object, we are nearly ready to trigger the prototype pollution. One obstacle remains: due to the details of Firefox's “cross-compartment” handling of JavaScript objects, the ContentProcessMessageManager object we want to access is hidden behind an opaque proxy object. This can be circumvented by reading the proxy’s underlying object pointer and using a “fakeObj” to convert it to a JavaScript object. We can now call the vulnerable NotificationDB interface:

Remember that a limitation applies to the way that we can overwrite properties of Object.prototype: we can set any property name to any value val, but val.id must equal name. For our purposes, the exact value of val will not matter. Only its string representation is important (more precisely, the result of running the ECMAScript ToString algorithm). The loose type system of JavaScript helps us here. Consider the following array object:

This object has its id property set to the arbitrary string "foo", but ToString will represent the object by just the string "bar". Therefore, as long as we only care about the string representation, we can set any property of Object.prototype to any value we desire.

Leveraging the Prototype Pollution for Sandbox Escape

Consider the following code in browser/components/sessionstore/TabAttributes.jsm, which executes in the chrome process:

Note that a for ... in loop will traverse all properties found in the prototype chain, and not only the properties found on the object itself. Therefore, by invoking the code shown above after we have polluted Object.prototype, we can cause tab.setAttribute to be called with arbitrary parameters. This will set an arbitrary HTML (technically XUL) attribute of a tab.

How can we cause this function to run? It turns out that the only time it is called is during the restoration of tabs. There are multiple ways to trigger this functionality:

        1 -- Session restoration after restarting the browser.
        2 -- Use of the “reopen closed tab” feature (Ctrl+Shift+T).
        3 -- Reactivating a tab after “Tab Unloading”, which occurs when Firefox starts to run out of memory.
        4 -- Automatically restoring a tab after it has crashed.

The first choice is not an option, since restarting the browser would not preserve the polluted prototype. In the real world, waiting for option #2 might work, but it requires user interaction, making it unsuitable for Pwn2Own. It’s also possible to force option #3 by allocating large chunks of memory. However, by default, it takes at least 10 minutes of inactivity before unloading will happen, which exceeds the Pwn2Own time constraint. This leaves just option #4. Fortunately, crashing the renderer process is trivial: we have already achieved memory corruption, and we can simply write to an invalid address to force a segmentation fault.

So far, the sandbox escape exploit proceeds as follows:

        1 -- Trigger the prototype pollution, adding a property and value to Object.prototype in the chrome process. The name/value pair we add corresponds to the parameters we want to pass to tab.setAttribute. For example, if we add a property named "a" with string value "b", then tab.setAttribute will ultimately be invoked with parameters ("a", "b").
        2 -- Open a new background tab. Note that a simple window.open method call without prior user interaction is blocked by the popup blocker. However, the check is entirely renderer-side, and the services.ww.openWindow API obtained from the components object has no such restriction.
        3 -- In this background tab, crash the renderer. The chrome process will immediately restore the background tab. The polluted prototype will cause the tab restoration logic to set our chosen attribute on the tab.

Next, we must consider: what parameters do we want to pass to tab.setAttribute? As the browser UI that contains the tab element is written not in HTML but rather the similar XUL markup language, attributes such as “onload” or “onerror” that are commonly used for XSS do not seem to work. Going through a list of XUL event handlers, there are only two that seem to work without any direct user interaction: “onoverflow” and “onunderflow”. These are triggered when the tab’s title text starts to exceed or no longer exceeds the available space. We can trigger the former by setting a style attribute with the value text-indent: 500px.

Once we have achieved JavaScript execution within the chrome process, there are many ways to complete the sandbox escape. For example, we could disable all sandboxing in the future by setting a preference:

  Services.prefs.setIntPref("security.sandbox.content.level", 0);

Afterward, the exploit could run script in a new tab, which will be created without any sandbox protections. Alternatively, it could run script directly in the chrome process. Either way, the file and process APIs that are available in chrome-level JavaScript can be used to gain native code execution not constrained by any sandbox:

Here is a short video demonstrating running the full exploit against Mozilla Firefox 100.0.1 (64-bit):

Final Notes

Modern browsers process large volumes of data coming from numerous untrusted sources. Modern browser architecture goes a long way towards containing damage in cases where the renderer process is compromised. However, there remain multiple security checks that are performed on the renderer side. We have seen how these checks could be bypassed, ultimately leading to full compromise of the main browser process. In general, it is wise to reduce renderer-side security checks and move them to the main process wherever it is practical.

You can find me on Twitter at @hosselot and follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

But You Told Me You Were Safe: Attacking the Mozilla Firefox Sandbox (Part 2)

But You Told Me You Were Safe: Attacking the Mozilla Firefox Renderer (Part 1)

Vulnerabilities and exploits in common targets like browsers are often associated with memory safety issues. Typically this involves either a direct error in memory management or a way to corrupt internal object state in the JavaScript engine. One way to eliminate such memory safety issues is to use a memory-safe language such as Rust or even JavaScript itself. At Pwn2Own Vancouver 2022, Manfred Paul compromised the Mozilla Firefox browser using a full chain exploit that broke the mold. Although his exploit used some memory corruptions, the vulnerable code was written in a memory-safe programming language: JavaScript! In fact, both vulnerabilities used in the chain were related to one rather notorious language aspect of JavaScript – prototypes. In this blog, we will look at the first vulnerability in the chain, which was used to compromise the Mozilla Firefox renderer process. This vulnerability, known as CVE-2022-1802, is a prototype pollution vulnerability in the await implementation. You can find more information about this vulnerability on the Zero Day Initiative advisory page tracked as ZDI-22-799. Mozilla fixed this vulnerability in Firefox 100.0.2 via Mozilla Foundation Security Advisory 2022-19.

Note: this blog series is heavily reliant on the details provided by Manfred Paul at the Pwn2Own competition.

 Compromising The Renderer Process

Modern JavaScript features the module syntax, which allows developers to split code into individual files. An even newer feature is the support of asynchronous modules, or, more precisely, the feature known as top level await. In Firefox’s JavaScript engine, SpiderMonkey, large parts of this feature are implemented using built-in JavaScript code. Consider the following function from the SpiderMonkey codebase, in /js/src/builtin/Module.js:

There are three facts we must note the code shown above:

      1 -- This function runs in the same JavaScript context as the user’s code. This is true for most JavaScript-based functions in Firefox. This means that global state, including prototypes of global objects, is shared between this built-in code and untrusted website code.

      2 -- The function has a default argument of execList = []. In practice, the function is called without specifying this argument (except for the recursive call in the function itself). Therefore, a new empty array object is constructed and used for this argument. Like any other ordinary array, this array object has the unique object Array.prototype as its prototype.

      3 -- The function invokes std_Array_push on this array object. The std_Array_push function leads to a call to the Array.prototype.push JavaScript method. While the usage of std_Array_push function instead of Array.prototype.push helps prevent side effects up to a certain point, the function still can interact with the object’s prototype. (Note that in various other places within this same built-in JavaScript file /js/src/builtin/Module.js, a different function is used to assign array values: DefineDataProperty. In contrast to std_Array_push, DefineDataProperty is safe and will not interact in any way with the object’s prototype.)

The semantics of Array.prototype.push with a single argument are very roughly equivalent to the following:

Notably, the assignment is not just the definition of a data property on the object itself. Instead, it searches the object’s prototype chain for existing properties as per usual JavaScript semantics. If the imported module defines a getter/setter for property 0 on the Array prototype (Array.prototype), this assignment operation will trigger the setter function. This call technically violates the ECMAScript specification that defines GatherAsyncParentCompletions in terms of abstract lists and not actual JavaScript arrays. Crucially, this has yet another effect: it leaks the value that is assigned to our setter, so we recover the value “m” representing a module! This object is not the same as the module namespace returned by import(), but rather, it is an internal type of the JavaScript engine not meant to be accessible to untrusted script. It exposes some unsafe methods via its prototype, such as GatherAsyncParentCompletions. Calling GatherAsyncParentCompletions results in a call to the UnsafeSetReservedSlot method, which can be used to achieve memory corruption if we pass in a non-module object.

Triggering The Vulnerability

It is easy to trigger the vulnerability and obtain a Module object:

As described, we simply need to attach a setter to the 0 property of Array.prototype and wait for it to be called. Note that this snippet will only work when imported as a module from another file. The last line exists solely to mark the module as asynchronous, which is needed to trigger the bug.

Achieving Memory Corruption

To achieve memory corruption, we can now call mod.gatherAsyncParentCompletions with an object of the form {asyncParentModules:[obj]}, resulting in a call to UnsafeSetReservedSlot . This will attempt to write the value obj.pendingAsyncDependencies-1 to the internal object slot with number MODULE_OBJECT_PENDING_ASYNC_DEPENDENCIES_SLOT=20. In SpiderMonkey, objects have space for up to 16 so-called fixed slots which are for internal use only. This number is defined by the MAX_FIXED_SLOTS constant. Slots with a higher index are indexed from an array pointed to by the slots_ field. This means our write will be directed to the array pointed to by slots_. No bounds checking exists to make sure that the slots_ array is large enough to accommodate the specified index, because the UnsafeSetReservedSlot function assumes, as the name implies, that the caller will pass only suitable objects.

The general idea now is to:

       1 -- Create a new array object.

       2 -- Set some named properties of the object to force the allocation of a slots_ array for the object. Among these properties, we should create one with the name pendingAsyncDependencies.

       3 -- Write to a few numbered elements of the object to ensure the allocation of elements_ (the backing store for array elements).

By getting the alignment right, slots_[4] will then point to the capacity value of elements_, which we can then overwrite. This is not trivial. Fortunately, the heap allocator is very simple and deterministic. All of the allocations so far will take place in the nursery heap, which is a special area for small short-lived objects. Memory in that area will be allocated by a simple bump allocator. After increasing the capacity, we can write out-of-bounds of the object’s elements_ array and corrupt other nearby objects. From here, arbitrary read and write primitives are easily constructed by overwriting the data pointer of a typed array. Note that corruption in objects in the nursery heap cannot be used for very long since the objects created there will be soon moved to the tenured heap. The best way to proceed is to use corruption in the nursery heap as a first stage only, and immediately use it to produce corruption in the tenured heap. For example, this can be done by corrupting ArrayBuffer objects.

Executing Shellcode

Firefox uses W^X JIT, which means all JIT-produced executable pages are non-writable. This prevents us from overwriting executable JIT code with our shellcode. There is an already well-known method to force JIT to emit arbitrary ROP gadgets by embedding chosen floating-point constants into a JIT-compiled JavaScript function. This results in the appearance of arbitrary short byte sequences in an executable page. Manfred Paul further enhanced this technique. Now it does not even need ROP at all! Instead of using a JavaScript function, the floating-point constants are embedded into a WebAssembly method, so they are compiled into consecutive memory in order of appearance. This makes it possible to insert not just ROP gadgets, but even somewhat longer stretches of shellcode by encoding them in the floating-point constants. There are still some restrictions, though: no 8-byte block may appear twice, or the constant will only be emitted once. Also, due to ambiguity in representation, byte sequences that are equal to NaN might not be encoded correctly. Therefore, Manfred Paul opted for a minimal first-stage shellcode that offers just the following two pieces of functionality:

       1 -- The ability to read a pointer from the Windows PEB structure.

       2 -- The ability to invoke a function given the function’s address.

The attacker, from ordinary JavaScript, triggers execution of the shellcode’s first function to leak a value from the PEB. Next, the JavaScript uses this value together with the arbitrary read primitive to locate kernel32.dll and its functions in memory. Once it has located the address for VirtualProtect, it invokes the shellcode’s second function to mark the backing store of an ArrayBuffer object as executable, making it possible to run a second-stage shellcode without constraints and compromise the renderer process.

Now that we have code execution inside the renderer, it is time to prepare to attack the sandbox. This will be covered in the second blog, coming next week.

Final Notes

For a long time, developers have tried to fight memory corruption vulnerabilities by introducing various mitigations, and they have succeeded in making it more difficult for attackers to fully compromise applications. However, attackers have also come up with their own creative methods to bypass mitigations. Using a memory-safe programming language is a critical move. If the introduction of memory corruption vulnerabilities can be avoided in the first place, it would not be necessary to rely upon the strength of mitigations. This post looked at a great vulnerability demonstrating that even if you replace existing code with JavaScript, you could still be prone to memory corruption.

Stay tuned to this blog for part two of this series coming next week. Until then, you can find me on Twitter at @hosselot and follow the team on Twitter or Instagram for the latest in exploit techniques and security patches.

But You Told Me You Were Safe: Attacking the Mozilla Firefox Renderer (Part 1)

New Disclosure Timelines for Bugs Resulting from Incomplete Patches

Today at the Black Hat USA conference, we announced some new disclosure timelines. Our standard 120-day disclosure timeline for most vulnerabilities remains, but for bug reports that result from faulty or incomplete patches, we will use a shorter timeline. Moving forward, the ZDI will adopt a tiered approach based on the severity of the bug and the efficacy of the original fix. The first tier will be a 30-day timeframe for most Critical-rated cases where exploitation is detected or expected. The second level will be a 60-day interval for Critical- and High-severity bugs where the patch offers some protections. Finally, there will be a 90-day period for other severities where no imminent exploitation is expected. As with our normal timelines, extensions will be limited and granted on a case-by-case basis.

Since 2005, the ZDI has disclosed more than 10,000 vulnerabilities to countless vendors. These bug reports and subsequent patches allow us to speak from vast experience when it comes to the topic of bug disclosure. Over the last few years, we’ve noticed a disturbing trend – a decrease in patch quality and a reduction in communications surrounding the patch. This has resulted in enterprises losing their ability to accurately estimate the risk to their systems. It’s also costing them money and resources as bad patches get re-released and thus re-applied.

Adjusting our disclosure timelines is one of the few areas that we as a disclosure wholesaler can control, and it’s something we have used in the past with positive results. For example, our disclosure timeline used to be 180 days. However, based on data we tracked through vulnerability disclosure and patch release, we were able to lower that to 120 days, which helped reduce the vendor’s overall time-to-fix. Moving forward, we will be tracking failed patches more closely and will make future policy adjustments based on the data we collect.

Another thing we announced today is the creation of a new Twitter handle: @thezdibugs. This feed will only tweet out published advisories that are either a high CVSS, 0-day, or resulting from Pwn2Own. If you’re interested in those types of bug reports, we ask that you give it a follow. We’re also now on Instagram, and you can follow us there if you prefer that platform over Twitter.

Looking at our published and upcoming bug reports, we are on track for our busiest year ever – for the third year in a row. That also means we’ll have plenty of data to look at as we track incomplete or otherwise faulty patches, and we’ll use this data to adjust these timelines as needed based on what we are seeing across the industry. Other groups may have different timelines, but this is our starting point. With an estimated 1,700 disclosures this year alone, we should be able to gather plenty of metrics. Hopefully, we will see improvements as time goes on.

Until then, stay tuned to this blog for updates, subscribe to our YouTube channel, and follow us on Twitter for the latest news and research from the ZDI. 

New Disclosure Timelines for Bugs Resulting from Incomplete Patches

The August 2022 Security Update Review

It’s the second Tuesday of the month, and the last second Tuesday before Black Hat and DEFCON, which means Microsoft and Adobe have released their latest security fixes. Take a break from packing (if you’re headed to hacker summer camp) or your normal activities and join us as we review the details of their latest patches and updates.

Adobe Patches for August 2022

For August, Adobe addressed 25 CVEs in five patches for Adobe Acrobat and Reader, Commerce, Illustrator, FrameMaker, and Adobe Premier Elements. A total of 13 of these bugs were reported through the ZDI program. The update for Acrobat and Reader addresses three Critical-rated and four Important-rated bugs. The critical vulnerabilities could allow code execution if an attacker could convince a user to open a specially crafted file. There are also seven total fixes for Commerce, including four Critical-rated bugs. Two of these could allow code execution and two could lead to a privilege escalation. The XML injection bug fixed by this has the highest CVSS of Adobe’s release at 9.1. The patch for Illustrator contains two Critical and two Important fixes for bugs submitted by ZDI Security Researcher Mat Powell. The most severe could lead to code execution when opening a specially crafted file. Mat is also responsible for the six FrameMaker bugs, five of which could lead to code execution. Finally, there’s a single Critical-rated CVE in the Premier Elements patch resulting from an uncontrolled search path element.

None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release. Adobe categorizes the majority of these updates as a deployment priority rating of 3, with the Acrobat patch being the lone exception at 2.

Microsoft Patches for August 2022

This month, Microsoft released 121 new patches addressing CVEs in Microsoft Windows and Windows Components; Azure Batch Node Agent, Real Time Operating System, Site Recovery, and Sphere; Microsoft Dynamics; Microsoft Edge (Chromium-based); Exchange Server; Office and Office Components; PPTP, SSTP, and Remote Access Service PPTP; Hyper-V; System Center Operations Manager; Windows Internet Information Services; Print Spooler Components; and Windows Defender Credential Guard. This is in addition to the 17 CVEs patched in Microsoft Edge (Chromium-based) and three patches related to secure boot from CERT/CC. That brings the total number of CVEs to 141. A total of eight of these bugs were reported through the ZDI, including some (but not all) of the bugs reported during the last Pwn2Own.

The volume of fixes released this month is markedly higher than what is normally expected in an August release. It’s almost triple the size of last year’s August release, and it’s the second largest release this year.

Of the 121 new CVEs released today, 17 are rated Critical, 102 are rated Important, one is rated Moderate, and one is rated Low in severity. Two of these bugs are listed as publicly known, and one is listed as under active attack at the time of release. Let’s take a closer look at some of the more interesting updates for this month, starting with the MSDT bug under active attack:

-       CVE-2022-34713 – Microsoft Windows Support Diagnostic Tool (MSDT) Remote Code Execution Vulnerability
This is not the first time an MSDT bug has been exploited in the wild this year. This bug also allows code execution when MSDT is called using the URL protocol from a calling application, typically Microsoft Word. There is an element of social engineering to this as a threat actor would need to convince a user to click a link or open a document. It’s not clear if this vulnerability is the result of a failed patch or something new. Either way, test and deploy this fix quickly.

 -       CVE-2022-35804 – SMB Client and Server Remote Code Execution Vulnerability
The server side of this bug would allow a remote, unauthenticated attacker to execute code with elevated privileges on affected SMB servers. Interestingly, this bug only affects Windows 11, which implies some new functionality introduced this vulnerability. Either way, this could potentially be wormable between affected Windows 11 systems with SMB server enabled. Disabling SMBv3 compression is a workaround for this bug, but applying the update is the best method to remediate the vulnerability.

 -       CVE-2022-21980/24516/24477 – Microsoft Exchange Server Elevation of Privilege Vulnerability
I couldn’t pick between these three Critical-rated Exchange bugs, so I’m listing them all. Rarely are elevation of privilege (EoP) bugs rated Critical, but these certainly qualify. These bugs could allow an authenticated attacker to take over the mailboxes of all Exchange users. They could then read and send emails or download attachments from any mailbox on the Exchange server. Administrators will also need to enable Extended Protection to fully address these vulnerabilities.

 -       CVE-2022-34715 – Windows Network File System Remote Code Execution Vulnerability
This is now the fourth month in a row with an NFS code execution patch, and this CVSS 9.8 bug could be the most severe of the lot. To exploit this, a remote, unauthenticated attacker would need to make a specially crafted call to an affected NFS server. This would provide the threat actor with code execution at elevated privileges. Microsoft lists this as Important severity, but if you’re using NFS, I would treat it as Critical. Definitely test and deploy this fix quickly.

-       CVE-2022-35742 - Microsoft Outlook Denial of Service Vulnerability
This was reported through the ZDI program and is a mighty interesting bug. Sending a crafted email to a victim causes their Outlook application to terminate immediately. Outlook cannot be restarted. Upon restart, it will terminate again once it retrieves and processes the invalid message. It is not necessary for the victim to open the message or to use the Reading pane. The only way to restore functionality is to access the mail account using a different client (i.e., webmail, or administrative tools) and remove the offending email(s) from the mailbox before restarting Outlook.

Here’s the full list of CVEs released by Microsoft for August 2022:

CVE Title Severity CVSS Public Exploited Type
CVE-2022-34713 Microsoft Windows Support Diagnostic Tool (MSDT) Remote Code Execution Vulnerability Important 7.8 Yes Yes RCE
CVE-2022-30134 Microsoft Exchange Information Disclosure Vulnerability Important 7.6 Yes No Info
CVE-2022-30133 Windows Point-to-Point Protocol (PPP) Remote Code Execution Vulnerability Critical 9.8 No No RCE
CVE-2022-35744 Windows Point-to-Point Protocol (PPP) Remote Code Execution Vulnerability Critical 9.8 No No RCE
CVE-2022-34691 Active Directory Domain Services Elevation of Privilege Vulnerability Critical 8.8 No No EoP
CVE-2022-33646 Azure Batch Node Agent Remote Code Execution Vulnerability Critical 7 No No RCE
CVE-2022-21980 Microsoft Exchange Server Elevation of Privilege Vulnerability Critical 8 No No EoP
CVE-2022-24477 Microsoft Exchange Server Elevation of Privilege Vulnerability Critical 8 No No EoP
CVE-2022-24516 Microsoft Exchange Server Elevation of Privilege Vulnerability Critical 8 No No EoP
CVE-2022-35752 RAS Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-35753 RAS Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-35804 SMB Client and Server Remote Code Execution Vulnerability Critical 8.8 No No RCE
CVE-2022-34696 Windows Hyper-V Remote Code Execution Vulnerability Critical 7.8 No No RCE
CVE-2022-34702 Windows Secure Socket Tunneling Protocol (SSTP) Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-34714 Windows Secure Socket Tunneling Protocol (SSTP) Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-35745 Windows Secure Socket Tunneling Protocol (SSTP) Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-35766 Windows Secure Socket Tunneling Protocol (SSTP) Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-35767 Windows Secure Socket Tunneling Protocol (SSTP) Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-35794 Windows Secure Socket Tunneling Protocol (SSTP) Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-34716 .NET Spoofing Vulnerability Important 5.9 No No Spoofing
CVE-2022-34685 Azure RTOS GUIX Studio Information Disclosure Vulnerability Important 7.8 No No Info
CVE-2022-34686 Azure RTOS GUIX Studio Information Disclosure Vulnerability Important 7.8 No No Info
CVE-2022-30175 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30176 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-34687 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-35773 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-35779 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-35806 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-35776 Azure Site Recovery Denial of Service Vulnerability Important 6.2 No No DoS
CVE-2022-35802 Azure Site Recovery Elevation of Privilege Vulnerability Important 8.1 No No EoP
CVE-2022-35775 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35780 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35781 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35782 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35784 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35785 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35786 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35788 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35789 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35790 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35791 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35799 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35801 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35807 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35808 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35809 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35810 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35811 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35813 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35814 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35815 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35816 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35817 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35818 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35819 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-35774 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-35787 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-35800 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-35783 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.4 No No EoP
CVE-2022-35812 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.4 No No EoP
CVE-2022-35824 Azure Site Recovery Remote Code Execution Vulnerability Important Unknown No No RCE
CVE-2022-35772 Azure Site Recovery Remote Code Execution Vulnerability Important 7.2 No No RCE
CVE-2022-35821 Azure Sphere Information Disclosure Vulnerability Important 4.4 No No Info
CVE-2022-34301 * CERT/CC: CVE-2022-34301 Eurosoft Boot Loader Bypass Important N/A No No SFB
CVE-2022-34302 * CERT/CC: CVE-2022-34302 New Horizon Data Systems Inc Boot Loader Bypass Important N/A No No SFB
CVE-2022-34303 * CERT/CC: CVE-20220-34303 Crypto Pro Boot Loader Bypass Important N/A No No SFB
CVE-2022-35748 HTTP.sys Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-35760 Microsoft ATA Port Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-33649 Microsoft Edge (Chromium-based) Security Feature Bypass Vulnerability Important 9.6 No No SFB
CVE-2022-33648 Microsoft Excel Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-33631 Microsoft Excel Security Feature Bypass Vulnerability Important 7.3 No No SFB
CVE-2022-34692 Microsoft Exchange Information Disclosure Vulnerability Important 5.3 No No Info
CVE-2022-21979 Microsoft Exchange Information Disclosure Vulnerability Important 4.8 No No Info
CVE-2022-34717 Microsoft Office Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35742 Microsoft Outlook Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-35743 Microsoft Windows Support Diagnostic Tool (MSDT) Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-35762 Storage Spaces Direct Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35763 Storage Spaces Direct Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35764 Storage Spaces Direct Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35765 Storage Spaces Direct Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35792 Storage Spaces Direct Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-33640 System Center Operations Manager: Open Management Infrastructure (OMI) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35754 Unified Write Filter Elevation of Privilege Vulnerability Important 6.7 No No EoP
CVE-2022-35777 Visual Studio Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35825 Visual Studio Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35826 Visual Studio Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35827 Visual Studio Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-35750 Win32k Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35820 Windows Bluetooth Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30144 Windows Bluetooth Service Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-35757 Windows Cloud Files Mini Filter Driver Elevation of Privilege Vulnerability Important 7.3 No No EoP
CVE-2022-34705 Windows Defender Credential Guard Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35771 Windows Defender Credential Guard Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34704 Windows Defender Credential Guard Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-34710 Windows Defender Credential Guard Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-34712 Windows Defender Credential Guard Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-34709 Windows Defender Credential Guard Security Feature Bypass Vulnerability Important 6 No No SFB
CVE-2022-35746 Windows Digital Media Receiver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35749 Windows Digital Media Receiver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35795 Windows Error Reporting Service Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34690 Windows Fax Service Elevation of Privilege Vulnerability Important 7.1 No No EoP
CVE-2022-35797 Windows Hello Security Feature Bypass Vulnerability Important 6.1 No No SFB
CVE-2022-35751 Windows Hyper-V Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35756 Windows Kerberos Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35761 Windows Kernel Elevation of Privilege Vulnerability Important 8.4 No No EoP
CVE-2022-34707 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35768 Windows Kernel Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34708 Windows Kernel Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-35758 Windows Kernel Memory Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30197 Windows Kernel Security Feature Bypass Important 7.8 No No SFB
CVE-2022-35759 Windows Local Security Authority (LSA) Denial of Service Vulnerability Important 6.5 No No DoS
CVE-2022-34706 Windows Local Security Authority (LSA) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34715 Windows Network File System Remote Code Execution Vulnerability Important 9.8 No No RCE
CVE-2022-33670 Windows Partition Management Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-34703 Windows Partition Management Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-35769 Windows Point-to-Point Protocol (PPP) Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-35747 Windows Point-to-Point Protocol (PPP) Denial of Service Vulnerability Important 5.9 No No DoS
CVE-2022-35755 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.3 No No EoP
CVE-2022-35793 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.3 No No EoP
CVE-2022-34701 Windows Secure Socket Tunneling Protocol (SSTP) Denial of Service Vulnerability Important 5.3 No No DoS
CVE-2022-30194 Windows WebBrowser Control Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-34699 Windows Win32k Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-33636 Microsoft Edge (Chromium-based) Remote Code Execution Vulnerability Moderate 8.3 No No RCE
CVE-2022-35796 Microsoft Edge (Chromium-based) Elevation of Privilege Vulnerability Low 7.5 No No EoP
CVE-2022-2603 * Chromium: CVE-2022-2603 Use after free in Omnibox High N/A No No RCE
CVE-2022-2604 * Chromium: CVE-2022-2604 Use after free in Safe Browsing High N/A No No RCE
CVE-2022-2605 * Chromium: CVE-2022-2605 Out of bounds read in Dawn High N/A No No RCE
CVE-2022-2606 * Chromium: CVE-2022-2606 Use after free in Managed devices API High N/A No No RCE
CVE-2022-2610 * Chromium: CVE-2022-2610 Insufficient policy enforcement in Background Fetch Medium N/A No No SFB
CVE-2022-2611 * Chromium: CVE-2022-2611 Inappropriate implementation in Fullscreen API Medium N/A No No N/A
CVE-2022-2612 * Chromium: CVE-2022-2612 Side-channel information leakage in Keyboard input Medium N/A No No Info
CVE-2022-2614 * Chromium: CVE-2022-2614 Use after free in Sign-In Flow Medium N/A No No RCE
CVE-2022-2615 * Chromium: CVE-2022-2615 Insufficient policy enforcement in Cookies Medium N/A No No SFB
CVE-2022-2616 * Chromium: CVE-2022-2616 Inappropriate implementation in Extensions API Medium N/A No No N/A
CVE-2022-2617 * Chromium: CVE-2022-2617 Use after free in Extensions API Medium N/A No No RCE
CVE-2022-2618 * Chromium: CVE-2022-2618 Insufficient validation of untrusted input in Internals Medium N/A No No Spoofing
CVE-2022-2619 * Chromium: CVE-2022-2619 Insufficient validation of untrusted input in Settings Medium N/A No No Spoofing
CVE-2022-2621 * Chromium: CVE-2022-2621 Use after free in Extensions Medium N/A No No RCE
CVE-2022-2622 * Chromium: CVE-2022-2622 Insufficient validation of untrusted input in Safe Browsing Medium N/A No No Spoofing
CVE-2022-2623 * Chromium: CVE-2022-2623 Use after free in Offline Medium N/A No No RCE
CVE-2022-2624 * Chromium: CVE-2022-2624 Heap buffer overflow in PDF Medium N/A No No RCE

* Indicates this CVE had previously been assigned by a 3rd-party and is now being incorporated into Microsoft products.

Looking at the remaining Critical-rated fixes, many impact older tunneling protocols. There are fixes for Point-to-Point Protocol (PPP), Secure Socket Tunneling Protocol (SSTP), and RAS Point-to-Point Tunneling Protocol – all of which are correcting remote code execution (RCE) bugs. These are older protocols that should be blocked at your perimeter. However, if you’re still using one of these, it’s probably because you need it, so don’t miss these patches. There’s also a Critical-rated Hyper-V guest-to-host bug being patched this month. The update for Azure Batch won’t be automatic. According to Microsoft, “If you are not running Batch Agent version 1.9.27 or later, you need to resize your pools to zero or recreate your pool.” The final Critical-rated patch this month fixes an EoP in Active Directory. An authenticated attacker could manipulate attributes on computer accounts they own or manage and acquire a certificate from AD CS that would allow elevation to SYSTEM. This bug appears similar to other certificate-based vulnerabilities as Microsoft recommends reviewing KB5014754 for additional steps admins can take to protect their systems.

Moving on to other components, August brings 34 updates just for the Azure Site Recovery component. That makes 66 updates for this component in July and August. This month, there are two RCE bugs, one DoS, and 31 EoP vulnerabilities being fixed. All these bugs involve the VMWare-to-Azure scenario. If you use Azure Site Recovery, you will need to update to 9.50 to be protected. Speaking of Azure, there are eight fixes for RTOS GUIX Studio – six RCEs and two info disclosure bugs. It’s not clear if applications built using RTOS will need to recompile their applications after the patches are applied or not, but it wouldn’t be a bad idea. Rounding out the Azure-related bugs is an info disclosure vulnerability in Azure Sphere that could disclose contents of memory, but root privileges are required to exploit this bug, so it won’t be on anyone’s top 10 list.

There are nine other code execution bugs fixed this month, including another bug in MSDT that is not under active attack (yet). There’s also an intriguing RCE bug in the Bluetooth Service, but Microsoft provides little information on how it would be exploited – just that is limited to network adjacent attackers. There are two Office RCEs and four more in Visual Studio. In these cases, the attacker would need to convince a user to open a specially crafted file. The final RCE bugs are both browser-related. The first is in the WebBrowser Control and the other is in Edge (Chromium-based). While the Edge bug is rated Moderate, the CVSS is listed as 8.3. The lowered severity rating is due to required user interaction, but studies have shown that users click on just about any pop-ups they see.

Looking at the six security feature bypass bugs patched this month, highlighted by a CVSS 9.6 bug in Edge that bypasses a dialog feature that asks users to allow the launching of the Microsoft Store application. There’s a vulnerability in Windows Defender Credential Guard that could bypass Kerberos protection. The SFB bug in Excel bypasses the Packager Object Filters feature. The patch for Windows Hello fixes a vulnerability that bypasses the facial recognition security feature. Finally, the bug in the Windows kernel bypasses ASLR – a vital defense-in-depth measure. It would not surprise me to find this bug incorporated into future exploits, as bypassing ASLR would likely make the exploit more reliable.

Moving on to the remaining EoP bugs fixed in August, the first that jump out are the patches for the Print Spooler. Microsoft lists these as an XI of 1, which means they expect exploitation within 30 days. One of the patches fixes a privilege escalation in System Center Operations Manager: Open Management Infrastructure (OMI). An attacker could abuse it to manipulate the OMI keytab and gain elevated privileges on the machine. For the most part, the remaining privilege escalation bugs require an attacker to already have the ability to execute code on the target. They can then use one of these bugs to escalate to SYSTEM or some other elevated level.

Most months, the information disclosure patches consist primarily of bugs that only result in leaks consisting of unspecified memory contents. There are a couple of those this month, but the others are much more interesting. There are two bugs in the Windows Defender Credential Guard. Both could allow an attacker to access Kerberos-protected data. The remaining info disclosure fixes are for Exchange and could allow an attacker to read target emails. Again, based on changes made to Exchange this month, admins need to enable Extended Protection to fully remediate these vulnerabilities.

Seven different Denial-of-Service (DoS) vulnerabilities receive fixes this month, including the aforementioned Outlook and Azure Site Recovery bugs. Three others impact the older tunneling protocols mentioned above. The LSA component gets a fix for a DoS bug. This is interesting, as LSA is responsible for writing to security logs. It is feasible that attackers could use this bug to try to cover their tracks after an intrusion. There’s also a fix for the HTTP Protocol Stack (http.sys). In this case, an unauthenticated attacker could send specially crafted packets to shut down the service.

The August release is rounded out by a fix for .NET to prevent a blind XXE attack.

No new advisories were released this month. The latest servicing stack updates can be found in the revised ADV990001. The latest updates will be required to install the fixes for the secure boot bugs submitted by CERT/CC.

Looking Ahead

The next Patch Tuesday falls on September 13, and we’ll return with details and patch analysis then. I’ll also be starting a webcast on patch Wednesday to quickly recap the month’s release. You can find it on our YouTube channel. Until then, stay safe, happy patching, and may all your reboots be smooth and clean!

The August 2022 Security Update Review

Looking at Patch Gap Vulnerabilities in the VMware ESXi TCP/IP Stack

Over the last few years, multiple VMware ESXi remote, unauthenticated code execution vulnerabilities have been publicly disclosed. Some were also found to be exploited in the wild. Since these bugs were found in ESXi’s implementation of the SLP service, VMware provided workarounds to turn off the service. VMware also disabled the service by default starting with ESX 7.0 Update 2c. In this blog post, we explore another remotely reachable attack surface: ESXi’s TCP/IP stack implemented as a VMkernel module. The most interesting outcome of this analysis is that ESXi’s TCP/IP stack is based on FreeBSD 8.2 and does not include security patches for the vulnerabilities disclosed over the years since that release of FreeBSD.

This result also prompted us to analyze the nature of vulnerabilities disclosed in other open-source components used by VMware, such as OpenSLP and ISC-DHCP. Once again, we observed that most of the disclosed vulnerabilities had upstream patches before the disclosure.

The FreeBSD Code in the ESXi TCP/IP Stack

An initial analysis was done to locate the VMkernel module implementing the TCP/IP stack. In ESXi, the module details can be enumerated using esxcfg-info or esxcli system module commands as seen below:

Checking the function names and strings available in the module, it is understood that the code is coming from FreeBSD, as shown in the following:

While the exact version of FreeBSD was not initially known, comparing the binary against the patches mentioned in advisories revealed multiple missing fixes. I performed a manual diff of FreeBSD branches 8.x, 9.x, and 10.x against the VMkernel module to narrow down the version of code used. Consider a couple of MFC (Merge From CURRENT) commits for example: 213158 and 215207. The 213158 commit was merged to FreeBSD 8.2 and later, whereas 215207 was merged to FreeBSD 8.3 and later. While 213158 was found in the VMkernel module, the 215207 commit was missing. This gave an approximate timeline of when the code was forked, which is around FreeBSD 8.2.

Porting Type Information from FreeBSD to the ESXi VMkernel Module

Once the version of the FreeBSD source is known, we can port type information from FreeBSD 8.2 to the VMkernel module. The goal here was to make function prototype and structure information available in IDA. Since creating type libraries for multiple dependent headers can be complex, I decided to rely on the FreeBSD kernel binary compiled from source with DWARF information. My first choice was to use IDA Pro’s Dump typeinfo to IDC feature. However, there were still missing structures because only assembler-level types were exported to the IDC.

The workaround for the problem is to use the TILIB idea by @rolfrolles. Using the above-mentioned technique, it is possible to create a type library from the FreeBSD 8.2 kernel binary and then load it into the VMkernel module’s IDB. This imports all the C-level types required for further analysis with the decompiler. While the Structure and Local Types view does not list all imported type information, we can apply the function prototypes as detailed in a previous blog post.

As a recap, begin by extracting the function prototype from the FreeBSD kernel as a key value pair of function_name:function_type, then iterate through the extracted type information and apply it to the VMkernel module having symbols.

Once the prototypes are applied, the Structure and Local Types views are automatically populated. Any other types required for local variables can be further added manually using the workflow mentioned in Importing types into IDB.

Figure 1 - VMkernel module before (left) and after (right) adding FreeBSD type information

Analyzing VMkernel Debug Information from VMware Workbench

VMware Workbench is an Eclipse IDE plugin provided by VMware. Amongst many other features, it also provides debug symbols for VMkernel. Jan Harrie and Matthias Luft have documented the usage of the VMkernel debug information in their research entitled Attacking VMware NSX [Slides 34 – 37 in the PDF]. The UI of the Eclipse plugin is shown below:

Figure 2 - List of VMkernel debug symbols available in VMware Workbench

Kernel modules in ESXi communicate with VMkernel using VMK APIs. By using a VMkernel build that has debug information, it becomes easier to understand the VMK API calls made by any VMkernel module, which includes the TCP/IP stack. Moreover, the type information from VMkernel can be ported to any desired VMkernel module or even to the Virtual Machine Monitor. Here is an example of type information ported to the TCP/IP module found in ESXi 6.7 Update 3 using debug information from VMkernel version 14320388:

Figure 3 - TCP/IP module before (left) and after (right) adding VMkernel type information

As soon as the function prototypes are applied to the binary, IDA helpfully propagates the type information to many of the variables found in the code. When working with code forked from FreeBSD, it is useful to place the Hex-Rays decompilation side-by-side with known FreeBSD source code to rename variables and add type information to variables that IDA did not detect automatically . However, in this case, we do not have access to local variable names or types. While some variables are given meaningful names by IDA, the rest were manually added using context information from the detected enums, structure names, and so forth.

VMware seems to have stopped publishing VMkernel debug information for more than a year now. The last public release for which I could find the debug information goes back to ESXi 6.7 16773714.

Missing FreeBSD Patches

At this point, we had enough information to perform a diff of the TCP/IP VMkernel module against the FreeBSD security advisories. Patches provided in the advisories were compared against ESXi’s version of the module to identify the missing bug fixes. Based on static analysis, patches for 16 vulnerabilities fixed in FreeBSD were found to be missing in ESXi. We reported these missing patches to VMware for further evaluation.  Shown below is the set of missing patches that we reported to VMware and their corresponding applicability to ESXi as evaluated by VMware:

CVE Disclosure Date Bug Applicable
CVE-2013-3077 8/22/13 Integer overflow in IP_MSFILTER Yes
CVE-2013-5691 9/10/13 Insufficient credential checks in network IOCTL No
CVE-2004-0230 9/16/14 Denial of Service in TCP packet processing Yes
CVE-2015-1414 2/25/15 Integer overflow in IGMP protocol Yes
CVE-2015-2923 4/7/15 Denial of Service with IPv6 Router Advertisements Yes
CVE-2015-5358 7/21/15 Resource exhaustion due to sessions stuck in LAST_ACK state Yes
CVE-2015-1417 7/28/15 Resource exhaustion in TCP reassembly No
CVE-2018-6916 3/7/18 IPSec validation and use-after-free Yes
CVE-2018-6918 4/4/18 IPSec crash or denial of service Yes
CVE-2018-6922 8/6/18 Resource exhaustion in TCP reassembly No
CVE-2018-6923 8/14/18 Resource exhaustion in IP fragment reassembly No
CVE-2019-5608 8/6/19 ICMPv6 / MLDv2 out-of-bounds memory access Yes
CVE-2019-5611 8/20/19 IPv6 remote Denial-of-Service Yes
CVE-2020-7451 3/19/20 TCP IPv6 SYN cache kernel information disclosure Yes
CVE-2020-7457 7/8/20 IPv6 socket option race condition and use after free Yes
CVE-2020-7469 12/1/20 ICMPv6 use-after-free in error message handling Yes

These issues were addressed in ESXi 7.0 Update 3f as well as ESXi 6.5 and ESXi 6.7.

Analysis of OpenSLP in ESXi  

The next component considered for analysis is the SLPD service in ESXi. ESXi’s SLP service is a fork of OpenSLP version 1.0.0. The version information and build configuration details can be fetched as below:

Just like the VMkernel modules, the SLPD service executable has symbols but not type information. Using the available function names, we observed that VMware’s forked code is not entirely based on version 1.0.0. It also has some of the functions added later, including some from version 2.0.0. There are also differences in some of the structure definitions as well as function prototypes. These observations can be made as soon as you port type information from OpenSLP and certain functions won’t decompile cleanly.

To fetch the type information, build OpenSLP from source and then use IDA Pro’s Create C header + Parse C header feature to populate the local types. The C header parses without much error. This is a quick workaround compared to creating type libraries from multiple dependent headers. Note that ESXi versions 7.0 and above run the SLPD service as a 64-bit executable. Because of this, care must be taken while using the created C header interchangeably between ESXi 7.0 and other versions. This is especially true as the header may require some modifications on data sizes, such as size_t being unsigned int vs unsigned long long.

Timeline of Upstream Patches vs Disclosures:

In the case of OpenSLP, there is enough public information regarding the vulnerabilities affecting ESXi and their relevant upstream patches, most notable being the one published by Lucas Leong on CVE-2020-3992 and CVE-2021-21974. For the scope of this blog, we will consider the following set of remote code execution vulnerabilities:

CVE VMSA Bug
CVE-2015-5177 VMSA-2015-0007 Double Free
CVE-2019-5544 VMSA-2019-0022 Heap Overflow
CVE-2020-3992 VMSA-2020-0023 Use-After-Free
CVE-2021-21974 VMSA-2021-0002 Heap Overflow

CVE-2015-5177 is a double-free vulnerability that occurs when processing a message buffer across functions: SLPDProcessMessage, ProcessDAAdvert, and SLPDKnownDAAdd. An upstream patch to fix the issue in SLPDKnownDAAdd() was already available.

Similarly, CVE-2020-3992 is a use-after-free vulnerability, again found in the handling of message buffer across functions SLPDProcessMessage, ProcessDAAdvert, and SLPDKnownDAAdd. However, this vulnerability does not affect the upstream version of OpenSLP. This bug can be traced back to CVE-2015-5177 based on the information provided in VMSA.

VMware released updates in the form of the VIB (vSphere Installation Bundle). Installing the VIBs one by one on ESXi to perform patch diffing of SLPD binary can be a tedious process. Instead, binaries can be directly extracted from the VIB to speed up the process. The relevant VIBs can be downloaded from the ESXi Patch Tracker, which lists them based on the timeline of release. Consider a diff between ESXi 6.7 build 8169922 and 8941472:

Figure 4 - ESXi Patch Tracker with VIBs

To replicate this, download the esx-base VIB to extract the slpd binary using the vmtar utility. The vmtar utility can be copied from ESXi and executed in Ubuntu since it does not have any ESXi-specific dependencies:

Similarly, in the case of the ESXi 6.7 GA ISO image, extract the S.V00 file from VMware-VMvisor-Installer-6.7.0-8169922.x86_64.iso:

A patch diff between slpd binaries confirms that CVE-2020-3992 was introduced when patching CVE-2015-5177 in ESXi versions 6.0 and above. The fix for CVE-2015-5177, in this case, was different from that of the working upstream fix in SLPDKnownDAAdd():

Figure 5 - Bindiff between ESXi 6.7.0 8169922 and 8941472

CVE-2020-3992 was in fact fixed twice (VMSA-2020-0023.1) since the initial patch did not completely address the issue. Additionally, this bug was also reported to be exploited in the wild by the Cybersecurity and Infrastructure Security Agency (CISA).

CVE-2021-21974, a heap overflow in SLPParseSrvUrl() leading to RCE, also had an upstream patch. This fix was part of a large code change in OpenSLP.

CVE-2019-5544 was the only bug that affected both the upstream and the VMware fork of OpenSLP at the time of disclosure. Though the bug has already been disclosed and fixed by many distros, the patch for this bug is still missing in the OpenSLP GitHub repository. This was another bug exploited in the wild.

Putting it all together, here is the timeline of disclosure vs availability of patches:

CVE Disclosure Date Patch Availability Patches
CVE-2015-5177 10/1/15 6/8/11 53bbd77
CVE-2019-5544 12/5/19 N/A N/A
CVE-2020-3992 10/20/20 6/8/11 53bbd77
CVE-2021-21974 2/23/21 3/1/06 3c8e45d

Analysis of ISC-DHCP in Workstation

The next component considered for analysis is the DHCP service of VMware Workstation, which is based on ISC-DHCP version 2.0. You can refer to the blog post Wandering through the Shady Corners of VMware Workstation/Fusion for an earlier analysis of this attack surface. It is noted that, though the codebase is a couple of decades old, VMware has backported fixes for known vulnerabilities. Keeping this in mind, only the recently disclosed bugs, CVE-2019-5540 and CVE-2020-3947, were analyzed.

Unlike earlier analysis where the executables had symbols, the vmnet-dhcp is completely stripped. The first task is to identify as many function names as possible to carry out the analysis. Looking for binaries with symbols led us to the very first release – VMware 1.0 Build 160. The vmnet-dhcpd binary from the first release of VMware had symbols and type information in stabs format.

For matching the available symbols with recent releases of the Workstation DHCP server, I relied on the updated version of Rizzo published by Quarkslab. Since Rizzo can be very slow on large binaries, only the string reference signatures were used in detection. With this, Rizzo identified around 69 functions using 226 matching strings available in VMware 1.0 Build 160 vmnet-dhcpd binary. A somewhat similar result can be achieved using the strings in ISC-DHCP 2.0. For anyone interested, the historical releases of ISC-DHCP can be found here.

During the patch diffing process, bug fixes in vmnet-dhcpd are easy to spot since the binary undergoes very limited changes per release. The first bug, CVE-2019-5540, is an information disclosure vulnerability due to an uninitialized field in the ICMP packet structure. This issue can be narrowed down to an upstream patch in the function icmp_echorequest().

The next bug, CVE-2020-3947, is a use-after-free vulnerability when handling the DHCPRELEASE packet. During the handling of a DHCPDISCOVER packet from a client, ISC-DHCP allocates memory in the heap. If the client identifier is long, it stores the resultant pointer as part of the lease structure. Otherwise, uid_buf is used for storage. The relevant code can be found in the ack_lease function of the server/dhcp.c source file:

Later when a DHCPRELEASE packet is received, the lease structure is adjusted. First, a copy of lease is made in the function release_lease and then supersede_lease is called. This code can be found in common/memory.c:

Note that the uid pointer is now found in both the old and the newly copied lease structures when it is passed to supersede_lease. In supersede_lease, the comp->uid pointer is freed (provided that it points to memory other than uid_buf, that is, in the case of a long client identifier):

Later, lease->uid entry is reused. See the code below assigning comp -> uid = lease -> uid, which by this time points to freed memory:

Finally, the comp structure that has a pointer to the freed uid buffer is passed to write_lease where the use-after-free happens. The bug can be triggered by adding a long dhcp-client-identifier entry to the DHCP client configuration and then initiating a DHCP request followed by a DHCP release using dhclient:

This issue was fixed in the release_lease function as part of a bigger code change by introducing a lease_copy function. The copied lease structure no longer holds a reference to the uid buffer of the old lease. Instead, a new allocation is requested and assigned. The release_lease function received further changes during later updates for handling the failover protocol. VMware’s fix for this bug is different from that of the upstream, possibly due to the divergence of the codebase.

Here is the timeline of disclosure vs availability of patches:

CVE Disclosure Date Patch Availability Patches
CVE-2019-5540 11/12/19 6/25/98 34436cc
CVE-2020-3947 3/12/20 5/17/00 20916ca

The IDA Python scripts used for the analysis can be found here.

Conclusion

Over the last few months, we analyzed three different VMware components: the ESXi networking stack, the ESXi SLPD service, and the Workstation DHCP server. The three components share the fact that they are forks of open-source code. Unlike open-source packages that can be updated to a new version with relative ease, updating a fork takes significantly more effort. This is because various challenges arise when cherry-picking patch commits.

In the ESXi FreeBSD networking stack, even the vulnerabilities with known CVE identifiers remained unfixed – the forked code was never tracked for vulnerabilities. Better tracking of FreeBSD disclosures is a good place to start and can help resolve some of the issues. Also, considering the criticality of the component, it might be possible for VMware to work with FreeBSD Security Officers to get prior information on vulnerabilities as per their Information handling policies:

The FreeBSD Security Officer has close working relationships with a number of other organizations, including third-party vendors that share code with FreeBSD…..Frequently vulnerabilities may extend beyond the scope of the FreeBSD implementation, and (perhaps less frequently) may have broad implications for the global networking community. Under such circumstances, the Security Officer may wish to disclose vulnerability information to these other organizations.”

In most cases, vendor advisories only list the supported versions of the affected software. Even if a legacy version is not listed in the advisory, the patch might still be applicable for the forked code.

In the case of OpenSLP and ISC-DHCP forks, the patch gap vulnerabilities come from bugs that do not have CVE identifiers. Some of the bug fixes have clear commit messages about the issue, whereas other fixes are done as part of large code changes or refactoring. Either way, it is a challenging process and requires a trained set of eyes to pick up security patches when the vulnerabilities are not explicitly called out. This also shows the significance of requesting CVE identifiers for security fixes since companies largely rely on them for cherry-picking patches.

As we showed, a couple of ESXi SLP patches had further issues despite the availability of working upstream fixes. To avoid this, it is important to evaluate a bug report not just against the fork but also against the upstream project. If a fix is found, developers should evaluate the upstream fix. Upstream fixes in most cases are a safe bet compared to that of custom patches, which may be written without having a comprehensive understanding of the code. However, this process of adopting patches can be further complicated if the codebases have diverged considerably.

The most important concern with forked code is the lifetime of bugs. When open-source code is used and updated as a package to the latest version, all the bug fixes are applied (i.e., vulnerabilities with or without CVE identifiers). In a forked codebase, when a patch is missed during cherry-picking, it will remain unfixed until the code is updated as a whole or someone finds and reports the issue. For example, the ISC-DHCP bugs were fixed in VMware’s DHCP server a couple of decades after the upstream fixes were available. In fact, the ISC-DHCP uninitialized memory information disclosure was fixed upstream even before the launch of CVE. Overall, forked code requires more attention compared to that of packages.

Considering the challenges of adopting security fixes and gaps in the tracking process, exploitable bugs might be still lying around without a fix. There are different types of patch gaps as well, so expect to hear more about these in the future. Until then, you can find me on Twitter @RenoRobertr, and follow the team for the latest in exploit techniques and security patches.

Looking at Patch Gap Vulnerabilities in the VMware ESXi TCP/IP Stack

Riding the InfoRail to Exploit Ivanti Avalanche

Back in 2021, I stumbled upon a proof of concept describing an arbitrary file read vulnerability in the Ivanti Avalanche mobile device management tool. As I was not aware of this product, I decided to take a quick look at the vendor’s website to learn more:

“Avalanche Enterprise Mobile Device Management manages some of the most demanding, high-profile supply chain mobility solutions in the world. So, we understand the pressure you're under to maximize worker (and device) uptime.”

“Manage all mobile devices in one place. Smartphones, barcode scanners, wearables and more—configure, deploy, update, and maintain them all in one system.”

“30,000 organizations. Over 10 million devices.”

As the product specification seemed to be both intriguing and encouraging, I decided to give it a shot and look for some vulnerabilities.

I was able to quickly identify a chain of three vulnerabilities in the Ivanti Avalanche Web Application:

- ZDI-21-1298 (CVE-2021-42124): Session takeover vulnerability, which requires user interaction.
- ZDI-21-1300 (CVE-2021-42126): privilege escalation vulnerability, which allows an attacker to gain administrative privileges.
- ZDI-21-1299 (CVE-2021-42125) – Remote code execution vulnerability, which can be exploited from the level of an administrator account.

Even though this chain is powerful, its first part heavily depends on factors that are not within the attacker’s control. We can do better, right?

The Inspiration

Later, I identified several interesting facts concerning Ivanti Avalanche:

- It contains multiple XStream 1.4.12 jar packages in its directories.
- It implements multiple ObjectGraph classes, which wrap the XStream serializer.
- Some of those classes define an allowlist of classes permitted for deserialization, while others lack such an allowlist.

This led me to suspect that there are multiple untrusted deserialization issues in the product. However, I was not yet able to determine how to reach those deserialization routines. Fortunately, I decided to pursue the matter further, and it turned out to be a long, exciting journey. It allowed me to not only exploit the XStream deserialization issues but to significantly increase the attack surface and find many more 0-days.

This blog post describes the first part of my Ivanti Avalanche research, where I identified the Ivanti Avalanche custom network protocol and abused it to perform several remote code executions. Moreover, it describes a cool race condition vulnerability that leads to an authentication bypass.

Identifying Ivanti Avalanche Services

To begin, let’s have a look at the Avalanche services:

Figure 1 - Ivanti Avalanche Services

We find we are dealing with the Tomcat Web Application plus other services. “Wavelink Information Router” seems to be the most interesting of them, due to the following description: “Coordinates communication between Wavelink processes…”.

At this stage, it all seemed complicated. Because of this, I used the following methods to gain some more insight:
• Network traffic analysis
• Static analysis
• Log file analysis

After a while, I was able to see a bigger picture. It seemed that the Avalanche Web Application is not able to perform tasks by itself, not even a login operation. However, it can freely use different services to perform tasks. The Information Router, also known as the InfoRail service, stands in between, and is responsible for the distribution of messages between the services. The InfoRail service listens on TCP port 0.0.0.0:7225 by default.

Figure 2 - Inter-Services communication

As can be seen in the above diagram, the communication flow is straightforward. The Web Backend creates a message and sends it to the InfoRail service, which forwards it to the appropriate destination service. The destination service handles the message and returns the response to the Web Backend, once more via the InfoRail service. In the default installation, all these services are running on the same host. However, it is possible to place some of these services on remote machines.

On the other hand, it is not easy to get more detailed information about the messages. Network traffic analysis was not of much use, as the messages seem to be obfuscated or encrypted. In order to learn something more about them, I had to conduct a detailed code analysis.

The following section presents an overview of the InfoRail protocol and all the basics needed to:
• Recreate the protocol and messages
• Understand its basics
• Understand the payload delivery mechanism

InfoRail Protocol Basics

A typical InfoRail message consists of three main parts:
• Preamble
• Header
• Optional XML payload

The following picture presents a message structure:

Figure 3 - Message Structure

The InfoRail Preamble

The preamble always has a length of 24 bytes. It consists of the following parts:
• Bytes 1-4: Length of the whole message
• Bytes 5-8: Length of the header
• Bytes 9-12: Length of the payload
• Bytes 13-16: Length of the uncompressed payload (payload can be optionally compressed)
• Bytes 17-20: Message ID (typically an incremented number, starting from 1)
• Byte 21: Protocol version (typically 0x10)
• Bytes 22-23: Reserved • Byte 24: Encryption flag (payload and header can be optionally encrypted) – 0 or 1

The InfoRail Header

The header of the typical message consists of multiple keys together with their corresponding values. Those keys and values are included in the header in the following way:
• 3 null bytes
• 0x02 byte
• 3 null bytes
• 1 byte which provides the length of a key (e.g. 0x08)
• 3 null bytes
• 1 byte which provides the length of a value (e.g. 0x06)
• Key + value

Here’s an example key and value:

         \x00\x00\x00\x02\x00\x00\x00\x08\x00\x00\x00\x06h.msgcat999999

As was mentioned before, a header can contain multiple keys. The most important ones that appear in most or all messages are:
h.msgcat - in typical requests, it is equal to 10 (request)
h.msgsubcat - information about the request type, thus it is crucial for the payload processing
h.msgtag - usually stores the JSESSIONID cookie, although no method that verifies this cookie was spotted, thus this value can be random.
h.distlist - specifies one or more services to which the message will be forwarded by InfoRail

The header must be padded with null bytes to a multiple of 16 bytes, due to the optional encryption that can be applied.

The Payload

As was mentioned before, the majority of messages contain an XML payload. An XStream serializer is used for the payload serialization and deserialization operations.

Different serialized objects can be transferred depending on the target service and the message subcategory. However, in most cases we are dealing with the RequestPayload object . The following snippet presents an example of the XML that is sent during an authentication operation. In this case, Avalanche Web Backend sends this XML to the Enterprise Server service, which then verifies user credentials.

RequestPayload.xml

As you can see, this message contains a serialized UserCredentials object, which consists of the loginName, encrypted password, domain, and clientIpAddress. You can also see that the RequestPayload contains the web cookie (sessionId). However, this cookie is never verified, so it can be set to any MD5 hash. As the payload can be optionally encrypted (and compressed), it must be padded to a multiple of 16 bytes.

Typically, every service implements its own ObjectGraph class, which defines the instance of the XStream serializer and configures it. Here’s a fragment of an example implementation:

ObjectGraphPart.java

When the service receives the XML payload, it deserializes it with the ObjectGraph.fromXML method.

Encryption

As was mentioned before, the header and the payload of the message can be encrypted. Furthermore, the payload can be compressed. InfoRail does not use the SSL/TLS protocol for encryption. Instead, it manually applies an encryption algorithm using a hardcoded encryption key.

As both the encryption algorithm and the encryption key can be extracted from the source code, the potential attacker can perform both the decryption and encryption operations without any obstacles.

Distribution to Services

The InfoRail service needs to know where to forward the received message. This information is stored in the h.distlist key of the message header. Values that can be used are stored in the IrConstants class. Variables that start with IR_TOPIC define the services where the message can be forwarded. The following code snippet presents several hardcoded variables:

DistributionVariables.java

If the sender wants the message to be forwarded to the license server, the h.distlist value must be set to 255.3.2.8.

Message Processing and Subcategories

This is probably the most important part of the protocol description. As was mentioned before, the message category is included in the message header under the h.msgsubcat key. As seen in the last line of the code snippet below, services protect themselves against the handling of an unknown message and, if the provided message subcategory is not implemented, the message is dropped.

Message processing may be implemented in slightly different ways depending on the service. Here, we are going to take a brief look at the Avalanche Notification Server. The following snippet represents the processMessage method found in the MessageDispatcher class:

processMessage.java

At [1], the message subcategory is retrieved from the header. Then, it is passed to the MessageProcessorVector.getProcessor method to obtain a reference to the appropriate message handler

At [2], the switch-case statement begins.

If the category is equal to 10 (request), the processInfoRailRequest method is invoked at [3]. Its arguments contain the handler that was retrieved at step [1]. We can have a quick look at this method here:

processInfoRailRequest.java

Basically, if the handler is not null, the code will invoke the handler.ProcessMessage method.

Finally, we must investigate how handlers are retrieved. The most important part is as follows:

MessageProcessorVector.java

At [1], a HashMap<Integer, IMessageProcessor> is defined.

At [2] and subsequent lines, the code invokes the setProcessor method. It accepts the message subcategory integer and the corresponding object that implements IMessageProcessor, such as AnsCredentialsHandler.

At [3], the setProcessor method is defined. It inserts the subcategory and appropriate object into the HashMap defined at [1].

At [4], getProcessor retrieves the handler based on the provided subcategory.

To summarize, there is a HashMap that stores the message subcategories and their corresponding handler objects. If we send a message to the Avalanche Notification Server with the subtype equal to 3706, the AnsTestHandler.processMessage method will be invoked.

Let’s have a look at one example of a message handler, AnsTestHandler:.

AnsTestHandler.java

At [1], the SUBCATEGORY variable is defined. It is common for the message processors to define such a variable.

At [2], the processMessage method is defined.

At [3], it retrieves the XML payload from the message.

At [4], it deserializes the payload with the ObjectGraph.fromXML method. It then casts it to AnsTestPayload, although the casting occurs after the deserialization. According to that, if the ObjectGraph does not implement any additional protections (such as an allowlist), we should be able to do harm here.

Success! We have identified the message processing routine. Moreover, we were able to quickly map the subcategory to the corresponding fragment of code that will handle our message. It seems that right now, we should be able to craft our own message.

Is There Any Authentication?

At this point, it seemed that I had everything necessary to send my own message. However, when I sent one, I saw no reaction from the targeted service. I looked at the InfoRail service log file and spotted these interesting lines:

Figure 4 InfoRail Log Files – Dropping the Unauthenticated Message

It seems that I had missed an important part: authentication. Having all the details regarding the protocol and encryption, I was able to quickly identify a registration message in the network traffic. It is one of the rare examples where the payload is not stored in the XML form. The following screenshot presents a fragment of a registration message:

Figure 5 - Fragment of an Exemplary Registration Message

Several important things can be spotted here:
         -- reg.appident – specifies the name of the service that tries to register.
         -- reg.uname / reg.puname – specifies something that looks like a username.
         -- reg.cred / reg.pcred – specifies something that looks like a hashed password.

After a good deal of code analysis, I determined the following:
         -- Uname and puname are partially random.
         -- Cred and pcred values are MD5 hashes, based on the following values:
                  -- Username (.anonymous.0.digits).
                  -- Appropriate fragment of the key, which is hardcoded in the source code.

Once more, the only secret that is needed is visible in the source code. The attacker can retrieve the key and construct his own, valid registration message.

Finally, we can properly register with the InfoRail service and send our own messages to any of the Avalanche services.

Just Give Me Those Pwns Please – Code Execution on Four Services

At this stage, one can verify the services that do not implement a allowlist in the ObjectGraph class. I identified 5 of them:

- Data Repository Service (ZDI-CAN-15169).
- StatServer Service (ZDI-CAN-15130).
- Notification Server Service (ZDI-CAN-15448).
- Certificate Management Server Service (ZDI-CAN-15449).
- Web File Server Service (ZDI-CAN-15330).

We have five XStream deserialization endpoints that will deserialize anything we provide. One can immediately begin to consider ways to exploit this deserialization. For starters, XStream is very transparent about its security. Their security page (available here) presents multiple gadgets based on classes available in the Java runtime. Sadly, no suitable gadget worked for the first four services that I tried to exploit, as the required classes were not loaded.

Going further, one can have a look at Moritz Bechler’s “Java Unmarshaller Security” paper:

XStream tries to permit as many object graphs as possible – the default converters are pretty much Java Serialization on steroids. Except for the call to the first non-serializable parent constructor, it seems that everything that can be achieved by Java Serialization can be with XStream – including proxy construction.

 Proxy construction does not seem to be a thing in the newer versions of XStream. However, we should still be able to exploit it with ysoserial gadgets. Ysoserial gadgets for XStream were not available back then, so I created several myself. They can be found in this GitHub repository.

 Using my ysoserial XStream gadgets, I was successful in getting remode code execution in four Avalanche services. Here is a summary of the services I was able to exploit, and the required gadgets:

- StatServer: Exploited using AspectJWeaver and CommonsBeanutils1
- Data Repository: Exploited using C3P0 and CommonsBeanutils1
- Certificate Management Server: Exploited using CommonsBeanutils1
- Avalanche Notification Server: Exploited using CommonsBeanutils1

For no particular reason, let’s focus on the StatServer. To begin, we must find the topic and subcategory of some message that will deserialize the included XML payload. According to that, the InfoRail protocol message headers should contain the following keys and values:
h.distlist = 255.3.2.12
h.msgsubcat = 3502 (GetMuCellTowerData message)

In this example, we will make use of the AspectJWeaver gadget, which allows us to upload files. Below is the AspectJWeaver gadget for the XStream:

AspectJWeaver.xml

Several things can be highlighted in this gadget:
• The iConstant tag contains the Base64 file content.
• The folder tag contains a path to the upload directory. I am targeting the Avalanche Web Application root directory here.
• The key tag specifies the name of the file.

Having all the data needed, we can start the exploitation process:

Figure 6 - StatServer Exploitation - Upload of Web shell

The following screenshot presents the uploaded web shell and the execution of the whoami command.

Figure 7 - StatServer Exploitation - Webshell and Command Execution

Success! To sum up this part, an attacker who can send messages to Avalanche services can abuse the XStream deserialization in 4 different services.

I also got remote code execution on a fifth serviceHowever, exploiting this one was way trickier.

Exploiting JNDI Lookups Before It Was Cool

Java Naming and Directory Interface (JNDI) Lookups have a long history, and a lot of researchers were familiar with this vector long before the Log4Shell vulnerability. One of the proofs for that is CVE-2021-39146 – an XStream deserialization gadget that triggers a lookup. It has occurred to be the only XStream gadget that worked against the Web File Server service, for which I was not able to craft a valid ysoserial gadget.

Still, we are dealing with a fresh Java version. Thus, we are not able to abuse remote class loading. Moreover, the attacker is not able to abuse the LDAP deserialization vector (described here [PDF]). Using the JNDI injection, we can deliver the serialized payload, which will be then deserialized by our target. However, we are not aware of any deserialization gadgets that could be abused in the Web File Server.  If there were any gadgets, we would not need the JNDI lookup in the first place. Luckily, there are several interesting JAR packages included in the Web File Server Classpath.

Figure 8 - Web File Server - Tomcat JARs

As you can see, the Web File Server loads several Tomcat JAR packages. You might perhaps also be familiar with the great technique discovered by Michael Stepankin, which abuses unsafe reflection in Tomcat BeanFactory to execute arbitrary commands through JNDI Lookup. The original description can be found here.

In summary, we can execute the following attack:

  1. Set up malicious LDAP server, which will serve the malicious BeanFactory. We will use the Rogue JNDI tool.
  2. Register with the InfoRail service.
  3. Send the message containing the CVE-2021-39146 gadget, targeting the Web File Server pointing to the server defined in step 1.
  4. The Web File Server makes an LDAP lookup and retrieves data from the malicious server.
  5. Remote code execution.

The following screenshot presents the setup of the LDAP server:

Figure 9 - Setup of Rogue Jndi

The next snippet presents the CVE-2021-39146 gadget, which was used for this Proof of Concept:

jndiGadget.xml

If everything goes well and the lookup was performed successfully, Rogue JNDI should show the following message and the code should be executed on the targeted system.

Figure 10 - Triggered JNDI Lookup

To summarize, we were able to abuse the custom Ivanti Avalanche protocol and XML message deserialization mechanisms to exploit five different services and get remote code execution with SYSTEM privileges. I have found more deserialization vulnerabilities in Ivanti Avalanche, but I am leaving them for the second part of the blog post. Right now, I would like to stay with the protocol and inter-services communication.

Abusing a Race Condition in the Communication and Authentication Messages

As detailed above, the various Avalanche services communicate with each other with the help of InfoRail. When a service provides a response, the response is again forwarded via the InfoRail service. The idea for this research was: is it possible for an attacker to spoof a response? If so, it may be possible to abuse Ivanti Avalanche behavior and perform potentially malicious actions.

I focused on the authentication operation, which is presented in the following scheme (read from top to bottom):

Figure 11 - Authentication Scheme

When a user authenticates through the Avalanche Web Application login panel, the backend transfers the authentication message to the Enterprise Server. This service verifies credentials and sends back an appropriate response. If the provided credentials were correct, the user gets authenticated.

During this research, I learned two important things:
• The attacker can register as any service.
• The authentication message is distributed amongst every instance of the registered Enterprise Server.

According to that, the attacker can register himself as the Enterprise Server and intercept the incoming authentication messages. However, this behavior does not have much of an immediate consequence, as the transferred password is hashed and encrypted.

The next question was whether it is possible to deliver the attacker’s own response to the Avalanche Web and whether it will be accepted or not. It turns out that yes, it is possible! If you would like to deliver your own response, you must properly set two values in the message header:
Origin – The topic (ID) of the Avalanche Web backend that sent the message.
MsgId – The message ID of the original authentication message.

Both values are relatively easy to get, and thus the attacker can provide his own response to the message. It will be accepted by the service, which is waiting for the response. An example attack scenario is presented in the following figure (read from top to bottom ).

Figure 12 - Race Condition Scheme

The attack scenario works as follows:
         -- The attacker tries to log into the Web Application with the wrong credentials.
         -- Web Application sends the authentication message.
         --The InfoRail service sends the message to both Enterprise Servers: the legitimate one and the malicious one.
         --Race time:
                  --The legitimate server responds with the “wrong credentials” message.
                  --The malicious server responds with the “credentials OK” message.          --If the attacker’s server was first to deliver the message, it is forwarded to the Avalanche Web Application.
         --The attacker gets authenticated.

Please note that the “Login message” targeting the attacker’s server is not present here on purpose (although it is in reality transmitted to the attacker). I wanted to highlight the fact, that this issue can be exploited without a possibility to read messages. In such a case, the attacker has to brute-force the already mentioned message ID value. It complicates the whole attack, but the exploitation is still possible.

To summarize this part, the attacker can set up his own malicious Enterprise Server and abuse a race condition to deliver his own authentication response to the Web Application. There are two more things to investigate: what does the response message look like and are we able to win the race?

Authentication Handling

The following snippet presents an example response to a login message. Please note that those messages are way bigger during legitimate usage. However, for the Proof of Concept, I have minimized them and stored only those parts that are needed for exploitation.

The response message consists of several important parts:
• It contains a responseObject tag, which is a serialized User object.
• It contains a responseCode tag, which will be important.

At some point during authentication, the Web Backend invokes the UserService.doLogin method:

doLogin.java

At [1], the UserCredentials object is instantiated. Then, its members are set.

At [2], the authenticate method is called, and the object initialized at [1] is passed as an argument:

authenticate.java

At [1], the UserLogin object is initialized.

At [2], the UserCredentials object is serialized.

At [3], the message is being sent to the Enterprise Server, and the Web Backend waits for the response.

At [4], the responseCode included in the response is verified. We want it to be equal to 0.

At [5], the userLogin.authenticated is set to True.

At [6], the userLogin.currentUser is set to the object that was included in the responseObject.

At [7], the method returns the userLogin object.

Basically, the response should have a responseCode equal to 0. It should also include a properly serialized User object in the responseObject tag.

Finally, we analyze the fragment of UserBean.loginInner method that was responsible for the invocation of the doLogin function.

loginInner.java

At [1], the doLogin method is invoked. It retrieves the object of UserLogin type (see the returns of previous code snippets).

At [2], it sets this.currentUser to the userLogin.currentUser (the one obtained from the response).

At [3], it sets various other settings. These will not be relevant for us.

One very important thing to note: the Web Backend does not compare the username provided in the login panel and the username retrieved by the Enterprise Server. Accordingly, the attacker can:
• Trigger the authentication with the username “poc”.
• Win the race and provide the user “amcadmin” in the response.
• The attacker will then be authenticated as the “amcadmin”.

To summarize, it seems that there are no obstacles for the attacker and his response should be handled by the Web Backend without any problems. Next, we turn our focus to winning the race.

Winning the Race

In a default installation, the Enterprise Server and InfoRail services are located on the same host as the Web Backend. This makes the exploitation of the race condition harder, as the legitimate communication is handled by the local interface, which is much faster than communication through an external network interface.

Still, the attacker has some advantages. For example, he does not have to generate dynamic responses, as the response payload can be hardcoded in the exploit. The following table presents a general overview of actions that must be performed by both the attacker and the legitimate Enterprise Server.

Attacker Enterprise Server
·       Get the message ID from the original Login message and place it in the header. ·       Get the message ID from the original Login message and place it in the header.
·      Send static response. ·       Decrypt and verify the user’s credentials.
  ·       Retrieve the user’s details and create the User object.
  ·       Dynamically create the response.

The remote attacker needs to perform far fewer operations and can prepare his response more rapidly. It makes the race winnable. One may ask – what if the attacker’s position in the network too disadvantageous and he still has no chance to win the race? Even then, there is an effective solution.

The unauthenticated attacker could modify the Avalanche System Settings. This is due to a separate vulnerability that allows to bypassing domain authentication (ZDI-CAN-15919). The remote attacker could enable the LDAP-based authentication and set any address for the LDAP server configuration. In such a scenario, the legitimate Enterprise Server will first try to access this “rogue” authentication server. This will give the attacker an additional second or two (or even more if played properly). In this way, an attacker can gain more time to win the race, should this be necessary

Exploitation

Having all the pieces, the race condition vulnerability can be exploited. The following video shows an example of the attacker providing wrong credentials via the panel but was still successfully authenticating as the “amcadmin” user.

Conclusion

When you don’t have ideas for further research, make sure that you have discovered the complete attack surface of your recent targets. When you find a spot that was not already studied by others, you might find a path to discovering a whole new set of exciting vulnerabilities.

Keep an eye out for the second part of this blog, where I will share some details about my favorite vulnerabilities in the Ivanti Avalanche services. It will cover one more deserialization vulnerability, cool chains leading to the remote code execution, and a pretty rare information disclosure vulnerability.

Until then, you can follow me @chudypb  and the team @thezdi on Twitter for the latest in exploit techniques and security patches.

Riding the InfoRail to Exploit Ivanti Avalanche

CVE-2022-30136: Microsoft Windows Network File System v4 Remote Code Execution Vulnerability

In this excerpt of a Trend Micro Vulnerability Research Service vulnerability report, Guy Lederfein and Quintin Crist of the Trend Micro Research Team detail a recently patched remote code execution vulnerability in the Microsoft Windows operating system, originally discovered and reported by Yuki Chen. The bug is found in the implementation of Network File System (NFS)and is due to improper handling of NFSv4 requests. An unauthenticated attacker could exploit this bug to execute arbitrary code in the context of SYSTEM. The following is a portion of their write-up covering CVE-2022-30136, with a few minimal modifications.


A remote code execution vulnerability exists in Windows Network File System. The vulnerability is due to improper handling of NFSv4 requests.

A remote attacker can exploit this vulnerability by sending malicious RPC calls to a target server. Successful exploitation results in arbitrary code execution in the context of SYSTEM. Unsuccessful exploitation may result in a crash of the target system.

The Vulnerability

Microsoft Windows ships with several network features designed to communicate and interact with non-Windows file shares. One of these modules is called Network File System (NFS).

NFS is a network file system protocol originally developed by Sun Microsystems in 1984. Version 2 is documented in RFC 1094. Version 3 is documented in RFC 1813. Version 4 was developed by the IETF and is documented in RFC 3010 (released December 2000) and revised in RFC 3530 (released April 2003) and RFC 7530 (released March 2015). NFS allows users to access remote file shares in the same way that the local file system is accessed. Different access levels and permissions can be set on the share, such as read-write and read-only. Additionally, IP/UID/GID/Kerberos security can be used. NFS uses Open Network Computing (ONC) Remote Procedure Call (RPC) to exchange control messages. ONC RPC was originally developed by Sun Microsystems and can also be referred to as Sun RPC.

When ONC RPC messages are transferred over TCP, they are prepended with a Fragment header structure (as illustrated in the following table) that specifies the length of the message. This allows the receiver to distinguish multiple messages sent over a single TCP session. Other protocols such as UDP do not use this field. Note that all multi-byte values are encoded in big-endian byte order.

The structure of ONC RPC request messages, in general, is as follows:

The Credentials structure in a Sun-RPC message has the following structure:

The Flavor field in the above structure serves as a type identifier of the Contents data. Security flavors have been called authentication flavors for historical reasons. There are multiple security flavors defined in the RPC specification, such as AUTH_NONE(0), AUTH_SYS(1), AUTH_SHORT(2), AUTH_DH(3), and RPCSEC_GSS(6).

The Contents field for the flavor RPCSEC_GSS has the following structure:

There are four types such as RPCSEC_GSS_DATA(0), RPCSEC_GSS_INIT(1), RPCSEC_GSS_CONTINUE_INIT(2), and RPCSEC_GSS_DESTROY(3) defined in the GSS Procedure field. Also, in the GSS Service field, there are three types: rpc_gss_svc_none(1), rpc_gss_svc_integrity(2), and rpc_gss_svc_privacy(3). When using RPCSEC_GSS to authenticate the RPC clients, a security context must be created by using RPCSEC_GSS_INIT and RPCSEC_GSS_CONTINUE_INIT RPC messages. First, the RPC client sends an RPCSEC_GSS_INIT message to start the creation of the context. Then, the RPC server decides whether it needs another token for the creation. If so, the server replies with a GSS_S_CONTINUE_NEEDED message, and the client needs to send an RPCSEC_GSS_CONTINUE_INIT message to continue.

If the GSS Service field is set to 2 (rpc_gss_svc_integrity), the Program-specific data field is prefixed with the following structure:

If the GSS Service field is set to 3 (rpc_gss_svc_privacy), the Program-specific data field is encrypted.

When the Program field is set to 100003 (NFS) and the Procedure field is set to 1 (Compound), the Program-specific data field has the following structure:

A buffer overflow vulnerability exists in the Windows implementation of NFS. The vulnerability is due to incorrect calculation of the size of response messages. The server calls the function Nfs4SvrXdrpGetEncodeOperationResultByteCount() to calculate the size of each opcode response, but it does not include the size of the opcode itself. This results in the size of the response buffer being too small by OP Count * 4 bytes. A corresponding buffer is allocated with OncRpcBufMgrpAllocate. When the response data is written to the buffer, the response data overflows. Due to the function only being used for NFS version 4, only NFS4 is vulnerable.

OncRpcBufMgrpAllocate() will actually allocate the data with either OncRpcBufMgrpAllocateDescriptorFromLLInlineBuffer(), when the request is under 0x800 bytes in size, or OncRpcBufMgrpAllocateDescriptorFromLLLargePoolAllocation(), which is used otherwise.

OncRpcBufMgrpAllocateDescriptorFromLLInlineBuffer() returns a buffer in a static 0x800 bytes inside the descriptor. The descriptor structure has 0x50 bytes of space that appears to be unused after the static buffer.

OncRpcBufMgrpAllocateDescriptorFromLLLargePoolAllocation() returns a buffer allocated with ExAllocatePoolWithTag(). The number of bytes allocated is equal to the following:

This means that for either buffer type, more than 0x48 bytes must be overflowed to get past the padding in either buffer type. Since the number of overflowed bytes is OP Count * 4, a minimum of 19 operations must be performed in a compound message for the overflow to have any impact.

An attacker can use this vulnerability to send a crafted request with many operations, producing a large size miscalculation, resulting in a buffer overflow. Successful exploitation results in arbitrary code execution in the context of SYSTEM. Unsuccessful exploitation may result in a crash of the target system.

Detecting Attacks

Much of this information is largely seen earlier in this post. It is reposted here for your convenience.

When ONC RPC messages are transferred over TCP, they are prepended with a Fragment header structure (as illustrated in the following table) that specifies the length of the message. This allows the receiver to distinguish multiple messages sent over a single TCP session. Other protocols such as UDP do not use this field. Note that all multi-byte values are encoded in big-endian byte order.

The structure of ONC RPC request messages is shown above, as is the Credentials structure in a Sun-RPC message. As shown above, the Flavor field in the above structure serves as a type identifier of the Contents data. Security flavors have been called authentication flavors for historical reasons. There are multiple security flavors defined in the RPC specification, such as AUTH_NONE(0), AUTH_SYS(1), AUTH_SHORT(2), AUTH_DH(3), and RPCSEC_GSS(6).

As a reminder, the Contents field for the flavor RPCSEC_GSS has the following structure:

There are four types such as RPCSEC_GSS_DATA(0), RPCSEC_GSS_INIT(1), RPCSEC_GSS_CONTINUE_INIT(2), and RPCSEC_GSS_DESTROY(3) defined in the GSS Procedure field. Also, in the GSS Service field, there are three types: rpc_gss_svc_none(1), rpc_gss_svc_integrity(2), and rpc_gss_svc_privacy(3). When using RPCSEC_GSS to authenticate the RPC clients, a security context must be created by using RPCSEC_GSS_INIT and RPCSEC_GSS_CONTINUE_INIT RPC messages. Firstly, the RPC client sends an RPCSEC_GSS_INIT message to start the creation of the context. Then, the RPC server will decide whether it needs another token for the creation. If so, the server will reply with a GSS_S_CONTINUE_NEEDED message, and the client needs to send an RPCSEC_GSS_CONTINUE_INIT message to continue.

If the GSS Service field is set to 2 (rpc_gss_svc_integrity), the Program-specific data field is prefixed with the following structure:

If the GSS Service field is set to 3 (rpc_gss_svc_privacy), the Program-specific data field is encrypted and must be decrypted before continuing.

The detection device needs to check if the Program field in an RPC request message has the value 100003 (NFS), the Procedure field has the value 1 (COMPOUND), and the Program Version field has the value 4 (NFS4). If found, the device must inspect the Program-specific data in the ONC RPC messages.

The data format of NFS COMPOUND has the following structure:

The buffer overflow is only triggered if at least 19 operations are present in the NFS reply. Since the NFS reply has the response for each operation in the NFS request, request messages should be monitored for an OP Count field greater than 18.

If a packet with greater than 18 operations is detected, the traffic should be considered suspicious; an attack exploiting this vulnerability is likely underway.

Note that all multi-byte values are expressed in network (big-endian) byte order. Also, this detection method may generate false positives if normal traffic contains similar NFS COMPOUND requests.

Conclusion

This bug was patched by Microsoft in June 2022 and assigned CVE-2022-30136. In their write-up, they also list disabling NFSv4.1 as a method to mitigate attacks. However, this could lead to a loss of functionality. Also, Microsoft notes the update to address this bug should not be applied unless the fix for CVE-2022-26937 is installed. Applying both updates in the appropriate order is the best method to fully address these vulnerabilities.

Special thanks to Guy Lederfein and Quintin Crist of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit http://go.trendmicro.com/tis/.

The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the ZDI team for the latest in exploit techniques and security patches.

CVE-2022-30136: Microsoft Windows Network File System v4 Remote Code Execution Vulnerability

The July 2022 Security Update Review

It’s once again Patch Tuesday, which means the latest security updates from Adobe and Microsoft have arrived. Take a break from your regularly scheduled activities and join us as we review the details of their latest security offerings.

Adobe Patches for July 2022

For July, Adobe addressed 27 CVEs in four patches for Acrobat and Reader, Photoshop, RoboHelp, and Adobe Character Animator. A total of 24 of these bugs were reported through the ZDI program. The update for Acrobat and Reader addresses a combination of 22 different Critical- and Important-rated bugs. The most severe of these could allow code execution if an attacker convinces a target to open a specially crafted PDF document. While there are no active attacks noted, Adobe does list this as a Priority 2 deployment rating. The update for Photoshop fixes one Critical- and one Important-rated bug. The Critical bug is a use-after-free (UAF) that could lead to code execution. The fix for Character Animator addresses two Critical-rated code execution bugs – one a heap overflow and the other an out-of-bounds (OOB) read. Finally, the patch for RoboHelp corrects a single Important-rated cross-site scripting (XSS) bug.

None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release. Adobe categorizes most of these updates as a deployment priority rating of 3, with the Acrobat patch being the lone exception at 2.

Microsoft Patches for July 2022

For July, Microsoft released 84 new patches addressing CVEs in Microsoft Windows and Windows Components; Windows Azure components; Microsoft Defender for Endpoint; Microsoft Edge (Chromium-based); Office and Office Components; Windows BitLocker; Windows Hyper-V; Skype for Business and Microsoft Lync; Open-Source Software; and Xbox. This is in addition to the two CVEs patched in Microsoft Edge (Chromium-based). That brings the total number of CVEs to 87.

While this higher volume is expected for a July release, there are still no fixes available for the multiple bugs submitted during the last Pwn2Own competition. And after a brief respite last month, there are additional updates for the Print Spooler. Looks like this component will be back to a monthly release schedule.

Of the 84 new CVEs released today, four are rated Critical, and 80 are rated Important in severity. One of these bugs was submitted through the ZDI program. None of the new bugs patched this month are listed as publicly known, but one of the updates for CSRSS is listed as under active attack. Let’s take a closer look at some of the more interesting updates for this month, starting with the CSRSS bug under active attack:

-       CVE-2022-22047 – Windows CSRSS Elevation of Privilege
This bug is listed as being under active attack, but there’s no information from Microsoft on where the vulnerability is being exploited or how widely it is being exploited. The vulnerability allows an attacker to execute code as SYSTEM, provided they can execute other code on the target. Bugs of this type are typically paired with a code execution bug, usually a specially crafted Office or Adobe document, to take over a system. These attacks often rely on macros, which is why so many were disheartened to hear Microsoft’s delay in blocking all Office macros by default.

-       CVE-2022-30216 – Windows Server Service Tampering Vulnerability
This patch corrects a tampering vulnerability in the Windows Server Service that could allow an authenticated attacker to upload a malicious certificate to a target server. While this is listed as “Tampering”, an attacker who could install their own certificate on a target system could use this bug for various purposes, including code execution. While tampering bugs don’t often get much attention, Microsoft does give this its highest exploit index rating, meaning they expect active exploits within 30 days. Definitely test and deploy this patch quickly – especially to your critical servers.

-       CVE-2022-22029 – Windows Network File System Remote Code Execution Vulnerability
This is the third month in a row with a Critical-rated NFS bug, and while this one has a lower CVSS than the previous ones, it could still allow a remote, unauthenticated attacker to execute their code on an affected system with no user interaction. Microsoft notes multiple exploit attempts may be required to do this, but unless you are specifically auditing for this, you may not notice. If you’re running NFS, make sure you don’t ignore this patch.

-       CVE-2022-22038 - Remote Procedure Call Runtime Remote Code Execution Vulnerability
This bug could allow a remote, unauthenticated attacker to exploit code on an affected system. While not specified in the bulletin, the presumption is that the code execution would occur at elevated privileges. Combine these attributes and you end up with a potentially wormable bug. Microsoft states the attack complexity is high since an attacker would need to make “repeated exploitation attempts” to take advantage of this bug, but again, unless you are actively blocking RPC activity, you may not see these attempts. If the exploit complexity were low, which some would argue since the attempts could likely be scripted, the CVSS would be 9.8. Test and deploy this one quickly.

Here’s the full list of CVEs released by Microsoft for July 2022:

CVE Title Severity CVSS Public Exploited Type
CVE-2022-22047 Windows CSRSS Elevation of Privilege Vulnerability Important 7.8 No Yes EoP
CVE-2022-22038 Remote Procedure Call Runtime Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-30221 Windows Graphics Component Remote Code Execution Vulnerability Critical 8.8 No No RCE
CVE-2022-22029 Windows Network File System Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-22039 Windows Network File System Remote Code Execution Vulnerability Critical 7.5 No No RCE
CVE-2022-30215 Active Directory Federation Services Elevation of Privilege Vulnerability Important 7.5 No No EoP
CVE-2022-23816 * AMD: CVE-2022-23816 AMD CPU Branch Type Confusion Important N/A No No Info
CVE-2022-23825 * AMD: CVE-2022-23825 AMD CPU Branch Type Confusion Important N/A No No Info
CVE-2022-30181 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33641 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33642 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33643 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33650 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33651 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33652 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.4 No No EoP
CVE-2022-33653 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33654 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33655 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33656 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33657 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33658 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.4 No No EoP
CVE-2022-33659 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33660 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33661 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33662 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33663 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33664 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33665 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33666 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33667 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33668 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33669 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33671 Azure Site Recovery Elevation of Privilege Vulnerability Important 4.9 No No EoP
CVE-2022-33672 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33673 Azure Site Recovery Elevation of Privilege Vulnerability Important 6.5 No No EoP
CVE-2022-33674 Azure Site Recovery Elevation of Privilege Vulnerability Important 8.3 No No EoP
CVE-2022-33675 Azure Site Recovery Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-33677 Azure Site Recovery Elevation of Privilege Vulnerability Important 7.2 No No EoP
CVE-2022-33676 Azure Site Recovery Remote Code Execution Vulnerability Important 7.2 No No RCE
CVE-2022-33678 Azure Site Recovery Remote Code Execution Vulnerability Important 7.2 No No RCE
CVE-2022-30187 Azure Storage Library Information Disclosure Vulnerability Important 4.7 No No Info
CVE-2022-22048 BitLocker Security Feature Bypass Vulnerability Important 6.1 No No SFB
CVE-2022-27776 * HackerOne: CVE-2022-27776 Insufficiently protected credentials vulnerability might leak authentication or cookie header data Important N/A No No Info
CVE-2022-22040 Internet Information Services Dynamic Compression Module Denial of Service Vulnerability Important 7.3 No No DoS
CVE-2022-33637 Microsoft Defender for Endpoint Tampering Vulnerability Important 6.5 No No Tampering
CVE-2022-33632 Microsoft Office Security Feature Bypass Vulnerability Important 4.7 No No SFB
CVE-2022-22036 Performance Counters for Windows Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-33633 Skype for Business and Lync Remote Code Execution Vulnerability Important 7.2 No No RCE
CVE-2022-22037 Windows Advanced Local Procedure Call Elevation of Privilege Vulnerability Important 7.5 No No EoP
CVE-2022-30202 Windows Advanced Local Procedure Call Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-30224 Windows Advanced Local Procedure Call Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-22711 Windows BitLocker Information Disclosure Vulnerability Important 6.7 No No Info
CVE-2022-30203 Windows Boot Manager Security Feature Bypass Vulnerability Important 7.4 No No SFB
CVE-2022-30220 Windows Common Log File System Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30212 Windows Connected Devices Platform Service Information Disclosure Vulnerability Important 4.7 No No Info
CVE-2022-22031 Windows Credential Guard Domain-joined Public Key Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-22026 Windows CSRSS Elevation of Privilege Vulnerability Important 8.8 No No EoP
CVE-2022-22049 Windows CSRSS Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30214 Windows DNS Server Remote Code Execution Vulnerability Important 6.6 No No RCE
CVE-2022-22043 Windows Fast FAT File System Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-22050 Windows Fax Service Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-22024 Windows Fax Service Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-22027 Windows Fax Service Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30213 Windows GDI+ Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-22034 Windows Graphics Component Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30205 Windows Group Policy Elevation of Privilege Vulnerability Important 6.6 No No EoP
CVE-2022-22042 Windows Hyper-V Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-30223 Windows Hyper-V Information Disclosure Vulnerability Important 5.7 No No Info
CVE-2022-30209 Windows IIS Server Elevation of Privilege Vulnerability Important 7.4 No No EoP
CVE-2022-22025 Windows Internet Information Services Cachuri Module Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-21845 Windows Kernel Information Disclosure Vulnerability Important 4.7 No No Info
CVE-2022-30211 Windows Layer 2 Tunneling Protocol (L2TP) Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-30225 Windows Media Player Network Sharing Service Elevation of Privilege Vulnerability Important 7.1 No No EoP
CVE-2022-22028 Windows Network File System Information Disclosure Vulnerability Important 5.9 No No Info
CVE-2022-22023 Windows Portable Device Enumerator Service Security Feature Bypass Vulnerability Important 6.6 No No SFB
CVE-2022-22022 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.1 No No EoP
CVE-2022-22041 Windows Print Spooler Elevation of Privilege Vulnerability Important 6.8 No No EoP
CVE-2022-30206 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30226 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.1 No No EoP
CVE-2022-30208 Windows Security Account Manager (SAM) Denial of Service Vulnerability Important 6.5 No No DoS
CVE-2022-30216 Windows Server Service Tampering Vulnerability Important 8.8 No No Tampering
CVE-2022-30222 Windows Shell Remote Code Execution Vulnerability Important 8.4 No No RCE
CVE-2022-22045 Windows.Devices.Picker.dll Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-33644 Xbox Live Save Service Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-2294 * Chromium: CVE-2022-2294 Heap buffer overflow in WebRTC High N/A No Yes RCE
CVE-2022-2295 * Chromium: CVE-2022-2295 Type Confusion in V8 High N/A No No RCE

* Indicates this CVE had previously been assigned by a 3rd-party and is now being incorporated into Microsoft products.

Please note that Google is aware that an exploit for one of the Chromium bugs (CVE-2022-2294) exists in the wild. If you’re using Microsoft Edge (Chromium-based), make sure it gets updated as soon as possible.

Looking at the rest of the release, the first thing that stands out is the 32(!) patches for the Azure Site Recovery service. Two are remote code execution (RCE) bugs while the rest are elevation of privilege (EoP) issues. This is primarily a cloud-based service, but there are some on-prem components. Don’t expect an automatic update for these bugs. In all cases, you will need to upgrade to version 9.49 to remediate these vulnerabilities. Instructions for this can be found here. It’s incredibly unusual to see so many CVEs addressed in a single month for a single component, and it’s not clear why Microsoft chose to address these bugs in this manner. Regardless of why, if you rely on Azure Site Recovery, make sure you update all the necessary components.

There are two other Critical-rated bugs still to cover. There’s a second Critical-rated NFS vulnerability in addition to the one previously discussed. This is very similar to the other one but rates a slightly lower CVSS. It’s still Critical and the CVSS is questionable, so don’t think it’s any less dangerous. The highest CVSS patch this month belongs to a bug in Windows Graphic Component. These types of bugs usually manifest by either opening a file or viewing an image.

The remaining Critical-rated bugs impact some critical business functions. The first is a patch for the DNS server component. While certainly worth paying attention to, it does require the attacker to have elevated privileges. There’s an RCE bug in Windows Shell, but it requires a local attacker to interact with the logon screen. As always, don’t ignore physical security. There’s a code execution bug in Skype for Business and Lync (remember those?), but there are several prerequisites that make exploitation less likely. There’s a patch for the Layer 2 Tunneling Protocol (L2TP). It’s not clear how many people are using L2TP these days, but if you’re one of them, make sure you get this patch installed. Speaking of outdated methods of communication, there are two RCE bugs in the Windows Fax service receiving patches.

There are 52 fixes for EoP bugs, which includes the 30 Azure Site Recovery bugs we’ve already mentioned. In addition to the one under active attack, there are two other EoP bugs in CSRSS. For the most part, the rest of these bugs require an attacker to already have the ability to execute code on the target. They can then use one of these bugs to escalate to SYSTEM or some other elevated level. An exception to this is the bug in the Media Player Network Sharing service, which could be leveraged to delete registry keys. There’s also a patch for IIS to address a bug that could allow attackers to bypass authentication on an affected IIS server. The Group Policy bug requires the attacker to have privileges to create Group Policy Templates. Microsoft reminds us to regularly audit these groups, and that’s good advice for many reasons. There’s a patch for the Xbox Live Save Service, but it’s not clear what privileges an attacker would gain if they exploited this bug. Microsoft does list the attack vector as local, so perhaps multiple user profiles on the same Xbox would be impacted? And finally, after getting a month off, there are four new patches for the Print Spooler. We will likely continue to see additional print spooler fixes for the foreseeable future.

There are three fixes for denial-of-service (DoS) bugs in this month’s release, and all are impactful. The first impacts the Security Account Manager (SAM). While Microsoft doesn’t state the impact of this bug, a DoS on the SAM would likely lead to problems logging on to a domain. The other DoS patches fix bugs in IIS. The first covers the Cachuri module, which provides user-mode caching of URL information. The other is in the dynamic compression module, which (as its name implies) allows IIS to compress responses coming from various handlers. It doesn’t seem like either of these would lead to a complete website shutdown, but they would certainly degrade services.

In addition to the tampering bug mentioned above, there’s another tampering issue in Microsoft Defender for Endpoint. However, this bug requires the attacker to authenticate to the management console appliance and to have an integration token.

Physical access is a common factor in three of the four security feature bypass bugs getting fixed this month. The first is a BitLocker bypass that allows an attacker with physical access to a powered-off system to gain access to encrypted data. Similarly, the bug in Boot Manager allows an attacker with physical access to bypass Secure Boot and access the pre-boot environment. The bypass in the Windows Portable Device Enumerator service allows an attacker to attach a USB storage device to a system where Group Policy failed to apply. The final SFB occurs when opening a specially crafted Office file.

The July release contains new fixes for seven information disclosure bugs. Most of these only result in leaks consisting of unspecified memory contents, but there are a couple of notable exceptions. The bug in BitLocker could allow a local attacker to view raw, unencrypted disk sector data. Considering BitLocker’s purpose, you could almost consider this a security feature bypass. One of the Hyper-V bugs could let an attacker on a guest OS gain data from the Hyper-V host. The bug in the Azure Storage Library allows an attacker to decrypt data on the client side and disclose the content of the file or blob. There’s also a CVE assigned by HackerOne that could leak authentication or cookie header data via curl. This was originally patched in April 2022 and is now being incorporated into Microsoft products that use curl.

Finally, there are two information disclosure bugs covering AMD CPU Branch Type Confusion issues. These are related to the “Hertzbleed” vulnerabilities first documented in Intel processors last month. While interesting from an academic perspective, exploits using speculative execution side channels haven’t had much of an impact in the real world. 

No new advisories were released this month. The latest servicing stack updates can be found in the revised ADV990001.

Looking Ahead

The next Patch Tuesday falls on August 9, and I’ll be at Black Hat in Las Vegas to present on determining risk in an era of low patch quality. I’ll still be able to publish details and patch analysis of the August release, but please come by for the presentation if you’re at the conference. Until then, stay safe, happy patching, and may all your reboots be smooth and clean!

The July 2022 Security Update Review

CVE-2022-23088: Exploiting a Heap Overflow in the FreeBSD Wi-Fi Stack

In April of this year, FreeBSD patched a 13-year-old heap overflow in the Wi-Fi stack that could allow network-adjacent attackers to execute arbitrary code on affected installations of FreeBSD Kernel. This bug was originally reported to the ZDI program by a researcher known as m00nbsd and patched in April 2022 as FreeBSD-SA-22:07.wifi_meshid. The researcher has graciously provided this detailed write-up of the vulnerability and a proof-of-concept exploit demonstrating the bug.


Our goal is to achieve kernel remote code execution on a target FreeBSD system using a heap overflow vulnerability in the Wi-Fi stack of the FreeBSD kernel. This vulnerability has been assigned CVE-2022-23088 and affects all FreeBSD versions since 2009, along with many FreeBSD derivatives such as pfSense and OPNsense. It was patched by the FreeBSD project in April 2022.

The Vulnerability

When a system is scanning for available Wi-Fi networks, it listens for management frames that are emitted by Wi-Fi access points in its vicinity. There are several types of management frames, but we are interested in only one: the beacon management subtype. A beacon frame has the following format:

In FreeBSD, beacon frames are parsed in ieee80211_parse_beacon(). This function iterates over the sequence of options in the frame and keeps pointers to the options it will use later.

One option, IEEE80211_ELEMID_MESHID, is particularly interesting:

There is no sanity check performed on the option length (frm[1]). Later, in function sta_add(), there is a memcpy that takes this option length as size argument and a fixed-size buffer as destination:

Due to the lack of a sanity check on the option length, there is an ideal buffer overflow condition here: the attacker can control both the size of the overflow (sp->meshid[1]) as well as the contents that will be written (sp->meshid).

Therefore, when a FreeBSD system is scanning for available networks, an attacker can trigger a kernel heap overflow by sending a beacon frame that has an oversized IEEE80211_ELEMID_MESHID option.

Building a “Write-What-Where” Primitive

Let’s look at ise->se_meshid, the buffer that is overflown during the memcpy. It is defined in the ieee80211_scan_entry structure:

Here, the overflow of se_meshid allows us to overwrite the se_ies field that follows. The se_ies field is of type struct ieee80211_ies, defined as follows:

We will be interested in overwriting the last two fields: data and len.

Back in sta_add(), not long after the memcpy, there is a function call that uses the se_ies field:

This ieee80211_ies_init() function is defined as:

The data parameter here points to the beginning of the beacon options in the frame, and len is the full length of all the beacon options. In other words, the (data,len) couple describes the options buffer that is part of the frame that the attacker sent:

Figure 1 - The Options Buffer

As noted in the code snippet, the ies structure is fully attacker-controlled thanks to the buffer overflow.

Therefore, at $1:

       -- We can control len, given that this is the full size of the options buffer, and we can decide that size by just adding or removing options to our frame.
       -- We can control the contents of data, given that this is the contents of the options buffer.
       -- We can control the ies->data pointer, by overflowing into it.

We thus have a near-perfect write-what-where primitive that allows us to write almost whatever data we want at whatever kernel memory address we want just by sending one beacon frame that has an oversized MeshId option.

Constraints on the Primitive

A few constraints apply to the primitive:

  1. The FreeBSD kernel expects there to be SSID and Rates options in the frame. That means that there are 2x2=4 bytes of the options buffer that we cannot control. In addition, our oversized MeshId option has a 2-byte header, so that makes 6 bytes we cannot control. For convenience and simplicity, we will place these bytes at the beginning of the options buffer.

  2. Our oversized MeshId option must be large enough to overwrite up to the ies->data and ies->len fields, but not more. This equates to a length of 182 bytes for the MeshId option, plus its 2-byte header. To accommodate the MeshId option plus the two options mentioned above, we will use an options buffer of size 188 bytes.

  3. The ies->data and ies->len fields we overwrite are respectively the last 8 and 4 bytes within the options buffer, so they too are constrained.

  4. The ies->len field must be equal to len for the branch at $0 not to be taken.

The big picture of what the frame looks like given the aforementioned constraints:

Figure 2 - The Big Picture

Maintaining stability of the target

Let’s say we send a beacon frame that uses the primitive to overwrite an area of kernel memory. There is going to be a problem at some point when the kernel subsequently tries to free ies->data. This is because ies->data is supposed to point to a malloc-allocated buffer, which may no longer be true after our overwrite.

To maintain stability and avoid crashing the target, we can send a second, corrective beacon frame that overflows ies->data to be NULL and ies->len to be 0. After that, when the kernel attempts to free ies->data, it will see that the pointer is NULL, and won’t do anything as a result. This allows us to maintain the stability of the target and ensure our primitive doesn’t crash it.

Choosing what to write, and where to write it

Now we have a nice write-what-where primitive that we can invoke with just one beacon frame plus one corrective frame. What exactly can we do with it now?

A first thought might be to use the primitive to overwrite the instructions that the kernel executes in memory. (Un)fortunately, in FreeBSD, the kernel text segment is not writable, so we cannot use our primitive to directly overwrite kernel instructions. Furthermore, the kernel implements W^X, so no writable pages are executable.

However, the page tables that map executable pages are writable.

Injecting an implant

Here we are going to inject an implant into the target's kernel that will process "commands" that we send to it later on via subsequent Wi-Fi frames — a full kernel backdoor, if you will.

The process of injecting this implant will take four beacon frames.

This is a bit of a bumpy technical ride, so fasten your seatbelt.

Frame 1: Injecting the payload

Background: the direct map is a special kernel memory region that contiguously maps the entire physical memory of the system as writable pages, except for the physical pages of read-only text segments.

We use the primitive to write data at the physical address 0x1000 using the direct map:

Figure 3 - Frame 1

0x1000 was chosen as a convenient physical address because it is unused. The data we write is as follows:

Figure 4 - Frame 1

The implant shellcode area contains the instructions of our implant. The rest of the fields are explained below.

Frame 2: Overwriting an L3 PTE

Quick Background: x64 CPUs use page tables to map virtual addresses to physical RAM pages, in a 4-level hierarchy that goes from L4 (root) to L0 (leaf). Refer to the official AMD and Intel specifications for more details.

In this step, we use the primitive to overwrite an L3 page table entry (PTE) and make it point to the L2 PTE that we wrote at physical address 0x1000 as part of Frame 1. We crafted that L2 PTE precisely to point to our three L1 PTEs, which themselves point to two different areas: (1) two physical pages of the kernel text segment, and (2) our implant shellcode.

In other words, by overwriting an L3 PTE, we create a branch in the page tables that maps two pages of kernel text as writable and our shellcode as executable:

Figure 5 - Frame 2

At this point, our shellcode is mapped into the target’s virtual memory space and is ready to be executed. We will see below why we're mapping the two pages of the kernel text segment.

The attentive reader may be concerned about the constraints of the primitive here. Nothing to worry about: the L3 PTE space is mostly unpopulated. We just have to choose an unpopulated range where overwriting 188 bytes will not matter.

Frame 3: Patching the text segment

In order to jump into our newly mapped shellcode, we will patch the beginning of the sta_input() function in the text segment. This function is part of the Wi-Fi stack and gets called each time the kernel receives a Wi-Fi frame, so it seems like the perfect place to invoke our implant.

How can we patch it, given that the kernel text segment is not writable? By mapping as writable the text pages that contain the function. This is what we did in frames 1 and 2, with the first two L1 PTEs, that now give us a writable view of the instruction bytes of sta_input():

Figure 6 - Our writable view of sta_input()

Back on topic, we use the primitive to patch the first bytes of sta_input() via the writable view we created in frames 1 and 2, and replace these bytes with:

This simply calls our shellcode. However, the constraints of our primitive come into play:

  1. The first constraint of the primitive is that the first 6 bytes that we overwrite cannot be controlled. Overwriting memory at sta_input would not be great, as it would put 6 bytes of garbage at the beginning of the function, causing the target to crash.

However, if we look at the instruction dump of sta_input, we can see that it actually has a convenient layout:

What we can do here is overwrite memory at sta_input-6. The 6 bytes of garbage will just overwrite the unreachable NOPs of the previous sta_newstate() function, with no effect on execution.

With this trick, we don’t have to worry about these first 6 bytes, as they are effectively discarded.

  1. The second constraint of the primitive is that we are forced to overwrite exactly 182 bytes, so we cannot overwrite the first few bytes only. This is not really a problem. We can just fill the rest of the bytes with the same instruction bytes that are there in memory already.

  2. The third constraint of the primitive is that the last 12 bytes that we write are the ies->data and ies->len fields, and these don’t disassemble to valid instructions. That’s a problem because these bytes are within sta_input(). If the kernel tries to execute these bytes, it won’t be long before it crashes. To work around this, we must have corrective code in our implant. When called for the first time, our implant must correct the last 12 bytes of garbage that we wrote into sta_input(). Although slightly annoying, this is not complicated to implement.

With all that established, we’re all set. Our implant will now execute each time sta_input() is called, meaning, each time a Wi-Fi frame is received by the target!

Frame 4: Corrective frame

Finally, to maintain the stability of the target, we send a final beacon frame where we overflow ies->data to be NULL and ies->len to be 0.

This ensures that the target won’t crash.

Subsequent communication channel

With the aforementioned four frames, we have a recipe to reliably inject an implant into the target’s kernel. The implant gets called in the same context as sta_input():

Notably, the second argument, m, is the memory region containing the buffer of the frame that the kernel is currently processing. The implant can therefore inspect that buffer (via %rsi) and act depending on its contents.

In other words, we have a communication channel with the implant. We can therefore code our implant as a server backdoor and send commands to it via this channel.

Full steps

Let’s recap:

  1. A heap buffer overflow vulnerability exists in the FreeBSD kernel. An attacker can trigger this bug by sending a beacon frame with an oversized MeshId option.
  2. Using that vulnerability, we can implement a write-what-where primitive that allows us to perform one kernel memory overwrite per beacon frame we send.
  3. We can use that primitive three times to inject an implant into the target’s kernel.
  4. A fourth beacon frame is used to clean up ies->data and ies->len, to prevent a crash.
  5. Finally, our implant runs in the kernel of the target and acts as a full backdoor that can process subsequent Wi-Fi frames we send to it.

The Exploit

A full exploit can be found here. It injects a simple implant that calls printf() with the strings that the attacker subsequently sends. To use this exploit from a Linux machine that has a Wi-Fi card called wifi0, switch the card to monitor mode with:

Then, build and run the exploit for the desired target. For example, if you wish to target a pfSense 2.5.2 system:

Please exercise caution - this will exploit all vulnerable systems in your vicinity.

Once you have done this, look at the target’s tty0 console. You should see: “Hello there, I’m in the kernel”.


Thanks again to m00nbsd for providing this thorough write-up. They have contributed multiple bugs to the ZDI program over the last few years, and we certainly hope to see more submissions from them in the future. Until then, follow the team for the latest in exploit techniques and security patches.

CVE-2022-23088: Exploiting a Heap Overflow in the FreeBSD Wi-Fi Stack

The June 2022 Security Update Review

It’s once again Patch Tuesday, which means the latest security updates from Adobe and Microsoft have arrived. Take a break from your regularly scheduled activities and join us as we review the details of their latest security offerings.

Adobe Patches for June 2022

This month, Adobe released six patches addressing 46 CVEs in Adobe Illustrator, InDesign, InCopy, Bridge, Robohelp, and Animate. A total of 40 of these CVEs were reported by ZDI vulnerability researcher Mat Powell. The largest update belongs to Illustrator, which addresses 17 total CVEs. The most severe of these bugs could allow code execution if an affected system opens a specially crafted file. Many of these bugs fall into the Out-Of-Bounds (OOB) Write category. The update for Adobe Bridge fixes 12 bugs, 11 of which are rated Critical. The patch for InCopy fixes eight Critical-rated bugs, all of which could lead to arbitrary code execution. Similarly, the InDesign patch fixes seven Critical-rated arbitrary code execution bugs. For both InDesign and InCopy, the bugs are a mix of OOB Read, OOB Write, heap overflow, and Use-After-Free (UAF) vulnerabilities. The lone bug fixed by the Animate patch is also a Critical-rated OOB Write that could lead to arbitrary code execution. Finally, the Robohelp patch fixes a Moderate-rated privilege escalation bug caused by improper authorization.

None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release. Adobe categorizes these updates as priority 3.

Microsoft Patches for June 2022

For June, Microsoft released 55 new patches addressing CVEs in Microsoft Windows and Windows Components; .NET and Visual Studio; Microsoft Office and Office Components; Microsoft Edge (Chromium-based); Windows Hyper-V Server; Windows App Store; Azure OMI, Real Time Operating System, and Service Fabric Container; SharePoint Server; Windows Defender; Windows Lightweight Directory Access Protocol (LDAP); and Windows Powershell. This is in addition to the 4 CVEs patched in Microsoft Edge (Chromium-based), and the new update for MSDT. That brings the total number of CVEs to 60.

Of the 55 new CVEs released today, three are rated Critical, 51 are rated Important, and one is rated Moderate in severity. None of the new bugs patched this month are listed as publicly known or under active attack at the time of release, however, we do have an update for MSDT, which is public and reported to be under active attack.

It's also interesting to note is what is not included in today’s release. This is the first month in recent memory without an update for the Print Spooler. We’ll see if that trend continues or if this reprieve is only temporary. Finally, there are no fixes listed for any of the bugs disclosed during Pwn2Own Vancouver.

Before we take a deeper dive into this month’s release, let’s take just a minute to remember Internet Explorer, which will go out of support tomorrow. The ubiquitous browser has served up websites to users since 1995, and while it’s doubtful anyone will miss it, it certainly had a good run. If you’re worried about your legacy apps still functioning, IE Mode in Microsoft Edge will be supported through at least 2029. With nostalgia out of the way, let’s take a closer look at some of the more interesting updates for this month, starting with the much anticipated fix for MSDT:

-       CVE-2022-30190 - Microsoft Windows Support Diagnostic Tool (MSDT) Remote Code Execution Vulnerability
Although it’s difficult to see from the Security Update Guide, Microsoft did release an update to address the much discuss “Follina” vulnerability in MSDT. This bug has been reported to be under active attack, so priority should be given to the testing and deployment of this update.

-       CVE-2022-30136 - Windows Network File System Remote Code Execution Vulnerability
This CVSS 9.8 bug looks eerily similar to CVE-2022-26937 – an NFS bug patched last month and one we blogged about last week. This vulnerability could allow a remote attacker to execute privileged code on affected systems running NFS. On the surface, the only difference between the patches is that this month’s update fixes a bug in NFSV4.1, whereas last month’s bug only affected versions NSFV2.0 and NSFV3.0. It’s not clear if this is a variant or a failed patch or a completely new issue. Regardless, enterprises running NFS should prioritize testing and deploying this fix.

 -       CVE-2022-30163 - Windows Hyper-V Remote Code Execution Vulnerability
This bug could allow a user on a Hyper-V guest to run their code on the underlying Hyper-V host OS. The update doesn’t list the privileges the attacker’s code would run at, but any guest-to-host escape should be taken seriously. Microsoft notes that attack complexity is high since an attacker would need to win a race condition. However, we have seen many reliable exploits demonstrated that involve race conditions, so take the appropriate step to test and deploy this update.

-       CVE-2022-30148 - Windows Desired State Configuration (DSC) Information Disclosure Vulnerability
Most info disclosure bugs simply leak unspecified memory contents, but this bug is different. An attacker could use this to recover plaintext passwords and usernames from log files. Since DSC is often used by SysAdmins to maintain machine configurations in an enterprise, there are likely some sought-after username/password combos that could be recovered. This would also be a great bug for an attacker to move laterally within a network. If you’re using DSC, make sure you don’t miss this update.

Here’s the full list of CVEs released by Microsoft for June 2022:

CVE Title Severity CVSS Public Exploited Type
CVE-2022-30163 Windows Hyper-V Remote Code Execution Vulnerability Critical 8.5 No No RCE
CVE-2022-30139 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Critical 7.5 No No RCE
CVE-2022-30136 Windows Network File System Remote Code Execution Vulnerability Critical 9.8 No No RCE
CVE-2022-30184 .NET and Visual Studio Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30167 AV1 Video Extension Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30193 AV1 Video Extension Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-29149 Azure Open Management Infrastructure (OMI) Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30180 Azure RTOS GUIX Studio Information Disclosure Vulnerability Important 7.8 No No Info
CVE-2022-30177 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30178 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30179 Azure RTOS GUIX Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30137 Azure Service Fabric Container Elevation of Privilege Vulnerability Important 6.7 No No EoP
CVE-2022-22018 HEVC Video Extensions Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-29111 HEVC Video Extensions Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-29119 HEVC Video Extensions Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30188 HEVC Video Extensions Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-21123 * Intel: CVE-2022-21123 Shared Buffer Data Read (SBDR) Important N/A No No Info
CVE-2022-21125 * Intel: CVE-2022-21125 Shared Buffers Data Sampling (SBDS) Important N/A No No Info
CVE-2022-21127 * Intel: CVE-2022-21127 Special Register Buffer Data Sampling Update (SRBDS Update) Important N/A No No Info
CVE-2022-21166 * Intel: CVE-2022-21166 Device Register Partial Write (DRPW) Important N/A No No Info
CVE-2022-30164 Kerberos AppContainer Security Feature Bypass Vulnerability Important 8.4 No No SFB
CVE-2022-30166 Local Security Authority Subsystem Service Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30173 Microsoft Excel Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30154 Microsoft File Server Shadow Copy Agent Service (RVSS) Elevation of Privilege Vulnerability Important 5.3 No No EoP
CVE-2022-30159 Microsoft Office Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30171 Microsoft Office Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30172 Microsoft Office Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30174 Microsoft Office Remote Code Execution Vulnerability Important 7.4 No No RCE
CVE-2022-30168 Microsoft Photos App Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-30157 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-30158 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29143 Microsoft SQL Server Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-30160 Windows Advanced Local Procedure Call Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30151 Windows Ancillary Function Driver for WinSock Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-30189 Windows Autopilot Device Management and Enrollment Client Spoofing Vulnerability Important 6.5 No No Spoofing
CVE-2022-30131 Windows Container Isolation FS Filter Driver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30132 Windows Container Manager Service Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30150 Windows Defender Remote Credential Guard Elevation of Privilege Vulnerability Important 7.5 No No EoP
CVE-2022-30148 Windows Desired State Configuration (DSC) Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30145 Windows Encrypting File System (EFS) Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-30142 Windows File History Remote Code Execution Vulnerability Important 7.1 No No RCE
CVE-2022-30147 Windows Installer Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30140 Windows iSCSI Discovery Service Remote Code Execution Vulnerability Important 7.1 No No RCE
CVE-2022-30165 Windows Kerberos Elevation of Privilege Vulnerability Important 8.8 No No EoP
CVE-2022-30155 Windows Kernel Denial of Service Vulnerability Important 5.5 No No DoS
CVE-2022-30162 Windows Kernel Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-30141 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Important 8.1 No No RCE
CVE-2022-30143 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-30146 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-30149 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Important 7.5 No No RCE
CVE-2022-30153 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-30161 Windows Lightweight Directory Access Protocol (LDAP) Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-30135 Windows Media Center Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-30152 Windows Network Address Translation (NAT) Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-32230 * Windows SMB Denial of Service Vulnerability Important N/A No No DoS
CVE-2022-22021 Microsoft Edge (Chromium-based) Remote Code Execution Vulnerability Moderate 8.3 No No RCE
CVE-2022-2007 * Chromium: Use after free in WebGPU High N/A No No RCE
CVE-2022-2008 * Chromium: Out of bounds memory access in WebGL High N/A No No RCE
CVE-2022-2010 * Chromium: Out of bounds read in compositing High N/A No No RCE
CVE-2022-2011 * Chromium: Use after free in ANGLE High N/A No No RC

* Indicates this CVE had previously been assigned by a 3rd-party and is now being incorporated into Microsoft products.

Looking at the rest of the release we that more than half of the patches this month deal with remote code execution. Seven of these deal with LDAP vulnerabilities, which is at least a decrease from the 10 LDAP patches last month. The most severe of these clocks in with a CVSS of 9.8 but would require the MaxReceiveBuffer LDAP policy to be set to a value higher than the default value. This doesn’t seem to be a common scenario. Still, the volume of bugs in LDAP over the last couple of months could indicate a broad attack surface in the component. Speaking of fertile attack surfaces, there are another six fixes for code execution bugs in the AV1 and HEVC media codecs. If you are connected to the Internet, you should automatically get updates from the Windows Store. However, if you are using these optional components in a disconnected environment, you’ll need to get these through either the Microsoft Store for Business or the Microsoft Store for Education. The same holds true for the patch addressing the RCE in the Photos App.

There are three RCE bugs receiving fixes in the Azure RTOS GUIX Studio, which provides developers a design for developing GUIs for IoT applications. What’s not clear is whether these apps will also need updates after installing these patches. There are a few RCE bugs in Office components, including a couple of interesting SharePoint bugs. Most of these require a user to open a specially crafted file. The SQL Server bug sounds pretty nasty but requires authentication. That should lessen the impact. Still, admins will need to carefully review the listed chart to determine which GDR and CU updates they require. This release includes patches impacting the iSCSI Discovery Service, Encrypting File System (EFS), and the File History component. All require some form of authentication, and the iSCSI and File History bugs require user interaction.

Moving on, there are 12 patches to address elevation of privilege (EoP) vulnerabilities. Most of these require an attacker to log on to a system and run specially crated code. There are, however, a couple of patches that stand out. The update for Azure Open Management Infrastructure (OMI) impacts multiple different Azure and SCOM components. Admins will need to touch most of these to ensure the bug is fully addressed, which will add to their workload. The patch for Azure Service Fabric doesn’t fix any bugs. Instead, it enforces the path to least privilege on Linux clusters. The bug in Kerberos affects servers with both Credential Security Service Provider (CredSSP) and Remote Credential Guard (RCG) installed. An attacker could elevate privileges and then spoof the Kerberos logon process when an RCG connection is made via CredSSP. Finally, the patch for the File Server Shadow Copy Agent Service (RVSS) only affects systems where the File Server VSS Agent Service is installed. However, on those systems, the patch alone isn’t enough. Admins must install the updates on Application and File Servers. Failure to do so could negatively impact backups and cause them to fail. See this KB article for more details.

The June release contains fixes for three Denial-of-Service (DoS) bugs. The DoS in the kernel could crash the OS, but it’s not clear how severe the bug in NAT could be. If it shut down NAT completely, it could devastate impacted enterprises. If you use NAT, treat this as a Critical update. Rapid7 also contributed a CVE in a Windows SMB that Microsoft had initially classified as a stability bug. This was silently fixed in the May 2022 updates and is being documented publicly here.

There’s a single security feature bypass being fixed this month in Kerberos AppContainer. If exploited, an attacker could bypass the Kerberos service ticketing feature that performs user access control checks. There’s also a single spoofing bug in this release for the Windows Autopilot Device Management component. There are a mountain of caveats to this bug, so if you’re using this management tool, read the bulletin carefully to determine if your systems are affected.

The release is rounded out by 11 information disclosure bugs. As previously mentioned, most of these only result in leaks consisting of unspecified memory contents. There are a couple of exceptions. The Office bug could expose device information such as resource IDs, SAS tokens, and user properties. The bug in .NET and Visual Studio could be used to intercept the API key intended for NuGet.org.

Finally, there are four info disclosure bugs addressing Intel Processor MMIO stale data vulnerabilities. An attacker could use these bugs to read privileged data across trust boundaries. Microsoft has also released Advisory ADV220002 detailing these bugs, and Intel has also released further details about this class of vulnerabilities.

Looking Ahead

The next Patch Tuesday falls on July 12, and we’ll return with details and patch analysis then. Until then, stay safe, happy patching, and may all your reboots be smooth and clean!

The June 2022 Security Update Review

CVE-2022-26937: Microsoft Windows Network File System NLM Portmap Stack Buffer Overflow

In this excerpt of a Trend Micro Vulnerability Research Service vulnerability report, Guy Lederfein and Jason McFadyen of the Trend Micro Research Team detail a recently patched code execution vulnerability in the Microsoft Windows operating system. The bug was originally discovered and reported to Microsoft by Yuki Chen. A stack buffer overflow vulnerability exists in Windows Network File System. A remote attacker can exploit this vulnerability by sending specially crafted RPC packets to a server, resulting in code execution in the context of SYSTEM. The following is a portion of their write-up covering CVE-2022-26937, with a few minimal modifications.


A stack buffer overflow vulnerability exists in Windows Network File System. The vulnerability is due to improper handling of crafted RPC responses to Portmap requests made by the Network Lock Manager (NLM) RPC program.

A remote attacker can exploit this vulnerability by sending malicious RPC calls to a target server. Successful exploitation may result in arbitrary code execution under the context of SYSTEM. Unsuccessful exploitation results in a crash of the target system.

The Vulnerability

Microsoft Windows ships with several network features designed to communicate and interact with non-Windows files shares. One of these modules is called Network File System (NFS).

NFS is a network file system protocol originally developed by Sun Microsystems in 1984. Version 2 is documented in RFC 1094. Version 3 is documented in RFC 1813. Version 4 was developed by the IETF and is documented in RFC 3010 (released December 2000) and revised in RFC 3530 (released April 2003) and RFC 7530 (released March 2015). NFS allows users to access remote file shares in the same way that the local file system is accessed. Different access levels and permissions can be set on the share, such as read-write and read-only. Additionally, IP/UID/GID/Kerberos security can be used. NFS uses Open Network Computing (ONC) Remote Procedure Call (RPC) to exchange control messages. ONC RPC was originally developed by Sun Microsystems and can also be referred to as Sun RPC.

The Network Lock Manager (NLM) protocol is an extension of NFS versions 2 and 3, which provides a System V style of advisory file and record locking over the network. Since NFS versions 2 and 3 are stateless protocols, the NLM protocol was developed to manage the state of locks on files stored on NFS shares. The NLM protocol supports both synchronous and asynchronous procedures to implement locking and file-sharing functionality. Similar to NFS, NLM also uses ONC RPC to exchange control messages.

ONC RPC uses XDR packets, which can be transmitted over UDP or TCP. Over UDP, the XDR packet is contained within the UDP payload. Over TCP, XDR packets are preceded by a Fragment header (as illustrated in the following table). The most significant bit of the Fragment header indicates whether the packet is the last fragment, and the remaining 31 bits are the length of the Fragment that follows. The Fragment itself contains the XDR packet.

The structure of an ONC RPC call is as follows:

The Program field of the RPC message specifies what RPC service the message is sent to. Windows NFS server implements the NLM protocol via RPC with Program type set to 100021. It supports multiple RPC procedures, which can be specified in the Procedure field in the RPC message. A list of synchronous and asynchronous procedures supported by the NLM protocol version 3 follows:

Microsoft Windows runs the RPCBIND RPC program, which implements the Port Mapper protocol, documented in RFC 1833. The RPCBIND program converts RPC program numbers into universal addresses, which can then be used by programs to communicate over UDP or TCP. Briefly, the way it works is that when a program wishes to use RPC, it registers its ports with the host's Port Mapper. A client that wishes to issue RPC calls connects to the Port Mapper, uses various RPC calls such as GETPORT, GETADDR etc. to obtain a port on which the RPC service is available, and connects to the desired RPC service. Standard RPC program numbers have been defined and maintained by IANA and they include portmapper (100000), nfs (100003), mount daemon (100005) and hundreds of other less commonly used programs. Only the portmapper service and NFS service have standard ports of 111 and 2049 respectively.

Windows implements the RPCBIND protocol via RPC with Program type set to 100000. It supports multiple RPC procedures, which can be specified in the Procedure field in the RPC message. One of the procedures supported by the RPCBIND program when Program Version is set to 3 or 4, is GETADDR, which is procedure number 3. The reply to this RPC call contains the Universal Address associated with the callee. The format for the returned Universal Address is XDR_String, which has the following format:

A stack buffer overflow vulnerability exists in Windows Network File System. More specifically, the vulnerability is due to incorrect handling of the Universal Address field returned in GETADDR RPC replies. When Windows NFS responds to an NLM call in an asynchronous manner, the NlmGetClientAddressAndConnection() function is called. This flow is triggered either as a response to an asynchronous NLM call, such as NLM_TEST_MSG, NLM_LOCK_MSG, NLM_UNLOCK_MSG, or when the server sends an `NLM_GRANTED` call to the client, after a previous (synchronous or asynchronous) call by the client to create a lock returned the status `LCK_BLOCKED`. If the IPv6 protocol is used for communication over the ONC RPC protocol, the server will issue a GETADDR RPC call to the client to retrieve its IP address. When the Universal Address field returned by the client in the GETADDR reply is processed by the NFS server, the field is copied using memmove() into a buffer of size 96 bytes. In addition, this buffer is later referenced at an index equal to the Universal Address field’s string size and set to 0. However, the NlmGetClientAddressAndConnection() function does not verify the size of the returned Universal Address string. Therefore, if the string provided by the client is 96 bytes or longer, the buffer will be written past its boundary, resulting in the stack buffer overflow condition.

A remote attacker can exploit this vulnerability by sending an NLM request triggering an asynchronous response by the NFS server. When the server sends a GETADDR RPC request, the attacker can respond with a crafted GETADDR reply. Successful exploitation may result in arbitrary code execution under the context of SYSTEM. Unsuccessful exploitation results in a crash of the target system.

Source Code Walkthrough

The following code snippet was taken from nfssvr.sys version 10.0.17763.1999. Comments added by Trend Micro have been highlighted.

 In function NlmGetClientAddressAndConnection():

Detecting Attacks

ONC RPC uses XDR packets, which can be transmitted over UDP or TCP. Over UDP, the XDR packet is contained within the UDP payload. Over TCP, XDR packets are preceded by a Fragment header (as illustrated in the following table). The most significant bit of the Fragment header indicates whether the packet is the last fragment, and the remaining 31 bits are the length of the Fragment that follows. The Fragment itself contains the XDR packet.

The detection device must inspect all outgoing ONC RPC calls, which have the following structure:

The detection device must check if the Message Type field is 0 (Call), the Program field is 100000 (portmap), the Program Version field is larger than 2, and the Procedure field is equal to 3 (GETADDR). If found, the device must inspect the Program-specific data object. This object uses the rpcb structure, which has the following format:

If the Program Number field is set to 100021 (NLM), the detection device must inspect all incoming ONC RPC replies, which have the following structure:

The detection device must check if the XID field is equal to the XID field of the GETADDR RPC call detected, and the Message Type field is 1 (Reply). If found, the device must inspect the Program-specific data object. This object uses the XDR_String structure, which has the following format:

If the String Length field is larger than 95, the traffic should be considered suspicious; an attack exploiting this vulnerability is likely underway.

Conclusion

This bug was patched by Microsoft in May 2022 and assigned CVE-2022-26937. In their write-up, they also list disabling NFSV2 and NFSV3 as a method to mitigate attacks. However, this could lead to a loss of functionality. Applying the security update is the best method to fully address this vulnerability.

Special thanks to Guy Lederfein and Jason McFadyen of the Trend Micro Research Team for providing such a thorough analysis of this vulnerability. For an overview of Trend Micro Research services please visit http://go.trendmicro.com/tis/.

The threat research team will be back with other great vulnerability analysis reports in the future. Until then, follow the ZDI team for the latest in exploit techniques and security patches.

CVE-2022-26937: Microsoft Windows Network File System NLM Portmap Stack Buffer Overflow

Is exploiting a null pointer deref for LPE just a pipe dream?

A lot of blog posts I have read go over interesting vulnerabilities and exploits but do not typically share the process behind discovery. I want to show how sometimes just manually poking around can quickly uncover vulnerabilities you might miss with other approaches to vulnerability discovery.

In my previous blog, I highlighted a tool named IO Ninja and shared why it is helpful when working with Inter-Process Communications (IPC). In this blog, I would like to show you how this tool helped me find two vulnerabilities: CVE-2021-4198 and CVE-2021-4199 in Bitdefender’s antivirus software on Windows. The exploit I wrote targets a named pipe used by the Vulnerability.scan.exe process. The first vulnerability results in a denial-of-service on almost any process within the AV. The second results in local privilege escalation by exploiting a link following issue.

Now you might be thinking, wait a minute... how does a tool that lets you communicate with named pipes allow you to find a link following vulnerability? That is what we are going to dive into next.

The pipelist tool from Sysinternals reveals that Bitdefender uses several pipes for IPC.

Figure 1 – Output of the pipelist utility from the Sysinternals tool suite.

bdservicehost.exe is one of the executables that runs as SYSTEM after installing Bitdefender. It uses these pipes to communicate with other processes on the system and might be an interesting target.

Figure 2 – List of named pipes used by bdservicehost.exe

Using IO Ninja, we can spawn a pipe server as our standard user to see if we can trigger a connection from the client. Without reading any code, we can poke around the agent GUI to see what IPC connections are being created and what the traffic looks like.

Figure 3 - Bitdefender Total Security GUI

The screenshot below shows that we receive a connection from the client of the pipe that sends data to our named pipe server every time we open the agent GUI. This can be done by double clicking the Bitdefender icon in the system tray or opening it from the start menu.

Figure 4 - Connection from client to our named pipe server

What is interesting here is that the connection remains open. This allows us to send data back to the client. I took the first 16 bytes of data that was being sent to the server and echoed it back to the client multiple times to see if anything interesting would happen. I was also looking to see if the pipe connection would remain open after sending the data.

Figure 5 - Pipe client disconnects after sending data to it

After sending several messages, the client disconnects, and we get a popup box from Bitdefender informing the user that something went wrong within the AV. Take note of the “x” at the top right for dismissing the dialog box. This will become relevant later.

Figure 6 - Bitdefender telling us that we broke something.

After seeing this message, I knew that debugging information in some shape or form must be getting saved or logged.  I fired up Process Monitor from Sysinternals to see if a crash dump file, which I can further analyze in a debugger, was created.

As it turns out, an executable named “BDReinit.exe”, which is Bitdefender’s own crash handler, produces a crash dump file for us on the system.

Figure 7 – Process Monitor showing crash dump files being created by BDReinit.exe.

Another interesting discovery here was finding out that the folder to which the .dmp file is being written to is readable and writeable by standard users.

Figure 8 - Permissions of the directory storing the dump files.

Unfortunately, after looking at the dump file, I concluded the crash alone was not very interesting, and the process being crashed runs as our current user. At this point, I knew I had a potential local DoS on the AV but there had to be more to chew on here.

Figure 9 - NULL pointer dereference: CVE-2021-4198

After crashing this first process “seccenter.exe,” which is Bitdefender’s main GUI interface, I realized that I was still getting connections to my named pipe server. I was able to crash almost any process related to the AV by simply spamming the incoming pipe connections with those 16 bytes as soon as a client connected. I sat in front of my computer, watching the AV processes fall like dominos one after the other in process explorer.

I knew that kicking off a “Vulnerability Scan” in the GUI would spawn vulnerability.scan.exe, which ran as SYSTEM. I quickly tried to see if I could also crash this privileged process.

Figure 10 - Process Monitor showing crash dump files being created by BDReinit.exe, this time running as SYSTEM.

Ahh, the same “BDReinit.exe” process runs again, but this time it runs as SYSTEM. Based on the file name of the dump, we know we can also crash “Vulnerability.scan.exe,” and it writes the dump to disk as SYSTEM.

When looking for link following vulnerabilities, there are a few directories that are of immediate interest.

         C:\ProgramData
         C:\windows\temp
         C:\Users\[standard user]\AppData

I often look for privileged file writes and delete operations in these directories.

In this case, a .dmp file is being written to this directory as SYSTEM when a highly privileged process that is part of the AV crashes. This alone is not very interesting as we do not control the contents of the dump being written, and it’s the same exact crash from before.

I further analyzed the Process Monitor log and discovered that “BDReinit.exe” was doing two very dangerous things. First, it was writing a very permissive DACL to a file with a predictable name in a different directory. This directory also allowed a standard user read and write access, and the DACL write happened every time a crash occurred.

Figure 11 - Read and write access for everyone

The permissive DACL would get written to this file as SYSTEM if you crashed a process running as SYSTEM within Bitdefender. In this case, I just chose to again crash “Vulnerability.scan.exe” because of how easy it was to trigger. All I had to do was kick off a vulnerability scan in the GUI, and I would get a connection to my named pipe server from this process.

Figure 12 - Kicking off a vulnerability scan

Figure 13 - BDReinit.exe ACL write after crashing Vulnerability.scan.exe

One of my favorite parts about logic bugs like this is that exploiting them is typically very quick and easy. All we need to do to escalate to SYSTEM is redirect the permissive DACL write to a DLL used by the system, modify the contents of that DLL, and then have it get loaded. To do this redirection we just need one symbolic link and a target DLL.

One great candidate for the job is:

         C:\Windows\System32\spool\Drivers\x64\3\PrintConfig.dll

This is because a standard user can easily trigger a print job which will force svchost.exe to load our modified DLL as SYSTEM.

Figure 14 - Creating Symbolic link

Figure 15 - Redirecting BDReinit.exe DACL write

Figure 16 - Svchost.exe Loading modified DLL

Putting this all together, the following screenshot demonstrates executing code at SYSTEM using the techniques described.

Figure 17 - Putting it all together

The second major issue I found was related to the crash dump itself. If you clicked the “x” at the top right of the popup box I showed earlier, “BDReinit.exe” or “BdSubWiz.exe” which is the submission wizard, would delete the crash dump as your current user. If the user waited or ignored it for a while, the dialog box would timeout and delete the dump file as SYSTEM if the process that crashed was running as SYSTEM!

Figure 18- Log of BDReinit.exe arbitrary file deletion PoC

In the above screenshot, you can see how we can redirect this highly privileged file deletion to any file on the system. You can also use the techniques described in this blog to achieve privilege escalation and execute code at SYSTEM. Again, this is because the crash dump was being written and deleted from a location that our standard user had read and write access to regardless of the user that was running the crashed process. Furthermore, the files in that folder were not protected at all, so deleting them and replacing one with our link before the timeout was not an issue.

Figure 19 - Unrestricted file permissions

Conclusion

Sometimes vulnerability discovery isn’t super methodical and that’s okay! I did not spend any time reversing the functions responsible for IPC in this application to figure out what data to send over the pipe. However, I identified an attack surface and started poking around. This led me to an entirely different attack surface where there were some critical vulnerabilities.

I hope this blog inspires and enables you to do the same with your targets. Furthermore, I hope it reminds you to look at custom crash handlers and their dialog boxes – both for bugs and to make sure you aren’t unintentionally giving away your research. 😀

Below is a Procmon filter I use that you can download and import to search for link-following vulnerabilities. Just be sure to either change your username to “lowpriv,” or edit the filter before you use it. You can download it here.

Keep an eye out for future blogs where I will share details on other vulnerabilities I have found. Until then, you can follow me @izobashi and the team @thezdi on Twitter for the latest in exploit techniques and security patches.

Happy hunting!

 

Tools used:

-       IO Ninja
-       SysInternals
-       Symboliclink Testing Tools

Advisories:

https://www.bitdefender.com/support/security-advisories/incorrect-permission-assignment-for-critical-resource-vulnerability-in-bdreinit-exe-va-10017/

https://www.bitdefender.com/support/security-advisories/messaging_ipc-dll-null-pointer-dereference-in-multiple-bitdefender-products-va-10016/

Other Resources:       

https://www.zerodayinitiative.com/blog/2021/11/17/mindshare-using-io-ninja-to-analyze-npfs

https://decoder.cloud/2019/11/13/from-arbitrary-file-overwrite-to-system/

https://www.zerodayinitiative.com/blog/2022/3/16/abusing-arbitrary-file-deletes-to-escalate-privilege-and-other-great-tricks

Is exploiting a null pointer deref for LPE just a pipe dream?

Pwn2Own Vancouver 2022 - The Results

Pwn2Own Vancouver for 2022 is underway, and the 15th anniversary of the contest has already seen some amazing research demonstrated. Stay tuned to this blog for updated results, picture, and videos from the event. We’ll be posting it all here - including the most recent Master of Pwn leaderboard.

Jump to Day One results; Jump to Day Two results; Jump to Day Three results

Here are the current standings for the Master of Pwn:

Current as of May 20, 12:00 Pacific

Day One - May 18, 2022

SUCCESS - Hector “p3rr0” Peralta was able to demonstrate an improper configuration against Microsoft Teams. He earns $150,000 and 15 Master of Pwn points.

Hector “p3rr0” Peralta demonstrates a improper configuration bug on Microsoft Teams by launching calc.

SUCCESS - Billy Jheng Bing-Jhong (@st424204), Muhammad Alifa Ramdhan (@n0psledbyte), and Nguyễn Hoàng Thạch (@hi_im_d4rkn3ss) of STAR Labs successfully used an OOB Read and OOB Write to achieve escalation on Oracle Virtualbox. They earn $40,000 and 4 Master of Pwn points.

SUCCESS - Masato Kinugawa was able to execute a 3-bug chain of injection, misconfiguraton and sandbox escape against Microsoft Teams, earning $150,000 and 15 Master of Pwn points.

SUCCESS - Manfred Paul (@_manfp) successfully demonstrated 2 bugs - prototype pollution and improper input validation - on Mozilla Firefox, earning him $100,000 and 10 Master of Pwn points.

Manfred Paul (left) demonstrates his 2 bug vulnerability submission on Mozilla Firefox to ZDI Analysts Hossein Lotfi and Michael DePlante.

SUCCESS - Marcin Wiązowski was able to execute an out-of-bounds write escalation of privilege on Microsoft Windows 11, earning $40,000 and 4 Master of Pwn points, and high praise on the accompanying whitepaper from the Microsoft team.

SUCCESS - Team Orca of Sea Security (security.sea.com) was able to execute 2 bugs on Ubuntu Desktop - an Out-of-Bounds Write (OOBW) and Use-After-Free (UAF) - earning $40,000 and 4 Master of Pwn points.

Team Orca of Sea Security successfully demonstrates their OOBW and UAF on Ubuntu Desktop.

SUCCESS - Daniel Lim Wee Soong (@daniellimws), Poh Jia Hao (@Chocologicall), Li Jiantao (@CurseRed) & Ngo Wei Lin (@Creastery) of STAR Labs successfully demonstrated their zero-click exploit of 2 bugs (injection and arbitrary file write) on Microsoft Teams. They earn $150,000 and 15 Master of Pwn points.

SUCCESS - Manfred Paul (@_manfp) successfully scored his second win of the day with an out-of-band write on Apple Safari, earning him another $50,000 and 5 additional Master of Pwn points.

SUCCESS - Phan Thanh Duy (@PTDuy and Lê Hữu Quang Linh (@linhlhq of STAR Labs earned $40K and 4 Master of Pwn points for a Use-After-Free elevation of privilege on Microsoft Windows 11.

SUCCESS - Keith Yeo (@kyeojy) earned $40K and 4 Master of Pwn points for a Use-After-Free exploit on Ubuntu Desktop.

Day Two - May 19, 2022

SUCCESS and BUG COLLISION - On the first attempt of the day, David BERARD and Vincent DEHORS from @Synacktiv were able to demonstrate 2 unique bugs (Double-Free & OOBW) with collision on a known sandbox escape on a Tesla Model 3 Infotainment System. They earn $75,000 and 7.5 Master of Pwn points, and although they don't win the car outright, they have made enough to go pick one up themselves!

First attempt of the day at Tesla. From left to right: 2 representatives from Tesla (standing and seated), ZDI Analyst Michael DePlante, Sr. Director of Vulnerability Research (ZDI) Brian Gorenc, David BERARD and Vincent DEHORS of Synacktiv.

FAILURE - On the second attempt of day 2, namnp was unable to get their exploit of Microsoft Windows 11 working within the time allotted.

SUCCESS - Bien Pham (@bienpnn) was able to execute a Use After Free bug leading to elevation of privilege on Unbuntu Desktop, earning $40,000 and 4 Master of Pwn points.

Local elevation of privilege on Ubuntu Desktop courtesy of Bien Pham.

FAILURE - @Jedar_LZ was unable to get today's second Tesla attempt working within the time allotted. On a positive note, @thedzi decided to acquire the details of the exploit and disclose them to Tesla.

SUCCESS - T0 was able to successfully show an improper access control bug leading to elevation of privilege on Microsoft Windows 11 - earning $40,000 and 4 Master of Pwn points.

SUCCESS - On the final attempt of Day 2, Zhenpeng Lin (@Markak_), Yueqi Chen (@Lewis_Chen_), and Xinyu Xing (@xingxinyu) of Team TUTELARY from Northwestern University successfully demonstrated a Use After Free bug leading to elevation of privilege on Ubuntu Desktop. This earns him $40,000 and 4 Master of Pwn points.

From left: Yueqi Chen of Team TUTELARY of Northwestern University with ZDI Analysts Tony Fuller and Bobby Gould.

Day Three - May 20, 2022

FAILURE - On the first attempt of day 3, Team DoubleDragon: Yonghwi Jin (@jinmo123) of Theori, and Yongjin Kim (@adm1nkyj1) of Enki was unable to get their exploit of Microsoft Teams working within the time allotted. All is not lost though, in that Team Double Dragon was able to get their research into the regular ZDI process.

SUCCESS - nghiadt12 from Viettel Cyber Security was able to successfully show an escalation of privilege via Integer Overflow on Microsoft Windows 11 - earning $40,000 and 4 Master of Pwn points.

EOP via Integer Overflow on Windows 11 courtesy of nghiadt12 from Viettel Cyber Security

SUCCESS - Billy Jheng Bing-Jhong (@st424204) STAR Labs was able to successfully demonstrate a Use-After-Free exploit on Ubuntu Desktop - earning another $40,000 and 4 Master of Pwn points.

SUCCESS - vinhthp1712 successfully achieved Elevation of Privilege via Improper Access Control on Microsoft Windows 11. vinhthp1712 earns $40,000 and 4 Master of Pwn points.

SUCCESS - On the final attempt of the competition, Bruno PUJOS (@brunopujos) from REverse Tactics successfully achieved Elevation of Privilege via Use-After-Free on Microsoft Windows 11. Bruno earns $40,000 and 4 Master of Pwn points.

Bruno PUJOS from REverse Tactics drops an EOP via UAF on Microsoft Windows 11.

That concludes the regular scheduled programming for our event! This year, we had a total of 21 attempts from 17 contestants with Trend Micro and ZDI awarding $1,155,000! We can’t wait to share more details in the near future about our fall event, so stay tuned!

As always, follow us on Twitter for the latest results, update, and breaking news.

Thanks again to our partners Tesla, Zoom, and Microsoft as well as our sponsor VMware. Thanks also to the researchers who participate and to the vendors for providing fixes for what was discovered and reported during the contest. As a reminder, vendors have 90 days to produce a fix for all vulnerabilities disclosed.

Pwn2Own Vancouver 2022 - The Results

Pwn2Own Vancouver 2022 - The Schedule

Welcome to Pwn2Own Vancouver 2022! This year marks the 15th anniversary of the contest, and we plan on celebrating by putting some amazing research on display. For this year’s event, we have 17 contestants attempting to exploit 21 targets across multiple categories. As always, we began our contest with a random drawing to determine the order of attempts. If you missed it, you can watch the replay here.

The complete schedule for the contest is below (all times Pacific [GMT -7:00]).

Note: All times subject to change - You can see the results and live updates here once they become available. Entries marked with a 📷 icon will be live-streamed on YouTube, Twitch, and Twitter.

Wednesday, May 18, 2022

0930: Hector “p3rr0” Peralta targeting Microsoft Teams in the Enterprise Communications category

📷  1030: Billy Jheng Bing-Jhong (@st424204), Muhammad Alifa Ramdhan (@n0psledbyte), and Nguyễn Hoàng Thạch (@hi_im_d4rkn3ss) of STAR Labs targeting Oracle VirtualBox with a guest-to-host escape in the Virtualization category

📷  1200: Masato Kinugawa targeting Microsoft Teams in the Enterprise Communications category

📷  1300: Manfred Paul (@_manfp) targeting Mozilla Firefox (including sandbox escape) in the Web Browser category

1330: Marcin Wiązowski targeting Microsoft Windows 11 in the Local Elevation of Privilege category

1400: Team Orca of Sea Security (security.sea.com) targeting Ubuntu Desktop in the Local Elevation of Privilege category

1450: Daniel Lim Wee Soong (@daniellimws), Poh Jia Hao (@Chocologicall), Li Jiantao (@CurseRed) & Ngo Wei Lin (@Creastery) of STAR Labs targeting Microsoft Teams in the Enterprise Communications category

📷  1550: Manfred Paul (@_manfp) targeting Apple Safari in the Web Browser category

📷  1650: Keith Yeo (@kyeojy) targeting Ubuntu Desktop in the Local Elevation of Privilege category

1720: Phan Thanh Duy (@PTDuy) and Lê Hữu Quang Linh (@linhlhq) of STAR Labs targeting Microsoft Windows 11 in the Local Elevation of Privilege category

Thursday, May 19, 2022

 📷  1000: David BERARD and Vincent DEHORS from @Synacktiv target the Tesla Model 3 Infotainment System (with Sandbox Escape) in the Automotive category

 1100: namnp targeting Microsoft Windows 11 in the Local Elevation of Privilege category

 📷  1130: Bien Pham (@bienpnn) targeting Ubuntu Desktop in the Local Elevation of Privilege category

 📷 1300: @Jedar_LZ targeting the Tesla Model 3 Diagnostic Ethernet (with Root Persistence) in the Automotive category

 1400: T0 targeting Microsoft Windows 11 in the Local Elevation of Privilege category

 📷  1430: TUTELARY from Northwestern University targeting Ubuntu Desktop in the Local Elevation of Privilege category

 Friday, May 20, 2022

 📷  1000: Team DoubleDragon: Yonghwi Jin (@jinmo123) of Theori, and Yongjin Kim (@adm1nkyj1) of Enki targeting Microsoft Teams in the Enterprise Communications category

 1030: nghiadt12 from Viettel Cyber Security targeting Microsoft Windows 11 in the Local Elevation of Privilege category

📷  1100: Billy Jheng Bing-Jhong (@st424204) of STAR Labs targeting Ubuntu Desktop in the Local Elevation of Privilege category

1300: vinhthp1712 targeting Microsoft Windows 11 in the Local Elevation of Privilege category

📷  1330: Bruno PUJOS (@brunopujos) from REverse Tactics targeting Microsoft Windows 11 in the Local Elevation of Privilege category

 📷  1520: Award Ceremony

Pwn2Own Vancouver 2022 - The Schedule

The May 2022 Security Update Review

It’s the fifth second Tuesday of 2022, which also means it’s the also the fifth Patch Tuesday of the year, and it brings with it the latest security updates from Adobe and Microsoft. This is also the last release before Pwn2Own Vancouver, which means multiple participants will be holding their breath to see if their exploits still work or were patched out. Take a break from your regularly scheduled activities and join us as we review the details of their latest security offerings.

Adobe Patches for May 2022

For May, Adobe released five bulletins addressing 18 CVEs in Adobe CloudFusion, InCopy, Framemaker, InDesign, and Adobe Character Animator. A total of 17 of these CVEs were reported by ZDI vulnerability researcher Mat Powell. The largest of these patches is the fix for Framemaker with 10 CVEs in total. Nine of these are Critical-rated bugs that could lead to code execution, mostly due to Out-of-Bounds (OOB) Write vulnerabilities. The patch for InDesign addresses three Critical-rated bugs that could lead to code execution. Two of these are due to OOB Writes while one is an OOB Read. The patch for InCopy also fixes three Critical-rated code execution bugs. In this case, it’s two OOB Writes plus a Use-After-Free (UAF). The patch for Character Animator fixes a single, Critical-rated OOB Write code execution bug. Finally, the ColdFusion patch corrects an Important-rated reflected cross-site scripting (XSS) bug.

None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release. Adobe categorizes all of these updates as priority 3.

Microsoft Patches for May 2022

For May, Microsoft released 74 new patches addressing CVEs in Microsoft Windows and Windows Components, .NET and Visual Studio, Microsoft Edge (Chromium-based), Microsoft Exchange Server, Office and Office Components, Windows Hyper-V, Windows Authentication Methods, BitLocker, Windows Cluster Shared Volume (CSV), Remote Desktop Client, Windows Network File System, NTFS, and Windows Point-to-Point Tunneling Protocol. This is in addition to the 36 CVEs patched by Microsoft Edge (Chromium-based) in late April.

Of the 74 CVEs released today, seven are rated Critical, 66 are rated Important, and one is rated Low in severity. A total of seven of these bugs came through the ZDI program. Historically speaking, this volume is in line with May releases in the past, with 19 more than May 2021, but 5 less than May 2019. The entire 2020 release volume was somewhat of an anomaly, so comparisons there aren’t as useful.

One of the bugs released today is listed as publicly known and under active attack, while two others are listed as publicly known at the time of release. Let’s take a closer look at some of the more interesting updates for this month, starting with the vulnerability currently being exploited:

-       CVE-2022-26925 – Windows LSA Spoofing Vulnerability
This complex-sounding vulnerability could allow an unauthenticated attacker to force a domain controller to authenticate against another server using NTLM. The threat actor would need to be in the logical network path between the target and the resource requested (e.g., Man-in-the-Middle), but since this is listed as under active attack, someone must have figured out how to make that happen. Microsoft notes this would be a CVSS 9.8 if combined with NTLM relay attacks, making this even more severe. In addition to this patch, sysadmins should review KB5005413 and Advisory ADV210003 to see what additional measures can be taken to prevent NTLM relay attacks. Also note this patch affects some backup functionality on Server 2008 SP2. If you’re running that OS, read this one carefully to ensure your backups can still be used to restore.

 -       CVE-2022-26923 – Active Directory Domain Services Elevation of Privilege Vulnerability
This bug was submitted through the ZDI program by Oliver Lyak (@ly4k_) of the Institut for Cyber Risk. The specific flaw exists within the issuance of certificates. By including crafted data in a certificate request, an attacker can obtain a certificate that allows the attacker to authenticate to a domain controller with a high level of privilege. In essence, any domain authenticated user can become a domain admin if Active Directory Certificate Services are running on the domain. This is a very common deployment. Considering the severity of this bug and the relative ease of exploit, it would not surprise me to see active attacks using this technique sooner rather than later.

 -       CVE-2022-26937 – Windows Network File System Remote Code Execution Vulnerability
This CVSS 9.8-rated bug could allow remote, unauthenticated attackers to execute code in the context of the Network File System (NFS) service on affected systems. NFS isn’t on by default, but it’s prevalent in environments where Windows systems are mixed with other OSes such as Linux or Unix. If this describes your environment, you should definitely test and deploy this patch quickly. Microsoft notes NFSv4.1 is not exploitable, so upgrade from NFSv2 or NFSv3 if possible.

 -       CVE-2022-29972 – Insight Software: Magnitude Simba Amazon Redshift ODBC Driver
This update was actually released yesterday and is complicated enough for Microsoft to blog about the bug and how it affects multiple Microsoft services. Microsoft also released its first advisory of the year, ADV220001, with additional information about the vulnerability. The flaw exists in the third-party ODBC data connector used to connect to Amazon Redshift, in Integration Runtime (IR) in Azure Synapse Pipelines, and Azure Data Factory, and could allow an attacker to execute remote commands across Integration Runtimes. If you use these services, review the blog and advisory to ensure you understand the risks to your services.

Here’s the full list of CVEs released by Microsoft for May 2022:

CVE Title Severity CVSS Public Exploited Type
CVE-2022-26925 Windows LSA Spoofing Vulnerability Important 8.1 Yes Yes Spoofing
CVE-2022-29972 Insight Software: CVE-2022-29972 Magnitude Simba Amazon Redshift ODBC Driver Critical N/A Yes No RCE
CVE-2022-22713 Windows Hyper-V Denial of Service Vulnerability Important 5.6 Yes No DoS
CVE-2022-26923 Active Directory Domain Services Elevation of Privilege Vulnerability Critical 8.8 No No EoP
CVE-2022-21972 Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-23270 Point-to-Point Tunneling Protocol Remote Code Execution Vulnerability Critical 8.1 No No RCE
CVE-2022-22017 Remote Desktop Client Remote Code Execution Vulnerability Critical 8.8 No No RCE
CVE-2022-26931 Windows Kerberos Elevation of Privilege Vulnerability Critical 7.5 No No EoP
CVE-2022-26937 Windows Network File System Remote Code Execution Vulnerability Critical 9.8 No No RCE
CVE-2022-23267 .NET and Visual Studio Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-29117 .NET and Visual Studio Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-29145 .NET and Visual Studio Denial of Service Vulnerability Important 7.5 No No DoS
CVE-2022-29127 BitLocker Security Feature Bypass Vulnerability Important 4.2 No No SFB
CVE-2022-29109 Microsoft Excel Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-29110 Microsoft Excel Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-21978 Microsoft Exchange Server Elevation of Privilege Vulnerability Important 8.2 No No EoP
CVE-2022-29107 Microsoft Office Security Feature Bypass Vulnerability Important 5.5 No No SFB
CVE-2022-29108 Microsoft SharePoint Server Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29105 Microsoft Windows Media Foundation Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-26940 Remote Desktop Protocol Client Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-22019 Remote Procedure Call Runtime Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-26932 Storage Spaces Direct Elevation of Privilege Vulnerability Important 8.2 No No EoP
CVE-2022-26938 Storage Spaces Direct Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-26939 Storage Spaces Direct Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29126 Tablet Windows User Interface Application Core Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-30129 Visual Studio Code Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29148 Visual Studio Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-26926 Windows Address Book Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-23279 Windows ALPC Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-26913 Windows Authentication Security Feature Bypass Vulnerability Important 7.4 No No SFB
CVE-2022-29135 Windows Cluster Shared Volume (CSV) Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29150 Windows Cluster Shared Volume (CSV) Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29151 Windows Cluster Shared Volume (CSV) Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29138 Windows Clustered Shared Volume Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29120 Windows Clustered Shared Volume Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-29122 Windows Clustered Shared Volume Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-29123 Windows Clustered Shared Volume Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-29134 Windows Clustered Shared Volume Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-29113 Windows Digital Media Receiver Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-29102 Windows Failover Cluster Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-29115 Windows Fax Service Remote Code Execution Vulnerability Important 7.8 No No RCE
CVE-2022-22011 Windows Graphics Component Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-26934 Windows Graphics Component Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-29112 Windows Graphics Component Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-26927 Windows Graphics Component Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-24466 Windows Hyper-V Security Feature Bypass Vulnerability Important 4.1 No No SFB
CVE-2022-29106 Windows Hyper-V Shared Virtual Disk Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29133 Windows Kernel Elevation of Privilege Vulnerability Important 8.8 No No EoP
CVE-2022-29142 Windows Kernel Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29116 Windows Kernel Information Disclosure Vulnerability Important 4.7 No No Info
CVE-2022-22012 Windows LDAP Remote Code Execution Vulnerability Important 9.8 No No RCE
CVE-2022-22013 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-22014 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29128 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29129 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29130 Windows LDAP Remote Code Execution Vulnerability Important 9.8 No No RCE
CVE-2022-29131 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29137 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29139 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-29141 Windows LDAP Remote Code Execution Vulnerability Important 8.8 No No RCE
CVE-2022-26933 Windows NTFS Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-22016 Windows PlayToManager Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29104 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-29132 Windows Print Spooler Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-29114 Windows Print Spooler Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-29140 Windows Print Spooler Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-29125 Windows Push Notifications Apps Elevation of Privilege Vulnerability Important 7 No No EoP
CVE-2022-29103 Windows Remote Access Connection Manager Elevation of Privilege Vulnerability Important 7.8 No No EoP
CVE-2022-26930 Windows Remote Access Connection Manager Information Disclosure Vulnerability Important 5.5 No No Info
CVE-2022-22015 Windows Remote Desktop Protocol (RDP) Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-26936 Windows Server Service Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-29121 Windows WLAN AutoConfig Service Denial of Service Vulnerability Important 6.5 No No DoS
CVE-2022-26935 Windows WLAN AutoConfig Service Information Disclosure Vulnerability Important 6.5 No No Info
CVE-2022-30130 .NET Framework Denial of Service Vulnerability Low 3.3 No No DoS

Looking at the remaining Critical-rated patches, there are two that affect the Windows implementation of Point-to-Point Tunneling Protocol (PPTP) that could allow an RCE. Microsoft notes an attacker would need to win a race condition to successfully exploit these bugs, but not every race condition is identical. In other words, an attacker may pull a Rich Strike and win that race. There’s a Critical-rated Elevation of Privilege (EoP) bug in Microsoft Kerberos, but no further information is provided. It’s unusual for an EoP to be rated Critical, so the privilege escalation must result in something beyond just a domain account. Finally, there’s another patch for the RDP Client, which seem to be coming at least once a month these days. An attacker would need to convince an affected system to connect to a specially crafted RDP server to gain code execution.

There are 20 other patches for RCE bugs in this month’s release, and half of those deal with LDAP vulnerabilities. The most severe of these clocks in with a CVSS of 9.8 but would require the MaxReceiveBuffer LDAP policy to be set to a value higher than the default value. It’s not clear if that is a common or rare configuration. The others would require some form of authentication. Three of the remaining RCEs came through the ZDI program. ZDI vulnerability researcher Hossein Lotfi discovered a bug in Windows Media Foundation that exists within the parsing of AVI files. The research known as ZhangYang found a heap overflow bug in Visual Studio, and Uncodable reported a use-after-free (UAF) bug in the Windows Graphic component. The remaining RCE bugs require some form of user interaction – mostly clicking on a link or opening a file. The only exception to this is the bugs in SharePoint, which requires an authenticated user with page creation permissions. By default, any authenticated user can create their own site where they have the necessary permissions.   

Moving on to EoP-related patches, there are 21 total privilege escalation bugs in the release, including the two previously mentioned. Most of these require an attacker to log on a run their specially crafted code or somehow convince (or trick) an authorized user to do so. However, there are a couple of patches that stand out. The most obvious is the patch for Exchange Server, which requires an admin to specifically prepare Active Directory before installing the patch. This entails running specific commands from the command prompt once the patch has been downloaded. Microsoft doesn’t indicate what could happen if these steps are not followed, but the bug allows an Exchange admin to become a Domain Admin, so ensure you take the appropriate steps to fully remediate this vulnerability. There’s a privilege escalation in the Remote Access Connection Manager, but without further details from Microsoft, it’s not clear how this vulnerability manifests. Finally, there are two EoP fixes for the Print Spooler, with one coming from Oliver Lyak through ZDI. The bug he reported could allow an attacker to create a symbolic link, which could then cause the service to load an arbitrary DLL.

Speaking of the Print Spooler, two of the 17 info disclosure bugs patched by this month’s release impact this component, and both were reported by Oliver through ZDI. These bugs result from the lack of proper validation of a user-supplied path prior to using it in file operations. An attacker can leverage these vulnerabilities to disclose information in the context of SYSTEM. Most of the other Info Disclosure bugs in this release only result in leaks consisting of unspecified memory contents. The other exception to this would be the bug in the Windows Server Service (aka LanManServer). Microsoft states that an attacker could confirm the presence of specific file names and users over an internal network, but they don’t state how this would occur.

There are four fixes for Security Feature Bypass (SFB) bugs in this release, and each one deserves a mention. The first relates to a Virtual Machine Switch with virtual networking in Hyper-V Network Virtualization (HNV). An attacker could bypass extended ACLs and other checks, which implies one guest OS could impact a different guest OS on the same server. Up next is a bug in Office that could allow an attacker to gain personally identifiable information (PII) by bypassing the “ThisDocument.RemovePersonalInformation” functionality. If you’re sharing files online but want your personal information removed, be sure to apply this update. The update for Windows Authentication addresses a vulnerability that could allow Man-in-the-Middle (MITM) attackers to decrypt and read or modify TLS traffic between the client and server. Finally, there is a bypass of BitLocker Device Encryption that requires physical access but could allow an attacker to gain access to encrypted data in certain scenarios. These final two bugs may be a bit unlikely to be seen in the wild, but if they are, the impact would be quite severe. Bugs like these are the ones sought by advanced threat actors for use on high-profile targets.

The May release is rounded out by six updates to address Denial-of-Service bugs in Hyper-V, the WLAN Autoconfig Service, and .NET and Visual Studio. The WLAN vulnerability is limited to a logically adjacent topology and can’t be reached from the internet. The bug in Hyper-V is listed as public, but Microsoft provides no information on where it was posted or how much detail was exposed. There are multiple DoS bugs listed for .NET and Visual Studio, but no further details are provided. One of these .NET bugs is the lone Low-severity bug in this release.

There is one new advisory for May covering improvements to Azure Data Factory and Azure Synapse Pipeline. This was previously mentioned (above) and is in response to CVE-2022-29972. While certainly not new, the latest servicing stack updates can be found in the revised ADV990001.

Looking Ahead

The next Patch Tuesday falls on June 14, and we’ll return with details and patch analysis then. Until then, stay safe, happy patching, and may all your reboots be smooth and clean! (And hope to see you in Vancouver!)

The May 2022 Security Update Review

What to Expect when Exploiting: A Guide to Pwn2Own Participation

So you’ve heard of Pwn2Own and think you are up to the challenge of competing in the world’s most prestigious hacking competition. Great! We would love to have you! However, there are a few things you should know before we get started. With Pwn2Own Vancouver just around the corner, here are 10 things you need to know before participating in Pwn2Own.

1.     You need to register before the contest.

We try to make this as apparent as possible in the rules, but we still have people walk into the room on the first day of the contest hoping to participate. There are a lot of logistics around Pwn2Own, so we need everyone to complete their registration before the contest starts. We can’t support anyone who wants to join on the first day of the competition.

2.     You need to answer the vetting email.

Again, the logistics of running the Pwn2Own competition can be daunting. One way we prepare is by vetting all entries before registration closes. We need to understand the nature of your exploit to ensure it fits within the rules and to ensure we have everything we need on hand to run the attempt. For example, we need to know how you plan on demonstrating if the exploit is successful. If you answer, “Our exploit will provide a root shell when it has succeeded” – we know you have a solid plan and that it is within the rules. If you tell us you need to start as an admin user and require four reboots, your entry is unlikely to qualify. We’ll also ask for things like other user interactions or the need for a Man-in-the-Middle (MitM). These could disqualify the entry – or it could be fine. It depends on the target and details, which is why we want to know before the competition. It’s not fair to any of the contestants to have them think their exploit is a winner just to be disqualified during the contest.

3.     What should we call you?

We know people enter Pwn2Own to win cash and prizes, but they want recognition, too. We’re more than happy to include your Twitter handle, your company name, or just about anything else. Just let us know. We try to pre-stage a lot of our communications, so an omission or misspelling could take a bit to get fixed, and we want to give contestants the attention they deserve. You’d be surprised how many people wait until during or after the event to clarify how they wish to be mentioned.

4.     Will you be participating locally or remotely?

This is a newer question but opening up the contest to remote participation has allowed many to participate that otherwise would not. However, remote contestants have a few extra hurdles the on-site participants do not. For remote participants, all artifacts must be submitted to the ZDI prior to registration closing. This includes things like the white paper, the exploit, and any further details needed for the entry. Contestants competing in person have until the contest begins to have these deliverables ready.

5.     Are you aware a white paper is required for each entry?

This is one aspect that many don’t realize. Each entry in Pwn2Own needs an accompanying white paper describing the vulnerabilities used during the attempt. These white papers are critical in the judging of the competition, especially if exploits from different contestants seem similar. For example, if two groups both use a use-after-free bug against a target, is it the same bug? Maybe. Maybe not. A clearly written white paper will help us understand your research and identify whether it is unique or a bug collision. It also helps the vendor pinpoint the exact place to look at when they start working on the fix.

6.     Ask questions before the competition.

There can be a lot of nuances in exploiting targets at Pwn2Own. How will we judge certain scenarios? How will the targets be configured? Does this type of exploit qualify for this bonus? Is the target in this configuration or that configuration? Is this software completely in the default configuration, or is this commonly applied setting used? There are a lot of very reasonable questions to ask before the contest, and we try to answer every one of them the best we can. If you are thinking about participating but have a specific configuration or rule-related questions, please e-mail us. Questions asked over Twitter or other means may not be answered in a timely manner. It might seem archaic to some, but e-mail makes it easier to track inquiries and ensure they get responses.

7.     Be prepared for things to go wrong.

Five minutes seems like plenty of time – until you’re on stage at Pwn2Own and there’s a clock counting down. If your first attempt fails, do you have a plan? What are you going to check? Can you adjust your exploit in a meaningful way within the allotted time? Certain types of exploits work better at Pwn2Own than others. For example, timing attacks and race conditions might not be the best choice to use at Pwn2Own. Yes, your exploit may work 100% of the time before you arrive at the contest, but what if it doesn’t when you’re on stage? Make a plan B, and probably a plan C and D as well.

8.     Are you participating as an individual, a part of a te