Class: Kscript::KkPortScanUtils

Inherits:
Base
  • Object
show all
Defined in:
lib/kscript/plugins/kk_port_scan_utils.rb

Instance Attribute Summary collapse

Attributes inherited from Base

#logger

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Base

#human_output?, inherited, #with_error_handling

Constructor Details

#initialize(*args, **opts) ⇒ KkPortScanUtils

Initialize the scanner with target host and port range

Parameters:

  • host (String)

    target host to scan

  • ports (Array<Integer>)

    list of ports to scan

  • thread_count (Integer)

    number of concurrent threads



19
20
21
22
23
24
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 19

def initialize(*args, **opts)
  super
  @target = args[0]
  @ports = parse_ports(args[1] || (1..1024))
  @thread_count = (opts[:thread_count] || 50).to_i
end

Instance Attribute Details

#hostObject (readonly)

Returns the value of attribute host.



13
14
15
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 13

def host
  @host
end

#portsObject (readonly)

Returns the value of attribute ports.



13
14
15
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 13

def ports
  @ports
end

#thread_countObject (readonly)

Returns the value of attribute thread_count.



13
14
15
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 13

def thread_count
  @thread_count
end

Class Method Details

.argumentsObject



86
87
88
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 86

def self.arguments
  '<target_host> [ports] [thread_count]'
end

.authorObject



98
99
100
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 98

def self.author
  'kk'
end

.descriptionObject



82
83
84
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 82

def self.description
  'Scan open ports on a target host.'
end

.groupObject



94
95
96
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 94

def self.group
  'network'
end

.usageObject



90
91
92
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 90

def self.usage
  "kscript port_scan 192.168.1.1\nkscript port_scan example.com 22,80,443 100\nkscript port_scan 192.168.1.1 1..1024 200"
end

Instance Method Details

#parse_ports(ports) ⇒ Object

支持多种端口参数格式: 22,80,443 或 1..1024



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 60

def parse_ports(ports)
  return ports.to_a if ports.is_a?(Range)

  if ports.is_a?(String)
    if ports.include?(',')
      ports.split(',').map(&:to_i)
    elsif ports.include?('..')
      begin
        eval(ports).to_a
      rescue StandardError
        (1..1024).to_a
      end
    else
      [ports.to_i]
    end
  elsif ports.is_a?(Array)
    ports.map(&:to_i)
  else
    (1..1024).to_a
  end
end

#run(*args, **_opts) ⇒ Object



26
27
28
29
30
31
32
33
34
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 26

def run(*args, **_opts)
  with_error_handling do
    # 支持命令行参数覆盖
    @target = args[0] if args[0]
    @ports = parse_ports(args[1]) if args[1]
    @thread_count = args[2].to_i if args[2]
    scan
  end
end

#scanObject

Execute port scanning using multiple threads



37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/kscript/plugins/kk_port_scan_utils.rb', line 37

def scan
  msg = "Scanning #{@target} ports #{@ports} with concurrency=#{@thread_count}"
  logger.kinfo(msg)
  pool = Concurrent::ThreadPoolExecutor.new(
    min_threads: [2, @thread_count].min,
    max_threads: @thread_count,
    max_queue: @ports.size,
    fallback_policy: :caller_runs
  )
  @ports.each do |port|
    pool.post do
      Socket.tcp(@target, port, connect_timeout: 0.5) do |_sock|
        logger.kinfo('Port open', port: port)
      end
    rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT, SocketError
      # closed or filtered
    end
  end
  pool.shutdown
  pool.wait_for_termination
end