 Hi, thank you for joining our talk. A decade after Stuxnet's print of vulnerability, printing is still the story to heaven. First, let's introduce ourselves. My name is Pele Gadar. I'm in the InfoSec field for more than 7 years. Currently working as a senior security researcher at SafeBridge Labs. My main focus is on Windows Internals and vulnerability research. Hi, my name is Tomer Bar. I'm in the InfoSec field for more than 15 years. Currently working as a research team leader at SafeBridge Labs. My main focus is on APT research, Windows Internals and vulnerability research. In this presentation, we will cover the following. We will demonstrate how a threat actor might have the ability to build the propagation part of Stuxnet 2.0. We will do that by walkthrough on the vulnerabilities which were used by Stuxnet. For each one, we will describe the root cause, describe the patch and evaluate the effectiveness of the patch. We will continue with a deep walkthrough of our print spooler research findings, including demos of the 2.0.0. Finally, we will suggest a new mitigation for the entire arbitrary file-write bulk loss. We will be focused on answering two fundamental questions. Is it possible to build equivalent propagation capabilities as Stuxnet capabilities? Second question, if I fully patch my entire Windows operating system, am I safe now? Last note before we start. We will use two symbols during our presentation. An error patch means that the patch logic is very specific and it was possible to re-exploit it. And secondly, a regular patch means that it solves the problem and had not been bypassed until nowadays, as much as we know. Now that we are ready, let's see the recap and the timeline of Stuxnet. Stuxnet is considered by many to be one of the most complex and well-engineered computer worms ever seen. It is believed that the project was developed in 2006 and lasted four years until it was discovered. Stuxnet can be described by the following three parts. The first part is the propagation to the target network by using three remote code-execution exploits and two local privilege-scholation exploits. The next part is the specially-version techniques, which allow Stuxnet to operate under the radar. The third part is the final payload, delivering specifically to Siemens PLC. In our opinion, a decade after Stuxnet, the most interesting part is the propagation capabilities, which is still relevant to almost any targeted attack. Let's zoom in into Stuxnet propagation capabilities. We will describe them one by one. Although it was a decade ago, it's still relevant to all of us, because according to a research posted in 2017, those capabilities were used widely after Stuxnet for attacking a wide range of organizations. Let's dive deeper, ending over to Peter. Thank you, Tomer. So let's start and talk about the LNK vulnerability, which was used by Stuxnet. It used it to spread via weaponized USB flash drive, traveling between internet-facing computers and internal network computers. So the attack vector contained a crafted LNK file, which is a shortcut file. Once it was displayed, an arbitrary DLL, which was specified as the icon file of the LNK, was executed. Here's a screenshot of a crafted LNK file, which exploited the vulnerability. You can observe that the LNK file contains the following. The path of the CPL, external file, and the icon ID, 0, which caused the code to trigger the execution of the DLL, every time the LNK file was displayed. So let's take a look at the exploitation path and how it was patched. The main problem was that instead of loading the CPL DLL file as a data-only file by using loadLibraryX, the code actually called the loadLibraryW function and also executed the DLL. We expected the patch to replace this call in order to avoid execution, but let's see what would actually happen. So the patch added two validations in order to mitigate the vulnerability. First, it checked that the provided CPL file was on Microsoft's white list and was allowed to be loaded. Next, the icon ID, which we control, would have been extracted and converted from a string. If the ID was 0, it would override the 0 with minus 1, meaning it wouldn't be loaded. The patch was very specific, because as you can see, the loadLibrary function still existed, meaning that if someone would have been able to bypass the validations, then the CPL could have been executed. So let's see the bypass which was patched five years later. In order to bypass the patch, we need to bypass the icon ID chat and transform it to 0. It can be done if you will be able to send the minus sign as a parameter to str2nw function. Let's see exactly how it was done. Because of a type confusion between a white car buffer and a car buffer, the original icon ID string was truncated. We can exploit it by providing a long enough buffer, so the icon ID will turn into the minus sign. Once str2nw will return 0 as the icon ID, our arbitrary CPL will be executed. The patch for this one was pretty simple. The truncation bug was removed. The call to loadLibrary, which was the actual root cut, wasn't changed. That means that if there's another way to trigger the loadCPLModule function, it would have been still vulnerable. And apparently there was. Two years later, a new vulnerability was discovered and patched. It called the loadCPLModule function by using another exploitation path which was left unpatched. So the patch for this one was adding the previous logic of a CPL white list. But loadLibrary still was not replaced. What's interesting here is that we have noticed that there is another last path to loadLibrary function. But we haven't seen any disclose vulnerability yet. So moving to the next propagation capability, next we will talk about the Stuxnet's RPC vulnerability, handing over to Tomer. Thanks, Pelik. On 2006, three years before Stuxnet's first non-infection, a new vulnerable RPC vulnerability was discovered and patched. According to Microsoft, it was a very limited scoped attack back then. But later on, a very similar exploitation path was used by both Stuxnet and KulfikerWarm, which became one of the most spreadable worm ever seen. RPC vulnerabilities were the main cause of global computer worms since 2003. Remember Blaster? So it's obvious that the cause of vulnerability in this mechanism is huge. Let's dive into the specific details. The RPC vulnerability root cause that we will present is due to your canonical path. So let's understand what is it, a canonical path. It's actually a pretty simple. It gets an absolute path and converts it to the shortest absolute path, in the meaning of string length. The most common usage of canonical path is for textual comparison of two different representation of the same canonical path. The original vulnerability was a type confusion which lead to a classic stack-based buffer overflow. The vulnerable function was copying a buffer which exceed the allocated buffer, causing memory corruption. Here is the exploitation path. The RPC request triggered a vulnerable function, remote, which lead to an out-of-bound write caused by WCScat function. Please notice the RPC functions name, and TnetPW, we will explain why it's important in the following slots. The patch added a proper buffer length check, which eliminated the original buffer overflow vulnerability. Two years later, a newer vulnerability was discovered in the same exploitation path. This time it was discovered in the RPC wrapper function, which is called NetPR. This function caused the original vulnerable function directly. Remember NetPW? Let's dive into the root cause. The root cause of the vulnerability is that the input path includes more slash dot dot slash cause than the number of prior directory entries. This will result in gaining control over the output buffer pointer, which will point backwards on the stack and will trigger out-of-bound writing after calling the WCScopy this time. So the patch MS867 replaced the WCScopy function with a safer function, StringCopyWorkerW. Let's dive into Stuxnet task scheduler vulnerability. But first, let's understand how the task scheduler worked. The task scheduler job XML file contains the metadata of a job, including which user will execute the job. The folder which contains it is writable by all users. To protect the integrity of the job configuration files and prevent user from modifying them, task scheduler calculated a CRC32 checksum on each created task XML. When it's time to start the job, task scheduler recalculated the XML checksum and compared it to the original value, if they matched the job executed. If not, it would have been ignored. The CRC32 algorithm is collision-prone, which may lead to data forgery. Stuxnet zero-day exploited this fact by forging an XML file of a job which was executed as anti-authority system. It had a custom CRC32 checksum, which was identical to the original task's XML, therefore it would have been executed as a system, resulting in a local previous relation. In the patch MS-1092, Microsoft implemented a second integrity check by using the SHA-256 algorithm, implemented by the compute-ash function, which is less collision-prone. Moving forward, nine years later, a new task scheduler vulnerability was found. The vulnerability abused the backward compatibility feature of the task scheduler mechanism, which provides the option of migrating all tasks from C windows task folder to the new task folder, which is system 32 tasks. In order to exploit it, the attacker would need to perform the following four stops. Step one, create a new job. As a result, an XML file would be created in the new task folder. Step two, override the job file in the legacy task folder with an R-link to the file which the attacker wishes to control. The third step is creating a new legacy task with the same name, and finally trigger an old to new task migration over RPC. As a result, the task scheduler service would update the security information of the file, which the attacker wishes to control, granting the attacker full control privileges on it. The attacker can now replace right to any file, gaining a local privilege escalation. So this is the exploitation path that was used. Let's see how Microsoft patched it. The patch makes sure that the file is not a symbolic link by using two different checks. The first checks verify that the original path is the final path of the file. If it's different, it means that it was redirected by a symbolic link. The second checks verify that the number of the file's NTFS links is not bigger than one. Okay, so let's see the fourth vulnerability moving over to Win32K. Actually, there were dozens of Win32K local privilege escalation vulnerabilities over the last decade. Here is the list of several options from 2020 which can replace the original already patched vulnerability in order to rebuild the Stuxnet 2.0 propagation capabilities part. The only capability which remained is the print spooler vulnerability. Let's start to talk about our printer spooler research and findings. We will start by presenting how we found a 20-plus year old bug by using 20 minutes of fuzzing. We have noticed that each time a print job is being created, it is represented by two files. First, an SPL file, which simply contains the data to be printed. Second, an SHD file, ShadowFile, which will be focused on. It is represented by the undocumented ShadowFile struct and contains the metadata of the print job. For example, printer name, printer port name, document name, and etc. We found that the printer's folder, which contains the SHD files, is writable by all users and that the SHD files are being processed once the service is started. So we asked ourselves, what will happen if we craft our own SHD file? So we started to mutate the SHD files and fuzz the service. After 20 minutes of fuzzing, we had our first crush. We have managed to crush the print spooler service by using a limited user and a crafted SHD file. It's appeared that the code was trying to dereference some part of our data. Treating it as a pointer to a security descriptor without any validation or sanitization of the data which provided in the SHD file. Microsoft did not fix this bug. We will show the response in the end of our talk. Okay, demo time. Let's see a demo of the crush in the latest Windows 10 Insider build. So on the left side, Johnny is a limited user. We can see that we are running on the latest Windows 10 fully patched machine. On the right, the user John is administrator and it is used only for convenience to avoid restarts of the OS instead will restart the service to trigger the vulnerability. So we are copying the crafted SHD file to the printer spooler directory. And now we will trigger the vulnerability by restarting the service and listing the printers via WMI command. As we can see in Procmon, we crushed the service. Ending over to Pelik. Thank you, Tomer. So the crush was cool, but we wanted more. Let's talk on how we got local privilege escalation, twice. One of them is still zero day. So in order to understand the next vulnerabilities we found, we will dive into the printing process in the Windows OS. The print spooler is the service which is responsible for creating and handling print-ups in the Windows OS. Accessing the print spooler is possible remotely, for example using a shared printer, and locally. We will focus on the local scenario. More specifically, we will focus on the fact that the spooler allows the user to print to a file by using a virtual printer. This is an important part, which our further slides rely on. A quick brief on the flow of printing to a file scenario. First, the user sends some data to be printed using an application, for example Notepad, and specifies which file he would like to print to. It means that the data will be printed, which means it will be written to a file using a virtual printer instead of printing to a real printer. The spooler service, spoolersv.exe, which is the RPC server, gets the request. Later on, the local print provider, which is responsible for printing data to files, will print the data into the file which was specified by the user. Let's start with the first print spooler vulnerability which was used in Stuxnet. This is the flow of the vulnerability which was providing a remote code execution. The vulnerability exploited the fact that the spooler allows the user to print to a file on a remote computer on behalf of System and has printed the malicious file to System32, which was a more file. So it was patched on 2010. The patch included two validations. A. Check if the printing job was dispatched locally on the machine itself or remotely. If remotely, it will override and ignore any requested file write operation. Second, it will check that the user have write permissions to the path of the file that he wanted to print before it's writing to it. Moving forward to 2020, we have found a way to bypass the patch locally using almost the same exploitation path. The first check bypass is obvious because we shifted from a remote code execution to a local privilege escalation. The second check needed some work, so let's dive into our print spooler research. We found that a limited user can do some interesting operations without any elevation required by just using partial commands. For example, adding a built-in printer which prints to a local printable, meaning it will print to a file. And specifying a path of the file which he doesn't have access to. For example, System32. Okay, interesting. So does that mean that a user can just print any data he would like to System32? Let's check. So apparently no, or that's what we thought. As we mentioned before, the MS-1061 patch has added a function which validates if the user can write to the path he asked to print to, which means that the user won't be able to print data to System32. So let's understand how can we bypass it. Every time the print spooler initializes, it processes the SHD files which are waiting to be spooled in the same directory for every user. A limited user can create an SHD file which represents a print job which prints to any path, for example, System32. Once the print spooler restarts, it will process the SHD file without being impersonated or aware of who created the print job. Therefore, it will operate as anti-authority system and will print the data to any file as anti-authority system, resulting with allowing the user to write data to any file on the system and gaining an arbitrary file write and a local pre-read escalation. This was actually the bypass of the second patch validation, specifically for the validate output file function. Because the spooler is running as anti-authority system, it has writing permissions to almost every file on the file system, so the check will pass successfully. So let's see a demo of the first local pre-read escalation we found in the print spooler. As you can see, we are running under the context of a limited user. We are using a Windows 10 machine from March before our vulnerability was patched. We are using Johnny which is a limited user. So first we will use PowerShell in order to do the following stuff. We will add a printer port which allows us to print to System32. We will add a printer driver which allows us to create a virtual printer and finally we will add a printer which is using the System32 port. Next we will use a pre-crafted SHD file which represents a print job which prints to System32 and we will use a DLL payload which we would like to write to System32. We will rename it to SPR and we will copy it by using our limited user to the spool printers folder in System32 which is writeable by all users. Now before we will restart the VM, I want you to notice that there are only three users in the computer administrator Johnny and John and that the following file in Windows 32 which is named exploited TXT does not exist. Next let's restart the VM by our limited user in order to... the print spooler will process our SHD file. Once we are logged in back into Johnny user, the print spooler service will process our SHD file will treat it as a print job and will write our file to System32. Next, Windows service will execute our DLL and as you can see we have been able to add a new administrator to the computer and he was able to write a file to System32 named exploited.txt. Now let's verify that we were actually added an administrator. We will open a command prompt which is elevated and we will just log in using our new administrator user. As you can see, the administrator's group contains our user. So we have been able to gain local previews escalation using the print spooler service. So now that we have coupled them all together, we reach our destination. We have found equivalent capabilities to allegedly build Stuxnet 2.0 propagation pump but our work is not over yet. After the first vulnerability we found was patched, we have been able to re-exploit it and we created it with CVE-2020-1337. Microsoft are currently working on a fix which will be deployed in the upcoming patch Tuesday. Therefore, we can't release any technical details right now. We will publish it once the patch will be deployed, but let's see a demo. So as you can see, we are running under the context of Johnny which is a limited user. We are running under a fully patched VM. Under the context of Johnny, we will execute our exploit which will bypass the patch of CVE-2020-1048. After we crafted our SHD file, we will copy to the print spooler directory. But first, you can notice that the exploited TXT file does not exist and that we have only three users as before. Now let's restart the VM. Once it was initialized, we will log in again toward limited user Johnny. Now, as before, the print spooler will process our SHD file and will print the data to System32 which is our payload which is a DLL file. Our DLL file will be loaded into an elevated anti-authority system service and we will gain code execution. Let's try and find the exploiting.txt file. As you can see, we've added the data to System32 and we have been able to add an administrator user once again to the VM. Let's execute command prompt which is elevated and let's log in using our new administrator user. As you can see, we have gained a local primary distillation and the code execution using the print spooler once again after the first one of the ability was patched. Ending over to Tomer. Wow, 1337, that's awesome. So going back to our second question, we would like to propose an additional possible solution as a second level for patching. We believe in a level security mitigation approach. So we reported to MSOC on each vulnerability we found but we still believe it's not enough. So we developed a POC for a real-time prevention of the attack. The main root cause of the arbitrary filerite bug loss in the context of local privilege distillation is the fact that a limited user is allowed to write directly to the following location. This is dangerous and can be exploited very easily and we found that it's actually not really needed for the regular use. Today we will release a mini-filter driver which restricts any far-right operation by a limited user to some of this location as a POC. This mitigation proposal is not specific to the spooler's vulnerabilities and can be used as a template for mitigating the arbitrary far-right bug loss. Please treat the driver as a POC and be careful not to execute it in production system before validating it for false positive. Let's see again. Okay, so this time we are running on Windows 10 RS1 an older version without the patch for the vulnerability we were going to use and as usual we are running as joining a limited user. Let's make sure that our driver is loaded to memory and now we'll present that a regular usage of printing is allowed so our driver will examine the filerite of the SPL and SHD file and we'll allow it. You can see that there are two files in the printer spooler folder with size which is not zero. And now let's copy the SHD and SPL file to the printer spooler directly. Now actually our driver examined the right and blocked it. You can see that the files are of zero size. Let's demonstrate the task scheduler exploit. This is a public exploit and you can see that our driver blocked the right. So for Microsoft's response for the spooler's local privilege escalation the additional vector for CVE-2020-1048 will be addressed in August 2020 as CVE-2020-1337 and for the spooler denial of service the technique results in a local denial of service which doesn't meet Microsoft's servicing bar for security updates. We would like to give credit for the following people for researching similar areas Alex UNESCO and Yaudenjo Fear, Dave Weinstein, IT Acker and Gingola Kia. Today we will list our repository which includes an exploit PLC for CVE-2020-1048 and an exploit PLC for the zero-day denial of service of the spooler service the driver for the arbitrary fire-ride mitigation and in a few days on August 12th we will release the CVE-2020-1337 superlit exploit PLC. Please check our repository. Thank you for joining us and let's go over for the UNI.