Jack O'Sullivan
March 22 2021
At the beginning of June, fellow researchers from Secarma published a review of released “EquationGroup” malware from a team of hackers known as “ShadowBrokers”. The purpose of the review was to understand the likelihood of a further malware campaign leveraging the released vulnerabilities, and which may follow the publicised “WannaCry” malware, a ransomware variant which caused worldwide destruction of data, impacting many organisations including Telefonica and the NHS (1).
Amongst the exploits identified, one in particular affecting older IIS servers with WebDAV enabled named “ExplodingCan” was highlighted as being of particularly high risk due to the exposed attack surface and readily available exploits which target the underlying vulnerability, CVE-2017-7269 (5).
This post will look at the process in which Secarma researchers analysed the vulnerability during the previous publication, focusing on how the flaw manifests itself, and what can be done to remediate the issue.
It is our hope that by sharing this analysis, the reader will have a better understanding of how vulnerability analysis is completed within our lab.
Windows Server 2003 R2 support
Windows Server 2003 R2 was a popular operating system offered by Microsoft. Released in 2003, Microsoft provided support until 14th July 2015, which marked the end of any security updates. Explicitly: Microsoft would not produce security updates after that date. Meaning that servers running that operating system would remain permanently vulnerable. This was exactly the case with the “ExplodingCan” exploit, which affected all versions of Windows Server 2003 R2 with WebDAV enabled.
While ending support was originally intended to mark the end of the operating system nearly 2 years ago, it was found that (according to Shodan) 375,000 pubic IP addresses exposed IIS 6, a version of Internet Information Services (IIS) found on Windows Server 2003 systems. While only a subset of these systems would be affected by this vulnerability (with the key requirement being WebDAV being enabled), it did provide an indication of just how many servers are running the outdated and unsupported operating system.
Testing the exploit
In order to understand just how the “ExplodingCan” exploit operated, a vulnerable environment was created within our lab by deploying Windows Server 2003 R2. Once installed, both IIS and WebDAV were enabled via the appropriate server roles.
The Windows firewall was configured to expose TCP port 80, and a Kali Linux docker image was used to simulate the attacking machine executing the exploit.
To help with debugging, a number of tools were utilised. A full list can be found at the end of this paper.
To begin our analysis, we wanted to select the simplest exploit available for CVE-2017-7269 to avoid complicating the analysis process with additional exploitation steps not required to trigger the vulnerability. At the time of review, the exploit was available in multiple languages and frameworks, including a Python script from Zhiniang Peng and Chen Wu of the South China University of Technology Guangzhou (2), and a Metasploit module developed by Dominic Chell of MDSec (3).
The simplest of the two exploits for analysis appeared to be the Python module from Zhiniang Peng and Chen Wu. This used a simple Python script utilising a TCP socket to send an ASCII payload (truncated below for brevity):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
import socket
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(( '127.0.0.1' , 80 ))
pay = 'PROPFIND / HTTP/1.1\r\nHost: localhost\r\nContent-Length: 0\r\n'
pay + = 'If: <http://localhost/aaaaaaa'
pay + = '\xe6\xbd\xa8...'
pay + = '>'
pay + = ' (Not ) <http://localhost/bbbbbbb'
pay + = '\xe7\xa5\x88...'
shellcode = 'VVY...'
pay + = shellcode
pay + = '>\r\n\r\n'
print pay
sock.send(pay)
data = sock.recv( 80960 )
print data
sock.close
|
As is always the case when using publicly available exploits, analysis of the script was performed to ensure that only the intended attack was being performed by the Python script, with no attempts to compromise the underlying host or perform unwanted actions.
Once this review was completed, the exploit was executed against the vulnerable deployment of Windows Server 2003 R2 with ProcessHacker running to identify any spawned processes. Immediately after triggering the vulnerability, we saw that “calc.exe” was spawned, with “w3wp.exe” as its parent process:
Reducing the exploit sample
With a stable exploit our attention was now focused on “w3wp.exe” as a good place to start debugging in search of the vulnerability. To do this, we attached WinDBG (a tool available from Microsoft as part of their downloadable debugging tools) to a running instance of “w3wp.exe”, the worker process for IIS.
Next, we wanted to ensure that the operating system was configured with a number of debugging options to increase our chances of identifying the vulnerability. To do this, we used Microsoft's gflags.exe, a tool which can enable a number of options during runtime. Most useful in our case was “Page Heap”, which triggers an exception on an attempt to overflow a heap allocation, and “Create user mode stack trace database”, which will cause Windows to store metadata on each heap allocation, including a stack trace. This information is invaluable during the triage of the crash.
Reviewing the exploit, we saw that the following HTTP request was issued to IIS:
PROPFIND / HTTP/1.1Host: localhost
Content-Length: 0
If: <http://localhost/aaaaaaa[BINARY DATA]>
(Not <locktoken:write1>)
<http://localhost/bbbbbbb[BINARY DATA]>
It is normally good practice to reduce an exploit sample when completing analysis to ensure that the analyst has a full understanding of how the vulnerability is triggered without worrying too much on additional exploitation steps. After some trial and error, we found the following code would trigger a crash in the w3wp.exe process:
1
2
3
4
5
6 |
python -c 'print "PROPFIND / HTTP /1 .1 \
\r\nHost: localhost \
\r\nContent-Length: 0 \
\r\nIf: " \
(Not ) \
\r\n\r\n" | nc test 80 - v
|
When executed with our debugger attached, we observed an “Access Violation” exception occurring on the following instruction:
Based on previous experience, the crash on the “rep movsd” instruction is usually consistent with an overflow.
Next we had to analyse the process runtime during the crash to understand the underlying cause of this overflow.
Reviewing the crash
As we can see from above, the "rep movsd" was the source of the access violation exception. The interesting register values used by this instruction upon the process crash were as follows:
ecx=00000064esi=01ce43fc
edi=01ce5000
Reviewing the edi register value, which serves as the destination pointer with this particular instruction, we immediately see something interesting in that the value is 4k aligned. It was apparent it's value was pointing beyond allocated heap space, which was the reason for the triggered “Access Violation” exception and allowed us to confidently categorise this as a heap overflow vulnerability.
Additionally, we saw that the vulnerability was triggered within the ScStoragePathFromUrl function. If we look at the exploit description, we see the following:
Buffer overflow in the ScStoragePathFromUrl function in the WebDAV service in Internet Information Services (IIS) 6.0...
It was also noteworthy that the vulnerability appeared within the “httpext.dll” library. A quick review of the DLL description indicated that this is a library used to provide WebDAV functionality:
This confirmed that we were looking in the right place.
Back in WinDBG and looking at the data being copied onto the heap, we saw a unicode version of our provided “If” header value:
After resetting the “w3wp.exe” process, and re-running the exploit, we added a breakpoint to the ScStoragePathFromUrl function for further analysis, and used the debugger’s single step function until we reached the rep movsd instruction, the position at which the heap overflow occurs. This time we analysed the heap allocation using WinDBG’s !heap command. This showed that a heap allocation of 0x600 bytes was pointed to by the edi register:
In addition, we the ecx register was set to a value of 0x2EF, meaning that 0xBBC (sizeof(DWORD) * 0x2EF) bytes were being copied into a heap allocation of 0x600 bytes. Ultimately it was this flaw which was responsible for overflowing the heap.
Again using the !heap command, combined with the “Create user mode stack trace database” debug option enabled in gflags, we were able to retrieve a stack trace showing the allocation of this buffer:
Disregarding some of the wrapper functions, we saw that the location “httpext!HrCheckIfHeader+0x13c” appears to under-allocate the heap, which meant that our analysis would now continue at this location.
Finding the bug
At this point, the DLL was loaded into IDA Pro and disassembly continued at HrCheckIfHeader+0x13c.
At this address is a call to the method “CStackBuffer<ushort,260>::resize(uint size)”, which is used to allocate space on the heap based on the provided size parameter. The value for the method parameter is actually taken from the stack, which is earlier set by a call to “wcslen(const wchar_t *wcs)”:
Returning to the debugger, by placing a breakpoint at this location, the unicode string which is passed to the wcslen function became clear as shown below:
It is here that the bug is finally revealed. |
The intention of this code is to calculate the length of our provided header, and allocate enough room on the heap to allow a path to be output. However, the wcslen function only provides the number of characters contained within the string, and not the memory length of the string. To quote the documentation (4):
This is the number of wide characters between wcs and the first null wide character (without including it).
The end result is that a buffer is under allocated by 50%, as each unicode character requires 2 bytes. It is by leveraging this flaw that the exploit is able to gain control of execution, by overwriting adjacent memory.
Microsoft response and official patch
During our investigations, like many security professionals we were in contact with Microsoft and the NCSC. It was apparent just how damaging this vulnerability could be if combined with a malware campaign in the same vein as WannaCry.
With no patch available, we released ExplodingCan-Checker, a tool made available on our GitHub account with the purpose of helping users identify vulnerable servers.
Then, on 13th June 2017, Microsoft announced the availability of a patch to CVE-2017-7269 for Windows Server 2003 R2 (5).
To ensure that our previous understanding of the vulnerability and corresponding risks were correct, the patch was reviewed by our research team.
To begin with, the patch was extracted and loaded into IDA Pro to produce an IDB file which we could work with during the comparison.
When the differences were reviewed, we saw one area which looked familiar:
This comparison shows that 2 x86 instructions have been added within the “HrCheckIfHeader” function:
mov eax, [ebp - 1076]lea edx, [eax+eax+2]
The first instruction loads the eax register with the previously calculated wcslen value (or the count of characters present within the header).
The second instruction doubles that value, with the addition of 2 bytes for the terminating NULL character of the string.
This simple two instruction fix is enough to avoid the vulnerability, by allocating 2 bytes per character instead of 1, meaning the heap now contains enough space for any subsequent writes from the ScStoragePathFromUrl function.
Conclusion
From our original analysis, it was clear just how damaging a vulnerability like this could be if exploited against a vulnerable system.
Originally, the decision by Microsoft to not patch their legacy operating systems meant that a number of systems accessible on the Internet were left affected by this vulnerability if WebDAV was enabled and exposed. Now that a patch has been provided, it is recommended that this is applied to avoid becoming victim to attackers using this exploit.
That said, it also highlights a further risk, in that other vulnerabilities identified in this operating system may not be patched, and with systems exposed over HTTP, applying firewall rules is not a simple solution.
Ensuring that plans are in place to migrate to a supported operating system is a solution which will ensure that when further vulnerabilities are reported, you are receiving the support needed to keep your environment secure.
Tools used
- IDA Pro (Interactive Disassembler) [https://www.hex-rays.com/products/ida/]
- WinDBG [https://developer.microsoft.com/en-us/windows/hardware/download-windbg]
- ProcessHacker [http://processhacker.sourceforge.net/]
- Python [https://www.python.org/]
- Kali Linux docker container [https://www.kali.org/news/official-kali-linux-docker-images/]
- gflags [https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/gflags]
References
- WannaCry: What is next. [https://www.secarma.co.uk/wannacry-what-is-next/]
- WedDAV ScStoragePathFromUrl Buffer Overflow exploit. [https://www.exploit-db.com/exploits/41738/]
- Microsoft IIS WedDav ScStoragePathFromUrl Overflow. [https://www.rapid7.com/db/modules/exploit/windows/iis/iis_webdav_scstoragepathfromurl]
- wcslen function - [http://www.cplusplus.com/reference/cwchar/wcslen/]
- CVE-2017-7269 patch. [https://support.microsoft.com/en-gb/help/3197835/description-of-the-security-update-for-windows-xp-and-windows-server]