def __new__(cls, name, bases, dct): c = super(ASN1_Object_metaclass, cls).__new__(cls, name, bases, dct) try: c.tag.register_asn1_object(c) except: warning("Error registering %r for %r" % (c.tag, c.codec)) return c
def recv(self, x=MTU): pkt, sa_ll = self.ins.recvfrom(x) if sa_ll[2] == socket.PACKET_OUTGOING: return None if sa_ll[3] in conf.l2types: cls = conf.l2types[sa_ll[3]] lvl = 2 elif sa_ll[1] in conf.l3types: cls = conf.l3types[sa_ll[1]] lvl = 3 else: cls = conf.default_l2 warning( "Unable to guess type (interface=%s protocol=%#x family=%i). Using %s" % (sa_ll[0], sa_ll[1], sa_ll[3], cls.name)) lvl = 3 try: pkt = cls(pkt) except KeyboardInterrupt: raise except: if conf.debug_dissector: raise pkt = conf.raw_layer(pkt) if lvl == 2: pkt = pkt.payload if pkt is not None: from .arch import get_last_packet_timestamp pkt.time = get_last_packet_timestamp(self.ins) return pkt
def recv(self, x=MTU): pkt, sa_ll = self.ins.recvfrom(x) if sa_ll[2] == socket.PACKET_OUTGOING: return None if sa_ll[3] in conf.l2types: cls = conf.l2types[sa_ll[3]] lvl = 2 elif sa_ll[1] in conf.l3types: cls = conf.l3types[sa_ll[1]] lvl = 3 else: cls = conf.default_l2 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s" % (sa_ll[0],sa_ll[1],sa_ll[3],cls.name)) lvl = 3 try: pkt = cls(pkt) except KeyboardInterrupt: raise except: if conf.debug_dissector: raise pkt = conf.raw_layer(pkt) if lvl == 2: pkt = pkt.payload if pkt is not None: from .arch import get_last_packet_timestamp pkt.time = get_last_packet_timestamp(self.ins) return pkt
def lazy_init(self): try: f=open(self.filename) except IOError: warning("Can't open base %s" % self.filename) return try: self.base = [] for l in f: if l[0] in ["#","\n"]: continue l = tuple(l.split(":")) if len(l) < 8: continue def a2i(x): if x.isdigit(): return int(x) return x li = [ a2i(i) for i in l[1:4] ] #if li[0] not in self.ttl_range: # self.ttl_range.append(li[0]) # self.ttl_range.sort() self.base.append((l[0], li[0], li[1], li[2], l[4], l[5], l[6], l[7][:-1])) except: warning("Can't parse p0f database (new p0f version ?)") self.base = None f.close()
def __new__(cls, name, bases, dct): c = super(BERcodec_metaclass, cls).__new__(cls, name, bases, dct) try: c.tag.register(c.codec, c) except: warning("Error registering %r for %r" % (c.tag, c.codec)) return c
def lazy_init(self): try: f = open(self.filename) except IOError: warning("Can't open base %s" % self.filename) return try: self.base = [] for l in f: if l[0] in ["#", "\n"]: continue l = tuple(l.split(":")) if len(l) < 8: continue def a2i(x): if x.isdigit(): return int(x) return x li = [a2i(i) for i in l[1:4]] #if li[0] not in self.ttl_range: # self.ttl_range.append(li[0]) # self.ttl_range.sort() self.base.append( (l[0], li[0], li[1], li[2], l[4], l[5], l[6], l[7][:-1])) except: warning("Can't parse p0f database (new p0f version ?)") self.base = None f.close()
def __init__(self, iface = None, type = ETH_P_ALL, filter=None, nofilter=0): if iface is None: iface = conf.iface self.ins = socket.socket(socket.AF_PACKET, socket.SOCK_RAW, socket.htons(type)) self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 0) if not nofilter: if conf.except_filter: if filter: filter = "(%s) and not (%s)" % (filter, conf.except_filter) else: filter = "not (%s)" % conf.except_filter if filter is not None: attach_filter(self.ins, filter, iface) self.ins.bind((iface, type)) _flush_fd(self.ins) self.ins.setsockopt(socket.SOL_SOCKET, socket.SO_RCVBUF, 2**30) self.outs = self.ins self.outs.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 2**30) sa_ll = self.outs.getsockname() if sa_ll[3] in conf.l2types: self.LL = conf.l2types[sa_ll[3]] elif sa_ll[1] in conf.l3types: self.LL = conf.l3types[sa_ll[1]] else: self.LL = conf.default_l2 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s" % (sa_ll[0],sa_ll[1],sa_ll[3],self.LL.name))
def delt(self, *args, **kargs): """delt(host|net, gw|dev)""" self.invalidate_cache() route = self.make_route(*args,**kargs) try: i=self.routes.index(route) del(self.routes[i]) except ValueError: warning("no matching route found")
def stop(self, _cmd="X"): try: with self.command_lock: if self.threadid is not None: os.write(self.__fdw, _cmd.encode(encoding='UTF-8')) while not self.thread_lock.acquire(0): time.sleep(0.01) # interruptible wait for thread to terminate self.thread_lock.release() # (not using .join() because it needs 'threading' module) else: warning("Pipe engine thread not running") except KeyboardInterrupt: print("Interrupted by user.")
def get_if_list(): try: f=open("/proc/net/dev","r") except IOError: warning("Can't open /proc/net/dev !") return [] lst = [] f.readline() f.readline() for l in f: lst.append(l.split(":")[0].strip()) f.close() return lst
def stop(self, _cmd="X"): try: with self.command_lock: if self.threadid is not None: os.write(self.__fdw, _cmd.encode(encoding='UTF-8')) while not self.thread_lock.acquire(0): time.sleep( 0.01) # interruptible wait for thread to terminate self.thread_lock.release( ) # (not using .join() because it needs 'threading' module) else: warning("Pipe engine thread not running") except KeyboardInterrupt: print("Interrupted by user.")
def run(self): log_interactive.info("Pipe engine thread started.") try: for p in self.active_pipes: p.start() sources = self.active_sources sources.add(self.__fdr) exhausted = set([]) RUN = True STOP_IF_EXHAUSTED = False while RUN and (not STOP_IF_EXHAUSTED or len(sources) > 1): fds, fdo, fde = select.select(sources, [], []) for fd in fds: if fd is self.__fdr: cmd = os.read(self.__fdr, 1).decode(encoding='UTF-8') if cmd == "X": RUN = False break elif cmd == "B": STOP_IF_EXHAUSTED = True elif cmd == "A": sources = self.active_sources - exhausted sources.add(self.__fdr) else: warning( "Unknown internal pipe engine command: %r. Ignoring." % cmd) elif fd in sources: try: fd.deliver() except Exception as e: log_interactive.exception( "piping from %s failed: %s" % (fd.name, e)) else: if fd.exhausted(): exhausted.add(fd) sources.remove(fd) except KeyboardInterrupt: pass finally: try: for p in self.active_pipes: p.stop() finally: self.thread_lock.release() log_interactive.info("Pipe engine thread stopped.")
def run(self): log_interactive.info("Pipe engine thread started.") try: for p in self.active_pipes: p.start() sources = self.active_sources sources.add(self.__fdr) exhausted = set([]) RUN=True STOP_IF_EXHAUSTED = False while RUN and (not STOP_IF_EXHAUSTED or len(sources) > 1): fds,fdo,fde=select.select(sources,[],[]) for fd in fds: if fd is self.__fdr: cmd = os.read(self.__fdr,1).decode(encoding='UTF-8') if cmd == "X": RUN=False break elif cmd == "B": STOP_IF_EXHAUSTED = True elif cmd == "A": sources = self.active_sources-exhausted sources.add(self.__fdr) else: warning("Unknown internal pipe engine command: %r. Ignoring." % cmd) elif fd in sources: try: fd.deliver() except Exception as e: log_interactive.exception("piping from %s failed: %s" % (fd.name, e)) else: if fd.exhausted(): exhausted.add(fd) sources.remove(fd) except KeyboardInterrupt: pass finally: try: for p in self.active_pipes: p.stop() finally: self.thread_lock.release() log_interactive.info("Pipe engine thread stopped.")
def recv(self, x=MTU): pkt, sa_ll = self.ins.recvfrom(x) if sa_ll[3] in conf.l2types : cls = conf.l2types[sa_ll[3]] elif sa_ll[1] in conf.l3types: cls = conf.l3types[sa_ll[1]] else: cls = conf.default_l2 warning("Unable to guess type (interface=%s protocol=%#x family=%i). Using %s" % (sa_ll[0],sa_ll[1],sa_ll[3],cls.name)) try: pkt = cls(pkt) except KeyboardInterrupt: raise except: if conf.debug_dissector: raise pkt = conf.raw_layer(pkt) pkt.time = get_last_packet_timestamp(self.ins) return pkt
def p0f(pkt): """Passive OS fingerprinting: which OS emitted this TCP packet ? p0f(packet) -> accuracy, [list of guesses] """ db, sig = packet2p0f(pkt) if db: pb = db.get_base() else: pb = [] if not pb: warning("p0f base empty.") return [] #s = len(pb[0][0]) r = [] max = len(sig[4].split(",")) + 5 for b in pb: d = p0f_correl(sig, b) if d == max: r.append((b[6], b[7], b[1] - pkt[IP].ttl)) return r
def p0f(pkt): """Passive OS fingerprinting: which OS emitted this TCP packet ? p0f(packet) -> accuracy, [list of guesses] """ db, sig = packet2p0f(pkt) if db: pb = db.get_base() else: pb = [] if not pb: warning("p0f base empty.") return [] #s = len(pb[0][0]) r = [] max = len(sig[4].split(",")) + 5 for b in pb: d = p0f_correl(sig,b) if d == max: r.append((b[6], b[7], b[1] - pkt[IP].ttl)) return r
def route(self,dest,verbose=None): if type(dest) is list and dest: dest = dest[0] if dest in self.cache: return self.cache[dest] if verbose is None: verbose=conf.verb # Transform "192.168.*.1-5" to one IP of the set dst = dest.split("/")[0] dst = dst.replace("*","0") while True: l = dst.find("-") if l < 0: break m = (dst[l:]+".").find(".") dst = dst[:l]+dst[l+m:] dst = atol(dst) pathes=[] for d,m,gw,i,a in self.routes: aa = atol(a) #Commented out after issue with virtual network with local address 0.0.0.0 #if aa == dst: # pathes.append((0xffffffff,(LOOPBACK_NAME,a,"0.0.0.0"))) if (dst & m) == (d & m): pathes.append((m,(i,a,gw))) if not pathes: if verbose: warning("No route found (no default route?)") return LOOPBACK_NAME,"0.0.0.0","0.0.0.0" #XXX linux specific! # Choose the more specific route (greatest netmask). # XXX: we don't care about metrics pathes.sort() ret = pathes[-1][1] self.cache[dest] = ret return ret
def read_routes(): try: f=open("/proc/net/route","rb") except IOError: warning("Can't open /proc/net/route !") return [] routes = [] s=socket.socket(socket.AF_INET, socket.SOCK_DGRAM) ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",LOOPBACK_NAME.encode('utf-8'))) addrfamily = struct.unpack("h",ifreq[16:18])[0] if addrfamily == socket.AF_INET: ifreq2 = ioctl(s, SIOCGIFNETMASK,struct.pack("16s16x",LOOPBACK_NAME.encode('utf-8'))) msk = socket.ntohl(struct.unpack("I",ifreq2[20:24])[0]) dst = socket.ntohl(struct.unpack("I",ifreq[20:24])[0]) & msk ifaddr = kamene.utils.inet_ntoa(ifreq[20:24]) routes.append((dst, msk, "0.0.0.0", LOOPBACK_NAME, ifaddr)) else: warning("Interface lo: unkown address family (%i)"% addrfamily) for l in f.readlines()[1:]: iff,dst,gw,flags,x,x,x,msk,x,x,x = l.split() flags = int(flags,16) if flags & RTF_UP == 0: continue if flags & RTF_REJECT: continue try: ifreq = ioctl(s, SIOCGIFADDR,struct.pack("16s16x",iff)) except IOError: # interface is present in routing tables but does not have any assigned IP ifaddr="0.0.0.0" else: addrfamily = struct.unpack("h",ifreq[16:18])[0] if addrfamily == socket.AF_INET: ifaddr = kamene.utils.inet_ntoa(ifreq[20:24]) else: warning("Interface %s: unkown address family (%i)"%(iff, addrfamily)) continue routes.append((socket.htonl(int(dst,16))&0xffffffff, socket.htonl(int(msk,16))&0xffffffff, kamene.utils.inet_ntoa(struct.pack("I",int(gw,16))), iff.decode('utf-8'), ifaddr)) f.close() return routes
def get_if_bcast(self, iff): for net, msk, gw, iface, addr in self.routes: if (iff == iface and net != 0): bcast = atol(addr)|(~msk&0xffffffff); # FIXME: check error in atol() return ltoa(bcast); warning("No broadcast address found for iface %s\n" % iff);
def p0f_impersonate(pkt, osgenre=None, osdetails=None, signature=None, extrahops=0, mtu=1500, uptime=None): """Modifies pkt so that p0f will think it has been sent by a specific OS. If osdetails is None, then we randomly pick up a personality matching osgenre. If osgenre and signature are also None, we use a local signature (using p0f_getlocalsigs). If signature is specified (as a tuple), we use the signature. For now, only TCP Syn packets are supported. Some specifications of the p0f.fp file are not (yet) implemented.""" pkt = pkt.copy() #pkt = pkt.__class__(str(pkt)) while pkt.haslayer(IP) and pkt.haslayer(TCP): pkt = pkt.getlayer(IP) if isinstance(pkt.payload, TCP): break pkt = pkt.payload if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP): raise TypeError("Not a TCP/IP packet") if uptime is None: uptime = random.randint(120,100*60*60*24*365) db = p0f_selectdb(pkt.payload.flags) if osgenre: pb = db.get_base() if pb is None: pb = [] #pb = filter(lambda x: x[6] == osgenre, pb) pb = [ x for x in pb if x[6] == osgenre ] if osdetails: #pb = filter(lambda x: x[7] == osdetails, pb) pb = [ x for x in pb if x[7] == osdetails ] elif signature: pb = [signature] else: pb = p0f_getlocalsigs()[db] if db == p0fr_kdb: # 'K' quirk <=> RST+ACK if pkt.payload.flags & 0x4 == 0x4: #pb = filter(lambda x: 'K' in x[5], pb) pb = [ x for x in pb if 'K' in x[5] ] else: #pb = filter(lambda x: 'K' not in x[5], pb) pb = [ x for x in pb if 'K' not in x[5] ] if not pb: raise Kamene_Exception("No match in the p0f database") pers = pb[random.randint(0, len(pb) - 1)] # options (we start with options because of MSS) ## TODO: let the options already set if they are valid options = [] if pers[4] != '.': for opt in pers[4].split(','): if opt[0] == 'M': # MSS might have a maximum size because of window size # specification if pers[0][0] == 'S': maxmss = (2**16-1) / int(pers[0][1:]) else: maxmss = (2**16-1) # If we have to randomly pick up a value, we cannot use # kamene RandXXX() functions, because the value has to be # set in case we need it for the window size value. That's # why we use random.randint() if opt[1:] == '*': options.append(('MSS', random.randint(1,maxmss))) elif opt[1] == '%': coef = int(opt[2:]) options.append(('MSS', coef*random.randint(1,maxmss/coef))) else: options.append(('MSS', int(opt[1:]))) elif opt[0] == 'W': if opt[1:] == '*': options.append(('WScale', RandByte())) elif opt[1] == '%': coef = int(opt[2:]) options.append(('WScale', coef*RandNum(min=1, max=(2**8-1)/coef))) else: options.append(('WScale', int(opt[1:]))) elif opt == 'T0': options.append(('Timestamp', (0, 0))) elif opt == 'T': if 'T' in pers[5]: # FIXME: RandInt() here does not work (bug (?) in # TCPOptionsField.m2i often raises "OverflowError: # long int too large to convert to int" in: # oval = struct.pack(ofmt, *oval)" # Actually, this is enough to often raise the error: # struct.pack('I', RandInt()) options.append(('Timestamp', (uptime, random.randint(1,2**32-1)))) else: options.append(('Timestamp', (uptime, 0))) elif opt == 'S': options.append(('SAckOK', '')) elif opt == 'N': options.append(('NOP', None)) elif opt == 'E': options.append(('EOL', None)) elif opt[0] == '?': if int(opt[1:]) in TCPOptions[0]: optname = TCPOptions[0][int(opt[1:])][0] optstruct = TCPOptions[0][int(opt[1:])][1] options.append((optname, struct.unpack(optstruct, RandString(struct.calcsize(optstruct))._fix()))) else: options.append((int(opt[1:]), '')) ## FIXME: qqP not handled else: warning("unhandled TCP option " + opt) pkt.payload.options = options # window size if pers[0] == '*': pkt.payload.window = RandShort() elif pers[0].isdigit(): pkt.payload.window = int(pers[0]) elif pers[0][0] == '%': coef = int(pers[0][1:]) pkt.payload.window = coef * RandNum(min=1,max=(2**16-1)/coef) elif pers[0][0] == 'T': pkt.payload.window = mtu * int(pers[0][1:]) elif pers[0][0] == 'S': ## needs MSS set #MSS = filter(lambda x: x[0] == 'MSS', options) MSS = [ x for x in options if x[0] == 'MSS' ] if not MSS: raise Kamene_Exception("TCP window value requires MSS, and MSS option not set") pkt.payload.window = MSS[0][1] * int(pers[0][1:]) else: raise Kamene_Exception('Unhandled window size specification') # ttl pkt.ttl = pers[1]-extrahops # DF flag pkt.flags |= (2 * pers[2]) ## FIXME: ss (packet size) not handled (how ? may be with D quirk ## if present) # Quirks if pers[5] != '.': for qq in pers[5]: ## FIXME: not handled: P, I, X, ! # T handled with the Timestamp option if qq == 'Z': pkt.id = 0 elif qq == 'U': pkt.payload.urgptr = RandShort() elif qq == 'A': pkt.payload.ack = RandInt() elif qq == 'F': #if db == p0fo_kdb: # pkt.payload.flags |= 0x20 # U #else: pkt.payload.flags |= RandChoice(8, 32, 40) #P / U / PU elif qq == 'D' and db != p0fo_kdb: pkt /= conf.raw_layer(load=RandString(random.randint(1, 10))) # XXX p0fo.fp elif qq == 'Q': pkt.payload.seq = pkt.payload.ack #elif qq == '0': pkt.payload.seq = 0 #if db == p0fr_kdb: # '0' quirk is actually not only for p0fr.fp (see # packet2p0f()) if '0' in pers[5]: pkt.payload.seq = 0 elif pkt.payload.seq == 0: pkt.payload.seq = RandInt() while pkt.underlayer: pkt = pkt.underlayer return pkt
def read_routes(): if kamene.arch.SOLARIS: f = check_output(["netstat", "-rvn"], universal_newlines=True) # -f inet elif kamene.arch.FREEBSD: f = check_output( ["netstat", "-rnW"], universal_newlines=True) # -W to handle long interface names else: f = check_output(["netstat", "-rn"], universal_newlines=True) # -f inet ok = False routes = [] pending_if = [] for l in f.split('\n'): l = l.strip() if l.find("----") >= 0: # a separation line continue if not ok: if_index = [ l.split().index(i) for i in ['Iface', 'Netif', 'Interface', 'Device'] if i in l.split() ] if if_index: ok = True if_index = if_index[0] continue if not l: break if kamene.arch.SOLARIS: lspl = l.split() if len(lspl) == 10: dest, mask, gw, netif, mxfrg, rtt, ref, flg = lspl[:8] else: # missing interface dest, mask, gw, mxfrg, rtt, ref, flg = lspl[:7] netif = None else: rt = l.split() dest, gw, flg = rt[:3] netif = rt[if_index] if flg.find("Lc") >= 0: continue if dest == "default": dest = 0 netmask = 0 else: if kamene.arch.SOLARIS: netmask = kamene.utils.atol(mask) elif "/" in dest: dest, netmask = dest.split("/") netmask = kamene.utils.itom(int(netmask)) else: netmask = kamene.utils.itom((dest.count(".") + 1) * 8) dest += ".0" * (3 - dest.count(".")) dest = kamene.utils.atol(dest) if not "G" in flg: gw = '0.0.0.0' if netif is not None: ifaddr = kamene.arch.get_if_addr(netif) routes.append((dest, netmask, gw, netif, ifaddr)) else: pending_if.append((dest, netmask, gw)) # On Solaris, netstat does not provide output interfaces for some routes # We need to parse completely the routing table to route their gw and # know their output interface for dest, netmask, gw in pending_if: gw_l = kamene.utils.atol(gw) max_rtmask, gw_if, gw_if_addr, = 0, None, None for rtdst, rtmask, _, rtif, rtaddr in routes[:]: if gw_l & rtmask == rtdst: if rtmask >= max_rtmask: max_rtmask = rtmask gw_if = rtif gw_if_addr = rtaddr if gw_if: routes.append((dest, netmask, gw, gw_if, gw_if_addr)) else: warning("Did not find output interface to reach gateway %s" % gw) return routes
def p0f_impersonate(pkt, osgenre=None, osdetails=None, signature=None, extrahops=0, mtu=1500, uptime=None): """Modifies pkt so that p0f will think it has been sent by a specific OS. If osdetails is None, then we randomly pick up a personality matching osgenre. If osgenre and signature are also None, we use a local signature (using p0f_getlocalsigs). If signature is specified (as a tuple), we use the signature. For now, only TCP Syn packets are supported. Some specifications of the p0f.fp file are not (yet) implemented.""" pkt = pkt.copy() #pkt = pkt.__class__(str(pkt)) while pkt.haslayer(IP) and pkt.haslayer(TCP): pkt = pkt.getlayer(IP) if isinstance(pkt.payload, TCP): break pkt = pkt.payload if not isinstance(pkt, IP) or not isinstance(pkt.payload, TCP): raise TypeError("Not a TCP/IP packet") if uptime is None: uptime = random.randint(120, 100 * 60 * 60 * 24 * 365) db = p0f_selectdb(pkt.payload.flags) if osgenre: pb = db.get_base() if pb is None: pb = [] #pb = filter(lambda x: x[6] == osgenre, pb) pb = [x for x in pb if x[6] == osgenre] if osdetails: #pb = filter(lambda x: x[7] == osdetails, pb) pb = [x for x in pb if x[7] == osdetails] elif signature: pb = [signature] else: pb = p0f_getlocalsigs()[db] if db == p0fr_kdb: # 'K' quirk <=> RST+ACK if pkt.payload.flags & 0x4 == 0x4: #pb = filter(lambda x: 'K' in x[5], pb) pb = [x for x in pb if 'K' in x[5]] else: #pb = filter(lambda x: 'K' not in x[5], pb) pb = [x for x in pb if 'K' not in x[5]] if not pb: raise Kamene_Exception("No match in the p0f database") pers = pb[random.randint(0, len(pb) - 1)] # options (we start with options because of MSS) ## TODO: let the options already set if they are valid options = [] if pers[4] != '.': for opt in pers[4].split(','): if opt[0] == 'M': # MSS might have a maximum size because of window size # specification if pers[0][0] == 'S': maxmss = (2**16 - 1) / int(pers[0][1:]) else: maxmss = (2**16 - 1) # If we have to randomly pick up a value, we cannot use # kamene RandXXX() functions, because the value has to be # set in case we need it for the window size value. That's # why we use random.randint() if opt[1:] == '*': options.append(('MSS', random.randint(1, maxmss))) elif opt[1] == '%': coef = int(opt[2:]) options.append( ('MSS', coef * random.randint(1, maxmss / coef))) else: options.append(('MSS', int(opt[1:]))) elif opt[0] == 'W': if opt[1:] == '*': options.append(('WScale', RandByte())) elif opt[1] == '%': coef = int(opt[2:]) options.append( ('WScale', coef * RandNum(min=1, max=(2**8 - 1) / coef))) else: options.append(('WScale', int(opt[1:]))) elif opt == 'T0': options.append(('Timestamp', (0, 0))) elif opt == 'T': if 'T' in pers[5]: # FIXME: RandInt() here does not work (bug (?) in # TCPOptionsField.m2i often raises "OverflowError: # long int too large to convert to int" in: # oval = struct.pack(ofmt, *oval)" # Actually, this is enough to often raise the error: # struct.pack('I', RandInt()) options.append( ('Timestamp', (uptime, random.randint(1, 2**32 - 1)))) else: options.append(('Timestamp', (uptime, 0))) elif opt == 'S': options.append(('SAckOK', '')) elif opt == 'N': options.append(('NOP', None)) elif opt == 'E': options.append(('EOL', None)) elif opt[0] == '?': if int(opt[1:]) in TCPOptions[0]: optname = TCPOptions[0][int(opt[1:])][0] optstruct = TCPOptions[0][int(opt[1:])][1] options.append( (optname, struct.unpack( optstruct, RandString(struct.calcsize(optstruct))._fix()))) else: options.append((int(opt[1:]), '')) ## FIXME: qqP not handled else: warning("unhandled TCP option " + opt) pkt.payload.options = options # window size if pers[0] == '*': pkt.payload.window = RandShort() elif pers[0].isdigit(): pkt.payload.window = int(pers[0]) elif pers[0][0] == '%': coef = int(pers[0][1:]) pkt.payload.window = coef * RandNum(min=1, max=(2**16 - 1) / coef) elif pers[0][0] == 'T': pkt.payload.window = mtu * int(pers[0][1:]) elif pers[0][0] == 'S': ## needs MSS set #MSS = filter(lambda x: x[0] == 'MSS', options) MSS = [x for x in options if x[0] == 'MSS'] if not MSS: raise Kamene_Exception( "TCP window value requires MSS, and MSS option not set") pkt.payload.window = MSS[0][1] * int(pers[0][1:]) else: raise Kamene_Exception('Unhandled window size specification') # ttl pkt.ttl = pers[1] - extrahops # DF flag pkt.flags |= (2 * pers[2]) ## FIXME: ss (packet size) not handled (how ? may be with D quirk ## if present) # Quirks if pers[5] != '.': for qq in pers[5]: ## FIXME: not handled: P, I, X, ! # T handled with the Timestamp option if qq == 'Z': pkt.id = 0 elif qq == 'U': pkt.payload.urgptr = RandShort() elif qq == 'A': pkt.payload.ack = RandInt() elif qq == 'F': #if db == p0fo_kdb: # pkt.payload.flags |= 0x20 # U #else: pkt.payload.flags |= RandChoice(8, 32, 40) #P / U / PU elif qq == 'D' and db != p0fo_kdb: pkt /= conf.raw_layer(load=RandString(random.randint( 1, 10))) # XXX p0fo.fp elif qq == 'Q': pkt.payload.seq = pkt.payload.ack #elif qq == '0': pkt.payload.seq = 0 #if db == p0fr_kdb: # '0' quirk is actually not only for p0fr.fp (see # packet2p0f()) if '0' in pers[5]: pkt.payload.seq = 0 elif pkt.payload.seq == 0: pkt.payload.seq = RandInt() while pkt.underlayer: pkt = pkt.underlayer return pkt
def start(self): if self.thread_lock.acquire(0): self.threadid = _thread.start_new_thread(self.run,()) else: warning("Pipe engine already running")
def read_routes(): if kamene.arch.SOLARIS: f=check_output(["netstat", "-rvn"], universal_newlines = True) # -f inet elif kamene.arch.FREEBSD: f=check_output(["netstat", "-rnW"], universal_newlines = True) # -W to handle long interface names else: f=check_output(["netstat", "-rn"], universal_newlines = True) # -f inet ok = False routes = [] pending_if = [] for l in f.split('\n'): l = l.strip() if l.find("----") >= 0: # a separation line continue if not ok: if_index = [ l.split().index(i) for i in ['Iface', 'Netif', 'Interface', 'Device'] if i in l.split()] if if_index: ok = True if_index = if_index[0] continue if not l: break if kamene.arch.SOLARIS: lspl = l.split() if len(lspl) == 10: dest,mask,gw,netif,mxfrg,rtt,ref,flg = lspl[:8] else: # missing interface dest,mask,gw,mxfrg,rtt,ref,flg = lspl[:7] netif=None else: rt = l.split() dest,gw,flg = rt[:3] netif = rt[if_index] if flg.find("Lc") >= 0: continue if dest == "default": dest = 0 netmask = 0 else: if kamene.arch.SOLARIS: netmask = kamene.utils.atol(mask) elif "/" in dest: dest,netmask = dest.split("/") netmask = kamene.utils.itom(int(netmask)) else: netmask = kamene.utils.itom((dest.count(".") + 1) * 8) dest += ".0"*(3-dest.count(".")) dest = kamene.utils.atol(dest) if not "G" in flg: gw = '0.0.0.0' if netif is not None: ifaddr = kamene.arch.get_if_addr(netif) routes.append((dest,netmask,gw,netif,ifaddr)) else: pending_if.append((dest,netmask,gw)) # On Solaris, netstat does not provide output interfaces for some routes # We need to parse completely the routing table to route their gw and # know their output interface for dest,netmask,gw in pending_if: gw_l = kamene.utils.atol(gw) max_rtmask,gw_if,gw_if_addr, = 0,None,None for rtdst,rtmask,_,rtif,rtaddr in routes[:]: if gw_l & rtmask == rtdst: if rtmask >= max_rtmask: max_rtmask = rtmask gw_if = rtif gw_if_addr = rtaddr if gw_if: routes.append((dest,netmask,gw,gw_if,gw_if_addr)) else: warning("Did not find output interface to reach gateway %s" % gw) return routes
def start(self): if self.thread_lock.acquire(0): self.threadid = _thread.start_new_thread(self.run, ()) else: warning("Pipe engine already running")