Commit 2265d4da88af76d553f8b0e74071b8d237bb175b

Authored by Alexander Kissinger
1 parent 9f4d511e63
Exists in master

Added basic classes and functionality to make and send IP packets

Showing 1 changed file with 106 additions and 0 deletions Side-by-side Diff

  1 +import sys
  2 +import socket
  3 +from struct import *
  4 +
  5 +class OutPipe:
  6 + socket = None
  7 +
  8 + #def __init__(self):
  9 +
  10 + def start(self):
  11 + try:
  12 + self.socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, socket.IPPROTO_RAW)
  13 + except socket.error , msg:
  14 + print('There was an issue with OutPipe. Error Code : ' + str(msg[0]) + ' Message ' + msg[1])
  15 + sys.exit()
  16 +
  17 + def transmit(self, data, addr):
  18 + if(self.socket != None):
  19 + self.socket.sendto(data, addr)
  20 + else:
  21 + print('OutPipe is not initialized')
  22 +
  23 + #Replace Later.. Maybe Cython Implementation
  24 + def checksum(self, msg):
  25 + s = 0
  26 + for i in range(0, len(msg), 2):
  27 + w = ord(msg[i]) + (ord(msg[i+1]) << 8 )
  28 + s = s + w
  29 + s = (s>>16) + (s & 0xffff);
  30 + s = s + (s >> 16);
  31 + s = ~s & 0xffff
  32 + return s
  33 +
  34 + #Simple IP Test
  35 + def ip_packet_test(self):
  36 + # tell kernel not to put in headers, since we are providing it, when using IPPROTO_RAW this is not necessary
  37 + # s.setsockopt(socket.IPPROTO_IP, socket.IP_HDRINCL, 1)
  38 +
  39 + # now start constructing the packet
  40 + packet = '';
  41 +
  42 + source_ip = '192.168.1.101'
  43 + dest_ip = '192.168.1.114' # or socket.gethostbyname('www.google.com')
  44 +
  45 + # ip header fields
  46 + ip_ihl = 5
  47 + ip_ver = 4
  48 + ip_tos = 0
  49 + ip_tot_len = 0 # kernel will fill the correct total length
  50 + ip_id = 54321 #Id of this packet
  51 + ip_frag_off = 0
  52 + ip_ttl = 255
  53 + ip_proto = socket.IPPROTO_TCP
  54 + ip_check = 0 # kernel will fill the correct checksum
  55 + ip_saddr = socket.inet_aton ( source_ip ) #Spoof the source ip address if you want to
  56 + ip_daddr = socket.inet_aton ( dest_ip )
  57 +
  58 + ip_ihl_ver = (ip_ver << 4) + ip_ihl
  59 +
  60 + # the ! in the pack format string means network order
  61 + ip_header = pack('!BBHHHBBH4s4s' , ip_ihl_ver, ip_tos, ip_tot_len, ip_id, ip_frag_off, ip_ttl, ip_proto, ip_check, ip_saddr, ip_daddr)
  62 +
  63 + # tcp header fields
  64 + tcp_source = 1234 # source port
  65 + tcp_dest = 80 # destination port
  66 + tcp_seq = 454
  67 + tcp_ack_seq = 0
  68 + tcp_doff = 5 #4 bit field, size of tcp header, 5 * 4 = 20 bytes
  69 + #tcp flags
  70 + tcp_fin = 0
  71 + tcp_syn = 1
  72 + tcp_rst = 0
  73 + tcp_psh = 0
  74 + tcp_ack = 0
  75 + tcp_urg = 0
  76 + tcp_window = socket.htons (5840) # maximum allowed window size
  77 + tcp_check = 0
  78 + tcp_urg_ptr = 0
  79 +
  80 + tcp_offset_res = (tcp_doff << 4) + 0
  81 + tcp_flags = tcp_fin + (tcp_syn << 1) + (tcp_rst << 2) + (tcp_psh <<3) + (tcp_ack << 4) + (tcp_urg << 5)
  82 +
  83 + # the ! in the pack format string means network order
  84 + tcp_header = pack('!HHLLBBHHH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags, tcp_window, tcp_check, tcp_urg_ptr)
  85 +
  86 + user_data = 'Hello, how are you'
  87 +
  88 + # pseudo header fields
  89 + source_address = socket.inet_aton( source_ip )
  90 + dest_address = socket.inet_aton(dest_ip)
  91 + placeholder = 0
  92 + protocol = socket.IPPROTO_TCP
  93 + tcp_length = len(tcp_header) + len(user_data)
  94 +
  95 + psh = pack('!4s4sBBH' , source_address , dest_address , placeholder , protocol , tcp_length);
  96 + psh = psh + tcp_header + user_data;
  97 +
  98 + tcp_check = self.checksum(psh)
  99 + #print tcp_checksum
  100 +
  101 + # make the tcp header again and fill the correct checksum - remember checksum is NOT in network byte order
  102 + tcp_header = pack('!HHLLBBH' , tcp_source, tcp_dest, tcp_seq, tcp_ack_seq, tcp_offset_res, tcp_flags, tcp_window) + pack('H' , tcp_check) + pack('!H' , tcp_urg_ptr)
  103 +
  104 + # final full packet - syn packets dont have any data
  105 + packet = ip_header + tcp_header + user_data
  106 + return packet