start	end	text
560	2880	Hi, thank you for joining our talk.
2880	5720	A decade after Stuxnet's printer vulnerability,
5720	7700	printing is still the stairway to heaven.
7800	9660	First, let's introduce ourselves.
10580	12180	My name is Pele Gadar.
12180	14760	I'm in the InfoSec field for more than 7 years.
14760	18140	Currently working as a Senior Security Researcher at Saybridge Labs.
18360	21960	My main focus is on Windows internals and vulnerability research.
24440	26840	Hi, my name is Tomer Bar.
26920	29720	I'm in the InfoSec field for more than 15 years.
29720	33860	Currently working as a Research Team Leader at Saybridge Labs.
33860	39640	My main focus is on APT research, Windows internals, and vulnerability research.
44020	47300	In this presentation, we will cover the following.
47320	50520	We will demonstrate how a threat actor might have the ability
50520	54480	to build the propagation part of Stuxnet 2.0.
54480	60000	We will do that by a walkthrough on the vulnerabilities which were used by Stuxnet.
60000	65080	For each one, we will describe the root cause, describe the patch,
65080	68160	and evaluate the effectiveness of the patch.
68640	73900	We will continue with a deep walkthrough of our print spooler research findings,
73900	76860	including demos of the 2.0 dates.
76860	82320	Finally, we will suggest a new mitigation for the entire arbitrary firewrite bug class.
83740	87300	We will be focused on answering two fundamental questions.
87300	91780	Is it possible to build equivalent propagation capabilities as Stuxnet capabilities?
92000	97520	Second question, if I fully patch my entire Windows operating system, am I safe now?
98500	100480	Last note before we start.
100480	103380	We will use two symbols during our presentation.
103620	109520	A narrow patch means that the patch logic is very specific and it was possible to re-exploit it.
109700	113880	And secondly, a regular patch means that it solved the problem
113880	118120	and had not been bypassed until nowadays, as much as we know.
118800	123100	Now that we are ready, let's see the recap and the timeline of Stuxnet.
124660	131700	Stuxnet is considered by many to be one of the most complex and well-engineered computer worms ever seen.
131880	138680	It is believed that the project was developed in 2006 and lasted four years until it was discovered.
139080	142920	Stuxnet can be described by the following three parts.
142920	149340	The first part is the propagation to the target network by using three remote code execution exploits
149340	152980	and two local privilege escalation exploits.
152980	160280	The next part is the special evasion techniques, which allows Stuxnet to operate under the radar.
161020	166140	The third part is the final payload, delivering specifically to Siemens PLC.
166140	173420	In our opinion, a decade after Stuxnet, the most interesting part is the propagation capabilities,
173420	176640	which is still relevant to almost any targeted attack.
178840	182720	Let's zoom in into Stuxnet propagation capabilities.
182720	185240	We will describe them one by one.
185540	192780	Although it was a decade ago, it's still relevant to all of us because according to a research posted in 2017,
192780	199560	those capabilities were used widely after Stuxnet for attacking a wide range of organizations.
199820	202500	Let's dive deeper. Ending over to Pele.
204800	206300	Thank you, Tomer.
206360	210780	So let's start and talk about the LNK vulnerability, which was used by Stuxnet.
211020	217520	It used it to spread via weaponized USB flash drives traveling between Internet-facing computers and internal network computers.
223160	227360	So the attack vector contained a crafted LNK file, which is a shortcut file.
227600	234240	Once it was displayed, an arbitrary DLL, which was specified as the icon file of the LNK, was executed.
236740	240500	Here's a screenshot of a crafted LNK file, which exploited the vulnerability.
240880	243620	You can observe that the LNK file contains the following.
243620	254120	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.
256300	260080	So let's take a look at the exploitation path and how it was patched.
260640	272520	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.
272520	278700	We expected the patch to replace this call in order to avoid execution, but let's see what would actually happen.
280940	284520	So the patch added two validations in order to mitigate the vulnerability.
284740	290660	First, it checked that the provided CPL file was on Microsoft's whitelist and was allowed to be loaded.
291400	296980	Next, the icon ID, which we control, would have been extracted and converted from a string.
297500	302940	If the ID was 0, it would override the 0 with minus 1, meaning it wouldn't be loaded.
304680	316220	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.
319120	322260	So let's see the bypass, which was patched five years later.
325330	330670	In order to bypass the patch, we need to bypass the icon ID check and transform it to 0.
331830	337710	It can be done if you will be able to send the minus sign as a parameter to strToIntW function.
338370	340470	Let's see exactly how it was done.
341010	347610	Because of a type confusion between a white car buffer and a cow buffer, the original icon ID string was truncated.
349130	354910	We can exploit it by providing a long enough buffer, so the icon ID will turn into the minus sign.
355290	361030	Once strToInt will return 0 as the icon ID, our arbitrary CPL will be executed.
364540	369240	The patch for this one was pretty simple. The truncation bug was removed.
369720	373800	The call to loadLibrary, which was the actual root call, wasn't changed.
373800	380360	That means that if there is another way to trigger the loadCplModule function, it would have been still vulnerable.
382840	384640	And apparently there was.
385280	389200	Two years later, a new vulnerability was discovered and patched.
389520	395280	It called the loadCplModule function by using another exploitation path, which was left unpatched.
397960	402220	The patch for this one was adding the previous logic of a CPL whitelist.
402220	406480	But loadLibrary still was not replaced.
408440	414060	What's interesting here is that we have noticed that there is another last patch to loadLibrary function.
414060	417880	But we haven't seen any disclosed vulnerability yet.
420010	423330	So moving to the next propagation capability.
423430	428450	Next, we will talk about the Stuxnet RPC vulnerability, handing over to Tomer.
432310	433950	Thanks, Penel.
434090	442170	On 2006, three years before Stuxnet's first known infection, a new vulnerable RPC vulnerability was discovered and patched.
442170	446390	According to Microsoft, it was a very limited scoped attack back then.
446390	456910	But later on, a very similar exploitation path was used by both Stuxnet and Configure.Warm, which became one of the most spreadable warms ever seen.
456910	462570	RPC vulnerabilities were the main cause of global computer warms since 2003.
462590	463590	Remember Blaster?
464070	468610	So it's obvious that the cost of a vulnerability in this mechanism is huge.
468610	470930	Let's dive into the specific details.
471130	475610	The RPC vulnerability root cause that we will present is due to a canonical path.
475610	478130	So let's understand what is it, a canonical path.
478130	479790	It's actually pretty simple.
479870	485310	It gets an absolute path and converts it to the shortest absolute path in the meaning of string length.
485310	493410	The most common usage of canonical path is for textual comparison of two different representations of the same canonical path.
495030	502250	The original vulnerability was a type confusion, which led to a classic stack-based buffer overflow.
502250	509210	The vulnerable function was copying a buffer which exceeded the allocated buffer, causing memory corruption.
509810	511990	Here is the exploitation path.
511990	520690	The RPC request triggered the vulnerable function remotely, which led to an out-of-bound write caused by WCSCAT function.
520990	525610	Please notice the RPC function's name, NTNetPW.
525610	529090	We will explain why it's important in the following slides.
530810	536970	The patch added a proper buffer length check, which eliminated the original buffer overflow vulnerability.
536970	543090	Two years later, a newer vulnerability was discovered in the same exploitation path.
543090	549190	This time, it was discovered in the RPC wrapper function, which is called NetPR.
549290	553150	This function calls the original vulnerable function directly.
553150	554910	Remember NetPW?
555050	557270	Let's dive into the root cause.
557270	567490	The root cause of the vulnerability is that the input path includes more slash-dot-dot-slash calls than the number of prior directory entries.
567530	572390	This will result in gaining control over the output buffer pointer,
572390	580170	which will point backwards on the stack and will trigger out-of-bound writing after calling the WCS copy this time.
580970	591070	So the patch MS867 replaced the WCS copy function with a safer function, StringCopyWorkerW.
592110	595990	Let's dive into Stuxnet task scheduler vulnerability.
596370	600050	But first, let's understand how the task scheduler works.
600050	607010	The task scheduler job XML file contains the metadata of a job, including which user will execute the job.
607010	611090	The folder which contains it is writable by all users.
611230	616550	To protect the integrity of the job configuration files and prevent users from modifying them,
616550	622230	task scheduler calculated a CRC32 checksum on each created task XML.
622350	629650	When it's time to start the job, task scheduler recalculated the XML checksum and compared it to the original value,
629650	632270	if they matched the job executed.
632690	635290	If not, it would have been ignored.
635290	640310	The CRC32 algorithm is collision-prone, which may lead to data forgery.
640530	649250	Stuxnet ZeoDay exploited this fact by forging an XML file of a job which was executed as anti-authority system.
649270	654470	It had a custom CRC32 checksum, which was identical to the original task XML.
654890	660710	Therefore, it would have been executed as a system, resulting in a local privilege isolation.
660710	669430	In the patch MS1092, Microsoft implemented a second integrity check by using the SHA256 algorithm,
669430	673690	implemented by the compute-hash function, which is less collision-prone.
674290	679570	Moving forward nine years later, a newer task scheduler vulnerability was found.
679570	684590	The vulnerability abused the backward compatibility feature of the task scheduler mechanism,
684590	694050	which provides the option of migrating all tasks from C Windows task folder to the new task folder, which is system32tasks.
694370	699670	In order to exploit it, the attacker would need to perform the following four steps.
699770	706970	Step one, create a new job. As a result, an XML file would be created in the new tasks folder.
706970	715130	Step two, override the job file in the legacy task folder with an R link to the file which the attacker wishes to control.
715770	721330	Third step is creating a new legacy task with the same name.
721390	725810	And finally, trigger an old to new task migration over RPC.
726170	731670	As a result, the task scheduler service would update the security information of the file,
731670	736970	which the attacker wishes to control, granting the attacker full control privileges on it.
737490	742950	The attacker can now replace or write to any file, gaining a local privilege escalation.
745660	751660	So this is the exploitation path that was used. Let's see how Microsoft patched it.
752320	758080	The patch makes sure that the file is not a symbolic thing by using two different checks.
758080	763700	The third check verified that the original path is the final path of the file.
763740	767960	If it's different, it means that it was redirected by a symbolic link.
767960	773480	And the second check verified that the number of the file's NTFS links is not bigger than one.
776200	780600	OK, so let's see the fourth vulnerability moving over to Win32k.
783760	790620	Actually, there were dozens of Win32k local privilege escalation vulnerabilities over the last decade.
790620	797100	Here is a list of several options from 2020, which can replace the original already patched vulnerability,
797100	802420	in order to rebuild the Stuxnet 2.0 propagation capabilities part.
803180	807220	The only capability which remained is the print spooler vulnerability.
811120	815140	Let's start to talk about our printer spooler research and findings.
816260	823940	We will start by presenting how we found a 20 plus year old bug by using 20 minutes of fuzzing.
824200	830220	We have noticed that each time a print job is being created, it is represented by two files.
830220	835620	First, an SPL file, which simply contains the data to be printed.
835680	840040	Second, an SHD file, shadow file, which will be focused on.
840040	846640	It is represented by the undocumented shadow file struct and contains the metadata of the print job.
846640	852080	For example, printer name, printer port name, document name, and etc.
852080	859920	We found that the printer's folder, which contains the SHD files, is writable by all users.
860460	865680	And that the SHD files are being processed once the service is started.
865680	871160	So, we asked ourselves, what will happen if we craft our own SHD file?
871300	875980	So, we started to mutate the SHD files and fuzz the service.
877340	880780	After 20 minutes of fuzzing, we had our first crash.
881120	888820	We have managed to crush the print spooler service by using a limited user and a crafted SHD file.
889080	893700	It appeared that the code was trying to dereference some part of our data.
893700	903580	Treating it as a pointer to a security descriptor without any validation or sanitization of the data we'd provided in the SHD file.
903900	905960	Microsoft did not fix this bug.
906260	909040	We will show the response in the end of our talk.
909560	910880	Okay, demo time.
910880	914840	Let's see a demo of the crash in the latest Windows 10 insider build.
916400	920000	So, on the left side, Johnny is a limited user.
920000	924200	We can see that we are running on the latest Windows 10 fully patched machine.
924200	927540	On the right, the user John is administrator.
927560	931320	And it is used only for convenience to avoid restarts of the OS.
931320	933960	Instead, we will restart the service to trigger the vulnerability.
934180	942180	So, we are copying the crafted SHD file to the printer spooler directory.
951710	971290	And now, we will trigger the vulnerability by restarting the service and listing the printers via WMI command.
977860	981520	As we can see in ProcMon, we crashed the service.
984830	986450	Handing over to Peleg.
989530	990870	Thank you, Tomer.
990910	993730	So, the crash was cool, but we wanted more.
993730	997070	Let's talk on how we got local privilege escalation twice.
997070	998850	One of them is still zero-day.
1000250	1006230	So, in order to understand the next vulnerabilities we found, we will dive into the printing process in the Windows OS.
1007410	1012430	The print spooler is the service which is responsible for creating and handling print ops in the Windows OS.
1012890	1019090	Accessing the print spooler is possible remotely, for example, using a shared printer, and locally.
1019530	1021450	We will focus on the local scenario.
1021450	1028070	More specifically, we will focus on the fact that the spooler allows the user to print to a file by using a virtual printer.
1028550	1031990	This is an important part which our further slides rely on.
1034700	1037600	A quick brief on the flow of printing to a file scenario.
1038040	1046600	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.
1046600	1056540	It means that the data will be printed, which means it will be written to a file using a virtual printer, instead of printed to a real printer.
1057240	1062620	The spooler service, spoolsv.exe, which is the RPC server, gets the request.
1063500	1072120	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.
1074980	1079160	Let's start with the first print spooler vulnerability which was used in Stuxnet.
1079620	1083900	This is the flow of the vulnerability which was providing a remote code execution.
1084340	1092240	The vulnerability exploited the fact that the spooler allows the user to print to a file on a remote computer on behalf of the system,
1092240	1097140	and has printed the malicious file to system32, which was a MOV file.
1099690	1102110	So it was patched on 2010.
1102550	1104630	The patch included two validations.
1104630	1111050	A. Check if the printing job was dispatched locally on the machine itself or remotely.
1111450	1115830	If remotely, it will override and ignore any requested file write operation.
1116750	1124350	Second, it will check that the user has write permissions to the path of the file that he wanted to print to, before retrying to it.
1126860	1133280	Moving forward to 2020, we have found a way to bypass the patch locally using almost the same exploitation path.
1133980	1141540	The first check bypass is obvious because we shifted from a remote code execution to a local privilege escalation.
1141800	1146720	The second check needed some work, so let's dive into our print spooler research.
1148580	1155760	We found that a limited user can do some interesting operations without any elevation required by just using partial commands.
1155760	1161960	For example, adding a virtual printer which prints to a local printer pool, meaning it will print to a file.
1161960	1168460	And, specifying a path of the file which it doesn't have access to, for example system32.
1168840	1176220	Ok, interesting, so does that mean that a user can just print any data he would like to system32? Let's check.
1177760	1180400	So apparently no, or that's what we thought.
1180480	1188180	As we mentioned before, the MS1061 patch has added a function which validates if the user can write to the path he asked to print to.
1188180	1191940	Which means that the user won't be able to print data to system32.
1191940	1195180	So let's understand how can we bypass it.
1199550	1207870	Every time the print spooler initializes, it processes the SHD files which are waiting to be spooled in the same directory for every user.
1208530	1216190	A limited user can create an SHD file which represents a print job which prints to any path, for example system32.
1216570	1224750	Once the print spooler restarts, it will process the SHD file without being impersonated or aware of who created the print job.
1224750	1231510	Therefore, it will operate as an anti-authority system and will print the data to any file as an anti-authority system.
1231690	1240490	Resulting with allowing the user to write data to any file on the system and gaining an arbitrary file write and a local pre-write escalation.
1242350	1248930	This was actually the bypass of the second patch validation, specifically for the validate output file function.
1248930	1255650	Because the spooler is running as an anti-authority system, it has writing permissions to almost every file on the file system.
1255650	1257590	So the check will pass successfully.
1259310	1263810	So let's see a demo of the first local pre-write escalation we found in the print spooler.
1267430	1270990	As you can see, we are running under the context of a limited user.
1271170	1277330	We are using a Windows 10 machine from March, before our vulnerability was patched.
1278090	1280230	We are using Johnny which is a limited user.
1283590	1288770	So first, we will use PowerShell in order to do the following stuff.
1289450	1293190	We will add a printer port which allows us to print to system32.
1295110	1299010	We will add a printer driver which allows us to create a virtual printer.
1300130	1305350	And finally, we will add a printer which is using the system32 port.
1306990	1312870	Next, we will use a pre-crafted SAGD file which represents a print job which prints to system32.
1312870	1317030	And we will use a DLL payload which we would like to write to system32.
1317030	1327670	We will rename it to SPL and we will copy it by using our limited user to the spool printers folder in system32 which is writable by all users.
1331830	1339570	Now, before we will restart the VM, I want you to notice that there are only three users in the computer.
1339630	1341350	Administrator, Johnny and John.
1341370	1348090	And that the following file in Windows 32 which is named exploited.txt does not exist.
1349130	1356550	Next, let's restart the VM by our limited user in order to... the print spooler will process our SAGD file.
1363110	1374410	Once we are logged in back into Johnny user, the print spooler service will process our SAGD file, will treat it as a print job and will write our file to system32.
1374510	1378430	Next, Windows service will execute our DLL.
1378690	1384670	And as you can see, we will be able to add a new administrator to the computer.
1385270	1391130	And it was able to write a file to system32 named exploited.txt.
1391950	1395390	Now, let's verify that we actually added an administrator.
1397350	1403730	We will open a command prompt which is elevated and we will just log in using our new administrator user.
1404670	1414310	As you can see, the administrators group contains our user.
1415250	1420150	So, we have been able to gain local privilege escalation using the print spooler service.
1422130	1425770	So, now that we coupled them all together, we reached our destination.
1436350	1444230	We have found equivalent capabilities to allegedly build Stuxnet 2.0 propagation prompt, but our work is not over yet.
1446870	1455790	After the first vulnerability we found was patched, we've been able to re-exploit it and we created it with CVE-2020-1337.
1456910	1461430	Microsoft are currently working on a fix which will be deployed in the upcoming patch Tuesday.
1461610	1464810	Therefore, we can't release any technical details right now.
1465110	1467550	We will publish it once the patch will be deployed.
1467730	1469390	But, let's see a demo.
1478770	1483230	So, as you can see, we are running under the context of Johnny, which is a limited user.
1488040	1491580	We are running under a fully patched VM.
1496700	1500080	Under the context of Johnny, we will execute our exploit.
1501340	1505500	Which will bypass the patch of CVE-2020-1048.
1510080	1517740	After we crafted our shd file, we will copy to the print spooler directory.
1518880	1526320	But first, you can notice that the exploited txt file does not exist and that we have only three users as before.
1526620	1528860	Now, let's restart the VM.
1534970	1539510	Once it was initialized, we will log in again to our limited user Johnny.
1541990	1550870	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.
1551050	1558070	Our dll file will be loaded into an elevated anti-authority system service and we will gain code execution.
1564400	1567940	Now, let's try and find the exploited.txt file.
1567940	1576020	As you can see, we write the data to system32 and we have been able to add an administrator user once again to the VM.
1576620	1579680	Let's execute a command prompt, which is elevated.
1586470	1589730	And let's log in using our new administrator user.
1592050	1601150	As you can see, we have gained a local private installation and code execution using the print spooler once again after the first vulnerability was patched.
1602390	1604310	Handing over to Tomer.
1606570	1610730	Wow, 1337, that's awesome.
1610930	1619310	So, going back to our second question, we would like to propose an additional possible solution as a second level for patching.
1619710	1631130	We believe in a level security mitigation approach, so we reported to MSRC on each vulnerability we found, but we still believe it's not enough.
1631150	1635990	So we developed a POC for real-time prevention of the attack.
1636610	1648770	The main root cause of the arbitrary file write bug loss in the context of local privilege installation is the fact that a limited user is allowed to write directly to the following location.
1649110	1656470	This is dangerous and can be exploited very easily, and we found that it's actually not really needed for the regular use.
1656470	1665730	Today, we will release a mini-filter driver which restricts any file write operation by a limited user to some of this location as a POC.
1665950	1675690	This mitigation proposal is not specific to the spooler's vulnerabilities and can be used as a template for mitigating the arbitrary file write bug loss.
1675790	1685170	Please treat that driver as a POC and be careful not to execute it in production system before validating it for false positive.
1685170	1687010	Let's see at the end.
1687650	1696370	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.
1696370	1699370	And as usual, we are running as Johnny, a limited user.
1703820	1707280	Let's make sure that our driver is loaded to memory.
1714350	1720630	And now we'll present that regular usage of printing is allowed.
1729400	1736940	So our driver will examine the file write of the SPL and SHD file and will allow it.
1736940	1742600	We can see that there are two files in the printer's spooler folder with size which is not zero.
1756400	1766640	And now, let's copy the SHD SPL file to the printer's spooler directly.
1768260	1773880	Now, actually, our driver examined the write and blocked it.
1773880	1778580	You can see that the files have zero size.
1781700	1786100	Let's demonstrate a task scheduler exploit.
1786100	1790120	Let's make sure that our driver blocked the write.
1793390	1808370	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.
1808550	1818410	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.
1820110	1825150	We would like to give credit for the following people for researching similar areas.
1825150	1831790	Alex Ionesco and Yarden Shafir, Dave Weinstein, Iti Aker, and Jingua Kia.
1833150	1842530	Today, we will release our repository which includes an exploit POC for CVE-2020-1048
1842530	1850530	and an exploit POC for the zero-day denial of service of the spooler service,
1850530	1854370	the driver for the arbitrary file write mitigation,
1854370	1862270	and in a few days, on August 12, we will release the CVE-2020-1337 super-lit exploit POC.
1862270	1863820	Please check our repository.
1866540	1870840	Thank you for joining us and let's go over for the Q&A.
