125 lines
4.8 KiB
Python
125 lines
4.8 KiB
Python
|
# This file is part of Scapy
|
||
|
# See http://www.secdev.org/projects/scapy for more information
|
||
|
# Copyright (C) Philippe Biondi <phil@secdev.org>
|
||
|
# This program is published under a GPLv2 license
|
||
|
|
||
|
"""
|
||
|
Sebek: kernel module for data collection on honeypots.
|
||
|
"""
|
||
|
|
||
|
# scapy.contrib.description = Sebek
|
||
|
# scapy.contrib.status = loads
|
||
|
|
||
|
from scapy.fields import FieldLenField, IPField, IntField, ShortEnumField, \
|
||
|
ShortField, StrFixedLenField, StrLenField, XIntField, ByteEnumField
|
||
|
from scapy.packet import Packet, bind_layers
|
||
|
from scapy.layers.inet import UDP
|
||
|
from scapy.data import IP_PROTOS
|
||
|
|
||
|
|
||
|
# SEBEK
|
||
|
|
||
|
|
||
|
class SebekHead(Packet):
|
||
|
name = "Sebek header"
|
||
|
fields_desc = [XIntField("magic", 0xd0d0d0),
|
||
|
ShortField("version", 1),
|
||
|
ShortEnumField("type", 0, {"read": 0, "write": 1,
|
||
|
"socket": 2, "open": 3}),
|
||
|
IntField("counter", 0),
|
||
|
IntField("time_sec", 0),
|
||
|
IntField("time_usec", 0)]
|
||
|
|
||
|
def mysummary(self):
|
||
|
return self.sprintf("Sebek Header v%SebekHead.version% %SebekHead.type%") # noqa: E501
|
||
|
|
||
|
# we need this because Sebek headers differ between v1 and v3, and
|
||
|
# between v3 type socket and v3 others
|
||
|
|
||
|
|
||
|
class SebekV1(Packet):
|
||
|
name = "Sebek v1"
|
||
|
fields_desc = [IntField("pid", 0),
|
||
|
IntField("uid", 0),
|
||
|
IntField("fd", 0),
|
||
|
StrFixedLenField("cmd", "", 12),
|
||
|
FieldLenField("data_length", None, "data", fmt="I"),
|
||
|
StrLenField("data", "", length_from=lambda x:x.data_length)]
|
||
|
|
||
|
def mysummary(self):
|
||
|
if isinstance(self.underlayer, SebekHead):
|
||
|
return self.underlayer.sprintf("Sebek v1 %SebekHead.type% (%SebekV1.cmd%)") # noqa: E501
|
||
|
else:
|
||
|
return self.sprintf("Sebek v1 (%SebekV1.cmd%)")
|
||
|
|
||
|
|
||
|
class SebekV3(Packet):
|
||
|
name = "Sebek v3"
|
||
|
fields_desc = [IntField("parent_pid", 0),
|
||
|
IntField("pid", 0),
|
||
|
IntField("uid", 0),
|
||
|
IntField("fd", 0),
|
||
|
IntField("inode", 0),
|
||
|
StrFixedLenField("cmd", "", 12),
|
||
|
FieldLenField("data_length", None, "data", fmt="I"),
|
||
|
StrLenField("data", "", length_from=lambda x:x.data_length)]
|
||
|
|
||
|
def mysummary(self):
|
||
|
if isinstance(self.underlayer, SebekHead):
|
||
|
return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3.cmd%)") # noqa: E501
|
||
|
else:
|
||
|
return self.sprintf("Sebek v3 (%SebekV3.cmd%)")
|
||
|
|
||
|
|
||
|
class SebekV2(SebekV3):
|
||
|
def mysummary(self):
|
||
|
if isinstance(self.underlayer, SebekHead):
|
||
|
return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2.cmd%)") # noqa: E501
|
||
|
else:
|
||
|
return self.sprintf("Sebek v2 (%SebekV2.cmd%)")
|
||
|
|
||
|
|
||
|
class SebekV3Sock(Packet):
|
||
|
name = "Sebek v2 socket"
|
||
|
fields_desc = [IntField("parent_pid", 0),
|
||
|
IntField("pid", 0),
|
||
|
IntField("uid", 0),
|
||
|
IntField("fd", 0),
|
||
|
IntField("inode", 0),
|
||
|
StrFixedLenField("cmd", "", 12),
|
||
|
IntField("data_length", 15),
|
||
|
IPField("dip", "127.0.0.1"),
|
||
|
ShortField("dport", 0),
|
||
|
IPField("sip", "127.0.0.1"),
|
||
|
ShortField("sport", 0),
|
||
|
ShortEnumField("call", 0, {"bind": 2,
|
||
|
"connect": 3, "listen": 4,
|
||
|
"accept": 5, "sendmsg": 16,
|
||
|
"recvmsg": 17, "sendto": 11,
|
||
|
"recvfrom": 12}),
|
||
|
ByteEnumField("proto", 0, IP_PROTOS)]
|
||
|
|
||
|
def mysummary(self):
|
||
|
if isinstance(self.underlayer, SebekHead):
|
||
|
return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV3Sock.cmd%)") # noqa: E501
|
||
|
else:
|
||
|
return self.sprintf("Sebek v3 socket (%SebekV3Sock.cmd%)")
|
||
|
|
||
|
|
||
|
class SebekV2Sock(SebekV3Sock):
|
||
|
def mysummary(self):
|
||
|
if isinstance(self.underlayer, SebekHead):
|
||
|
return self.underlayer.sprintf("Sebek v%SebekHead.version% %SebekHead.type% (%SebekV2Sock.cmd%)") # noqa: E501
|
||
|
else:
|
||
|
return self.sprintf("Sebek v2 socket (%SebekV2Sock.cmd%)")
|
||
|
|
||
|
|
||
|
bind_layers(UDP, SebekHead, sport=1101)
|
||
|
bind_layers(UDP, SebekHead, dport=1101)
|
||
|
bind_layers(UDP, SebekHead, dport=1101, sport=1101)
|
||
|
bind_layers(SebekHead, SebekV1, version=1)
|
||
|
bind_layers(SebekHead, SebekV2Sock, version=2, type=2)
|
||
|
bind_layers(SebekHead, SebekV2, version=2)
|
||
|
bind_layers(SebekHead, SebekV3Sock, version=3, type=2)
|
||
|
bind_layers(SebekHead, SebekV3, version=3)
|