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.
Here are the current standings for the Master of Pwn:
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.
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.
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.
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!
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.
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.
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.
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.
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.
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
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:
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.
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!)
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 team, or representing a company?
While we do want maximum participation in each contest, we also need to place some restrictions on how that participation occurs. For example, if you are representing a company, you can’t also participate as an individual. If you are a part of a small team, you can’t also represent a company. This restriction helps keep the contest fair to everyone involved and prevents bug sharing meant to skew the overall results.
9. When you arrive at the contest, take a minute to confirm the target versions.
Before the contest begins – even before we do the drawing for order – we allow contestants to verify configurations and software versions of the targets. We always use the latest and greatest versions of available software as Pwn2Own targets, and vendors are known to release patches right before the competition in a last-ditch attempt to thwart contestants. It’s a good idea to take a minute and double-check the versions in the contest are the same versions you were testing back home. We will communicate the versions before the contest, so you will know what to target.
10. Rub a rabbit’s foot, grab a four-leafed clover, or do whatever else brings you luck.
Thanks to the drawing for order at the beginning of each contest, there is a degree of randomness to the competition. You could end up with a great spot in the schedule, or you could end up late in the contest when the chances for bug collisions are higher. But you can’t rely on luck, either. Some teams will just move on to a new target as soon as they find a bug to try to get as many entries in as possible and hope for a good draw - even if their bugs are low-hanging fruit. However, the teams that really want to compete for Master of Pwn spend a lot of time going deep and finding bugs other teams may miss. Pwn2Own is certainly a competition of skill but having a little luck (at least good luck) never hurts either.
Of course, there’s a lot more to participating in Pwn2Own than just these 10 things, but these will definitely help you prepare for the competition and, hopefully, increase your chances of winning. We really do root for all of the contestants, and we want to do all we can to increase your chances of success. Still, we need to adjudicate the contest fairly for all competitors. If you are on the fence about participating in Pwn2Own, I hope this guidance helps you find the right path to joining us. We celebrate the 15th anniversary of the contest this year in Vancouver, and we’d love to see you there.
What to Expect when Exploiting: A Guide to Pwn2Own Participation
Pwn2Own Miami for 2022 has wrapped up, and it was an amazing three days of competition. In total, we awarded $400,000 for 26 unique 0-days (plus a few bug collisions). With 90 points accumulated over three days, the team of Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) have won Master of Pwn! You can see all of the points and full results from all entries below.
Thanks again to all of the competitors who participated. We couldn’t have a contest without them. Thanks also to the participating vendors for their cooperation and for providing fixes for the bugs disclosed throughout the contest. As a reminder, vendors have 120 days to produce a fix for all vulnerabilities reported.
SUCCESS - 20urdjk was able to execute their DoS attack against Unified Automation C++ Demo Server. They earn $5,000 and 5 Master of Pwn points.
SUCCESS - Sam Thomas (@_s_n_t) from @pentestltd combined an auth bypass and a deserialization bug to get code execution. They win $20,000 and 20 points towards Master of Pwn.
SUCCESS - Or Peles, Omer Kaspi and Uriya Yavnieli from JFrog Security Research leveraged a Use-After-Free (UAF) bug to create a DoS on the Unified Automation C++ Demo Server. They win $5,000 and 5 Master of Pwn points.
SUCCESS - After a slight logistical delay, Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) used a deserialization bug to get their code executing on #Iconics Genesis64. They earn $20,000 and 20 Master of Pwn points.
SUCCESS - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) used a missing authentication for critical function vuln to execute code on Inductive Automation Ignition. They win $20,000 and 20 Master of Pwn points.
SUCCESS - Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) used an Uncontrolled Search Path bug in AVEVA Edge to execute their code. In doing so, they win $20,000 and 20 points towards Master of Pwn.
SUCCESS - The Claroty Research (@claroty) team of Noam Moshe, Vera Mens, Amir Preminger, Uri Katz, and Sharon Brizinov used a resource exhaustion bug to execute their DoS on the Prosys OPC UA SDK for Java. This wins them $5,000 and 5 Master of Pwn points.
SUCCESS - Axel '0vercl0k' Souchet of https://doar-e.github.io used a double free bug to execute his code on Iconics Genesis64. He wins $20,000 and 20 Master of Pwn points. You can watch a replay of this attempt here.
SUCCESS - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) used an uncontrolled search path vulnerability to get RCE in AVEVA Edge. They win $20,000 and 20 Master of Pwn points.
SUCCESS - 20urdjk used a file upload vulnerability on Inductive Automation Ignition to get RCE. He wins $20,000 and 20 more points towards Master of Pwn. His contest total is now $25,000 and 25 points.
SUCCESS - The Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) used a pair of bugs, including a directory traversal, to get code execution on Triangle Microworks SCADA Data Gateway. The win another $20,000 and 20 more Master of Pwn points.
BUG COLLISION - While the Claroty Research (@claroty) team of Noam Moshe, Vera Mens, Amir Preminger, Uri Katz, and Sharon Brizinov successfully demonstrated RCE against Iconics Genesis64, the bug used was one we already knew about. They still win $5,000 and 5 Master of Pwn points.
BUG COLLISION - The Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) were able to get code execution on Inductive Automation Ignition, but the bug they used was previously known. They still win $5,000 and 5 Master of Pwn points.
BUG COLLISION - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) successfully popped calc, but the bug they used had been disclosed earlier in the competition. They still win $5,000 and 5 Master of Pwn points.
SUCCESS - The Claroty Research (@claroty) team of Noam Moshe, Vera Mens, Amir Preminger, Uri Katz, and Sharon Brizinov used a resource exhaustion bug to perform a DoS on the OPC Foundation OPC UA .NET Standard. They earn $5,000 and 5 Master of Pwn points.
SUCCESS - Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) end Day One of Pwn2Own Miami 2022 by using a deserialization bug to execute code on AVEVA Edge. They win another $20,000 and 20 more Master of Pwn points. Their Day One total is $60,000 and 60 points.
Day Two - April 20, 2022
SUCCESS - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) used an infinite loop condition to create a DoS against the Unified Automation C++ Demo Server. They earn $5,000 and 5 points towards Master of Pwn.
SUCCESS - Piotr Bazydło (@chudyPB) used a deserialization bug to exploit Inductive Automation Ignition and execute his code on the system. He earns $20,000 and 20 Master of Pwn points.
SUCCESS - Ben McBride (@bdmcbri) used an exposed dangerous function bug to get RCE on Iconics Genesis64. He earns himself $20,000 and 20 Master of Pwn points.
SUCCESS - Or Peles, Omer Kaspi and Uriya Yavnieli from JFrog Security Research used a stack exhaustion bug to perform a DoS on the OPC Foundation OPC UA .NET Standard. They earn another $5,000 and 5 more Master of Pwn points.
BUG COLLISION - The Claroty Research (@claroty) team of Noam Moshe, Vera Mens, Amir Preminger, Uri Katz, and Sharon Brizinov did achieve RCE against AVEVA Edge, however the bug they used had been seen previously in the contest. They still earn $5,000 and 5 more Master of Pwn points.
FAILURE - Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) were unable to get their exploit of Inductive Automation Ignition working within the time allotted.
BUG COLLISION - Piotr Bazydło (@chudyPB) was able to get RCE on Iconics Genesis64, however the bug he used had been previously seen. He still earns $5,000 and 5 Master of Pwn points.
SUCCESS - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) used one of the more interesting bugs we've ever seen at a Pwn2Own to bypass the trusted application check on the OPC Foundation OPC UA .NET Standard. The earn $40,000 and 40 Master of Pwn points. Their contest total is now at $90,000 with a commanding lead in Master of Pwn.
BUG COLLISION - While Christopher Hernandez (@piffd0s) was able to show his RCE on AVEVA Edge, the bug he used was previous disclosed. He still earns $5,000 and 5 Master of Pwn points.
FAILURE - The Claroty Research (@claroty) team of Noam Moshe, Vera Mens, Amir Preminger, Uri Katz, and Sharon Brizinov were unable to get their DoS exploit of the Unified Automation C++ Demo Server working within the time allotted.
BUG COLLISION - The Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) did demonstrate their RCE on Iconics Genesis64, the bug used had been previously disclosed. They still win $5,000 and 5 Master of Pwn points.
SUCCESS - Piotr Bazydło (@chudyPB) used an untrusted search path bug to get code execution on AVEVA Edge. He wins another $20,000 and 20 Master of Pwn points. That brings his contest total to $45,000.
SUCCESS - The Claroty Research (@claroty) team of Noam Moshe, Vera Mens, Amir Preminger, Uri Katz, and Sharon Brizinov needed a little time, but they did get their amazing buffer overrun chain to achieve code execution against Kepware KEPServerEx. They earned $20,000 and 20 Master of Pwn points.
Day Three - April 21, 2022
SUCCESS - The Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) used a pair of bugs, including a directory traversal, to exploit the Softing Secure Integration server and run their code. They earn $20K and 20 Master of Pwn points. That brings their conference total to $80,000.
SUCCESS/BUG COLLISION - The Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) combined 3 bugs to get RCE on the Softing Secure Integration Server, but two were previously known. Their exploit chain earned them $10,000 and 10 Master of Pwn points. They end the contest with $40,000 total.
SUCCESS - The Claroty Research (@claroty) team of Noam Moshe, Vera Mens, Amir Preminger, Uri Katz, and Sharon Brizinov used a null pointer deref to perform their DoS on the Softing Secure Integration Server. They earn $5,000 and 5 Master of Pwn points, which brings their contest total to $45,000.
Welcome to Pwn2Own Miami 2022! This year’s ICS-focused event promises to be three days of great research and exploits, as we have 32 total entries from 11 contestants. 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 Eastern [GMT -4: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.
Tuesday, April 19
09:30 - 20urdjk targeting Unified Automation C++ Demo Server with a DoS in the OPC UA Server category
10:30 - @_s_n_t from @pentestltd targeting Inductive Automation Ignition with an RCE in the Control Server category
📷 11:30 - Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) targeting Iconics Genesis64 with an RCE in the Control Server category
11:30: Or Peles, Omer Kaspi and Uriya Yavnieli from JFrog Security Research targeting the Unified Automation C++ Demo Server with a DoS in the OPC UA Server category
13:00 - Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) targeting AVEVA Edge with an RCE in the Human Machine Interface category
13:00 - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) targeting Inductive Automation Ignition with an RCE in the Control Server category
📷 14:00 - Axel '0vercl0k' Souchet of https://doar-e.github.io targeting Iconics Genesis64 with an RCE in the Control Server category
14:00 - Claroty Research targeting the Prosys OPC UA SDK for Java with a DoS in the OPC UA Server category
15:00 - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) targeting AVEVA Edge with an RCE in the Human Machine Interface category
15:00 - 20urdjk targeting Inductive Automation Ignition with an RCE in the Control Server category
16:00 - Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) targeting Triangle Microworks SCADA Data Gateway with an RCE in the Data Gateway category
16:00 - Claroty Research (@claroty) targeting Iconics Genesis64 with an RCE in the Control Server category
📷 17:00 - Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) targeting Inductive Automation Ignition with an RCE in the Control Server category
18:00 - Claroty Research (@claroty) targeting the OPC Foundation OPC UA .NET Standard with a DoS in the OPC UA Server category
18:00 - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) targeting Iconics Genesis64 with an RCE in the Control Server category
19:00 - Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) targeting AVEVA Edge with an RCE in the Human Machine Interface category
Wednesday, April 20
09:30 - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) targeting the Unified Automation C++ Demo Server with a DoS in the OPC UA Server category
10:30 - Piotr Bazydło (@chudyPB) targeting Inductive Automation Ignition with an RCE in the Control Server category
11:30 - Or Peles, Omer Kaspi and Uriya Yavnieli from JFrog Security Research targeting the OPC Foundation OPC UA .NET Standard with an DoS in the OPC UA Server category
11:30 - Ben McBride (@bdmcbri) targeting Iconics Genesis64 with an RCE in the Control Server category
12:30 - Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) targeting Inductive Automation Ignition with an RCE in the Control Server category
12:30 - Claroty Research (@claroty) targeting AVEVA Edge with an RCE in the Human Machine Interface category
📷 13:30 - Daan Keuper (@daankeuper) and Thijs Alkemade (@xnyhps) from Computest Sector 7 (@sector7_nl) targeting the OPC Foundation OPC UA .NET Standard with a Bypass of the Trusted Application Check in the OPC UA Server category
13:30 - Piotr Bazydło (@chudypb) targeting Iconics Genesis64 with an RCE in the Control Server category
14:30 - Christopher Hernandez targeting AVEVA Edge with an RCE in the Human Machine Interface category
15:30 - Claroty Research (@claroty) targeting Unified Automation C++ Demo Server with a DoS in the OPC UA Server category
15:30 - Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) targeting Iconics Genesis64 with an RCE in the Control Server category
16:30 - Piotr Bazydło (@chudypb) targeting AVEVA Edge with an RCE in the Human Machine Interface category
📷 17:20 - Claroty Research (@claroty) targeting Kepware KEPServerEx with an RCE in the Data Gateway category
Thursday, April 21
09:30 - Incite Team of Steven Seeley (@steventseeley) and Chris Anastasio (@mufinnnnnnn) targeting Softing Secure Integration Server with an RCE in the OPC UA Server category
10:30 - Flashback Team of Pedro Ribeiro (@pedrib1337) and Radek Domanski (@RabbitPro) targeting Softing Secure Integration Server with an RCE in the OPC UA Server category
11:30 - Claroty Research (@claroty) targeting the Softing Secure Integration Server with a DoS in the OPC UA Server category
We’ll be posting updates on our Twitter page, and look for live video updates on Twitter as well. We wish all contestants good luck, and may all your exploits be unique and effective.
Another Patch Tuesday is upon, 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 April 2022
For April, Adobe released four updates addressing 70 CVEs in Acrobat and Reader, Photoshop, After Effects, and Adobe Commerce. The update for Acrobat and Reader is by far the largest, with 62 CVEs being addressed. A total of 54 of these CVEs were reported through the ZDI program, with ZDI vulnerability analyst Mat Powell responsible for 27 of these. The more severe vulnerabilities being fixed are the Critical-Rated Use-After-Free (UAF) and Out-of-Bounds (OOB) Write bugs. These could allow an attacker to execute code on a target system if they can convince a user to open a specially crafted PDF document. There are 13 CVEs fixed in the patch for Photoshop, and all of these were reported through the ZDI program. All the vulnerabilities addressed by this patch address Critical-rated code execution bugs. Again, an attacker would need to convince a user to open a specially crafted file to gain code execution.
The update for After Effects addresses two Critical-rated CVEs that could allow for code execution. Both bugs are listed as stack-based buffer overflows. Finally, the patch for Adobe Commerce fixes a single, Critical-rated vulnerability. Adobe rates this as a CVSS 9.1, but they also point out authentication would be required to exploit this bug. They also note admin privileges are required, so the high CVSS is somewhat puzzling. Still, if you’re using Commerce, test and deploy this patch as soon as you are able.
None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release.
Microsoft Patches for April 2022
This month, Microsoft released 128 new patches addressing CVEs in Microsoft Windows and Windows Components, Microsoft Defender and Defender for Endpoint, Microsoft Dynamics, Microsoft Edge (Chromium-based), Exchange Server, Office and Office Components, SharePoint Server, Windows Hyper-V, DNS Server, Skype for Business, .NET and Visual Studio, Windows App Store, and Windows Print Spooler Components. This is in addition to the 17 CVEs consumed from the Chromium Open-Source Software (OSS) by Microsoft Edge (Chromium-based), which brings the April total to 145 CVEs.
Of the 128 new CVEs released today, 10 are rated Critical, 115 are rated Important, and three are rated Moderate in severity. A total of six of these bugs came through the ZDI program. This large volume of patches hasn’t been seen since the fall of 2020. However, this level is similar to what we saw in the first quarter of last year.
One of the bugs patched is listed as under active exploit this month, and one other is 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 a Critical-rated bug that could prove wormable:
- CVE-2022-26809 - RPC Runtime Library Remote Code Execution Vulnerability This bug is rated as a CVSS 9.8, and the exploit index notes exploitation is more likely. The vulnerability could allow a remote attacker to executed code at high privileges on an affected system. Since no user interaction is required, these factors combine to make this wormable, at least between machine where RPC can be reached. However, the static port used here (TCP port 135) is typically blocked at the network perimeter. Still, this bug could be used for lateral movement by an attacker. Definitely test and deploy this one quickly.
- CVE-2022-24491/24497 – Windows Network File System Remote Code Execution Vulnerability Speaking of nearly wormable bugs, these two NFS vulnerabilities also rate a 9.8 CVSS and are listed as exploitation more likely. On systems where the NFS role is enabled, a remote attacker could execute their code on an affected system with high privileges and without user interaction. Again, that adds up to a wormable bug – at least between NFS servers. Similar to RPC, this is often blocked at the network perimeter. However, Microsoft does provide guidance on how the RPC port multiplexer (port 2049) “is firewall-friendly and simplifies deployment of NFS.” Check your installations and roll out these patches rapidly.
- CVE-2022-26815 - Windows DNS Server Remote Code Execution Vulnerability This vulnerability is the most severe of the 18(!) DNS Server bugs receiving patches this month. This bug is also very similar to one patched back in February, which makes one wonder if this bug is the result of a failed patch. There are a couple of important mitigations to point out here. The first is that dynamic updates must be enabled for a server to be affected by this bug. The CVSS also lists some level of privileges to exploit. Still, any chance of an attacker getting RCE on a DNS server is one too many, so get your DNS servers patched.
- CVE-2022-26904 - Windows User Profile Service Elevation of Privilege Vulnerability This is one of the publicly known bugs patched this month, and not only is PoC out there for it, there’s a Metasploit module as well. This privilege escalation vulnerability allows an attacker to gain code execution at SYSTEM level on affected systems. They would, of course, need some level privileges before they could escalate. That’s why these types of bugs are often paired with code execution bugs like the ones in Adobe Reader (mentioned above) to completely take over a system.
Here’s the full list of CVEs released by Microsoft for April 2022:
Chromium: Inappropriate implementation in
* Indicates this CVE had previously been released by a 3rd-party and is now being incorporated into Microsoft products.
We should also call attention CVE-2022-24521, which is a bug in the Windows Common Log File System Driver and listed as under active attack. Since this vulnerability only allows a privilege escalation, it is likely paired with a separate code execution bug. We should also point out that this was reported by the National Security Agency. It’s not stated how widely the exploit is being used in the wild, but it’s likely still targeted at this point and not broadly available. Go patch your systems before that situation changes.
Looking at the remaining Critical-rated bugs patched this month, there are three RCE vulnerabilities impacted the Hyper-V server. In these cases, someone on a guest OS could gain code execution on the underlying host OS. There’s a bug in the LDAP service that’s remote and does not require user interaction. However, to be affected, the default setting for MaxReceiveBuffer LDAP setting must be changed. This isn’t something that’s commonly tweaked, but if your environment has this setting, pay attention to this one. There are Critical patches for SMB and the Server service. In both cases, a user must connect to a malicious share, which would typically require some form of social engineering – like a link in an email or instant message. This is yet another port (TCP 445) that should be blocked at the perimeter. Finally, there’s an update for Microsoft Dynamics 365 (on prem). This vulnerability requires a user to run a specially crafted trusted solution package to execute arbitrary SQL commands. This would allow an attacker to escalate and execute commands with the privileges of the db_owner.
Moving on to the Important-rated patches, the first that stand out are the bunches of fixes for some all too familiar components. We’ve already mentioned the 18 fixes for the DNS Server component. Most of these have multiple mitigations, but many could allow remote code execution. There’s one info disclosure bug thrown in there for good measure. Despite this component being around for years, it seems there are still bugs to find. There are also 15 patches for the Print Spooler this month. Ever since PrintNightmare last year, print spooler bugs seem to just keep coming. It makes sense as the printing system is complex and offers attackers a broad attack surface. Let’s hope these patches don’t cause the types of problems introduced by some the other printer-related patches. And when it comes to large groups of patches, there are a mountain of CVEs affecting the Edge (Chromium-based) browser as well. Most of these bugs were patched by Google and consumed by Edge earlier this month. However, this demonstrates the risk of everyone relying on the same browser platform. A bug in one is now shared by many.
In total, there are 47 patches to correct RCE bugs in this month’s patch. Beyond those already mentioned, there’s yet another RDP client bug that would allow code execution if a user connected to a malicious RDP server. If that sounds familiar, there was a similar bug last month (and more going back months prior). There are a few open-and-own bug in Office components, most notably Excel. The chances of people applying patches to Excel before April 15 seem low, so let’s hope these bugs don’t get exploited. There are a couple of intriguing bugs affecting Win32 file enumeration, although these also require a user to connect to a malicious server or share. There hasn’t been much research on this component, so it will be interesting to see if further bugs are found. Finally, there’s an RCE in Kerberos, but to be affected, the system needs Restricted Admin or Windows Defender Remote Credential Guard enabled on a box with Remote Desktop Connections configured. It’s not clear how common this configuration is, but you should check your systems and apply the update as needed.
The April release includes 59 patches to address Elevation of Privilege (EoP) bugs this month. For the most part, these are in Windows components and would need to be paired with an RCE to allow an attacker to take over a system. A few do stand out. The first is a vulnerability in the Windows Telephony Server that was reported by ZDI vulnerability researcher Simon Zuckerbraun. This flaw exists within the CreateObjectHandler COM object. Crafted method invocations on this object can trigger the deserialization of untrusted data. There are also a pair of bugs in Azure Site Recovery that should be called out as well. Don’t let the admin credential requirement fool you. This bug applies to the VMWare-to-Azure scenario, and administrators will need to upgrade to the latest version to mitigate these vulns.
There are 10 fixes address that address information disclosure bugs. For the most part, these only result in leaks consisting of unspecified memory contents. The lone exception is the bug impacting the Skype for Business. This vulnerability could inadvertently disclose file content to an attacker, but Microsoft doesn’t specific if any file content can be exposed or if just files in specific locations.
April brings eight updates to address DoS bugs, and a few stand out over the others. There’s a DoS in Microsoft Defender, but Microsoft provides no details. Another is a DoS bug in Hyper-V, which is always inconvenient if you happen to be one of the other guest OSes on that Hyper-V server. There are a trio of DoS vulnerabilities in the Windows Cluster Shared Volume (CSV) component, but again, Microsoft provides not details on how the DoS manifests. There are also no details provided about the DoS in Windows Secure Channel, but considering how much relies on schannel these days, definitely don’t take this update lightly.
This month’s update is rounded out by three updates addressing spoofing bugs. The spoofing bug in SharePoint could allow an authenticated user to send malicious content in SIP Address field. This would allow the user to have access to content that is otherwise not authorized. The spoofing vulnerability in Skype for Business and Lync could expose IP addresses or port numbers to an attacker. Finally, the patch for Power BI requires multiple uses hitting the gateway at the same time. While this can likely be scripted, it does increase the attack complexity.
No new advisories were released this month. The latest servicing stack updates can be found in the revised ADV990001.
The next Patch Tuesday falls on May 10, 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!
Memory corruption vulnerabilities have been well known for a long time and programmers have developed various methods to prevent them. One type of memory corruption that is very hard to prevent is the use-after-free and the reason is that it has too many faces! Since it cannot be associated with any specific pattern in source code, it is not trivial to eliminate this vulnerability class. In this blog, a use-after-free vulnerability in Mozilla Firefox will be explained which has been assigned CVE-2022-26381. The Mozilla bug entry 1756793 is still closed to the public as of this writing, but the Zero Day Initiative advisory page ZDI-22-502 can provide a bit more information.
What Is a Use-After-Free Vulnerability?
A use-after-free (UAF) vulnerability happens when a pointer to a freed object is accessed. It does not make sense! Why would a programmer free an object and afterward access it again?
It happens due to the complexity of today’s software. A browser, for example, has many components and each of them may allocate different objects. They may even pass these objects to each other for processing. A component may free an object when it is done using it, while other components still have a pointer to that object. Any dereference of that pointer can lead to a use-after-free vulnerability.
Let’s start quickly by having a look at the minimized proof-of-concept:
When running this on the latest vulnerable release version of Mozilla Firefox, which is 97.0.1, it gives a very promising crash:
This is what the crash point looks like in IDA. It happens inside a loop:
It dereferences a value from memory and then makes an indirect call (a virtual function call) using the fetched value. Thus, this is rated as a remote code execution vulnerability. The value of the “rax” register which is used during dereferencing is particularly interesting: 0xE5E5E5E5E5E5E5E5. This is a magic value that Firefox uses to “poison” the memory of a freed object so that a dereference of a value fetched from that freed object will cause a crash, as this value is never a valid memory address. This helps greatly to catch use-after-free conditions.
To analyze a use-after-free vulnerability, it is always desired to have more information about the freed object: its type, size, where it is allocated, where it is freed, and where it is subsequently used. On Windows, this is usually done by enabling advanced debugging features using the GFlags tool to enable various global flags. Specifically, it can be used to enable pageheap and create a user-mode stack trace to capture the stack trace at the time a particular object is allocated. Unfortunately, this will not help us on Mozilla Firefox, because Firefox has its own memory management mechanism called jemalloc. The way we can get more information about the object is to run the PoC on an ASAN version of Firefox. You can see the result below:
We got lots of information. Let’s break it down a bit by checking where the object is allocated:
Let’s further check this by looking at the source code (line 1164 of /builds/worker/checkouts/gecko/layout/svg/SVGObserverUtils.cpp). You can download the source code of Firefox 97.0.1 or use the online version (note that line numbers of the online version may not match, as it gets updated constantly):
And this is how it looks in the compiled release version:
So the object size is 0x70 (112) bytes and it is used to store and track properties of frames during reflow triggered by scrolling.
Then we want to know where it is freed and reused. ASAN provides a long stack trace. A closer look gives a good hint. Let’s first check the stack trace when the object is freed:
And now the stack trace when the object is subsequently used:
We can see the “mozilla::SVGRenderingObserverSet::InvalidateAll” function in the stack trace when the crash happens and when the object free is initiated. This also matches the crash point of the release version which is inside the OnNonDOMMutationRenderingChange function (it says it is inlined in xul!mozilla::SVGRenderingObserverSet::InvalidateAll). We can now make an initial educated guess: while an object was being processed in a loop in the “mozilla::SVGRenderingObserverSet::InvalidateAll” function, a code path was reached that freed the object being processed, leading to a use-after-free vulnerability.
Now that we have all the details, we can validate this hypothesis step-by-step by running the PoC on the released version of Firefox.
First, we want to know the address of an allocated object so we can monitor it. This can easily be achieved by setting a breakpoint that prints the address of the object upon allocation:
Then, let’s see how the objects are processed in the loop we saw in IDA inside the “mozilla::SVGRenderingObserverSet::InvalidateAll” function. We will print the address of the object that is going to be processed. We also set a breakpoint on the subsequent virtual function call:
We run the PoC, and the debugger stops before calling the virtual function. As you can see, two objects are allocated and these two are going to be processed in the loop. First, one object is processed and a call to the “SVGTextPathObserver::OnRenderingChange” function is made, which eventually frees various allocated objects including the second object which is awaiting processing!
We can see this clearly in the picture below, which is taken immediately after the return from the call. As you can see, the second object has been freed (and poisoned with 0xe5) during the processing of the first object:
In the second iteration, the freed object is loaded for processing, leading to a load of the poison value and resulting in a crash:
Release Versus ASAN Behavior
When running the PoC against the release version, we got a crash during a dereference of 0xE5E5E5E5E5E5E5E5. However, in the ASAN version, it crashed when writing to memory. Why is there a difference? The reason is as follows:
In a release (non-ASAN) build, when freeing an object, its memory remains accessible (not unmapped), and thus any read and write to that memory will still succeed without triggering an immediate crash. That is why the instruction “mov byte ptr [rcx+8], 0” in the above picture executed without error. A crash is likely to occur further along, though. As in our case, if a value is fetched value from a freed object and then dereferenced, the dereference may cause a crash. This is especially true if the freed object content is overwritten by “poison” values as seen above. Note that there is a chance that there will be no crash at all, for example, if there are only reads and writes to the freed object without any dereference operations on fetched values, or if the poison value becomes overwritten with unrelated data. This means that if we fuzz a release version, there is a chance we could miss a vulnerability.
ASAN, on the other hand, monitors all read, write, and dereferences on memory and can catch such vulnerabilities as soon as possible. That is why it is recommended to use an ASAN version for fuzzing.
Use-after-free vulnerabilities are often fixed by converting raw pointers to smart pointers or by correcting the management of the object reference count. Here, it was fixed by changing how continuations frame reflows are handled in the engine:
Developers have expended a great deal of effort to eliminate vulnerabilities associated with known patterns in source code, and they have mostly succeeded in decreasing their prevalence. However, there are some classes of vulnerabilities that are harder to prevent, and use-after-free is one of them. Assuring perfect management of object lifecycles in software with a million lines of code is extremely difficult. This is one of the main motivations behind languages like Rust that enforce proper object ownership and lifetime management.
You can find me on Twitter at @hosselot and follow the team for the latest in exploit techniques and security patches.
CVE-2022-26381: Gone by others! Triggering a UAF in Firefox
What do you do when you’ve found an arbitrary file delete as NT AUTHORITY\SYSTEM? Probably just sigh and call it a DoS. Well, no more. In this article, we’ll show you some great techniques for getting much more out of your arbitrary file deletes, arbitrary folder deletes, and other seemingly low-impact filesystem-based exploit primitives.
The Trouble with Arbitrary File Deletes
When you consider how to leverage an arbitrary file delete on Windows, two great obstacles present themselves:
Most critical Windows OS files are locked down with DACLs that prevent modification even by SYSTEM. Instead, most OS files are owned by TrustedInstaller, and only that account has permission to modify them. (Exercise for the reader: Find the critical Windows OS files that can still be deleted or overwritten by SYSTEM!)
Even if you find a file that you can delete as SYSTEM, it needs to be something that causes a “fail-open” (degradation of security) if deleted.
A third problem that can arise is that some critical system files are inaccessible at all times due to sharing violations.
Experience shows that finding a file to delete that meets all the above criteria is very hard. When looking in the usual places, which would be within C:\Windows, C:\Program Files or C:\Program Data, we’re not aware of anything that fits the bill. There is some prior work that involves exploiting antivirus and other products, but this is dependent on vulnerable behavior in those products.
The Solution is Found Elsewhere: Windows Installer
In March of 2021, we received a vulnerability report from researcher Abdelhamid Naceri (halov). The vulnerability he reported was an arbitrary file delete in the User Profile service, running as SYSTEM. Remarkably, his submission also included a technique to parlay this file delete into an escalation of privilege (EoP), resulting in a command prompt running as SYSTEM. The EoP works by deleting a file, but not in any of the locations you would usually think of.
To understand the route to privilege escalation, we need to explain a bit about the operation of the Windows Installer service. The following explanation is simplified somewhat.
The Windows Installer service is responsible for performing installations of applications. An application author supplies an .msi file, which is a database defining the changes that must be made to install the application: folders to be created, files to be copied, registry keys to be modified, custom actions to be executed, and so forth.
To ensure that system integrity is maintained when an installation cannot be completed, and to make it possible to revert an installation cleanly, the Windows Installer service enforces transactionality. Each time it makes a change to the system, Windows Installer makes a record of the change, and each time it overwrites an existing file on the system with a newer version from the package being installed, it retains a copy of the older version. In case the install needs to be rolled back, these records allow the Windows Installer service to restore the system to its original state. In the simplest scenario, the location for these records is a folder named C:\Config.Msi.
During an installation, the Windows Installer service creates a folder named C:\Config.Msi and populates it with rollback information. Whenever the install process makes a change to the system, Windows Installer records the change in a file of type .rbs (rollback script) within C:\Config.Msi. Additionally, whenever the install overwrites an older version of some file with a newer version, Windows Installer will place a copy of the original file within C:\Config.Msi. This type of a file will be given the .rbf (rollback file) extension. In case an incomplete install needs to be rolled back, the service will read the .rbs and .rbf files and use them to revert the system to the state that existed before the install.
This mechanism must be protected against tampering. If a malicious user were able to alter the .rbs and/or .rbf files before they are read, arbitrary changes to the state of the system could occur during rollback. Therefore, Windows Installer sets a strong DACL on C:\Config.Msi and the enclosed files.
Here is where an opening arises, though: What if an attacker has an arbitrary folder delete vulnerability? They can use it to completely remove C:\Config.Msi immediately after Windows Installer creates it. The attacker can then recreate C:\Config.Msi with a weak DACL (note that ordinary users are allowed to create folders at the root of C:\). Once Windows Installer creates its rollback files within C:\Config.Msi, the attacker will be able to replace C:\Config.Msi with a fraudulent version that contains attacker-specified .rbs and .rbf files. Then, upon rollback, Windows Installer will make arbitrary changes to the system, as specified in the malicious rollback scripts.
Note that the only required exploit primitive here is the ability to delete an empty folder. Moving or renaming the folder works equally well.
From Arbitrary Folder Delete/Move/Rename to SYSTEM EoP
In conjunction with this article, we are releasing source code for Abdelhamid Naceri’s privilege escalation technique. This exploit has wide applicability in cases where you have a primitive for deleting, moving, or renaming an arbitrary empty folder in the context of SYSTEM or an administrator. The exploit should be built in the Release configuration for either x64 or x86 to match the architecture of the target system. Upon running the exploit, it will prompt you to initiate a delete of C:\Config.Msi. You can do this by triggering an arbitrary folder delete vulnerability, or, for testing purposes, you can simply run rmdir C:\Config.Msi from an elevated command prompt. Upon a successful run, the exploit will drop a file to C:\Program Files\Common Files\microsoft shared\ink\HID.DLL. You can then get a SYSTEM command prompt by starting the On-Screen Keyboard osk.exe and then switching to the Secure Desktop, for example by pressing Ctrl-Alt-Delete.
The exploit contains an .msi file. The main thing that’s special about this .msi is that it contains two custom actions: one that produces a short delay, and a second that throws an error. When the Windows Installer service tries to install this .msi, the installation will halt midway and rollback. By the time the rollback begins, the exploit will have replaced the contents of C:\Config.Msi with a malicious .rbs and .rbf. The .rbf contains the bits of the malicious HID.DLL, and the .rbs instructs Windows Installer to “restore” it to our desired location (C:\Program Files\Common Files\microsoft shared\ink\).
The full mechanism of the EoP exploit is as follows:
The EoP creates a dummy C:\Config.Msi and sets an oplock.
The attacker triggers the folder delete vulnerability to delete C:\Config.Msi (or move C:\Config.Msi elsewhere) in the context of SYSTEM (or admin). Due to the oplock, the SYSTEM process is forced to wait.
Within the EoP, the oplock callback is invoked. The following several steps take place within the callback.
The EoP moves the dummy C:\Config.Msi elsewhere. This is done so that the oplock remains in place and the vulnerable process is forced to continue waiting, while the filesystem location C:\Config.Msi becomes available for other purposes (see further).
The EoP spawns a new thread that invokes the Windows Installer service to install the .msi, with UI disabled.
The callback thread of the EoP continues and begins polling for the existence of C:\Config.Msi. For reasons that are not clear to me, Windows Installer will create C:\Config.Msi, use it briefly for a temp file, delete it, and then create it a second time to use for rollback scripts. The callback thread polls C:\Config.Msi to wait for each of these actions to take place.
As soon as the EoP detects that Windows Installer has created C:\Config.Msi for the second time, the callback thread exits, releasing the oplock. This allows the vulnerable process to proceed and delete (or move, or rename) the C:\Config.Msi created by Windows Installer.
The EoP main thread resumes. It repeatedly attempts to create C:\Config.Msi with a weak DACL. As soon as the vulnerable process deletes (or moves, or renames) C:\Config.Msi, the EoP’s create operation succeeds.
The EoP watches the contents of C:\Config.Msi and waits for Windows Installer to create an .rbs file there.
The EoP repeatedly attempts to move C:\Config.Msi elsewhere. As soon as Windows Installer closes its handle to the .rbs, the move succeeds, and the EoP proceeds.
The EoP creates C:\Config.Msi one final time. Within it, it places a malicious .rbs file having the same name as the original .rbs. Together with the .rbs, it writes a malicious .rbf.
After the delay and the error action specified in the .msi, Windows Installer performs a rollback. It consumes the malicious .rbs and .rbf, dropping the DLL.
Note that at step 7, there is a race condition that sometimes causes problems. If the vulnerable process does not immediately awaken and delete C:\Config.Msi, the window of opportunity may be lost because Windows Installer will soon open a handle to C:\Config.Msi and begin writing an .rbs there. At that point, deleting C:\Config.Msi will no longer work, because it is not an empty folder. To avoid this, it is recommended to run the EoP on a system with a minimum of 4 processor cores. A quiet system, where not much other activity is taking place, is probably ideal. If you do experience a failure, it will be necessary to retry the EoP and trigger the vulnerability a second time.
From Arbitrary File Delete to SYSTEM EoP
The technique described above assumes a primitive that deletes an arbitrary empty folder. Often, though, one has a file delete primitive as opposed to a folder delete primitive. That was the case with Abdelhamid Naceri’s User Profile bug. To achieve SYSTEM EoP in this case, his exploit used one additional trick, which we will now explain.
In NTFS, the metadata (index data) associated with a folder is stored in an alternate data stream on that folder. If the folder is named C:\MyFolder, then the index data is found in a stream referred to as C:\MyFolder::$INDEX_ALLOCATION. Some implementation details can be found here. For our purposes, though, what we need to know is this: deleting the ::$INDEX_ALLOCATION stream of a folder effectively deletes the folder from the filesystem, and a stream name, such as C:\MyFolder::$INDEX_ALLOCATION, can be passed to APIs that expect the name of a file, including DeleteFileW.
So, if you are able to get a process running as SYSTEM or admin to pass an arbitrary string to DeleteFileW, then you can use it not only as a file delete primitive but also as a folder delete primitive. From there, you can get a SYSTEM EoP using the exploit technique discussed above. In our case, the string you want to pass is C:\Config.Msi::$INDEX_ALLOCATION.
Be advised that success depends on the particular code present in the vulnerable process. If the vulnerable process simply calls DeleteFileA/DeleteFileW, you should be fine. In other cases, though, the privileged process performs other associated actions, such as checking the attributes of the specified file. This is why you cannot test this scenario from the command prompt by running del C:\Config.Msi::$INDEX_ALLOCATION.
From Folder Contents Delete to SYSTEM EoP
Leveling up once more, let us suppose that the vulnerable SYSTEM process does not allow us to specify an arbitrary folder or file to be deleted, but we can get it to delete the contents of an arbitrary folder, or alternatively, to recursively delete files from an attacker-writable folder. Can this also be used for EoP? Researcher Abdelhamid Naceri demonstrated this as well, in a subsequent submission in July 2021. In this submission he detailed a vulnerability in the SilentCleanup scheduled task, running as SYSTEM. This task iterates over the contents of a temp folder and deletes each file it finds there. His technique was as follows:
Create a subfolder, temp\folder1.
Create a file, temp\folder1\file1.txt.
Set an oplock on temp\folder1\file1.txt.
Wait for the vulnerable process to enumerate the contents of temp\folder1 and try to delete the file file1.txt it finds there. This will trigger the oplock.
When the oplock triggers, perform the following in the callback: a. Move file1.txt elsewhere, so that temp\folder1 is empty and can be deleted. We move file1.txt as opposed to just deleting it because deleting it would require us to first release the oplock. This way, we maintain the oplock so that the vulnerable process continues to wait, while we perform the next step. b. Recreate temp\folder1 as a junction to the ‘\RPC Controlfolder of the object namespace.
c. Create a symlink at\RPC Control\file1.txtpointing toC:\Config.Msi::$INDEX_ALLOCATION`.
When the callback completes, the oplock is released and the vulnerable process continues execution. The delete of file1.txt becomes a delete of C:\Config.Msi.
Readers may recognize the symlink technique involving \RPC Control from James Forshaw’s symboliclink-testing-tools. Note, though, that it’s not sufficient to set up the junction from temp\folder1 to \RPC Control and then let the arbitrary file delete vulnerability do its thing. That’s because \RPC Control is not an enumerable file system location, so the vulnerable process would not be able to find \RPC Control\file1.txt via enumeration. Instead, we must start off by creating temp\folder1\file1.txt as a bona fide file, allowing the vulnerable process to find it through enumeration. Only afterward, just as the vulnerable process attempts to open the file for deletion, we turn temp\folder1 into a junction pointing into the object namespace.
For working exploit code, see project FolderContentsDeleteToFolderDelete. Note that the built-in malware detection in Windows will flag this process and shut it down. I recommend adding a “Process” exclusion for FolderContentsDeleteToFolderDelete.exe.
You can chain these two exploits together. To begin, run FolderOrFileDeleteToSystem and wait for it to prompt you to trigger privileged deletion of Config.Msi. Then, run FolderContentsDeleteToFolderDelete /target C:\Config.Msi. It will prompt you to trigger privileged deletion of the contents of C:\test1. If necessary for your exploit primitive, you can customize this location using the /initial command-line switch. For testing purposes, you can simulate the privileged folder contents deletion primitive by running del /q C:\test1\* from an elevated command prompt. FolderContentsDeleteToFolderDelete will turn this into a delete of C:\Config.Msi, and this will enable FolderOrFileDeleteToSystem to drop the HID.DLL. Finally, open the On-Screen Keyboard and hit Ctrl-Alt-Delete for your SYSTEM shell.
From Arbitrary Folder Create to Permanent DoS
Before closing, we’d like to share one more technique we learned from this same researcher. Suppose you have an exploit primitive for creating an arbitrary folder as SYSTEM or admin. Unless the folder is created with a weak DACL, it doesn’t sound like this would be something that could have any security impact at all. Surprisingly, though, it does: it can be used for a powerful denial of service. The trick is to create a folder such as this one:
Normally there is no file or folder by that name. If an attacker name squats on that filesystem location with an extraneous file or even an empty folder, the Windows boot process is disrupted. The exact mechanism is a bit of a mystery. It would appear that Windows attempts to load the cng.sys kernel module from the improper location and fails, and there is no retry logic that allows it to continue and locate the proper driver. The result is a complete inability to boot the system. Other drivers can be used as well for the same effect.
Depending on the vulnerability at hand, this DoS exploit could even be a remote DoS, as nothing is required besides the ability to drop a single folder or file.
The techniques we’ve presented here show how some rather weak exploit primitives can be used for great effect. We have learned that:
• An arbitrary folder delete/move/rename (even of an empty folder), as SYSTEM or admin, can be used to escalate to SYSTEM. • An arbitrary file delete, as SYSTEM or admin, can usually be used to escalate to SYSTEM. • A delete of contents of an arbitrary folder, as SYSTEM or admin, can be used to escalate to SYSTEM. • A recursive delete, as SYSTEM or admin, of contents of a fixed but attacker-writable folder (such as a temp folder), can be used to escalate to SYSTEM. • An arbitrary folder create, as SYSTEM or admin, can be used for a permanent system denial-of-service. • An arbitrary file delete or overwrite, as SYSTEM or admin, even if there is no control of contents, can be used for a permanent system denial-of-service.
We would like to thank researcher Abdelhamid Naceri for his great work in developing these exploit techniques, as well as for the vulnerabilities he has been reporting to our program. We look forward to seeing more from him in the future. Until then, you can find me on Twitter at @HexKitchen, and follow the team for the latest in exploit techniques and security patches.
Abusing Arbitrary File Deletes to Escalate Privilege and Other Great Tricks
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 March 2022
The Adobe release for March is quite small. This month, Adobe released only three patches addressing six CVEs in Adobe Photoshop, Illustrator, and After Effects. The patch for After Effects is the largest of the three. It fixes four Critical-rated, stacked-based buffer overflows that could result in arbitrary code execution. The fix for Illustrator is also rated Critical. It addresses a single buffer overflow that could lead to arbitrary code execution. Finally, the update for Photoshop fixes a single Important-rated memory leak.
None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release.
Microsoft Patches for March 2022
For March, Microsoft released 71 new patches addressing CVEs in Microsoft Windows and Windows Components, Azure Site Recovery, Microsoft Defender for Endpoint and IoT, Intune, Edge (Chromium-based), Windows HTML Platforms, Office and Office Components, Skype for Chrome, .NET and Visual Studio, Windows RDP, SMB Server, and Xbox. This is in addition to the 21 CVEs patched by Microsoft Edge (Chromium-based) earlier this month, which brings the March total to 92 CVEs.
Of the 71 CVEs released today, three are rated Critical and 68 are rated Important in severity. A total of seven of these bugs came through the ZDI program. Historically speaking, this is volume is in line with previous March releases. However, the number of Critical-rated patches is again strangely low for this number of bugs. It’s unclear if this low percentage of bugs is just a coincidence or if Microsoft might be evaluating the severity using different calculus than in the past.
None of the bugs are listed as under active exploit this month, while three 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 one of the bugs listed as publicly known:
- CVE-2022-21990 – Remote Desktop Client Remote Code Execution Vulnerability This client-side bug doesn’t have the same punch as server-side related RDP vulnerabilities, but since it’s listed as publicly known, it makes sense to go ahead and treat this as a Critical-rated bug. If an attacker can lure an affected RDP client to connect to their RDP server, the attacker could trigger code execution on the targeted client. Again, this isn’t as severe as BlueKeep or some of the other RDP server bugs, but it definitely shouldn’t be overlooked.
- CVE-2022-23277 – Microsoft Exchange Server Remote Code Execution Vulnerability This Critical-rated bug in Exchange Server was reported by long-time ZDI contributor Markus Wulftange. The vulnerability would allow an authenticated attacker to execute their code with elevated privileges through a network call. This is also listed as low complexity with exploitation more likely, so it would not surprise me to see this bug exploited in the wild soon - despite the authentication requirement. Test and deploy this to your Exchange servers quickly.
- CVE-2022-24508 – Windows SMBv3 Client/Server Remote Code Execution Vulnerability This bug could allow an attacker to execute code on Windows 10 version 2004 and newer systems. It’s also reminiscent of CVE-2020-0796 from a couple of years ago. Both also list disabling SMBv3 compression as a workaround for SMB servers, but this doesn’t help clients. In 2020, Microsoft noted SMBv3 compression “is not yet used by Windows or Windows Server and disabling SMB Compression has no negative performance impact.” That’s not in the current advisory, so it’s unclear what disabling this feature will have now. Authentication is required here, but since this affected both clients and servers, an attacker could use this for lateral movement within a network. This is another one I would treat as Critical and mitigate quickly.
- CVE-2022-21967 – Xbox Live Auth Manager for Windows Elevation of Privilege Vulnerability This appears to be the first security patch impacting Xbox specifically. There was an advisory for an inadvertently disclosed Xbox Live certificate back in 2015, but this seems to be the first security-specific update for the device itself. Microsoft even notes other Windows OSes are not affected by this bug. It’s not clear how an attacker could escalate privileges using this vulnerability, but the Auth Manager component is listed as affected. This service handles interacting with the Xbox Live service. I doubt many enterprises are reliant on Xbox or Xbox Live, but if you are, make sure this patch doesn’t go unnoticed.
Here’s the full list of CVEs released by Microsoft for March 2022:
* Indicates this CVE had previously been released by a 3rd-party and is now being incorporated into Microsoft products.
Looking at the rest of the March release, the 11 CVEs impacting Azure Site Recovery stand out. For those not familiar with it, Site Recovery is a native disaster recovery as a service (DRaaS). This month’s release includes fixes for five elevation of privilege (EoP) and six remote code execution (RCE) bugs in the platform. Considering everything going on in the world, now is a bad time to have issues with your disaster recovery plans. If you’re using this platform, make sure these patches get installed. If you’re not using this platform, take time to review your disaster recovery plans anyway. It couldn’t hurt.
Besides the Exchange bug already mentioned, the Critical-rated fixes in this release both address bugs in HEVC and VP9 video extensions. These updates can be found in the Microsoft Store. If you aren’t connected to the internet or are in an otherwise disconnected environment, you’ll need to manually apply the patch.
Including those already mentioned, there are a total of 28 RCE fixes released today. There are additional updates for the HEVC video extension component. Again, these fixes are obtained through the Microsoft Store. The raw image extension bugs fall into this class as well. There are three fixes for Visio that were reported by kdot through this ZDI program. These bugs include a type confusion, an untrusted pointer deref, and an Out-Of-Bounds (OOB) Write. In each case, a user must open a specially crafted Visio file to be impacted. One of the other publicly known bugs is an RCE in .NET and Visual Studio. There’s scant information about this bug, but if you are developing apps in .NET or Visual Studio, review it carefully. Since RPC bugs are never out of fashion, there’s a fix for event tracing that could result in code execution through a specially crafted RPC connection. There are several caveats to this one that lower the severity, but don’t remove the risk completely.
Rounding out the RCE bugs is one submitted by an anonymous researcher through the ZDI program impacts Microsoft Defender for IoT. The vulnerability exists within the password change mechanism. It results from the lack of proper validation of a user-supplied string before using it to execute a system call. Defender for IoT also receives a patch for an EoP bug found by ZDI Vulnerability Researcher Simon Zuckerbraun. This bug also occurs within the password change mechanism, but here, the bug is caused by the lack of proper validation of a user-supplied string before using it to execute a system call. An attacker can leverage this vulnerability to escalate privileges and execute arbitrary code in the context of root.
Moving on to the other EoP cases, most would require an attacker to log on to a system and run a specially crafted program. Several of these fixes note that the vulnerability is the result of a race condition, making exploitation somewhat unreliable. There are some interesting components receiving fixes for privilege escalations this month, including the FAT file system, the Fax and Scan Service, and the CD-ROM driver. It’s almost retro. Another interesting component is the Windows PDEV, which is a logical representation of a physical device characterized by the type of hardware, logical address, and surfaces that can be supported. ZDI Vulnerability Researcher Lucas Leong reported a Use-After-Free (UAF) bug in the handling of PDEV objects. An attacker could use this to escalate privileges and execute arbitrary code in the context of SYSTEM.
Six of this month’s fixes address information disclosure bugs. For the most part, these only result in leaks consisting of unspecified memory contents. The lone exception is the bug impacting the Skype for Chrome extension. This vulnerability could inadvertently disclose the Skype ID of a target. An attacker could gain access to that ID they could match it within Skype to a name and Avatar of the target user. If you’re using Skype for Chrome, you’ll need to get the update through the Chrome Web Store.
There are four updates to address DoS bugs in this release, and two stand out over the others. The first is a DoS in Hyper-V, which is always inconvenient if you happen to be one of the other guest OSes on that Hyper-V server. The other is a vulnerability in the Point-to-Point Tunneling (PPTP) protocol, which is used in the implementation of virtual private networks (VPN) that allow people to extend their private networks over the Internet via “tunnels”. There are no details about this bug given, but anything that could take down a VPN is unwelcome – especially since so many of us rely on VPNs to work from home (or wherever).
Three different components receive fixes for security feature bypasses (SFB) in this month’s release. The first continues the retro theme by fixing bugs in the Windows HTML platforms, including Internet Explorer and Edge (HTML-Based). Microsoft does not indicate which security feature is bypassed, but considering how pervasive MSHTML continues to be, patching is certainly recommended. Word receives a fix for an SFB bug that could allow specific protections to be bypassed in Protected View. This could potentially result in a user opening a malicious document but not receiving the intended warning dialogs. The final SFB fix applies to the Intune Portal for iOS. An attacker could use this vulnerability to bypass the Intune policy file save location and presumably load their own policy instead.
This month’s release includes three updates for spoofing bugs. The Exchange spoofing bug could allow an authenticated attacker to view file content on the affected server. Microsoft provides little information about the spoofing bugs in Defender Endpoint and Visual Studio other than to say the Defender bug requires knowledge of the target environment and the Visual Studio bug requires a user to open a file.
We wrap up this month’s release with an odd tampering bug in Microsoft Word. Microsoft gives no information on how the vulnerability can be exploited, but they do indicate information from the victim can be sent to the attacker, and that the Preview Pane is an attack vector. It sounds like a specially crafted Word doc can send potentially sensitive information to an attacker when the document is opened or viewed in the Preview Pane. Office for Mac users are out of luck as well, as the patches for Microsoft Office 2019 for Mac and Microsoft Office LTSC for Mac 2021 are not available yet. It will be interesting to see if additional information is released about this bug in the future.
No new advisories were released this month. The latest servicing stack updates can be found in the revised ADV990001.
The next Patch Tuesday falls on April 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!
In the first blog of the series, we saw how CodeQL and Clang checkers can be used to find bugs in MySQL Cluster involving untrusted size arguments leading to buffer overflow or out-of-bound array accesses. Though the majority of bugs were out-of-bounds array accesses, there were also bugs involving untrusted data being used in loop conditions or casted to pointers. In this final blog of the series, we experiment with CodeQL’s IR and Clang checkers for detecting such bug classes.
Defining taint sources - CSA vs CodeQL
The first part of the problem is defining the taint sources. Clang Static Analyzer (CSA) provides an experimental checker alpha.security.taint.TaintPropagation for performing static taint analysis. Implemented as GenericTaintChecker, it has a set of built-in taint sources. Since the Signal data used by message handlers does not come directly from these built-in taint sources, it is necessary to find an alternative approach to define taint sources. Lucas Leong had a quick approach to work around the problem - rewrite all access to signal->theData with getenv(). Since the return value of getenv() is considered tainted by GenericTaintChecker, taint propagation works after rewrite. Refer to his blog post “MindShaRE: When MySQL Cluster Encounters Taint Analysis” for details on using existing taint checkers and CodeQL to find memory corruption bugs.
One has to be careful with this approach to avoid missing potential taint sources. Though MySQL Cluster has defined APIs like Signal::getDataPtr() to fetch the Signal data pointer, various handlers don’t follow the standard. Instead, signal->theData is accessed in numerous other ways from offset 0 or from various other offsets. I rewrote some common patterns using find and sed. This may not be exhaustive but provides sufficient taint sources to experiment with the checkers.
The situation is much different when working with CodeQL, where defining taint sources is far more flexible. All we have to do is override the isSource() predicate to something like this:
CWE-822: Untrusted Pointer Dereference
In an untrusted pointer deference vulnerability, data from an untrusted source is casted to a pointer for further use. The impact of the bug depends on the usage of the casted pointer. This section provides details about detecting such pointer load operation using CSA and CodeQL.
Detecting untrusted pointer dereference using CSA
To detect this vulnerability using CSA, I relied on path-sensitive checker callback check::Location which fires every time a program accesses memory for read or write. The information below is from the checker documentation:
The SVal symbolic valueLoc points to the memory region being accessed. IsLoad indicates whether the access is a read or a write. To check if a memory load is happening from a tainted memory region, we can check if Loc is tainted. If so, we can use the statement S to get the type of the expression:
Whenever the expression type is a pointer, it is logged as a bug. Scanning MySQL Cluster with this checker gave about 86 results, which is significantly high and also has false positives. Here is what the scan results look like:
The large number of results is due to the fact that any pointer derived from a tainted value (via pointer arithmetic, array indexing, etc.) is also considered tainted, irrespective of whether the tainted value is constrained by validation. In some cases, OOB reads which load pointers are also reported. Understanding the nature of false-positive results significantly improves the triage experience.
Considering the high number of results, we can sort the results by “File” which is likely to organize the result by feature, or for a less familiar code base, sorting by “Path Length” can help identify code paths reachable with minimum complexity.
scan-view results sorted by File
scan-view results sorted by Path Length
CSA reported a number of bugs in the code handling DBDIH block with a path length of 1. Here is an example bug report:
Using a known bug pattern, it is possible to apply filters to reduce the results in addition to the taint check. For example, we can check the AST statements for pointer loads which are only assignment statements like above. The checker can be tweaked as per the nature of bugs in the codebase.
Analyzing memory loads using CodeQL IR
To perform a similar analysis in CodeQL, one can possibly rely on expression classes such as PointerDereferenceExpr, VariableAccess, FieldAccess and its subtypes. But in this case, I was curious to explore CodeQL’s Intermediate Representation (IR) to track memory loads. Since the documentation around CodeQL’s IR is limited, I used the Instruction class to dump the IR for further analysis. Here is a partial dump of IR for the line EmulatedJamBuffer * jambuf = (EmulatedJamBuffer*)req->jamBufferPtr in function execDIH_SCAN_TAB_REQ():
The CodeQL query used to dump the IR along with source code information:
Consider the below set of instructions in the IR:
Here the LoadInstruction relies on 2 operands - a source address operand (r17303_4) and a source value operand (m17300_12). The source value operand is a MemoryOperand. The MemoryOperand describes the memory address accessed by the instruction, whose value gets copied to the result register (r17303_5). Moreover, the result is also associated with type information. The idea was to filter all tainted memory load operations whose return type is a pointer. However, such a query resulted in an unusably large number of results.
Adding constraints using overlap relationship and virtual variables
Consulting CodeQL’s IR SSA Construction documentation, I found a couple of features that could be useful for refining the query: the overlap relationship and VirtualVariables.
Overlap defines the relationship between the definition of a memory location and its usage. The most interesting relationship for this analysis is MustExactlyOverlap - the set of bits written by the definition is identical to the set of bits read by the use, and the data type of both the definition and the use are the same. For more clarity on the overlap relationship, refer to the SSA test case found in the repository. In the case of untrusted pointer load bugs, it is very likely that there will be a mismatch of data type between definition and usage (type casting) or that the number of bits read will be a subset of the definition. Therefore, we can skip Load operations where the source value operand has an exactly overlapping relationship with its definition. The getOperandMemoryLocation() predicate provides information regarding the MemoryLocation read by a memory operand. Consider the output of the following query:
The memory operands that are marked with tilde “~” are the ones that do not have an exactly overlapping relationship. This can also be checked using isDefinitionInexact() predicate. Putting all this together, we can override the isSink() predicate to get a meaningful number of results to work with.
Many of the false-positive results were due to multiple load operations performed using some misidentified pointer. These results can be either skipped or removed by adding further constraints to the query, such as ignoring certain variable names in the sink or checking for AST patterns.
In the case of MySQL Cluster, one such constraint explored for filtering memory access to the Signal structure is VirtualVariable. As per the documentation, “Each MemoryLocation is associated with exactly one VirtualVariable. A VirtualVariable represents a set of MemoryLocations such that any two MemoryLocations that overlap have the same VirtualVariable.” VirtualVariable information can be fetched from a MemoryLocation using the getVirtualVariable() predicate.
When the variable names are consistent, we can add a constraint to consider only Load operations where the memory operand points to the signal variable. A more generic option is to fetch the type information of the virtual variable to check if it is a Signalstructure. Such a query is still restrictive (not as much variable name) but significantly reduces false positives and returns results involving jamBufferPtr:
CWE-606: Unchecked Input for Loop Condition
In CWE-606: Unchecked Input for Loop Condition, values from an untrusted source are used for loop termination conditions. This may lead to a DoS or other issues depending on the operations done in the loop body. This section provides details about detecting such tainted loop conditions using CSA and CodeQL.
Detecting tainted loop condition using CSA
Unlike tainted memory loads, I couldn’t find any path-sensitive callback to trigger on loop conditions. Moreover, AST-based matchers without path-sensitivity are not useful in this case. Therefore, I relied on the check::BranchCondition callback which fires every time a control flow branching occurs during analysis. The following information is from the checker documentation:
The idea here is, whenever the callback triggers due to a conditional statement, walk up the AST using ParentMap and check for a loop statement. Here is what an example AST looks like for while loop:
For loop operations we are only interested in 3 AST statement classes – WhileStmtClass, DoStmtClass and ForStmtClass. Below is the loop detection code used in the checker:
Once we know that the condition statement triggering the callback is part of a loop statement, we can check if it is tainted. Specifically, I wanted to look for some common code patterns involving induction variables compared against untrusted values, or untrusted values used as induction variables to decide on loop termination. Consider a couple of common code patterns below that involve explicit binary comparison operations:
• The induction variable is compared against a potentially untrusted value. For example, RHS could be tainted and LHS is not. • The induction variable could be potentially untrusted. Here LHS value is compared against constant 0 on RHS.
The checker specifically looks for these cases to make decisions on bugs. When RHS is constant 0, check if LHS is tainted. Otherwise, check if RHS is tainted:
Another common code pattern is unary operations in loop statements, especially while and do while loops:
No special breakdown is necessary in case of unary operations in the way we handled binary operations. However, in certain cases, implicit Boolean conversions result in implicit conditional statements received by the check::BranchCondition callback. Here is what the AST looks like:
To handle these, if any non-binary conditional operations have a Boolean outcome, it is possibly due to implicit casting and hence we get the sub-expression associated with the expression.
Evaluating constraints on tainted variables
While it is possible to know if an input is tainted or not, there is no way to know if the tainted input value is constrained by some validation. Without this information, the checker is going to generate a lot of false-positive results. To solve this problem, I used the solution provided by Andrew Ruef in the blog post Trail of Bits - Using Static Analysis and Clang to Find Heartbleed. Since Signal data is treated as an unsigned 32-bit integer in most cases, I queried if the variable can take a value greater than 0x10000. If yes, consider the variable as unconstrained and log the bug.
Configuring analyzer-max-loop in CSA
Clang analyzer has a configuration parameter to choose the number of times a basic block in a loop gets executed. By default, this value is 4.
So how does it matter in our analysis? Consider the below code:
Here is buffer->index is validated and the loop operation is considered safe. But the checker still reports a false positive bug.
What seems to be happening here is, the symbolic expression gets evaluated analyzer-max-loop number of times i.e., for each visit to the basic block.
The analyzer seems to evaluate that the decrement operation can underflow resulting in a value greater than 0x10000, therefore reporting it as a bug. I’m not entirely sure of the right way to solve this issue, but a quick workaround is to set analyzer-max-loop to 1. This can also be done in scan-build using the maxloop parameter. In this case, the expression is evaluated only once and it does not report the bug.
The scan reported around 46 bugs, with some valid ones including previously found issues like ZDI-CAN-14488, ZDI-CAN-15120, ZDI-CAN-15121.
Here is the example bug report for vulnerability in Dbdict::execLIST_TABLES_CONF():
Detecting tainted loop condition using CodeQL
Using the analysis done earlier for CSA, an equivalent query in CodeQL can be implemented using the Loop class. The isSink() predicate essentially looks as follows:
Building and Performing the Scan
In order to build clang with custom checkers, copy the source files to the clang/lib/StaticAnalyzer/Checkers directory in the LLVM toolchain. Then add the filenames to the CMakeLists:
Also update the clang/include/clang/StaticAnalyzer/Checkers/Checkers.td file to add the package information:
Once you make clang, the new checkers will be listed alongside other alpha checkers.
Now we can use scan-build to perform the analysis. Use the maxloop and use-analyzer configurations if necessary.
Building with checkers can be slow. To speed up the scan, limit the target path by either modifying the Makefile as necessary or use the custom Makefile by Lucas. All this analysis was performed on clang 12.0 and MySQL Cluster 8.0.25
Scanning with CodeQL requires creating a database, followed by running any queries we are interested in against the created database.
The source code for the Clang checkers and CodeQL queries can be found here.
We hope you’ve enjoyed this look at finding bugs using Clang Static Analyzer, CodeQL, and Binary Ninja. As ZDI Vulnerability Analysts, these have proved helpful in finding new bugs. If you use these (or other) tools to find bugs of your own, consider submitting them to our program. Until then, you can find me on Twitter @RenoRobertr, and follow the team for the latest in exploit techniques and security patches.
Clang Checkers and CodeQL Queries for Detecting Untrusted Pointer Derefs and Tainted Loop Conditions
Taint analysis is an effective technique for finding vulnerabilities, even in large codebases. My colleague, Lucas Leong, recently demonstrated how Clang Static Analyzer and CodeQL can be used to model and find vulnerabilities in MySQL NDB Cluster using taint analysis. Largely inspired by his work, I wanted to try something similar but using Binary Ninja since it can also work with closed-source programs.
These are a few things I had in mind while working:
• Identify vulnerabilities due to uses of untrusted values without bounds checking • Taint propagation and filtering should be control-flow sensitive • Support inter-procedure analysis
I approached this as a graph reachability problem, for which Tainted Flow Analysis on e-SSA-form Programs served as an excellent reference. All the analysis in this article is based on MySQL Cluster 8.0.25 and Binary Ninja 2.4.2846.
Defining Taint Sources
To get taint analysis working, it is essential to define the taint sources clearly. MySQL Cluster has a message passing architecture, and interesting taint sources are the messages themselves. This section provides details on message handling and how the message handlers can be identified for analysis.
MySQL NDB Cluster Signals
MySQL NDB Cluster defines functionalities as “blocks” and messages passing between them as “signals”. The NDB blocks are implemented as C++ classes, and each block registers multiple signal handlers during initialization, which are also methods of the class. Most of the vulnerabilities reported were in these message handlers, also known as signal handlers.
All the blocks inherit the SimulatedBlock class to register their signals using addRecSignal(), which invokes the SimulatedBlock::addRecSignalImpl() method. The registered signal handlers are of type ExecSignalLocal, which takes a single argument. Interested readers can refer to blog posts on Ndb software architecture by Frazer Clement and Code Reading Notes – MySQL Cluster by Steinway Wu for further details. The scope of this article is limited to entry points to signal handlers. Below is an example of the code of the NDBCNTR block registering a signal handler:
The “Signal” object that each handler receives contains untrusted data. The signal handlers can access the data as signal->getDataPtr() or with a few other methods. The handlers can also further pass the “Signal” object to other functions. There are a couple of ways to proceed here. You can either analyze any function that takes Signal as an argument or analyze only the actual signal handlers by cross-referencing calls to SimulatedBlock::addRecSignalImpl() and then let inter-procedure analysis take care of the rest. I chose to start with the former since the inter-procedure analysis was implemented at a later stage.
The Signal object is 0x8030 bytes in size and not all bytes should be considered tainted. We should only define a small region of memory of the object as tainted so that only memory reads from the tainted region are propagated. Marking the entire structure as tainted will lead to a lot of false positives. In this case, the signal’s tainted data starts at offset 0x28 and any memory loads from this offset are marked tainted. Both Signal::getDataPtr() and Signal::getDataPtrSend() return a pointer to this memory.
Porting type information from IDA Pro to Binary Ninja
The executable under analysis is “ndbd”, which is the NDB Cluster Data Node Daemon built with DWARF debug information. In order to find functions that take a pointer to a Signal object as an argument, check the type information of all functions as follows:
However, at the moment, Binary Ninja does not handle DWARF information as robustly as IDA Pro does. Another issue with Binary Ninja is its failure to detect the “this” argument when analyzing C++ executables. As a result, argument detection will not be accurate, breaking our taint source analysis. An easy fix is to import type information from IDA Pro into Binary Ninja. For example, the Dblqh::prepareContinueAfterBlockedLab() method has the following type information as per IDA Pro:
The same function looks different in Binary Ninja. In this case, the “this” pointer is missing, and Signal becomes the first argument. Marking “arg1” as a taint source makes the entire analysis wrong.
Since we are only interested in the right argument position and type information of the Signal argument, we fix it using the scripts provided in ida2bn directory:
Once the type information is fixed, we are good to identify functions and mark taint sources using the Signal argument. More details on working with types in Binary Ninja are documented here Working with Types, Structures, and Symbols.
Taint Propagation and Filtering
The goals of taint propagation are simple: when a variable is assigned a value from the Signal data, mark it as tainted. If any other variable is derived from the tainted variable, also mark it tainted, and so on. The challenge comes when there are sanitizers. Say a variable is tainted, and in some code path there is a validation for that variable. In this case, the variable is no longer tainted in that code path. Taint propagation should be control-flow sensitive to avoid over tainting and false positives. This section details how I approached the problem using Binary Ninja’s IL and SSA form. For a thorough reading on the topic, please refer to blog posts Breaking Down Binary Ninja’s Low-Level IL and Vulnerability Modeling with Binary Ninja.
Binary Ninja ILs and SSA form
Binary Ninja supports a variety of Intermediate Languages (IL) like Low-Level IL (LLIL), Medium Level IL (MLIL), and High-Level IL (HLIL). Since MLIL abstracts away stack memory access with variables and has parameters associated with call sites, I found it more suitable to perform inter-procedure taint analysis. Moreover, it is better documented than HLIL.
Another powerful feature supported is the Single Static Assignment (SSA) form of the available ILs. In SSA form, each variable is defined only once. When the variable is reassigned to another value, a new version of the variable is created. Therefore, it is easy to track a tainted variable at any point in a function. Consider this minimalistic example: when variable x is reassigned a new value, a new version of the variable is created in the SSA form:
SSA variable def-use chain
Binary Ninja provides get_ssa_var_definition() and get_ssa_var_uses() APIs to get a variable’s definition site and their uses respectively. Consider the MLIL SSA code snippet of Thrman::execOVERLOAD_STATUS_REP() method below:
Here, arg2 is a pointer to a Signal object. At the address 0x00784165, the SSA variable “rax#1” is loaded with a tainted value from [arg2#0 + 0x28]. The MLIL instructions that use the tainted SSA variable rax#1 can be fetched as below:
These APIs form the building blocks of our taint analysis going further.
Taint propagation with SSA def-use chain
Binary Ninja’s ILs are structured as an expression tree such that operands of an operation can be composed of other operations. Consider the graph generated for the below MLIL SSA instruction by the BNIL Instruction Graph plugin:
The MLIL_SET_VAR_SSA operation marks the definition of a new SSA variable, which sets the dest variable to the result of the src expression. The src expression could be composed of many other operations. In this case, MLIL_ADD adds an offset 0x28 to the base address of Signal and then MLIL_LOAD_SSA reads the value from the address computed using MLIL_ADD. Effective taint propagation requires visiting all the MLIL SSA operations for every instruction expression. Josh Watson’s emILator and IL instruction counting by Jordan are good examples for visiting and processing MLIL SSA instruction expressions. What does the taint propagation algorithm look like?
• Visit all MLIL SSA instructions in the function linearly • For any MLIL_SET_VAR_SSA operation, resolve the src expression to check if it is tainted data • If the src operand returns tainted data, get the uses of the dest SSA variable with get_ssa_var_uses() • Visit the instructions that use the tainted SSA variable and propagate taint when MLIL_SET_VAR_SSA is encountered • Once an instruction taints a variable, mark it as visited and never visit again
Constraints on SSA variables
Once we have the taint propagation algorithm in place, how do we handle sanitizers on the tainted variables? We are only interested in code paths without any validations. With this in mind, let’s revisit our taint propagation algorithm, which relies on the def-use chain. Def-use chains are sequential statements of code; therefore, taint propagation is not control-flow sensitive. Here is an example to demonstrate the issue:
The “value” variable passed to the function is tainted and gets used in two different code paths. Along the code path executing the basic block at 0x1184, the variable is validated and considered clean. The get_ssa_var_uses() for the variable returns 3 instructions:
Processing these 3 instructions linearly would lead to the incorrect conclusion that the validation precedes both usages of the tainted value. In reality, only one instruction is protected. The other two are vulnerable. This problem can be solved by taking control flow into account.
Control-flow sensitive propagation using constraint graph
The MediumLevelILInstruction class has an il_basic_block property to get the basic block information of the MLIL instruction.
Using this property, we can fetch the basic blocks of SSA variable definition and SSA variable uses, which also includes the basic blocks where the validations are done. The basic blocks are also referred to as the “constraint” blocks. Some properties of these basic blocks are as follows:
• The definition block always dominates all uses of the SSA variable. • The basic block that has the definition can contain constraints. The same applies to any basic blocks of the def-use chain. • A definition block is always reachable and hence all the instructions in it are reachable too.
Considering this as a graph reachability problem, the question is, can we reach all the instructions in the def-use chain of the SSA variable in the presence of a constraint block? To answer this, we build a constraint graph from the CFG of the function and use a pathfinding algorithm on it:
• Remove the outgoing edges of constraint blocks from the CFG. This is our constraint graph. • Find if a path exists between the definition basic block and other basic blocks of the def-use chain in the constraint graph. • If any def-use basic blocks are not reachable, then those instructions are not used for taint propagation.
Since each assignment is unique in SSA representation, we maintain a per-variable dictionary of the necessary information including the constraint graph for later analysis. Here is a sample pseudocode to find reachable blocks in the presence of constraint blocks:
To find if an SSA variable is tainted at a given instruction, all we need to do is check its reachable def-use chain:
Arithmetic operations as filters
Other than explicit filters, there are also arithmetic operations that can also be taint filters. For example, AND or Logical Shift Right (LSR) operations may place constraints on a value. In such circumstances, a heuristic can be used to filter out undesired results. Consider the example below:
Here, the tainted value is not explicitly compared against anything, but operations such as LSR and AND limit the input range. This is where I found the possible_values property very useful. Binary Ninja’s data flow analysis can provide possible values for an expression:
Handling Transitively Tainted Variables
The first stage of analysis propagates taint data and generates information such as a list of tainted variables, constraints placed on each SSA variable, and their respective constraint subgraphs.
During the second stage of analysis, we explore the relationships between the tainted SSA variables. Why is this important? We are only looking for unbounded SSA variables. While any direct constraints placed on an SSA variable are already handled in the first stage, the constraints placed on SSA variables that are propagated transitively are not yet handled. Consider the example below:
The index#0 variable could be tainted and not constrained. However, the derived variable constrained_var#1 is validated, indirectly placing constraints on the index variables. Therefore index#3 is not tainted during the memory access at 0x11f2. Here is another example:
Here, index#1, index#2, rax#1, and constrained_var#1 are copies or direct assignments of the variable index#0. When variable constrained_var#1 is validated, the other variables are also validated. Not analyzing the effect of constraints on derived variables or copies of variables leads to false-positives. This section details ideas on handling constraints on related variables.
Constraints on transitively related SSA variables
After the taint propagation phase is over, we iterate through all the tainted variables that have constraints on them. For every variable with constraints, we find its child variables and parent variables.
• Variables that are derived from a given variable are called child variables. • Variables from which a given variable is derived are called parent variables.
To check if the constraints on the variable under consideration have any effect on its parent or child variables, we perform the below checks:
• Pick the constraint subgraph for the SSA variable under consideration. • Check if the definitions of child variables are reachable from the definition of the current variable. · If not, the constraint is placed before defining the child variable in the CFG, and therefore none of the basic blocks in the def-use chain are tainted. · If yes, the constraint is placed after defining the child variable in the CFG. In this case, also check if all basic blocks of the def-use chain of the child variable are reachable from the definition of child. Mark the non-reachable blocks as clean.
• For each parent variable, get its list of child variables. While all the child variables of the current variable are also child variables of the parent, parent variables might have other child variables too. The child variables already visited in the previous step can be skipped. Now check if the definitions of child variables are reachable from the definition of parent variable. For a yes or no, repeat the same as mentioned in the previous step to mark the non-reachable blocks as clean.
This way the non-reachable basic blocks are removed from tainted entries of variables related to a constrained variable. We can also choose to perform analysis on variables that are derived or just direct assignments using tags associated with a variable.
While propagating taint, two different tags were used – a direct memory load using MLIL_LOAD_SSA from tainted memory returns an offset, size pair as tag and it gets associated with the destination variable. Whereas for any derived variable, the destination variable is associated with a marker but not the offset, size pair. Consider the code:
The variable rcx_1#2 is tainted with a tag [0x2c, 0x4], which is the offset size pair. This is the same as the case with rbx#1, which is a direct assignment. However, rbx_1#2 derived from the expression rbx#1 u>> 5 is tainted with a tag [0xdeadbeef, 0xdeadbeef]. Using different tag type information, it is possible to identify the nature of taint propagation.
Constraints on SSA variables from multiple taint sources
While propagating taint, we mark a destination variable as tainted if any of the source variables are tainted, including the PHI function. During filtering in the second stage, if a variable is constrained, we apply the constraints to all is related variables. But, when the derived variable (child) is coming from more than one independent taint sources (parents) and only one of the parent variables is validated, the child variable is also considered validated. But this is not desirable. Consider the example below:
Let’s say x and y are coming from two independent taint sources and index is a sum of both, hence a derived variable. When x gets validated, index can still be tainted since y is not validated. The previous algorithm does not take this into account.
To solve this problem, I considered associating each derived tainted variable with the actual source variables referred to as root variables and maintain copies of def-use chain per root variable. For example, variable index#3 has two roots – x#0 and y#0. For each root, maintain a copy of reachable blocks in taint information associated with index#3. When x#1 is validated, only the x#0 copy of index#3 is marked not reachable and the y#0 copy is still considered tainted. A dependency graph of variables is built to establish these relationships.
Establishing SSA variable relationship using a dependency graph
In a variable dependency graph, any tainted variable in the function is represented as a node. When a variable is derived from another variable, it forms a directed edge from the parent variable (node) to the child variable (node).
In order to establish a relationship between variables, the definition site of all the tainted variables is visited using get_ssa_var_definition(). When any of the source variables in the MLIL expression are tainted, create an edge connection in the graph. A variable tainted during MLIL_LOAD_SSA operation does not have a parent node or incoming edges and therefore becomes the root node.
Such a dependency graph will have many weakly connected components because each memory load from the tainted memory region will be assigned to a new variable and therefore a new node in the graph. Put simply, each memory load creates a subgraph along with its derived variables. A subgraph might connect with another when a variable is derived out of more than one root node. Here is a sample dependency graph from the function Dbtux::execTUX_ADD_ATTRREQ():
Another property to note is that dependency graphs are not necessarily Directed Acyclic Graphs (DAG). This is because loops can be introduced by a circular dependency of variables in PHI functions. Consider the below SSA representation of a loop operation:
Here, the value of counter#2 depends on counter#1 or counter#4, which is a PHI function. The predecessor block decides the outcome of the function. Further down in the loop, counter#4 depends on counter#2. This relationship will be represented as a cycle in a dependency graph.
Once the dependency graph is generated, it is easy to get the root variables associated with any tainted variables. Moreover, child and parent variables for any given variable can be fetched for handling transitive relationships. The only missing part now is the forward propagation of tainted information to other functions.
Static Function Hooks and Inter-procedure Taint Propagation
All the MLIL_CALL_SSA and MLIL_TAILCALL_SSA instructions with tainted arguments are processed once the analysis of the current function is finished. For any CALL instructions with a known destination (e.g., MLIL_CONST_PTR), the symbol is fetched to check for static hooks. Here is the code snippet:
Static hooks are handlers to functions that we intend to handle differently compared to other functions. Consider a call to the libcmemcpy function, where taint propagation is not necessary but only interested in checking for tainted size, source, or destination arguments. In order to provide this information to the analyzer and make it configurable, a JSON config with function names and arguments is used as below:
The arguments to check are indexed from 0. In the case of memcpy, all 3 parameters are marked for analysis. The argument index provided in the JSON config is checked against the tainted SSA variables. For example, arg2 in the config maps to an SSA argument variable associated with memcpy’s size argument.
Static hooks can also be used to mark an output variable or return value of a function to be tainted and further propagated. However, this is not currently implemented since function-specific details are not considered. When necessary, the visitor handler for the MLIL_SET_VAR_SSA operation can be reused for implementing backward taint propagation during CALL operations. For any other function without hooks, taint information is propagated by marking the target function’s variable as tainted.
Tracing Vulnerabilities from Reachable Blocks
Once the taint propagation and filtering phases are over, the last phase of analysis involves iterating through all tainted variables and checking the reachable blocks for potential sinks. Based on the bugs already reported, I chose to look for vulnerabilities involving Out-Of-Bounds (OOB) memory access, buffer overflows during function calls to APIs such as memcpy, untrusted inputs casted to a pointer, and tainted loop counters. The rest of this section details additional detection strategies.
OOB reads and writes
The majority of vulnerabilities in MySQL Cluster were OOB read and write memory access bugs due to the missing validation of untrusted array indexes. To detect these bugs, we can specifically consider any MLIL_LOAD_SSA or MLIL_STORE_SSA instructions as sinks. Here is an example code from Dbdih::execGET_LATEST_GCI_REQ():
Here, rax#1 is tainted, hence the read operation using MLIL_LOAD_SSA can be considered an OOB read condition. Similarly, consider another case from Thrman::execOVERLOAD_STATUS_REP():
Here again, rax#1 is tainted, hence write operation using MLIL_STORE_SSA can be considered an OOB write condition.
API buffer overflows
Static function hooks are used to detect buffer overflows caused by a lack of validation of arguments passed to functions like memcpy, memmove, etc. Details regarding this are already detailed in the section “Static Function Hooks and Inter-procedure taint propagation” above. Essentially, if any of the interesting parameters of a hooked function are tainted, we log it as a potential vulnerability.
Untrusted pointer dereferences
In some cases, I noticed that MySQL Cluster converts untrusted input to a pointer then dereferences it. To identify this, I relied on Binary Ninja’s type information. The MLIL variable object has a Type property that returns the Type object associated with a variable. A Type object’s type can be accessed using the type_class property. Here the pattern is that the source points to a tainted memory region within a Signal structure, and the destination variable is of type PointerTypeClass. The Type object also has a confidence property, as seen below:
The maximum confidence value for a variable type is 255. To reduce false positives, the analyzer only considers type information having the maximum confidence.
Tainted control flow operations in a loop
Loop termination conditions depending on tainted variables can lead to interesting bugs. Binary Ninja’s MLIL does not provide information on loops, therefore the alternative was to rely on HLIL to detect tainted loop conditions. The HLIL of a loop in Cmvmi::execEVENT_SUBSCRIBE_REQ() looks like the example below:
The trouble here is that we have implemented the entire taint propagation using MLIL, and Binary Ninja does not provide a mapping between MLIL and HLIL. Therefore, even if loops can be detected, the challenge is to know if a tainted MLIL variable maps to a HLIL variable used in a loop condition.
As a workaround, the HLIL instruction has a condition property that fetches the condition statement associated with a loop. The address of this condition statement can be mapped to a MLIL_IF instruction.
Therefore, if any of the MLIL_IF instructions are tainted and are a part of a HLIL loop condition, then the analyzer logs it as a potential bug.
Experiments with Dominance Relationships
A dominance relationship provides information on the order of execution of some basic blocks. A basic block X is said to dominate another basic block Y if all paths to Y should go through X. Let’s take the example from Wikipedia:
In the provided graph, node B dominates the 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 full set of nodes that are dominated by node B is B, C, D, E and F. There is also a related concept called the strict dominator, which does not consider the node in question. Therefore, the set of all nodes that are strictly dominated by node B is C, D, E and F.
Binary Ninja’s BasicBlock object has dominators and strict_dominators properties which provides information regarding dominance relation in a function.
What about using the already available dominance properties in Binary Ninja for handling taint constraints instead of relying on graph reachability algorithms from networkx package?
Mapping constraints to dominator blocks
In order to check if any basic blocks in a def-use chain of an SSA variable are reachable, we can follow the steps below:
• Find all constraint blocks associated with a variable. • Get all the basic blocks that reference the variable using the def-use chain. • For each basic block, check if it is strictly dominated by a constraint block. If yes, the variable is considered validated for that basic block and considered not reachable.
Going back to the same example, the index gets validated in <mlil block: [email protected]> which dominates the <mlil block: [email protected]>. Therefore, by checking a constraint block against dominators it is possible to establish reachability.
False positives with dominators
While the dominance relationship was promising and gives good results, it does give rise to certain false positives. Consider the following CFG, where validation is done in two different program paths:
Here, the index is validated in two different program paths before hitting a potential sink block <mlil block: [email protected]>. However, none of the constraint blocks that perform validation <mlil block: [email protected]> and <mlil block: [email protected]> are dominators. In such cases, since constraint blocks cannot be mapped to any dominators, the potential sink block <mlil block: [email protected]> will be considered vulnerable on read access at address 0x11ba. This is a false-positive result.
The same is the case with the branch_dependence property, which returns a dictionary of branch instruction index and the branching decision taken to reach the instruction. When both the True and False branches dominate the instruction basic block, we do not get information regarding reachability.
A general observation from the scan result is that most constraints are part of dominator blocks. Very few are validated across multiple code paths, producing false positives. Since path-finding algorithms relying on the definition and usage of variables eliminate these false-positive results, I preferred it over dominators. However, the code is still in the repository for experimental purposes.
Notes on Analysis
The target ndbd executable is loaded in Binary Ninja to generate the BNDB analysis database. Then the analyzer is executed against ndbd.bndb for faster analysis:
Though not optimized for speed, the analyzer runs for about 4-5 minutes and returns 195 results. Some of the results are duplicates because a single vulnerability in a helper function might get used by multiple handlers. The analyzer was able to find most of the issues already known as well as a few that were not previously known: ZDI-CAN-15120, ZDI-CAN-15121 and ZDI-CAN-15122. However, there is a high triage cost associated with static analysis results, especially when the target is less familiar. Luckily, my colleague Lucas had already spent a fair amount of time on the codebase making it easier to triage the results.
I hope you have enjoyed this look at using Binary Ninja to find vulnerabilities through taint analysis. In a few days, I’ll be back to discuss using Clang Static Analyzer (CSA) for detecting untrusted pointer dereferences and tainted loop conditions. Until then, you can find me on Twitter @RenoRobertr, and follow the team for the latest in exploit techniques and security patches.
Static Taint Analysis using Binary Ninja: A Case Study of MySQL Cluster Vulnerabilities
Recently, the ZDI received multiple submissions of vulnerabilities in MySQL Cluster. MySQL Cluster is a clustering solution providing linear scalability and high availability for the MySQL database management system. The common attack vector identified in these reports is the open port for the cluster management node and data nodes. Attackers can utilize the protocol and interact with nodes without authentication.
After investigating these submissions, I realized that the code is very buggy, and the pattern of the vulnerabilities is simple. However, the codebase is too large for a manual review. Therefore, the question becomes, “Is it possible to identify all low-hanging-fruit bugs automatically and quickly?” Fuzzing works, but it depends on coverage and cannot precisely focus on a specific type of bug. Taint analysis is probably the more suitable answer for this question.
Two tools are chosen for taint analysis: Clang Static Analyzer and CodeQL. Although they have their own pros and cons, both can lead to positive results. This blog looks at both methods and shows how they can be used for taint analysis against this and other programs.
Here is an example of the kind of low-hanging-fruit bug we are looking for:
The Qmgr::execCM_REGREF function is a registered signal of the QMGR NDB kernel block. These registered signals can be invoked remotely. The signal->getDataPtr() at (1) returns a pointer to a buffer that contains untrusted input from the network. TaddNodeno at (2) is therefore a controlled 32-bit integer from the network, and it is subsequently used as an argument at (3). Finally, at (4) within BitmaskImpl::set, it is used as an array index. Since no validation has been performed on this value, this potentially produces an out-of-bounds (OOB) write.
MySQL Cluster registers around 1,400 signals (the number of calls to addRecSignal()) and around 6,500 accesses on untrusted input (the number of calls to getDataPtr() plus the number of calls to getDataPtrSend() plus the number of direct accesses of theData). Although the example above is not very challenging, the manual review is still very time consuming due to the required scale. It's time to introduce taint analysis.
There are 4 common terms used during taint analysis: SOURCE, SINK, PROPAGATION, and SANITIZER. SOURCE refers to where data originates. In the example above, signal->getDataPtr() at (1) is the SOURCE. SINK refers to where data ends. In the example above, the access of array index at (4) is a SINK. PROPAGATION refers to how the data flows. In our example, the assignment at (2) and the argument copy at (3) are considered PROPAGTIONs. SANITIZER indicates where data is either sanitized or validated. There is no SANITIZER on the above example, and that is the root cause of the bug. The task of taint analysis is to look for a flow from SOURCE to SINK where the flow did not meet SANITIZER during the PROPAGATION. By defining the suitable SOURCE, SINK, PROPAGATION, and SANITIZER, taint analysis should return the types of bugs we seek.
Two taint analysis tools were used to search for these types of bugs: Clang Static Analyzer and CodeQL. The scanning scope of source code is limited to storage/ndb/src/kernel/ only. We will restrict our search to low-hanging-fruit, which we define as two bug types only: (1) buffer overflows in memcpy-like functions and (2) array index OOB accesses. The version of MySQL Cluster we are using for our examples in this blog is 8.0.25.
Clang Static Analyzer
Clang Static Analyzer (CSA) has a checker, GenericTaintChecker, which provides the taint analysis feature. By default, it has a set of pre-defined SOURCE and PROPAGATION values. The default SINK will check some dangerous APIs and arguments, such as format string, command injection, buffer size in memcpy-like function, and so forth. GenericTaintChecker also shares tainted information with ArrayBoundCheckerV2 in order to recognize that the use of a value as an array index is a SINK. Users can also customize some simple SOURCE, SINK, PROPAGATION, and SANITIZER values by providing a config file. If the config file cannot satisfy your requirement, such as for a more complicated semantic, you may have to write a new CSA checker in C++.
Using CSA for taint analysis, we first must let the checker know our SOURCE at (1). The config file cannot define an access to a variable, and writing a new checker would be an unwise expense of effort. Instead, I modified the code base to be analyzed, so that all the accesses of untrusted input have been replaced with something recognized as a pre-defined SOURCE. Some examples are shown as below:
Another untrusted SOURCE is the return of SegmentedSectionPtr in the getSection() function.
The default SINK missed some functions, which can easily be added to the config file as below:
Then, we can scan the project and get the reports using the following commands:
The Makefile2 file specified the target scanning directory:
The reports can be viewed in a browser by running the scan-view command to start up a local web server.
There is some duplication in the output, where multiple reports flag the same line of code. Also, we are interested only in reports that show taints reaching memcpy-like functions and array indexes. In the end, I found approximately 100 interesting reports.
CodeQL also supports taint analysis. It refers to it as taint tracking. There are no pre-defined SOURCEs or SINKs. Users define these with the QL language. We defined our SOURCE and SINK as follows:
Once defined, we can scan the project with the following command line:
A quick cross-check of the scan results against the results from the Clang Static Analysis above showed that CodeQL was missing some bugs. After some investigation, the root cause was that PROPAGATION on some structure field accesses were not being recognized. A similar situation is discussed here, and I enhanced the PROPAGATION as follows:
The generated report became longer, but the number of bugs found was excessive. After reviewing the report, I found that in some cases, validation was being performed by ptrCheckGuard(), arrGuard(), or other bounds checking. SANITIZER can help here to reduce the number. The bounds checking is assumed when there is an if statement that includes >, <, data-preserve-html-node="true" >=, or <=. data-preserve-html-node="true" Make sure that your SANITIZER does not accidentally drop some real bugs before applying this modification.
We then scanned the project again. The scanning can also be done in Visual Studio Code with CodeQL extension. However, some complicated queries are too slow to process and may fail due to memory exhaustion.
Some reports are duplicated at the same line of code. After de-duplicating, the number of interesting reports is around 320. However, the number should be fewer since some of them are still similar or even identical.
After reviewing all the reports, I generated Proof of Concept (POC) manually to confirm each bug. CSA found 28 bugs. A total of 18 of these bugs are array index OOB vulnerabilities and 10 are overflows on memcpy-like functions. CodeQL found 34 bugs. This tool found 21 array index OOB bugs and 13 overflows on memcpy-like functions. Using these methods, we discovered 37 unique bugs, with 25 of them being found by both tools. Only nine of 37 of these bugs overlapped from ZDI submissions, which means 28 are new for us. These numbers not only mean that the taint analysis is useful in this scenario, but also mean that MySQL Cluster has quite a few bugs to be discovered.
Each of these two tools has its pros and cons. By using both Clang Static Analyzer and CodeQL, we can learn from their different feedback and improve the output from each tool. These variances can be compared to the concept of differential testing. The taint propagation provided by either tool has its deficiencies, but can still yield useful results.
The power of these tools could be extended further by adding additional bug classes in SINK. I recommend applying taint analysis to loop counters and pointer dereferences.
Due to the large-scale codebase and simple bug pattern present in MySQL Cluster, taint analysis was quite useful. It identified low-hanging-fruit bugs automatically and quickly. Each tool discussed has its own pros and cons, and we recommend trying more than one tool to get the best results. The difference can be the feedback, which can be used to improve the overall results. Furthermore, we cannot blindly trust the output of either tool and must verify them carefully.
Also, thanks to my colleague @RenoRobertr, who provided feedback and several contributions to this work. He will publish a write-up of additional work on MySQL Cluster soon with his advanced Binary Ninja skills. That blog should be available in a couple of days.
We are looking forward to seeing more submissions of this type in the future. Until then, you can find me on Twitter @_wmliang_, and follow the team for the latest in exploit techniques and security patches.
MindShaRE: When MySQL Cluster Encounters Taint Analysis
It’s the second patch Tuesday of 2022, which means the latest security updates from Adobe and Microsoft are here. Take a break from your regularly scheduled activities and join us as we review the details of their latest security offerings.
Adobe Patches for February 2022
For February, Adobe released five bulletins addressing 17 CVEs in Adobe Illustrator, Creative Cloud Desktop, After Effects, Photoshop, and Premiere Rush. Two of these 17 were reported by ZDI Vulnerability Researcher Mat Powell. The update for Illustrator fixes a total of 13 bugs, the most severe of which could allow arbitrary code execution through either a buffer overflow or an Out-Of-Bounds (OOB) Write. The patch for Creative Cloud Desktop also fixes a single, Critical-rated code execution bug.
The theme of Critical-rated code execution bugs continues with the fix for After Effects. This patch addresses an OOB write bug that exists within the parsing of 3GP files. The issue results from the lack of proper validation of user-supplied data, which can result in a write past the end of an allocated structure. The final Critical-rated patch from Adobe this month fixes a buffer overflow in Photoshop that could allow code execution.
The only Moderate-rated patch this month is the update for Premiere Rush. This patch fixes a bug that exists within the parsing of JPEG images. The issue results from the lack of proper validation of user-supplied data, which can result in a read past the end of an allocated buffer.
None of the bugs fixed by Adobe this month are listed as publicly known or under active attack at the time of release.
Microsoft Patches for February 2022
For February, Microsoft released 51 new patches addressing CVEs in Microsoft Windows and Windows Components, Azure Data Explorer, Kestrel Web Server, Microsoft Edge (Chromium-based), Windows Codecs Library, Microsoft Dynamics, Microsoft Dynamics GP, Microsoft Office and Office Components, Windows Hyper-V Server, SQL Server, Visual Studio Code, and Microsoft Teams. A total of five of these bugs came through the ZDI program. This is in addition to the 19 CVEs patched by Microsoft Edge (Chromium-based) earlier this month, which brings the February total to 70 CVEs.
This volume is in line with February releases from previous years, which (apart from 2020) tend to be around 50 CVEs. What’s more curious about this release is the complete lack of Critical-rated patches. Of the patches released today, 50 are rated Important and one is rated Moderate in severity. It may have happened before, but I can’t find an example of a monthly release from Microsoft that doesn’t include at least one Critical-rated patch. It certainly hasn’t happened in recent memory. Interestingly, Microsoft has chosen to provide some additional explanations of CVSS ratings in this month’s release, but there are still many details about the bugs themselves that are left obscured.
None of the bugs are listed as under active exploit this month, while one is listed as publicly known at the time of release. Last month, Microsoft also initially listed the release as having no active attacks only to revise CVE-2022-21882 two days post release to indicate “Microsoft was aware of limited, targeted attacks that attempt to exploit this vulnerability.” We’ll update this blog should they change their mind this month as well.
Let’s take a closer look at some of the more interesting updates for this month, starting with a significant bug in the Windows DNS Server:
- CVE-2022-21984 – Windows DNS Server Remote Code Execution Vulnerability This patch fixes a remote code execution bug in the Microsoft DNS server. The server is only affected if dynamic updates are enabled, but this is a relatively common configuration. If you have this setup in your environment, an attacker could completely take over your DNS and execute code with elevated privileges. Since dynamic updates aren’t enabled by default, this doesn’t get a Critical rating. However, if your DNS servers do use dynamic updates, you should treat this bug as Critical.
- CVE-2022-23280 – Microsoft Outlook for Mac Security Feature Bypass Vulnerability This Outlook bug could allow images to appear in the Preview Pane automatically, even if this option is disabled. On its own, exploiting this will only expose the target's IP information. However, it’s possible a second bug affecting image rendering could be paired with this bug to allow remote code execution. If you are using Outlook for Mac, you should double-check to ensure your version has been updated to an unaffected version.
- CVE-2022-21995 – Windows Hyper-V Remote Code Execution Vulnerability This patch fixes a guest-to-host escape in Hyper-V server. Microsoft marks the CVSS exploit complexity as High here stating an attacker, “must prepare the target environment to improve exploit reliability.” Since this is the case for most exploits, it’s not clear how this vulnerability is different. If you rely on Hyper-V servers in your enterprise, it’s recommended to treat this as a Critical update.
- CVE-2022-22005 – Microsoft SharePoint Server Remote Code Execution Vulnerability This patch fixes a bug in SharePoint Server that could allow an authenticated user to execute any arbitrary .NET code on the server under the context and permissions of the service account of SharePoint Web Application. An attacker would need “Manage Lists” permissions to exploit this, by default, authenticated users are able to create their own sites and, in this case, the user will be the owner of this site and will have all necessary permissions. This case came through the ZDI, and we’ll have additional details out about it in the near future.
Here’s the full list of CVEs released by Microsoft for February 2022:
Chromium: CVE-2022-0470 Out of bounds memory
access in V8
* Indicates this CVE had previously been released by a 3rd-party and is now being incorporated into Microsoft products.
Looking at the additional remote code execution bugs in this month’s patch release, the updates for HVEC and VP9 video extensions. Microsoft indicates this requires the exploit to be local. However, they also state viewing a specially crafted image file could result in Windows Explorer crashing. If this is the case, it stands to reason the image file could also be hosted on an SMB share, which would make this a remote exploit vector rather than local. The updates for these extensions can be found in the Microsoft Store, so you really only need to verify you have the updated versions unless you are in a disconnected environment.
In addition to those already mentioned, there are nine additional remote code execution-related patches this month. There’s an update for Roaming Security Rights Management Services, but Microsoft offers no information on how an attacker could exploit this vulnerability. There are also no details for the Windows Runtime or the Mobile Device Management bug. If you’re using Windows for MDM, definitely take this update seriously. There are also a couple of open-and-own Office bugs getting fixed. The RCE bugs are rounded out by updates for Dynamics 365 (on-prem) and Dynamics GP.
Speaking of Dynamics GP, there are three patches fixing elevation of privilege (EoP) bugs in the component. Those are three of the 18 EoP patches in this month’s release. This includes an update for the Windows Kernel that is listed as publicly known. The remaining patches are mostly in other Windows components and require a logged-on user to execute a specially crafted program. The other EoP updates that stand out fix vulnerabilities in the Windows Print Spooler. Ever since PrintNightmare, the print spooler has been an attractive target for attackers and researchers alike. Pay special attention to CVE-2022-21999 since it was reported during the Tianfu Cup. Other bugs associated with this contest have been used in active attacks.
Moving on to the Security Feature Bypass (SFB) updates, there are two in addition to the previously mentioned one in Outlook for Mac. The bug in OneDrive for Android requires physical access to an unlocked phone but could allow an attacker to access OneDrive files while bypassing authentication. Really, if an attacker has access to your unlocked Android, this bug is probably the least of your concerns. The SFB for SharePoint is more severe since it could allow an attacker to bypass the blocking of HTTP requests based on IP range.
There are five patches fixing Denial-of-Service (DoS) bugs in this month’s release, and the one for Microsoft Teams stands out. While Microsoft provides no details about the exploit, it does indicate all versions of Teams need an update, including iOS and Android versions. The DoS in Hyper-V server should also be noted as successful exploitation could affect functionality of a Hyper-V host. The DoS vulnerability in .NET affects applications using the Kestrel web server. If you aren’t familiar with it, Kestrel is a cross-platform server within ASP.NET Core and is enabled by default. If you’re using Kestrel as an Internet-facing server, definitely apply this patch to prevent a DoS while handling certain HTTP/2 and HTTP/3 requests.
The February release contains three patches for spoofing bugs. There’s a patch for Azure Data Explorer. To receive the update, you will need to restart the Kusto.Explorer application. Dynamics GP receives an update here that could almost be considered code execution. While the vulnerability is in the web server, successful exploitation could allow malicious scripts to execute in the user’s browser on the target machine. And while spoofing bugs in SharePoint usually mean some form, the bug getting patched this month is different. An authenticated attacker could manipulate a SharePoint page they control to trick targeted users into sending attacker-controlled requests to the server under the permissions context of the target.
The lone Moderate-rated patch this month addresses a tampering bug in the Edge (Chromium-based) web browser.
No new advisories were released this month. The latest servicing stack updates can be found in the revised ADV990001.
The next Patch Tuesday falls on March 8, 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!
Recently, Samba released a patch to address an Out-of-Bounds (OOB) Heap Read/Write vulnerability found in Samba versions prior to 4.13.17. This vulnerability was disclosed at Pwn2Own Austin 2021 by Nguyễn Hoàng Thạch (@hi_im_d4rkn3ss) and Billy Jheng Bing-Jhong (@st424204) of STAR Labs. After the event, Lucas Leong of Trend Micro Zero Day Initiative discovered additional variants of the vulnerability which were disclosed to Samba as part of this fix. This bug was also independently reported to Samba by Orange Tsai of DEVCORE.
This vulnerability allows remote attackers to execute arbitrary code on affected installations of Samba. Authentication is not required to exploit this vulnerability. The specific flaw exists within the parsing of EA metadata in the Samba server daemon (smbd) when opening a file. An attacker can leverage this vulnerability to execute code in the context of root.
Now that the patch has been made available, let’s take a more detailed look at the bugs involved and the patch released to fix them. Much of this information was derived from the white paper submitted by STARLabs as a part of their Pwn2Own entry.
Within Samba, the server daemon that provides the file sharing service is known as smbd. This analysis was conducted on smbd version 4.9.5, which can be downloaded here. While this isn’t the latest version of Samba, there are still quite a few vendors that incorporate this version or prior versions in their products. This was the case during Pwn2Own Austin 2021. Since Samba provides file sharing between devices, it is often enabled by default. The configuration of smbd is found in /etc/samba/smb.conf. Here’s a portion of an smb.conf file showing how Samba would be configured to support a Time Machine share for Apple devices:
In this section, you can see that guest ok = yes is declared, which allows guest authentication. The vfs objects list contains three modules: catia, fruit, and streams_xattr. The bugs we’re concerned with reside in the fruit module, which provides enhanced compatibility with Apple SMB clients. As stated by the vendor advisory, “The problem in vfs_fruit exists in the default configuration of the fruit VFS module using fruit:metadata=netatalk or fruit:resource=file. If both options are set to different settings than [sic] the default values, the system is not affected by the security issue.”
The fruit module that ships with Samba is designed to provide interoperability between Samba and Netatalk. Netatalk is an open-source implementation of the Apple Filing Protocol (AFP). It allows Unix-like systems to serve as file servers for Apple devices. Once a session is established, smbd allows an unauthenticated user to set extended file attributes of a file via SMB2_SET_INFO. This is done by the set_ea function found in “source3/smbd/trans2.c”. The name of the attribute must not be within the private Samba attribute name list, which includes user.SAMBA_PAI, user.DOSATTRIB, user.SAMBA_STREAMS, and security.NACL. With the exception of these attributes, an attacker can set arbitrary extended attributes.
The fruit module handles requests that access a file with the stream name :AFP_AfpInfo or :AFP_Resource. If using the stream name :AFP_AfpInfo, an attacker can open, read, and write Netatalk metadata of a file. Netatalk metadata is stored in a adouble structure, which is initialized by the ad_get/ad_fget functions.
The Netatalk metadata of a file is stored in the value of the extended attribute identified by the name org.netatalk.Metadata. The metadata will be parsed to fill the adouble (AppleDouble) structure. Since org.netatalk.Metadata isn't in the private Samba attribute name list discussed above, an attacker can set an arbitrary value for this attribute. Therefore, it's possible for an attacker to inject malformed metadata values. This can lead to multiple out-of-bounds memory accesses when the adouble structure is later used.
Let’s take a more detailed look at the bugs used to exploit this vulnerability during the Pwn2Own competition.
The fruit_pread function reads metadata of a file. Since our file stream is named :AFP_AfpInfo and the file type is ADOUBLE_META, the function chain fruit_pread_meta -> fruit_pread_meta_adouble will be executed.
Consider the following source code:
At line 4279, the ad_fget function creates an adouble structure containing attacker-controlled data.
At line 4285, the call to ad_get_entry returns the pointer to the ADEID_FINDERI entry. Since this is controllable by the attacker, they can make p point to the last byte of the ad->data buffer. This will cause the memcpy call at line 4300 to read past the end of the allocated buffer and dump up to thirty-one bytes of memory from the heap.
The fruit_pwrite function is used to write metadata to a file. Since we can already control an ADEID_FINDERI entry, we can leverage that to control a memcpy call, which allows us to write up to thirty-one bytes of data to the heap.
Consider the following source code:
At line 4657, the ad_fget function creates the adadouble structure from metadata. As mentioned before, an attacker could inject malformed metadata here and control the values within.
Later at line 4664, the ad_get_entry returns the pointer to the ADEID_FINDERI entry. Since this is controllable by the attacker, they can set p to point to the last byte of the ad->data buffer. This allows the memcpy call at line 4671 to write past the end of the ad->ad_data buffer. Since ad->ad_data is allocated from heap memory, the attacker can leverage this vulnerability to write up to 31 bytes of data past the end of the heap buffer.
When analyzing the bugs used during Pwn2Own, ZDI Vulnerability Researcher Lucas Leong noticed a variant of the vulnerability used at the contest.
In the case of the bugs used during Pwn2Own, Samba fails to validate the ADEID_FINDERI function, which leads to an OOB read and OOB write. Further analysis from Lucas found that Samba does not validate the ADEID_FILEDATESI entry either. This leads to OOB read in ad_getdate and an OOB write in ad_setdate. This leads to an overflow of three bytes, as seen in the code below:
An attacker can possibly leverage this vulnerability to execute code in the context of the smbd daemon.
The source code of the patch for CVE-2021-44142 can be found here. The primary change from the vendor was an update to two areas to mitigate this vulnerability.
First, Samba added the function ad_entry_check_size(), which validates the size of each entry when parsing the AppleDouble format.
Second, Samba added the Netatalk extended attribute AFPINFO_EA_NETATALK to the list of the private attribute name list. Since an attacker needs to set the malformed extended attribute on a file at the beginning stage of this exploit, this change effectively blocks any user attempting to set any Netatalk extended attribute. This is a generic mitigation for this attack vector.
Samba patched this and other bugs on January 31, 2022. They assigned CVE-2021-44142 to cover the bugs discussed in this report. In addition to 4.13.17, Samba 4.14.12 and 4.15.5 have been released to address this vulnerability. The vendor does list removing the fruit VFS module from the list of configured VFS in “smb.conf” as a workaround. However, this will severely impact the functionality of any macOS systems attempting to access the Samba server. Because of this, you should focus on testing and deploying the patch to remediate this vulnerability. It’s also recommended to reach out to any third-party vendors with devices on your enterprise to ensure they have consumed the patch and provided updates to their devices as well. It is expected that many different vendors will need to update the version of Samba they ship with their devices, so expect lots of additional patches to address these bugs.
Thanks again to Nguyễn Hoàng Thạch (@hi_im_d4rkn3ss) and Billy Jheng Bing-Jhong (@st424204) of STAR Labs for participating in Pwn2Own Austin 2021 and demonstrating this bug. At the contest, they won $45,000 from this exploit alone, and a total of $113,500 for the entire event. We certainly hope to see them at future competitions. Until then, follow the team for the latest in exploit techniques and security patches.
CVE-2021-44142: Details on a Samba Code Execution Bug Demonstrated at Pwn2Own Austin
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 recent code execution vulnerability in the Apache webserver. The bug was originally discovered and reported by the researcher named Chamal. A carefully crafted request body can cause a buffer overflow in the mod_lua multipart parser, which could lead to code execution in the context of the security process. The following is a portion of their write-up covering CVE-2021-44790, with a few minimal modifications.
An integer underflow vulnerability has been reported in the mod_lua module of Apache httpd. The vulnerability is due to improper validation of the request body in the module's multipart parser, called via the r:parsebody() function in Lua scripts. A remote, unauthenticated attacker could exploit this vulnerability by sending a crafted request to the target server. Successful exploitation could lead to remote code execution under the security context of the server process, while an unsuccessful attack could lead to a denial-of-service condition.
The Apache HTTP server is the most popular webserver used on the Internet. The server is capable of being utilized with many different options and configurations. A wide variety of runtime loadable plug-in modules can be used to extend its functionality.
One of the official plug-in modules is the mod_lua module. As with all other modules, it can be compiled as a separate shared library with a “.so” extension. The purpose of this module is to allow the extension of the HTTP server with scripts written in the Lua programming language. If this module is loaded in the HTTP server configuration file, the lua-script handler can be set for files ending in “.lua”. The following demonstrates such a sample configuration:
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 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 similar request using the POST method might look like:
If there is more than one parameter/value pair, they are encoded as &-delimited name=value pairs:
The data in the Body of HTTP POST requests can be encoded using various standardized or proprietary methods. One of the standardized methods is multipart/form-data, defined in RFC 2388. 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. The Content-Type must also be 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.
One of the built-in functions supported by the mod_lua module is r:parsebody(). This function allows Lua scripts to parse the body of HTTP POST requests sent to the server. The function returns two Lua tables containing the parameter names and values parsed from the body. This function also supports HTTP POST requests encoded using the multipart/form-data content type.
An integer underflow vulnerability exists in the Apache HTTP server. When the mod_lua module is enabled and the r:parsebody() function is called from within a Lua script parsed by the server, the function req_parsebody() is called. This function checks if the HTTP POST request received by the server contains a Content-Type header beginning with the string "multipart/form-data; boundary=", indicating that the request body is encoded using the multipart/form-data content type. If found, the function searches for the boundary string defined in the ContentType header, saved to the multipart variable. After each match of the multipart string, the function searches for the first occurrence of two consecutive CRLF sequences, stored to the CRLF variable. If this match is found, the function searches in the following content for another occurrence of the multipart variable, stored to the end variable, indicating the end of the form element's data.
Later, the size of the form element's data is calculated by taking the end variable, subtracting the CRLF variable, then subtracting 8 (representing the two CRLF sequences before the element's data, and the CRLF and "--" characters at the end of the element's data). However, if the form element is not properly formatted, such that the end boundary string appears within less than 8 characters after the beginning of the two CRLF sequences, this subtraction would result in a negative number. The result of the subtraction is stored in a variable named vlen of type size_t. Therefore, if the subtraction results in a negative number, it will be converted into a large positive number before being stored in the vlen variable, resulting in an integer underflow. Specifically, if the subtraction results in -1, the vlen variable will contain the maximum size of size_t. Later, a buffer named buffer is allocated on the heap with a size of vlen+1. In the case described, this will result in an integer overflow, resulting in the allocation of a buffer of size 0. Later, the memcpy() function is called to copy the element's data into the buffer variable, with a size of vlen, resulting in a buffer overflow.
A remote, unauthenticated attacker could exploit this vulnerability by sending an HTTP POST request with a crafted body, encoded using the multipart/form-data content type, to the target server. Successful exploitation could lead to remote code execution under the security context of the server process, while an unsuccessful attack could lead to a denial-of-service condition.
Detection of Generic Attacks
The detection device must inspect all HTTP POST requests to URLs resolving to Lua scripts hosted on the Apache server. The detection device must then inspect the Content-Type header and check if it is set to “multipart/formdata”. If found, the detection device must inspect all instances of the boundary string from the Content-Type header in the HTTP body. For each instance of the boundary string found, the detection device must search for the first instance of two consecutive CRLF sequences following the found boundary. If found, the detection device must search for the next instance of the boundary string. If found, the detection device must calculate the number of characters between the beginning of the two consecutive CRLF sequences and the following boundary string. If the number of characters is less than 8, the traffic should be considered malicious; an attack exploiting this vulnerability is likely underway.
A sample malicious request, with 7 characters between beginning of the two consecutive CRLF sequences and the end boundary string, follows:
Note that the string matching must be performed in a case-sensitive manner
This bug has been patched by Apache with HTTP Server 2.4.52. They do not list any mitigating factors, so applying the update is the only method to fully address this vulnerability.
Special thanks to Guy Lederfein and Dusan Stevanovicof 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-2021-44790: Code Execution on Apache via an Integer Underflow
Now that we’re almost through the first month of 2022, it’s a good opportunity for us to take a look back at 2021 and the accomplishments of the Zero Day Initiative throughout the year. The past year was certainly a year full of its challenges, but we also celebrated some unique achievements in our busiest year ever. In addition to publishing the highest number of advisories in the history of the program, we hit our first million-dollar Pwn2Own in April. And as if that weren’t enough, we did it again in the fall as Pwn2Own Austin also exceeded the $1,000,000 threshold.
To say these were superlative events is an understatement. In the spring edition, we saw multiple Exchange exploits demonstrated, including ProxyShell. We saw 0-click remote code execution demonstrated on Zoom messenger and a 1-click code execution on Microsoft Teams. That’s on top of the Chrome, Edge, and Safari web browsers all getting compromised, too. The fall event had its own highlights, with the Samsung Galaxy, multiple routers, NAS devices, and printers being exploited. Watching a printer rock out some AC/DC after an exploit was just a bonus.
Of course, that should not detract from the great submissions we received throughout the year. We’ve already listed our Top 5 bugs from 2021, but that barely scratches the surface of the tremendous research disclosed to ZDI this past year. And while we are always impressed with the quality of research submitted to the program, ZDI’s own researchers stepped up this year and account for 31% of all published advisories. Still, we’re super thankful for our global community of independent researchers, and we congratulate the 25 researchers to achieve reward levels in 2021. We had six people reach Platinum status, two reach Gold, 4 Silver, and 13 Bronze. The work and submissions from our community of independent researchers are key to our success, and we thank all of them for their continued trust in our program.
Our program also wouldn’t work without vendors generating and releasing fixes for the vulnerabilities we report to them. The ZDI would not be able to sustain this level of advisories – and thus, better protections for Trend Micro customers – without the contributions of researchers and vendors, and we thank them for all they do.
Let’s take a look at some of the more interesting stats from 2021.
By the Numbers
In 2021, the ZDI has published 1,604 advisories – the most ever in the history of the program. This is the second year in a row where eclipsed our previous all-time total. While it’s unlikely we’ll keep up a record-breaking pace for the third year in a row, it does speak to the overall health of the program. Here’s how that number of advisories stacks up year-over-year.
Coordinated disclosure of vulnerabilities continues to be a successful venture. While 2020 saw our largest percentage of 0-day disclosures, the number declined in 2021 to be in line with our “average” number of disclosures from previous years. The 137 0-day disclosures this past year represents 8.5% of our total disclosures – down from 18.6% the year before. This is a positive trend, and we hope it continues moving forward.
Here’s a breakdown of advisories by vendor. The top vendors here should not be surprising, although it is interesting to see Siemens in the top 5. We purchase quite a few ICS-related bugs throughout the year, and our Pwn2Own Miami competition focuses solely on ICS and SCADA-related bugs. In all, we disclosed 586 ICS-related bugs in 2021 – roughly 36.5% of the total number of advisories published by ZDI. As far as enterprise software goes, it’s no surprise at all to see Microsoft on top of the list again this year. In fact, 19.6% of all bugs addressed by Microsoft in 2021 came through the ZDI program, and we remain a significant source of bugs reported to Adobe, Apple, and others.
We’re always looking to acquire impactful bugs and, looking at the CVSS scores for the advisories we published in 2021, we did just that. A total of 74% of these vulnerabilities were rated Critical or High severity.
Here’s how that compares year-over-year going back to 2015:
As you can see, after 2018 we made a conscious effort to ensure we were acquiring vulnerabilities that have the greatest impact on our customers. We’ll continue to do that in the coming year as well. We continually work with Trend Micro customers to determine which products they have deployed in their enterprise. That helps us shape our purchasing and research directions.
When it comes to the types of bugs we’re buying, here’s a look at the top 10 Common Weakness Enumerations (CWEs) from 2021:
It’s no surprise to see two CWEs related to out-of-bounds accesses at the top of the list, nor is it surprising to see this followed by use-after-free (UAF) bugs and heap-based buffer overflow issues. In fact, the top seven CWEs are all related to memory corruption somehow. A total of 72% of the advisories we published in 2021 were related to memory corruption bugs. Clearly, we as an industry still have work to do in this area.
Moving into the new year, we anticipate staying just as busy. We currently have more than 600 bugs reported to vendors awaiting disclosure. We have Pwn2Own Miami and Pwn2Own Vancouver just on the horizon – and both will (fingers crossed) have participation on location. This year will be the 15th anniversary of Pwn2Own in Vancouver, and we’re planning some very special treats as a way to celebrate. Don’t worry if you can’t come to the contest themselves, as we’ll be streaming the events on YouTube and Twitch as they occur. If you ever wanted to attend Pwn2Own but couldn’t, you have a chance to watch them online.
In the coming year, we’re also looking to expand our program by acquiring bugs with an even bigger impact on our customers and the global community. Expect to see us purchasing more bugs in cloud-native applications, the Linux operating system, and anything else that poses a significant threat to our customer’s networks and resources. We look forward to refining our outreach and acquisition efforts by further aligning with the risks our customers are facing to ensure the bugs we squash have the biggest impact on our customers and the broader ecosystem.
In other words, 2022 is shaping up to be another exciting year with impactful research, great contests, and real information you can use. We hope you come along for the ride. Until then, be well, stay tuned to this blog, subscribe to our YouTube channel, and follow us on Twitter for the latest updates from the ZDI.
In October of this year, we received a report from ngocnb and khuyenn from GiaoHangTietKiem JSC covering a SQL injection vulnerability in WordPress. The bug could allow an attacker to expose data stored in a connected database. This vulnerability was recently addressed as CVE-2022-21661 (ZDI-22-020). This blog covers the root cause of the bug and looks at how the WordPress team chose to address it. First, here’s a quick video demonstrating the vulnerability:
The vulnerability occurs in the WordPress Query (WP_Query) class. The WP_Query object is used to perform custom queries to the WordPress database. This object is used by plugins and themes to create their custom display of posts.
The vulnerability occurs when a plugin uses the vulnerable class. One such plugin is Elementor Custom Skin. For this post, we tested the vulnerability against WordPress version 5.8.1 and Elementor Custom Skin plugin version 3.1.3.
In this plugin, the vulnerable WP_Query class is utilized in the get_document_data method of ajax-pagination.php:
The get_document_data method is invoked when a request is sent to wp-admin/admin-ajax.php and the action parameter is ecsload.
Figure 2 - wordpress/wp-admin/admin-ajax.php
The admin-ajax.php page checks whether the request was made by an authenticated user. If the request came from a non-authenticated user, admin-ajax.php calls a non-authenticated Ajax action. Here, the request is sent without authentication so that the non-authenticated Ajax action is called, which is wp_ajax_nopriv_ecsload.
Searching for the string “wp_ajax_nopriv_ecsload” shows that it is a hook name present in the ajax-pagination.php page:
The get_posts method first parses the user-supplied parameters. Next, it calls the get_sql method which eventually calls get_sql_for_clause to create clauses of the SQL statement from the user-supplied data. get_sql_for_clause calls clean_query to validate the user-supplied string. However, the method fails to validate the terms parameter if the taxonomy parameter is empty and the value of the field parameter is the string “term_taxonomy_id”. The value of the terms parameter is later used in the SQL statement.
Note that the sql variable returned by get_sql() is appended to an SQL SELECT statement and assembled using strings returned from the WP_Tax_Query->get_sql() method. Later, in the get_posts method, this query is executed by $wpdb->get_col() method, where an SQL injection condition occurs.
This vulnerability can be exploited to read the WordPress database:
The patch to address CVE-2022-21661 adds some additional checks to the terms parameter to help prevent further SQL injections from occurring.
Active attacks on WordPress sites often focus on optional plugins rather than the core of WordPress itself. That was the case earlier this year when a bug in the Fancy Product Designer plugin was reported as being under active attack. Similarly, a file upload vulnerability in the Contact Form 7 plugin was also detected as being exploited by Trend Micro sensors. In this case, the bug is exposed through plugins, but exists within WordPress itself. While this is a matter of information disclosure rather than code execution, the data exposed could prove valuable for attackers. It would not surprise us to see this bug in active attacks in the near future. We recommend applying the patch or taking other remedial action as soon as possible. Special thanks to ngocnb and khuyenn from GiaoHangTietKiem JSC for reporting this to the ZDI. You can read their analysis of the bug here.
CVE-2022-21661: Exposing Database Info via WordPress SQL Injection
Starting in 2007, Pwn2Own has grown from a small, browser-focused event to become one of the most well-known security contests in the industry. Back then, a successful exploit earned a MacBook and $10,000 for the winner. This past year, the ZDI awarded over $2.5 million dollars at Pwn2Own competitions around the world (plus a whole bunch of hardware). 2022 marks the 15th anniversary of the contest, and we’ve set out to make it the best competition ever.
To start, we’ll return in person to the Sheraton Wall Center in Vancouver for the CanSecWest conference on May 18-20, 2022. We’ll still allow remote participation in this hybrid event. If you have either travel restrictions or travel safety concerns, you can opt to compete remotely. You will still need to register before the contest registration deadline (May 12, 2022) and submit a detailed whitepaper completely explaining your exploit chain and instructions on how to run the entry. A member of the ZDI staff in Vancouver will run your exploit for you.
Next, Tesla returns as a partner, but driving off with a new car will be more of a challenge this year. We’ll have both a Tesla Model 3 and a Tesla Model S available as targets. Of course, with a greater challenge comes a greater reward, with the top prize going for $600,000 (plus the car itself). Other partners this year include Zoom and Microsoft. In last year’s event, Zoom and Teams exploits were highlights, and both return as targets in the Enterprise Communications category. Of course, virtualization exploits are always a contest highlight, and VMware returns as a sponsor with VMware Workstation and ESXi returning as targets.
In addition to the in-person attempts at the conference, we’ll be live-streaming select attempts on Twitch, YouTube, and more. Contestants will be able to participate in almost all categories remotely, but we hope many will join us in Vancouver to demonstrate their exploits. All told, more than $1,000,000 USD in cash and prizes are available to contestants, including the Tesla Model 3, in the following categories:
Of course, no Pwn2Own competition would not be complete without us crowning a Master of Pwn. Since the order of the contest is decided by a random draw, contestants with an unlucky draw could still demonstrate fantastic research but receive less money since subsequent rounds go down in value. However, the points awarded for each successful entry do not go down. Someone could have a bad draw and still accumulate the most points. The person or team with the most points at the end of the contest will be crowned Master of Pwn, receive 65,000 ZDI reward points (instant Platinum status), a killer trophy, and a prettysnazzyjacket to boot.
Let's take a look at the details of the rules for this year's contest.
We’re happy to have VMware returning as a Pwn2Own sponsor for 2022, and this year, again we’ll have VMware ESXi alongside VMware Workstation as a target with awards of $150,000 and $75,000 respectively. VMware has been a sponsor of Pwn2Own for several years, and we’ve seen some great research presented at the contest in years past. Microsoft also returns as a target for 2022 and leads the virtualization category with a $250,000 award for a successful Hyper-V Client guest-to-host escalation. Oracle VirtualBox rounds out this category with a prize of $40,000. We’ve seen some amazing guest-to-host OS escalations demonstrated at previous Pwn2Own contests. Here’s hoping we see more this year.
There’s an add-on bonus in this category as well. If a contestant can escape the guest OS, then escalate privileges on the host OS through a Windows kernel vulnerability (excluding VMware ESXi), they can earn an additional $50,000 and 5 more Master of Pwn points. That could push the payout on a Hyper-V bug to $300,000. Here’s a detailed look at the targets and available payouts in the Virtualization category:
While browsers are the “traditional” Pwn2Own target, we’re continuously tweaking the targets in this category to ensure they remain relevant. For this year’s event, a successful demonstration no longer requires a sandbox escape. Renderer-only exploits will earn $50,000, but if you have that Windows kernel privilege escalation or sandbox escape, that will earn you up to $100,000 or $150,000 respectively. If your exploit works on both Chrome and Edge, it will qualify for the “Double Tap” add-on of $25,000. The Windows-based targets will be running in a VMware Workstation virtual machine. Consequently, all browsers (except Safari) are eligible for a VMware escape add-on. If a contestant can compromise the browser in such a way that also executes code on the host operating system by escaping the VMware Workstation virtual machine, they will earn themselves an additional $75,000 and 8 more Master of Pwn points. Here’s a detailed look at the targets and available payouts:
Enterprise applications also return as targets with Adobe Reader and various Office components on the target list once again. Prizes in this category run from $50,000 for a Reader exploit with a sandbox escape or a Reader exploit with a Windows kernel privilege escalation and $100,000 for an Office 365 application. Word, Excel, and PowerPoint are all valid targets. Microsoft Office-based targets will have Protected View enabled. Adobe Reader will have Protected Mode enabled. Here’s a detailed view of the targets and payouts in the Enterprise Application category:
Last year, we expanded the Server category by adding Microsoft Exchange and SharePoint. Consequently, we saw some amazing Exchange exploits demonstrated – including ProxyShell. Both targets return for this year’s contest with SharePoint garnering a larger payout. We’ve also added Samba to this year’s event, and we’re excited to see what research may be demonstrated. This category is rounded out by Microsoft Windows RDP/RDS, which also has a payout of $200,000. Here’s a detailed look at the targets and payouts in the Server category:
This category is a classic for Pwn2Own and focuses on attacks that originate from a standard user and result in executing code as a high-privileged user. A successful entry in this category must leverage a kernel vulnerability to escalate privileges. Ubuntu Desktop and Microsoft Windows 11 are the two OSes available as targets in this category.
We introduced this category last year to reflect the importance of these tools in our modern, remote workforce, and we were thrilled to see both targets compromised during the contest. We’re also excited to have Zoom return as a partner for this year’s Pwn2Own event. A successful attempt in this category must compromise the target application by communicating with the contestant. Example communication requests could be audio calls, video conferences, or messages. Both Zoom and Microsoft Teams have a $150,000 award available, so we’re hoping to see more great research in this category.
We introduced the Automotive category in 2019, and we are excited to have Tesla return as a partner for 2022. We awarded a Tesla Model 3 in that first contest, but we wanted to raise the level of complexity for this year’s event. Tesla vehicles are equipped with multiple layers of security, and for this year’s event, there are three different tiers of awards within the Automotive category that corresponds to some of the different layers of security within a Tesla car, with additional prize options available in certain instances. Contestants can register an entry against either a Tesla Model 3 (Intel or Ryzen-based) or the Tesla Model S (Ryzen-based).
Tier 1 earns the top prizes and represents a complete vehicle compromise. Correspondingly, this also has the highest award amounts. To win this level, a contestant will need to pivot through multiple systems in the car, meaning they will need a complex exploit chain to get arbitrary code execution on three different sub-systems in the vehicle. Success here gets a big payout and, of course, a brand-new Tesla.
In addition to the vehicle itself and $500,000, contestants can go for the additional options to raise the payout to $600,000. This represents the single largest target in Pwn2Own history. If someone can do this, it would also mean 60 total Master of Pwn points, which is nearly insurmountable. Here’s some additional info on the optional add-ons that are included in the various tier levels.
Again, it’s difficult to express the complexity of completing such a demonstration, but we’re certainly hopeful that someone can show off their exploit skills and drive off a winner.
The second tier in this category is not quite as complex but still requires the attacker to pivot through some of the vehicle’s sub-systems. This level requires the contestant to get arbitrary code execution on two different sub-systems in the vehicle, which is certainly a difficult challenge. If you include the optional targets, the largest single payout for Tier 2 would be $400,000. A winning entry in Tier 2 would still be an impressive and exciting demonstration and includes driving off with the Tesla. Tier 2 also includes some of the above add-ons, as detailed below:
The targets in Tier 3 could prove to be just as difficult, but you only need to compromise one sub-system for a win here, which is still no easy task. Not every instance within Tier 3 includes winning the car. This year also introduces the Diagnostic Ethernet as a vector of attack. Some of the Tier 3 targets have add-ons available, but to drive away with a Tier 3 prize, a contestant would need to target one of the entries marked “Vehicle Included” in the table below:
The complete rules for Pwn2Own 2022 are found here. As always, we encourage entrants to read the rules thoroughly if they choose to participate. If you are thinking about participating but have a specific configuration or rule-related questions, email us. Questions asked over Twitter or other means will not be answered. 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. Registration closes at 5 p.m. Pacific Time on May 12, 2022.
Be sure to stay tuned to this blog and follow us on Twitter for the latest information and updates about the contest. We look forward to seeing everyone wherever they may be, and we hope someone has a sweet ride home from this year’s Pwn2Own competition.
With special thanks to our Pwn2Own 2022 Partners Tesla, Zoom, and Microsoft.
Thanks also to our Pwn2Own 2022 Sponsor
Pwn2Own Vancouver Returns for the 15th Anniversary of the Contest