def compose_options(options): tcpsoption = "" avail_opt_len = 40 for opt in options: if opt[0] == 'NOP': if avail_opt_len < 1: break nop = tcplib.create_nop() tcpsoption += nop avail_opt_len -= 1 continue if opt[0] == 'MSS': if avail_opt_len < 4: break mssoption = tcplib.create_mss(opt[1]) tcpsoption += mssoption avail_opt_len -= 4 continue if opt[0] == 'WSCALE': if avail_opt_len < 3: break wsoption = tcplib.create_winscale(opt[1]) tcpsoption += wsoption avail_opt_len -= 3 continue if opt[0] == 'SACKOK': if avail_opt_len < 2: break sackok_option = tcplib.create_sackok() tcpsoption += sackok_option avail_opt_len -= 2 continue if opt[0] == 'TIMESTAMP': if avail_opt_len < 10: break tsoption = tcplib.create_timestamp(opt[1], opt[2]) tcpsoption += tsoption avail_opt_len -= 10 continue if opt[0] == 'MP_CAPABLE': if avail_opt_len < 12: break mpcap_option = tcplib.create_mpcapable(opt[1], opt[2]) tcpsoption += mpcap_option avail_opt_len -= 12 continue if opt[0] == 'MP_DATA': if avail_opt_len < 16: break # (Dsn (8 Byte), Dlen (2 Byte), Ssn(4 Byte)) dsn_option = tcplib.create_mpdata(opt[1], opt[2], opt[3]) tcpsoption += dsn_option avail_opt_len -= 16 continue if opt[0] == 'MP_ACK': if avail_opt_len < 10: break dataack_option = tcplib.create_mpack(opt[1]) tcpsoption += dataack_option avail_opt_len -= 10 continue tcpsoption += tcplib.check_padding(tcpsoption) return tcpsoption
def send_packet(): global tcpsoption ackno = tcpackno # add padding to tcp option tcpsoption += tcplib.check_padding(tcpsoption) # special hack parse sdata = "" if datalen > 3 or (len(data) > 1 and tcpflag & tcplib.TH_SYN): trimmed, http = httpenc.trim_httphdr(data) if not http and \ struct.unpack('!B', trimmed[0:1])[0] == request_hdrdata_http: http = 1 if http and httpenc.is_http_get(data, 'hoge.cgi'): sdata = httpenc.httphdr_ok_dummy() elif len(trimmed) == 0: pass elif struct.unpack('!B', trimmed[0:1])[0] == request_dupack: ackno = tcph.seqno elif struct.unpack('!B', trimmed[0:1])[0] == request_differ_tsecr or \ struct.unpack('!B', trimmed[0:1])[0] == request_hdrdata or \ struct.unpack('!B', trimmed[0:1])[0] == request_hdrdata_http or \ struct.unpack('!B', trimmed[0:1])[0] == Hdrdata_and_advsyndata_ack: if struct.unpack('!B', trimmed[0:1])[0] == request_differ_tsecr: tcpsoption = tcplib.create_timestamp(TSval, tsecr-1) tcpsoption += tcplib.check_padding(tcpsoption) target_len = 512 - len(tcpsoption) if tcpflag & tcplib.TH_SYN: target_len = len(data) # Prepare HTTP OK header if http: sdata = httpenc.httphdr_ok(target_len) # Prepare receiving headers sdata += rcvhdrdata # Prepare sending headers (IP and TCP checksums are zero) tmpiph = tcplib.iphdr(ipsrc, ipdest, tcplib.BASEHDRLEN + 512, \ ipid, ipttl) tmptcph = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, ackno, \ tcpflag, tcpwindow, tcpsoption) sdata += tmpiph.bin() + tmptcph.bin() cur_len = len(sdata) if len(trimmed) >= target_len - cur_len: sdata += trimmed[0: target_len - cur_len] else: sdata += trimmed cur_len += len(trimmed) for i in range(0, target_len - cur_len): sdata += struct.pack('!B', 0xAB) # prepare ip header iplen = tcplib.BASEHDRLEN + len(tcpsoption) + len(sdata) iphs = tcplib.iphdr(ipsrc, ipdest, iplen, ipid, ipttl) # prepare tcp header tcphs = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, ackno, \ tcpflag, tcpwindow, tcpsoption) if len(sdata) == 0: tcphs.calccksum(iphs) else: tcphs.calccksum(iphs, sdata) payload = iphs.bin() payload += tcphs.bin() if len(sdata) > 0: payload += sdata dstr = socket.inet_ntoa(struct.pack('!L',ipdest)) s.sendto(payload, (dstr, 0))
def compose_options(options): tcpsoption = "" avail_opt_len = 40 for opt in options: if opt[0] == 'NOP': if avail_opt_len < 1: break nop = tcplib.create_nop() tcpsoption += nop avail_opt_len -= 1 continue if opt[0] == 'MSS': if avail_opt_len < 4: break mssoption = tcplib.create_mss(opt[1]) tcpsoption += mssoption avail_opt_len -= 4 continue if opt[0] == 'WSCALE': if avail_opt_len < 3: break wsoption = tcplib.create_winscale(opt[1]) tcpsoption += wsoption avail_opt_len -= 3 continue if opt[0] == 'SACKOK': if avail_opt_len < 2: break sackok_option = tcplib.create_sackok() tcpsoption += sackok_option avail_opt_len -= 2 continue if opt[0] == 'TIMESTAMP': if avail_opt_len < 10: break tsoption = tcplib.create_timestamp(opt[1], opt[2]) tcpsoption += tsoption avail_opt_len -= 10 continue if opt[0] == 'MP_CAPABLE': length = 20 if opt[3] is not None else 12 if avail_opt_len < length: break mpcap_option = tcplib.create_mpcapable(opt[1], opt[2], opt[3]) tcpsoption += mpcap_option avail_opt_len -= length continue if opt[0] == 'MP_DSS': length = (14 if opt[6] is not None else 0) + (4 if opt[4] is not None else 0) + \ (4 if opt[4] is not None and opt[3] else 0) + (4 if opt[5] else 0) if avail_opt_len < length: break dss_option = tcplib.create_mpdss(opt[1], opt[2], opt[3], opt[4], \ opt[5], opt[6], opt[7]) tcpsoption += dss_option avail_opt_len -= length continue if opt[0] == 'MP_ACK': if avail_opt_len < 10: break dataack_option = tcplib.create_mpack(opt[1]) tcpsoption += dataack_option avail_opt_len -= 10 continue tcpsoption += tcplib.check_padding(tcpsoption) return tcpsoption
def send_packet(): global tcpsoption # add padding to tcp option tcpsoption += tcplib.check_padding(tcpsoption) # special hack parse sdata = "" http = 0 abbrev_header = "" http_response = "" if len(data) > 3: unpacked = struct.unpack(str(len(data)) + 's', data)[0] if unpacked[0:3] == "GET": http = 1 end_of_request_line = unpacked.find("\r\n") abbrev_header = "GET /%s HTTP/1.1%s" % (unpacked[6], unpacked[end_of_request_line:]) if (struct.unpack('!B', data[0:1])[0] == request_hdrdata) or (struct.unpack('!B', struct.unpack(str(len(data)) + 's', data)[0][6])[0] == request_hdrdata): # Prepare receiving headers sdata = rcvhdrdata # Prepare sending headers (IP and TCP checksums are zero) tmpiph = tcplib.iphdr(ipsrc, ipdest, tcplib.BASEHDRLEN + 512, \ ipid, ipttl) tmptcph = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, tcpackno, \ tcpflag, tcpwindow, tcpsoption) sdata += tmpiph.bin() + tmptcph.bin() target_len = 512 - len(tcpsoption) cur_len = len(sdata) if http == 1: sdata += struct.pack(str(len(abbrev_header)) + 's', abbrev_header) cur_len += len(abbrev_header) if len(data) >= target_len - cur_len: sdata += data[6: target_len - cur_len + 6] else: sdata += data[6:] cur_len += len(data)-6 for i in range(0, target_len - cur_len): sdata += struct.pack('!B', 0xAB) # prepare ip header iplen = tcplib.BASEHDRLEN + len(tcpsoption) + len(sdata) iphs = tcplib.iphdr(ipsrc, ipdest, iplen, ipid, ipttl) # prepare tcp header tcphs = tcplib.tcphdr(tcpsport, tcpdport, tcpseqno, tcpackno, \ tcpflag, tcpwindow, tcpsoption) if len(sdata) == 0: tcphs.calccksum(iphs) else: tcphs.calccksum(iphs, sdata) payload = iphs.bin() payload += tcphs.bin() if http == 1: if (len(sdata) > 0): http_response = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n" % (len(sdata)-40) payload += struct.pack(str(len(http_response)) + 's', http_response) payload += sdata[:-(len(http_response))] else: http_response = "HTTP/1.1 200 OK\r\nContent-Length: %d\r\n\r\n" % 0 payload += struct.pack(str(len(http_response)) + 's', http_response) elif len(sdata) > 0: payload += sdata dstr = socket.inet_ntoa(struct.pack('!L',ipdest)) s.sendto(payload, (dstr, 0))