Skip to content

Commit 80ebcf2

Browse files
author
HD Moore
committed
See PR rapid7#981.Only real change is to retry on ENOBUF
1 parent 0d6acad commit 80ebcf2

File tree

2 files changed

+34
-26
lines changed

2 files changed

+34
-26
lines changed

modules/auxiliary/scanner/scada/digi_addp_reboot.rb

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ def initialize
4141
], self.class)
4242
end
4343

44-
45-
# Define our batch size
4644
def run_batch_size
4745
datastore['BATCHSIZE'].to_i
4846
end
@@ -51,7 +49,6 @@ def rport
5149
datastore['RPORT'].to_i
5250
end
5351

54-
# Fingerprint a single host
5552
def run_batch(batch)
5653

5754
print_status("Finding ADDP nodes within #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")
@@ -68,16 +65,23 @@ def run_batch(batch)
6865

6966
batch.each do |ip|
7067
begin
71-
7268
# Try all currently-known magic probe values
7369
Rex::Proto::ADDP.request_config_all.each do |pkt|
74-
udp_sock.sendto(pkt, ip, rport, 0)
70+
begin
71+
udp_sock.sendto(pkt, ip, rport, 0)
72+
rescue ::Errno::ENOBUFS
73+
print_status("Socket buffers are full, waiting for them to flush...")
74+
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
75+
parse_reply(r)
76+
end
77+
select(nil, nil, nil, 0.25)
78+
retry
79+
end
7580
end
7681

7782
rescue ::Interrupt
7883
raise $!
79-
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
80-
nil
84+
rescue ::Rex::ConnectionError
8185
end
8286

8387
if (idx % 30 == 0)
@@ -103,7 +107,18 @@ def run_batch(batch)
103107
info = Rex::Proto::ADDP.reply_to_string(res)
104108
print_status("#{ip}:#{rport} Sending reboot request to device with MAC #{res[:mac]}...")
105109
pkt = Rex::Proto::ADDP.request_reboot(res[:magic], res[:mac], datastore['ADDP_PASSWORD'])
106-
udp_sock.sendto(pkt, ip, rport, 0)
110+
111+
begin
112+
udp_sock.sendto(pkt, ip, rport, 0)
113+
rescue ::Errno::ENOBUFS
114+
print_status("Socket buffers are full, waiting for them to flush...")
115+
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
116+
parse_reply(r)
117+
end
118+
select(nil, nil, nil, 0.25)
119+
retry
120+
end
121+
107122
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
108123
parse_reply(r)
109124
end
@@ -115,12 +130,6 @@ def run_batch(batch)
115130

116131
rescue ::Interrupt
117132
raise $!
118-
rescue ::Errno::ENOBUFS
119-
print_status("Socket buffers are full, waiting for them to flush...")
120-
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
121-
parse_reply(r)
122-
end
123-
select(nil, nil, nil, 0.25)
124133
rescue ::Exception => e
125134
print_error("Unknown error: #{e.class} #{e} #{e.backtrace}")
126135
end

modules/auxiliary/scanner/scada/digi_addp_version.rb

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,6 @@ def initialize
4040
], self.class)
4141
end
4242

43-
44-
# Define our batch size
4543
def run_batch_size
4644
datastore['BATCHSIZE'].to_i
4745
end
@@ -50,7 +48,6 @@ def rport
5048
datastore['RPORT'].to_i
5149
end
5250

53-
# Fingerprint a single host
5451
def run_batch(batch)
5552

5653
print_status("Sending Digi ADDP probes to #{batch[0]}->#{batch[-1]} (#{batch.length} hosts)")
@@ -70,13 +67,21 @@ def run_batch(batch)
7067

7168
# Try all currently-known magic probe values
7269
Rex::Proto::ADDP.request_config_all.each do |pkt|
73-
udp_sock.sendto(pkt, ip, rport, 0)
70+
begin
71+
udp_sock.sendto(pkt, ip, rport, 0)
72+
rescue ::Errno::ENOBUFS
73+
print_status("Socket buffers are full, waiting for them to flush...")
74+
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
75+
parse_reply(r)
76+
end
77+
select(nil, nil, nil, 0.25)
78+
retry
79+
end
7480
end
7581

7682
rescue ::Interrupt
7783
raise $!
78-
rescue ::Rex::HostUnreachable, ::Rex::ConnectionTimeout, ::Rex::ConnectionRefused
79-
nil
84+
rescue ::Rex::ConnectionError
8085
end
8186

8287
if (idx % 30 == 0)
@@ -94,12 +99,6 @@ def run_batch(batch)
9499

95100
rescue ::Interrupt
96101
raise $!
97-
rescue ::Errno::ENOBUFS
98-
print_status("Socket buffers are full, waiting for them to flush...")
99-
while (r = udp_sock.recvfrom(65535, 0.1) and r[1])
100-
parse_reply(r)
101-
end
102-
select(nil, nil, nil, 0.25)
103102
rescue ::Exception => e
104103
print_error("Unknown error: #{e.class} #{e} #{e.backtrace}")
105104
end

0 commit comments

Comments
 (0)