require 'openssl'
require 'socket'
require 'zlib'
BAD_PORTS = [ 0, 25, 135, 139, 445 ]
def packet(generation, ip, time)
a = [ generation ]
a.concat(ip.split('.').map(&:to_i))
a << time
p = a.pack('C5N')
a << Zlib.crc32(p)
a.pack('C5NN')
end
def encrypt(packet, key)
key.private_encrypt(packet)
end
def fmt(packet)
out = []
idx = 0
stack = packet.unpack('C*')
while a = stack.shift
b = stack.shift
c = stack.shift
one = ( a << 4 ) + ( b & 0xf )
two = ( ( b & 0x0f ) << 8 ) + c
out << ( ( one << 4 ) + idx )
idx += 1
out << ( ( two << 4 ) + idx )
idx += 1
end
out
end
# Returns true if the packet contains no bad ports; false if it does
def check(packet, bad_ports)
bad_ports - packet == bad_ports
end
def knock(ip, key)
time = Time.now.to_i
generation = 0
packet = nil
until packet && check(packet, BAD_PORTS)
packet = fmt(encrypt(packet(generation, ip, time), key))
generation += 1
end
sock = UDPSocket.new
packet.each {|port|
sock.send('', 0, ip, port)
}
end
key = OpenSSL::PKey::RSA.new(192)
ip = '127.0.0.1'
knock(ip)
Note: You are viewing an old version of this page. View the current version.
