Merhaba ben Bunjo, bu konuda eskiden açmış bulunduğum Konu için tıkla!
"Beraber Üst Düzey Port Scanner Kodlayalım!" konusunun devamını yazıyorum.
Çok zor olduğunu bliyorum fakat yavaş yavaş Nmap yazılımına yaklaşmaya çalışıyoruz.
Yeni Kod:
Bu şekilde kodu ayırmamız bize daha düzenl ve stabil bir ortam sağlıyor.
İçerik:
- bunjo.rb -
Sınıfımızı oluşturduk ve default parametrelerimizi ekledik.
"Beraber Üst Düzey Port Scanner Kodlayalım!" konusunun devamını yazıyorum.
Çok zor olduğunu bliyorum fakat yavaş yavaş Nmap yazılımına yaklaşmaya çalışıyoruz.
Yeni Kod:
Bu şekilde kodu ayırmamız bize daha düzenl ve stabil bir ortam sağlıyor.
İçerik:
- bunjo.rb -
Sınıfımızı oluşturduk ve default parametrelerimizi ekledik.
Ruby:
class Bunjo
def initialize
require 'optparse'
require 'colorize'
@parameters = {
help: false,
host: nil,
timeout: 1,
tcp_all: false,
udp_all: false
}
parse_options
$current_directory = File.expand_path File.dirname __FILE__
end
Parserimizi oluşturduk.
Ruby:
def parse_options
OptionParser.new do |params|
params.on "--host HOST", String, "Define the target host" do |host|
@parameters[:host] = host
end
params.on "--tcp-ports TCP_PORTS", Array, "Define tcp ports to scan" do |tcp_ports|
@parameters[:tcp_ports] = tcp_ports.map(&:to_i) if valid_ports?(tcp_ports)
end
params.on "--tcp-all ALL_TCP_PORTS", String, "Use all tcp ports to scan" do |tcp_all|
@parameters[:all_tcp] = true
end
params.on "--udp-ports UDP_PORTS", Array, "Define udp ports to scan" do |udp_ports|
@parameters[:udp_ports] = udp_ports.map(&:to_i) if valid_ports?(udp_ports)
end
params.on "--udp-all", String, "Use all udp ports to scan" do |udp_all|
@parameters[:udp_all] = true
end
params.on "--timeout TIMEOUT", Float, "Define udp ports to scan" do |timeout|
if timeout >= 0
@parameters[:timeout] = timeout.to_f
else
@parameters[:timeout] = 0
end
end
params.on "--help", "-h", String, "Print help text" do
@parameters[:help] = true
end
end.parse!
end
Gelip negatif port ve negatif timeout değer girenler için kontrol mekanizması ayarladık
Ruby:
def valid_ports?(ports)
valid = ports.all? { |port| port.to_i >= 0 }
unless valid
$stdout.puts "Error: Ports must be non-negative integers.\n".colorize :red
end
valid
end
Yardım mesajı
Ruby:
def print_help
puts
help_text = <<-'HELP_TEXT'
HELP STAGE
DEFINE TARGET
--host: Define the target host
PORT SCANNING
--tcp: Ports for TCP scanning
--udp: Ports for UDP scanning
TIMING
--timeout: Enter timeout time (default: 1)
HELP
--help: Prints this text message
SAVE OUTPUT
EXAMPLES
bunjo --host example.com --tcp-ports 80,3306 --udp-ports 139
bunjo --host example.com --tcp-ports 80,3306 --timeout 2
HELP_TEXT
$stdout.puts help_text.colorize :light_white
end
Kontrol için kullanıcı parametrelerini ekrana yazdırdık
Ruby:
def display_parameters
def display_parameter(key, label)
if @parameters[key].is_a? Array
$stdout.puts "#{label}: #{@parameters[key].join(', ')}".colorize(:light_white) if @parameters[key].any?
else
$stdout.puts "#{label}: #{@parameters[key]}".colorize(:light_white) if @parameters[key]
end
end
unless @parameters[:host].nil?
display_parameter(:host, "Target Host")
display_parameter(:tcp_ports, "TCP Ports")
display_parameter(:udp_ports, "UDP Ports")
display_parameter(:timeout, "Timeout")
end
end
Parçalara ayırdığımız dosyaların arasında iletişim için sınıf aktarması yaptık
Ruby:
def import_classes
@scanner_file = File.join $current_directory, 'source', 'scanner.rb'
@version_detecter_file = File.join $current_directory, 'source', 'version_detecter.rb'
require @scanner_file
# require @version_detecter_file
@scanner = BunjoScan.new @parameters[:host], @parameters[:timeout]
# @version_detecter = BunjoVersionDetect.new
end
Sınıfımızı kapattık ve başlangıç ayarlarını oluşturduk
Ruby:
def start
if @parameters[:help]
print_help
exit 0
elsif @parameters[:tcp_ports]
import_classes
tcp_threads = []
@parameters[:tcp_ports].each do |tcp_port|
tcp_threads << Thread.new { @scanner.tcp_scan tcp_port }
end
tcp_threads.each &:join
elsif @parameters[:udp_ports]
import_classes
@parameters[:udp_ports].each do |udp_port|
@scanner.udp_scan udp_port
end
elsif @parameters[:host].nil? and @parameters[:tcp_ports].nil? and @parameters[:udp_ports].nil?
print_help
end
end
end
port_scanner = Bunjo.new
port_scanner.display_parameters
port_scanner.start
- scanner.rb -
Socket kütüphanesini aktardık ve sınıfımızı oluşturduk
Ruby:
require 'socket'
class BunjoScan
def initialize host, timeout
@host = host
@timeout = timeout
end
TCP port tarama fonksiyonu
Ruby:
def tcp_scan tcp_port
tcp_socket = Socket.new Socket::AF_INET, Socket::SOCK_STREAM, 0
begin
tcp_socket_addr = Socket.sockaddr_in tcp_port, @host
rescue SocketError => socket_addr_error
$stdout.puts socket_addr_error.message
tcp_socket.close
return
end
begin
tcp_socket.connect_nonblock tcp_socket_addr
$stdout.puts "#{tcp_port}/tcp open".colorize :green
rescue IO::WaitWritable
IO.select(nil, [tcp_socket], nil, @timeout)
retry
rescue Errno::EISCONN
$stdout.puts "#{tcp_port}/tcp open".colorize :green
rescue Errno::ECONNREFUSED
# Ignored
rescue Errno::ETIMEDOUT
# Ignored
rescue Errno::EHOSTUNREACH
# Ignored
rescue Errno::ENETUNREACH
# Ignored
rescue Errno::EINVAL
# Ignored
rescue Exception
# Ignored
ensure
tcp_socket.close unless tcp_socket.closed?
end
end
UDP port tarama fonksiyonu (daha kodlanmadı.)
Ruby:
def udp_scan udp_port
begin
@udp_socket_addr = Socket.sockaddr_in udp_port, @host
rescue SocketError => socket_addr_error
$stdout.puts socket_addr_error.message
end
end
end
- version_detecter.rb -
Banner bilgisi alıp yazdırmak dışında ekstradan her servis için versiyon analizini ayrı ayrı kodlayacağımız için şimdlik boş
Banner bilgisi alıp yazdırmak dışında ekstradan her servis için versiyon analizini ayrı ayrı kodlayacağımız için şimdlik boş
Ruby:
class BunjoVersionDetect
def initialize host
end
def get_banner
end
end
Eski Kod:
Ruby:
def print_usage_text
puts "Usage: ruby your_script_name.rb [options]"
puts "\nOptions:"
puts " --help, -h\t\tPrints this help text"
puts " --tcp PORTS\t\tTCP ports input"
puts " --udp PORTS\t\tUDP ports input"
puts " --host HOST\t\tTarget host to port scan"
puts " --threads THREADS\tThreads to speed up the scan"
puts " --verbose, -v\t\tSet verbose output"
puts " --output FILE\t\tSet scan output file"
puts " --timeout TIMEOUT\tSet timeout"
exit(0)
end
Ruby:
$options = {
:timeout => 1 #Define default timeout = 1
}
OptionParser.new do |opts|
opts.on("--help", "-h", "Help parameter") do |help|
$options[:help] = help
end
opts.on("--tcp PORTS", "TCP ports input") do |tcp_ports_input|
$options[:tcp_ports_input] = tcp_ports_input
end
opts.on("--udp PORTS", "UDP ports input") do |udp_ports_input|
$options[:udp_ports_input] = udp_ports_input
end
opts.on("--host HOST", "Target host to port scan") do |target_host|
$options[:target_host] = target_host
end
opts.on("--threads THREADS", "Threads to speed for scan") do |threads_to_speed|
$options[:threads_to_speed] = threads_to_speed.to_i
end
opts.on("--verbose", "-v", "Set verbose output") do
$options[:verbose] = true
end
opts.on("--output FILE", "Set scan output file name") do |output|
$options[:output] = output
end
opts.on("--timeout TIMEOUT", "Set timeout") do |timeout|
$options[:timeout] = timeout.to_i
end
end.parse!
Ruby:
def validate_arguments
unless $options[:target_host]
puts "Error: Target host is required. Use --host HOST."
print_usage_text
end
end
Ruby:
def tcp_scan(host, port, timeout_seconds)
$start_time = Time.now
socket = Socket.new(Socket::AF_INET, Socket::SOCK_STREAM, 0)
sockaddr = Socket.sockaddr_in(port, host)
begin
socket.connect_nonblock(sockaddr)
puts "#{port} Open."
rescue IO::WaitWritable
IO.select(nil, [socket], nil, timeout_seconds)
retry
rescue Errno::EISCONN
puts "#{port}/TCP Open"
rescue Errno::ECONNREFUSED
puts "#{port}/TCP Closed (Error: Connection refused)."
rescue Errno::ETIMEDOUT
puts "#{port}/TCP Closed (Error: Connection timed out)."
rescue Errno::EHOSTUNREACH
puts "#{port}/TCP Closed (Error: Host unreachable)."
rescue Errno::ENETUNREACH
puts "#{port}/TCP Closed (Error: Network unreachable)."
rescue Errno::EINVAL
puts "#{port}/TCP Closed (Error: Invalid argument)."
rescue Exception => e
puts "#{port}/TCP Closed #{e.message}"
ensure
socket.close if socket
end
end
Ruby:
def udp_scan(host, port)
timeout_occurred = false
start_time = Time.now
begin
Timeout.timeout($options[:timeout]) do
udp_socket = UDPSocket.new
udp_socket.send("ping", 0, host, port)
response, _ = udp_socket.recvfrom(1)
puts "Port #{port}/UDP is open"
udp_socket.close
end
rescue Timeout::Error
elapsed_time = Time.now - start_time
if elapsed_time >= $options[:timeout]
timeout_occurred = true
puts "Port #{port}/UDP timed out (elapsed time: #{elapsed_time} seconds)"
else
raise MyCustomTimeoutError, "Timeout error (elapsed time: #{elapsed_time} seconds)"
end
rescue StandardError => e
puts "An error occurred: #{e.class} - #{e.message}"
ensure
return timeout_occurred
end
end
Ruby:
def main
validate_arguments
threads = []
if $options[:tcp_ports_input]
puts "Starting TCP scan on #{$options[:target_host]}..."
$options[:tcp_ports_input].split(',').each do |tcp_port|
threads << Thread.new { tcp_scan($options[:target_host], tcp_port.to_i) }
end
end
if $options[:udp_ports_input]
puts "Starting UDP scan on #{$options[:target_host]}..."
$options[:udp_ports_input].split(',').each do |udp_port|
threads << Thread.new { udp_scan($options[:target_host], udp_port.to_i) }
end
end
threads.each(&:join)
end
main
Örnek kullanım:
Not: Programa girdiğiniz timeout değeri kadar program bağlantı isteği yolladığı porttan dönüş alana kadar bekler, default olarak 1 değerine tanımlıdır.
Program linux sistemlerde de sorunsuz çalışır.
Her port içim ayrı ayrı threadler oluşturur ve taramaları eş zamanlı yapar.
Her port için ayrı thread oluşturmak 65 bin port taranacağı zaman sorunlu olacağı için portları bölerek her bir threade farklı farklı atamaları ileri zamanlarda yapcağız.
Anlatacaklarım bu kadardı internette kaynak olmadığı için kaynağı ben sağlamaya çalışıyorum, eksiklerim ve hatalarım olabilir nazik bir dil kullanarak belirtirseniz saygı çerçevesinde kalmış bulunuruz.
Konuyu beğenip mesaj yazarsanız sevinirim.
Github: GitHub - thebunjo/BunjoMap
Okuyan herkese teşekkür ederim.
ruby bunjo.rb --host example.com --tcp-ports 21,22,80,443
ruby bunjo.rb -h
Not: Programa girdiğiniz timeout değeri kadar program bağlantı isteği yolladığı porttan dönüş alana kadar bekler, default olarak 1 değerine tanımlıdır.
Program linux sistemlerde de sorunsuz çalışır.
Her port içim ayrı ayrı threadler oluşturur ve taramaları eş zamanlı yapar.
Her port için ayrı thread oluşturmak 65 bin port taranacağı zaman sorunlu olacağı için portları bölerek her bir threade farklı farklı atamaları ileri zamanlarda yapcağız.
Anlatacaklarım bu kadardı internette kaynak olmadığı için kaynağı ben sağlamaya çalışıyorum, eksiklerim ve hatalarım olabilir nazik bir dil kullanarak belirtirseniz saygı çerçevesinde kalmış bulunuruz.
Konuyu beğenip mesaj yazarsanız sevinirim.
Github: GitHub - thebunjo/BunjoMap
Okuyan herkese teşekkür ederim.
Son düzenleme: