| ## This file is part of Scapy |
| ## See http://www.secdev.org/projects/scapy for more informations |
| ## Copyright (C) Philippe Biondi <phil@secdev.org> |
| ## This program is published under a GPLv2 license |
| |
| """ |
| Clone of queso OS fingerprinting |
| """ |
| |
| from scapy.data import KnowledgeBase |
| from scapy.config import conf |
| from scapy.layers.inet import IP,TCP |
| from scapy.error import warning |
| from scapy.volatile import RandInt |
| from scapy.sendrecv import sr |
| #from |
| |
| conf.queso_base ="/etc/queso.conf" |
| |
| |
| ################# |
| ## Queso stuff ## |
| ################# |
| |
| |
| def quesoTCPflags(flags): |
| if flags == "-": |
| return "-" |
| flv = "FSRPAUXY" |
| v = 0 |
| for i in flags: |
| v |= 2**flv.index(i) |
| return "%x" % v |
| |
| class QuesoKnowledgeBase(KnowledgeBase): |
| def lazy_init(self): |
| try: |
| f = open(self.filename) |
| except IOError: |
| return |
| self.base = {} |
| p = None |
| try: |
| for l in f: |
| l = l.strip() |
| if not l or l[0] == ';': |
| continue |
| if l[0] == '*': |
| if p is not None: |
| p[""] = name |
| name = l[1:].strip() |
| p = self.base |
| continue |
| if l[0] not in list("0123456"): |
| continue |
| res = l[2:].split() |
| res[-1] = quesoTCPflags(res[-1]) |
| res = " ".join(res) |
| if res not in p: |
| p[res] = {} |
| p = p[res] |
| if p is not None: |
| p[""] = name |
| except: |
| self.base = None |
| warning("Can't load queso base [%s]", self.filename) |
| f.close() |
| |
| |
| queso_kdb = QuesoKnowledgeBase(conf.queso_base) |
| |
| |
| def queso_sig(target, dport=80, timeout=3): |
| p = queso_kdb.get_base() |
| ret = [] |
| for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]: |
| ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()), |
| timeout=timeout, verbose=0) |
| if len(ans) == 0: |
| rs = "- - - -" |
| else: |
| s,r = ans[0] |
| rs = "%i" % (r.seq != 0) |
| if not r.ack: |
| r += " 0" |
| elif r.ack-s.seq > 666: |
| rs += " R" % 0 |
| else: |
| rs += " +%i" % (r.ack-s.seq) |
| rs += " %X" % r.window |
| rs += " %x" % r.payload.flags |
| ret.append(rs) |
| return ret |
| |
| def queso_search(sig): |
| p = queso_kdb.get_base() |
| sig.reverse() |
| ret = [] |
| try: |
| while sig: |
| s = sig.pop() |
| p = p[s] |
| if "" in p: |
| ret.append(p[""]) |
| except KeyError: |
| pass |
| return ret |
| |
| |
| @conf.commands.register |
| def queso(*args,**kargs): |
| """Queso OS fingerprinting |
| queso(target, dport=80, timeout=3)""" |
| return queso_search(queso_sig(*args, **kargs)) |
| |
| |