Home | History | Annotate | Download | only in contrib
      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 Sebek: kernel module for data collection on honeypots.
      8 """
      9 
     10 # scapy.contrib.description = Sebek
     11 # scapy.contrib.status = loads
     12 
     13 from scapy.fields import *
     14 from scapy.packet import *
     15 from scapy.layers.inet import UDP
     16 
     17 
     18 ### SEBEK
     19 
     20 
     21 class SebekHead(Packet):
     22     name = "Sebek header"
     23     fields_desc = [ XIntField("magic", 0xd0d0d0),
     24                     ShortField("version", 1),
     25                     ShortEnumField("type", 0, {"read":0, "write":1,
     26                                              "socket":2, "open":3}),
     27                     IntField("counter", 0),
     28                     IntField("time_sec", 0),
     29                     IntField("time_usec", 0) ]
     30     def mysummary(self):
     31         return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%")
     32 
     33 # we need this because Sebek headers differ between v1 and v3, and
     34 # between v3 type socket and v3 others
     35 
     36 class SebekV1(Packet):
     37     name = "Sebek v1"
     38     fields_desc = [ IntField("pid", 0),
     39                     IntField("uid", 0),
     40                     IntField("fd", 0),
     41                     StrFixedLenField("cmd", "", 12),
     42                     FieldLenField("data_length", None, "data",fmt="I"),
     43                     StrLenField("data", "", length_from=lambda x:x.data_length) ]
     44     def mysummary(self):
     45         if isinstance(self.underlayer, SebekHead):
     46             return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.cmd%)")
     47         else:
     48             return self.sprintf("Sebek v1 (%SebekV1.cmd%)")
     49 
     50 class SebekV3(Packet):
     51     name = "Sebek v3"
     52     fields_desc = [ IntField("parent_pid", 0),
     53                     IntField("pid", 0),
     54                     IntField("uid", 0),
     55                     IntField("fd", 0),
     56                     IntField("inode", 0),
     57                     StrFixedLenField("cmd", "", 12),
     58                     FieldLenField("data_length", None, "data",fmt="I"),
     59                     StrLenField("data", "", length_from=lambda x:x.data_length) ]
     60     def mysummary(self):
     61         if isinstance(self.underlayer, SebekHead):
     62             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.cmd%)")
     63         else:
     64             return self.sprintf("Sebek v3 (%SebekV3.cmd%)")
     65 
     66 class SebekV2(SebekV3):
     67     def mysummary(self):
     68         if isinstance(self.underlayer, SebekHead):
     69             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.cmd%)")
     70         else:
     71             return self.sprintf("Sebek v2 (%SebekV2.cmd%)")
     72 
     73 class SebekV3Sock(Packet):
     74     name = "Sebek v2 socket"
     75     fields_desc = [ IntField("parent_pid", 0),
     76                     IntField("pid", 0),
     77                     IntField("uid", 0),
     78                     IntField("fd", 0),
     79                     IntField("inode", 0),
     80                     StrFixedLenField("cmd", "", 12),
     81                     IntField("data_length", 15),
     82                     IPField("dip", "127.0.0.1"),
     83                     ShortField("dport", 0),
     84                     IPField("sip", "127.0.0.1"),
     85                     ShortField("sport", 0),
     86                     ShortEnumField("call", 0, { "bind":2,
     87                                                 "connect":3, "listen":4,
     88                                                "accept":5, "sendmsg":16,
     89                                                "recvmsg":17, "sendto":11,
     90                                                "recvfrom":12}),
     91                     ByteEnumField("proto", 0, IP_PROTOS) ]
     92     def mysummary(self):
     93         if isinstance(self.underlayer, SebekHead):
     94             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.cmd%)")
     95         else:
     96             return self.sprintf("Sebek v3 socket (%SebekV3Sock.cmd%)")
     97 
     98 class SebekV2Sock(SebekV3Sock):
     99     def mysummary(self):
    100         if isinstance(self.underlayer, SebekHead):
    101             return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.cmd%)")
    102         else:
    103             return self.sprintf("Sebek v2 socket (%SebekV2Sock.cmd%)")
    104 
    105 bind_layers( UDP,           SebekHead,     sport=1101)
    106 bind_layers( UDP,           SebekHead,     dport=1101)
    107 bind_layers( UDP,           SebekHead,     dport=1101, sport=1101)
    108 bind_layers( SebekHead,     SebekV1,       version=1)
    109 bind_layers( SebekHead,     SebekV2Sock,   version=2, type=2)
    110 bind_layers( SebekHead,     SebekV2,       version=2)
    111 bind_layers( SebekHead,     SebekV3Sock,   version=3, type=2)
    112 bind_layers( SebekHead,     SebekV3,       version=3)
    113