Skip to content

Commit

Permalink
Syncing with master repo
Browse files Browse the repository at this point in the history
  • Loading branch information
Jonathan Claudius committed Feb 8, 2012
2 parents 936d0f1 + 4f2adbe commit 49d1988
Show file tree
Hide file tree
Showing 4 changed files with 237 additions and 72 deletions.
14 changes: 14 additions & 0 deletions README.md
Expand Up @@ -24,6 +24,20 @@ BNAT-Router: http://www.youtube.com/watch?v=C8zv10VHyUg (BNAT-Router handling BN

BNAT in Metasploit: http://www.youtube.com/watch?v=FS_cg1PVhkI (Using BNAT msf auxmod's to exploit Tomcat)

# Blog Posts

Metasploit Blog - A Tale From Defcon and the Fun of BNAT

https://community.rapid7.com/community/metasploit/blog/2011/08/26/a-tale-from-defcon-and-the-fun-of-bnat

Spiderlabs Blog - Advanced BNAT in the Wild

http://blog.spiderlabs.com/2011/09/advanced-bnat-broken-network-address-translation-in-the-wild.html

Phocean Blog - BNAT

http://www.phocean.net/2011/09/13/bnat.html

# Native Setup on BT5#

## Prep the System ##
Expand Down
113 changes: 99 additions & 14 deletions bnat-pcap.rb
Expand Up @@ -23,7 +23,7 @@
syn_hash = Hash.new
synarray = Array.new

puts "\nbnat-pcap.rb v0.2\n\n"
puts "\nbnat-pcap.rb v0.3\n"

def usage
puts "\nUsage: ruby ./bnat-pcap.rb <packetcapture>.pcap\n\n"
Expand All @@ -41,78 +41,163 @@ def usage
puts "\nParsing SYN/ACK data from PCAP..."
system("tcpdump -nn -r #{sample} -w ./synack.pcap tcp[13] == 18")
puts "Parsed SYN/ACK data from PCAP in #{Time.now - beginning} seconds"
last = Time.now

<<<<<<< HEAD
pcap = PcapFile.new.f2a(
=======
pcap = PacketFu::PcapFile.new.f2a(
>>>>>>> upstream/master
:f => "./synack.pcap",
:filter => "tcp and tcp[13] == 18"
)

puts "SYN/ACK PCAP Load time was #{Time.now - beginning} seconds"
puts "SYN/ACK PCAP Load time was #{Time.now - last} seconds"
last = Time.now

pcap.each do |pkt|
packet = PacketFu::Packet.parse(pkt)
synack_hash = {
"ip" => packet.ip_saddr.to_s,
<<<<<<< HEAD
"port" => packet.tcp_sport.to_s,
"seq" => packet.tcp_ack.to_s
=======
"sport" => packet.tcp_sport.to_s,
"seq" => packet.tcp_ack.to_s,
"dport" => packet.tcp_dport.to_s
>>>>>>> upstream/master
}
synackarray.push(synack_hash)
end
synackarray = synackarray.uniq
#Build BPF so we can focus on just SYN's that have a matching seq
bpf = ""
temp = ""
temp2 = 0
synackarray.each do |synack|
temp = synack["seq"]
temp2 = temp.to_i-1
if bpf == ""
bpf = "'tcp [4:4] == 0x"+temp2.to_s(16)+"'"
bpf = "'tcp[4:4] == 0x"+temp2.to_s(16)+"'"
else
bpf = bpf+" or 'tcp [4:4] == 0x"+temp2.to_s(16)+"'"
bpf += " or 'tcp[4:4] == 0x"+temp2.to_s(16)+"'"
end
end
puts "BPF: "+bpf
#Build BPF so we can focus on just SYN's that have a matching src port
bpf2 = ""
synackarray.each do |synack|
temp3 = synack["dport"].to_i
if bpf2 == ""
bpf2 = "'tcp[0:2] == 0x"+temp3.to_s(16)+"'"
else
bpf2 += " or 'tcp[0:2] == 0x"+temp3.to_s(16)+"'"
end
end
puts "SYN/ACK PCAP Process time was #{Time.now - beginning} seconds"
#Mark our SYN/ACK PCAP Process Start
puts "SYN/ACK PCAP Process time was #{Time.now - last} seconds"
last = Time.now

puts "\nParsing SYN data from PCAP..."
#Scrap our SYN's that have matching SEQ's to our SYN/ACK array
puts "\nParsing SYN data from PCAP based on SYN/ACK SEQ matches..."
system("tcpdump -nn -r #{sample} -w ./syn.pcap 'tcp[13] == 2' and #{bpf}")
puts "Parsed SYN data from PCAP in #{Time.now - beginning} seconds"

pcap2 = PcapFile.new.f2a(:f => './syn.pcap')
#Scrap our SYN's that have matching SRC ports to our SYN/ACK array
puts "Parsing SYN data from PCAP based on SYN/ACK src port matches..."
system("tcpdump -nn -r #{sample} -w ./syn2.pcap 'tcp[13] == 2' and #{bpf2}")

#Mark our SYN/ACK PCAP Process Completion
puts "Parsed SYN data from PCAP in #{Time.now - last} seconds"
last = Time.now

#Load the pcaps of SYN's we scraped out
pcap2 = PacketFu::PcapFile.new.f2a(:f => './syn.pcap')
pcap3 = PacketFu::PcapFile.new.f2a(:f => './syn2.pcap')

puts "SYN PCAP Load time was #{Time.now - beginning} seconds"
#Combine and de-dup our SYN's to speed up process time later
pcap4 = (pcap2 + pcap3).uniq

pcap2.each do |pkt|
#Mark our SYN PCAP load completion
puts "SYN PCAP Load time was #{Time.now - last} seconds"
last = Time.now

#For Each SYN, index it into a usable hash for comparison
pcap4.each do |pkt|
packet = PacketFu::Packet.parse(pkt)
syn_hash = {
"ip" => packet.ip_daddr.to_s,
<<<<<<< HEAD
"port" => packet.tcp_dport.to_s,
"seq" => packet.tcp_seq.to_s}
=======
"dport" => packet.tcp_dport.to_s,
"seq" => packet.tcp_seq.to_s,
"sport" => packet.tcp_sport.to_s
}
>>>>>>> upstream/master
synarray.push(syn_hash)
end
puts "SYN PCAP Process time was #{Time.now - beginning} seconds\n\n"
#Mark our process time
puts "SYN PCAP Process time was #{Time.now - last} seconds\n\n"
last = Time.now

synarray = synarray.uniq
#synarray = synarray.uniq

#Loop through each SYN/ACK and compare to each SYN
synackarray.each do |synackpacket|
synarray.each do |synpacket|
temp = synpacket["seq"]
temp2 = temp.to_i
<<<<<<< HEAD
seq = temp2+1
if synackpacket["ip"] != synpacket["ip"] and
synackpacket["port"] == synpacket["port"] and
synackpacket["seq"] == seq.to_s

puts "[+]BNAT DETECTED:\t Requested:"+synpacket["ip"]+":"+synpacket["port"]+"\t Responded:"+synackpacket["ip"]+":"+synackpacket["port"]+"\tSession:"+seq.to_s
=======
tempseq = temp2+1

ip, dport, sport, seq = false, false, false, false

ip = true if synackpacket["ip"] == synpacket["ip"]
dport = true if synackpacket["dport"] == synpacket["sport"]
sport = true if synackpacket["sport"] == synpacket["dport"]
seq = true if synackpacket["seq"] == tempseq.to_s

if !ip and dport and sport and seq
puts "IP Based BNAT Detected:"
puts "Request: #{synpacket}"
puts "Response: #{synackpacket}"
end

if ip and dport and !sport and seq
puts "Source Port Based BNAT Detected:"
puts "Request: #{synpacket}"
puts "Response: #{synackpacket}"
end

if ip and dport and sport and !seq
puts "Sequence Number Based BNAT Detected:"
puts "Request: #{synpacket}"
puts "Response: #{synackpacket}"
end

if !ip and dport and !sport and seq
puts "IP and Source Port Based BNAT Detected:"
puts "Request: #{synpacket}"
puts "Response: #{synackpacket}"
>>>>>>> upstream/master
end
end
end

#Mark our end to end process time
puts "\nTime elapsed #{Time.now - beginning} seconds\n\n"

system("rm syn.pcap synack.pcap")
system("rm syn.pcap syn2.pcap synack.pcap")
61 changes: 61 additions & 0 deletions bnat-simulator.rb
@@ -0,0 +1,61 @@
#bnat-simulator - A tool to simulate a BNAT service
#
#Jonathan Claudius
#Copyright (C) 2011 Trustwave
#
#This program is free software: you can redistribute it and/or modify it under
#the terms of the GNU General Public License as published by the Free Software
#Foundation, either version 3 of the License, or (at your option) any later
#version.
#
#This program is distributed in the hope that it will be useful, but WITHOUT
#ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
#FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
#You should have received a copy of the GNU General Public License along with
#this program. If not, see <http://www.gnu.org/licenses/>.

require 'rubygems'
require 'packetfu'

#Get our local int config
$config = PacketFu::Utils.whoami?() #Learn Auto-magically
#$config = PacketFu::Utils.whoami?(:iface=>"en0") #Manually Specify

#Start capture
cap = PacketFu::Capture.new(
:iface => $config[:iface], :start => true,
:filter => "tcp and dst #{$config[:ip_saddr]} and tcp[13] == 2"
)

#Loop through any match to our filter and respond with 192.168.1.1
listen=Thread.new do
loop {cap.stream.each {|pkt| synpkt = PacketFu::Packet.parse(pkt)
puts "got the syn"
synackpkt = PacketFu::TCPPacket.new(
:config=>$config,
:timeout=> 0.1,
:flavor=>"Windows"
)
#Simulate BNAT SYN/ACK
synackpkt.ip_saddr="192.168.1.1"
#Simulate Normal SYN/ACK
#synackpkt.ip_saddr=synpkt.ip_daddr
synackpkt.ip_daddr=synpkt.ip_saddr
synackpkt.eth_saddr=synpkt.eth_daddr
synackpkt.eth_daddr=synpkt.eth_saddr
synackpkt.tcp_sport=synpkt.tcp_dport
synackpkt.tcp_dport=synpkt.tcp_sport
synackpkt.tcp_flags.syn=1
synackpkt.tcp_flags.ack=1
synackpkt.tcp_ack=synpkt.tcp_seq+1
synackpkt.tcp_seq=rand(64511)+1024
synackpkt.tcp_win=183
synackpkt.recalc
synackpkt.to_w
puts "sent the syn/ack"
}
}
end

listen.join

0 comments on commit 49d1988

Please sign in to comment.