Home | History | Annotate | Download | only in modules
      1 ## This file is part of Scapy
      2 ## See http://www.secdev.org/projects/scapy for more informations
      3 ## Copyright (C) Philippe Biondi <phil (at] secdev.org>
      4 ## This program is published under a GPLv2 license
      5 
      6 """
      7 Clone of queso OS fingerprinting
      8 """
      9 
     10 from scapy.data import KnowledgeBase
     11 from scapy.config import conf
     12 from scapy.layers.inet import IP,TCP
     13 from scapy.error import warning
     14 from scapy.volatile import RandInt
     15 from scapy.sendrecv import sr
     16 #from 
     17 
     18 conf.queso_base ="/etc/queso.conf"
     19 
     20 
     21 #################
     22 ## Queso stuff ##
     23 #################
     24 
     25 
     26 def quesoTCPflags(flags):
     27     if flags == "-":
     28         return "-"
     29     flv = "FSRPAUXY"
     30     v = 0
     31     for i in flags:
     32         v |= 2**flv.index(i)
     33     return "%x" % v
     34 
     35 class QuesoKnowledgeBase(KnowledgeBase):
     36     def lazy_init(self):
     37         try:
     38             f = open(self.filename)
     39         except IOError:
     40             return
     41         self.base = {}
     42         p = None
     43         try:
     44             for l in f:
     45                 l = l.strip()
     46                 if not l or l[0] == ';':
     47                     continue
     48                 if l[0] == '*':
     49                     if p is not None:
     50                         p[""] = name
     51                     name = l[1:].strip()
     52                     p = self.base
     53                     continue
     54                 if l[0] not in list("0123456"):
     55                     continue
     56                 res = l[2:].split()
     57                 res[-1] = quesoTCPflags(res[-1])
     58                 res = " ".join(res)
     59                 if res not in p:
     60                     p[res] = {}
     61                 p = p[res]
     62             if p is not None:
     63                 p[""] = name
     64         except:
     65             self.base = None
     66             warning("Can't load queso base [%s]", self.filename)
     67         f.close()
     68             
     69         
     70 queso_kdb = QuesoKnowledgeBase(conf.queso_base)
     71 
     72     
     73 def queso_sig(target, dport=80, timeout=3):
     74     p = queso_kdb.get_base()
     75     ret = []
     76     for flags in ["S", "SA", "F", "FA", "SF", "P", "SEC"]:
     77         ans, unans = sr(IP(dst=target)/TCP(dport=dport,flags=flags,seq=RandInt()),
     78                         timeout=timeout, verbose=0)
     79         if len(ans) == 0:
     80             rs = "- - - -"
     81         else:
     82             s,r = ans[0]
     83             rs = "%i" % (r.seq != 0)
     84             if not r.ack:
     85                 r += " 0"
     86             elif r.ack-s.seq > 666:
     87                 rs += " R" % 0
     88             else:
     89                 rs += " +%i" % (r.ack-s.seq)
     90             rs += " %X" % r.window
     91             rs += " %x" % r.payload.flags
     92         ret.append(rs)
     93     return ret
     94             
     95 def queso_search(sig):
     96     p = queso_kdb.get_base()
     97     sig.reverse()
     98     ret = []
     99     try:
    100         while sig:
    101             s = sig.pop()
    102             p = p[s]
    103             if "" in p:
    104                 ret.append(p[""])
    105     except KeyError:
    106         pass
    107     return ret
    108         
    109 
    110 @conf.commands.register
    111 def queso(*args,**kargs):
    112     """Queso OS fingerprinting
    113 queso(target, dport=80, timeout=3)"""
    114     return queso_search(queso_sig(*args, **kargs))
    115 
    116 
    117