[RUBY] Быстрое сканирование портов в сети

Пример скрипта для быстрого сканирования диапазона адресов на предмет открытого TCP порта.
Сканирование ведётся в асинхронном режиме.
Гемы: Сelluloid GEM для потоков, Net-Ping GEM что-бы не писать велосипед с сокетами

1
2
3
gem install celluloid net-ping
wget https://gist.githubusercontent.com/POStroi/181d2dd3291ce707c8cc/raw/19931c85c6fe7a088d289a73bbe1282f9b29fd78/scan.rb
ruby scan.rb 192.168.0.1-254 80

Github GIST

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
#!/usr/bin/env ruby
# gem install celluloid net-ping
require 'celluloid/current'
require 'net/ping'
require 'ipaddr'

class ScanPort
  include Celluloid

  def scan host, port
    res = Net::Ping::TCP.new(host, port)
    if res.ping?
      type = detect(res.host)
      puts "[+] #{host} : #{type}\n"
    end
  end

  def detect(ip)
    begin
      data = Net::HTTP.get_response(ip, '/')
      if !data.body.empty?
        response = data.body
      else
        response = data.header['set-cookie']
      end

      case response
        when /LuCI/
          'OpenWRT LuCI'
        when /mikrotik/
          'MikroTik'
        when /AIROS_/
          'Ubiquiti'
        when /DVR Components/
          'eDVR'
        when /ITV/
          'ITV WebServer Client'
        when /It works!/
          'Blank NGINX'
        when /m.jsp/
          'Phantom DWDR'
        when /DVR IE Video/
          'DVR IE Video - model?'
        when />TL-(.*)</
          "TP-Link #{$1}"
        when /doc\/page\/login.asp/, /\/index.asp">location<\/a>./
          'HikVision DVR'
        when />WEB SERVICE</
          'Maybe - Dahua DVR'

        else
          'Not detect'
      end
    rescue
      'Response error'
    end
  end
end

def make_hosts_list(network)
  ip_range = IPAddr.new network
  (ip_range.to_range).map(&:to_s)
end

def main network, port
  hosts = make_hosts_list(network)
  hosts.each do |host|
    sc = ScanPort.new
    sc.async.scan host, port
  end
end

if ARGV.size < 2
  puts "USE: #{File.basename(__FILE__)} network port "
  puts "Sample: #{File.basename(__FILE__)} 192.168.0.1/24 80 "
  exit
end

main ARGV[0], ARGV[1].to_i

Комментарии