1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
|
# Usage:
# rvmsudo ruby examples/tcp_handshake.rb 192.30.252.130
# Notes:
# because we're bypassing the kernel for this raw TCP handshake it will normally
# RST SYN/ACK operations because the kernel is not tracking the TCP session.
# You can prevent the RST from being sent by your client using the following iptables hack.
#
# iptables -A OUTPUT -p tcp --tcp-flags RST RST -j DROP
# Path setting slight of hand:
$: << File.expand_path("../../lib", __FILE__)
require 'packetfu'
ip = ARGV[0].chomp
config = PacketFu::Utils.whoami?()
syn_packet = PacketFu::TCPPacket.new(:config => config)
syn_packet.ip_daddr = ip
syn_packet.tcp_dst = 80
syn_packet.tcp_flags.syn = 1
syn_packet.recalc
capture_thread = Thread.new do
begin
Timeout::timeout(3) {
cap = PacketFu::Capture.new(:iface => config[:iface], :start => true)
cap.stream.each do |p|
pkt = PacketFu::Packet.parse p
next unless pkt.is_tcp?
if pkt.ip_saddr == ip &&
pkt.tcp_flags.syn == 1 &&
pkt.tcp_flags.ack == 1
puts "Got SYN/ACK reply from #{ip}"
syn_ack_packet = pkt
ack_packet = syn_packet.dup
ack_packet.tcp_flags.syn = 0
ack_packet.tcp_flags.ack = 1
ack_packet.tcp_ack = syn_ack_packet.tcp_seq + 1
ack_packet.tcp_seq = syn_ack_packet.tcp_ack
puts "Sending ACK reply to #{ip}"
ack_packet.to_w
break
end
end
}
rescue Timeout::Error
puts "SYN request timed out"
end
end
puts "Sending SYN request to #{ip}"
syn_packet.to_w
capture_thread.join
|