Exemple #1
0
 def getfield(self, pkt, s):
     if pkt.tls_session.consider_read_padding():
         return ByteField.getfield(self, pkt, s)
     return s, None
Exemple #2
0
class RadioTap(Packet):
    name = "RadioTap dummy"
    deprecated_fields = {
        "Channel": ("ChannelFrequency", "2.4.3"),
        "ChannelFlags2": ("ChannelPlusFlags", "2.4.3"),
        "ChannelNumber": ("ChannelPlusNumber", "2.4.3"),
    }
    fields_desc = [
        ByteField('version', 0),
        ByteField('pad', 0),
        LEShortField('len', None),
        FlagsField('present', None, -32, _rt_present),  # noqa: E501
        # Extended presence mask
        ConditionalField(
            PacketListField("Ext", [], next_cls_cb=_next_radiotap_extpm),
            lambda pkt: pkt.present and pkt.present.Ext),  # noqa: E501
        # RadioTap fields - each starts with a _RadiotapReversePadField
        # to handle padding

        # TSFT
        ConditionalField(
            _RadiotapReversePadField(LELongField("mac_timestamp", 0)),
            lambda pkt: pkt.present and pkt.present.TSFT),
        # Flags
        ConditionalField(
            _RadiotapReversePadField(FlagsField("Flags", None, -8, _rt_flags)),
            lambda pkt: pkt.present and pkt.present.Flags),
        # Rate
        ConditionalField(_RadiotapReversePadField(ByteField("Rate", 0)),
                         lambda pkt: pkt.present and pkt.present.Rate),
        # Channel
        ConditionalField(
            _RadiotapReversePadField(LEShortField("ChannelFrequency", 0)),
            lambda pkt: pkt.present and pkt.present.Channel),
        ConditionalField(
            FlagsField("ChannelFlags", None, -16, _rt_channelflags),
            lambda pkt: pkt.present and pkt.present.Channel),
        # dBm_AntSignal
        ConditionalField(
            _RadiotapReversePadField(_dbmField("dBm_AntSignal", -256)),
            lambda pkt: pkt.present and pkt.present.dBm_AntSignal),
        # dBm_AntNoise
        ConditionalField(
            _RadiotapReversePadField(_dbmField("dBm_AntNoise", -256)),
            lambda pkt: pkt.present and pkt.present.dBm_AntNoise),
        # Lock_Quality
        ConditionalField(
            _RadiotapReversePadField(LEShortField("Lock_Quality", 0), ),
            lambda pkt: pkt.present and pkt.present.Lock_Quality),
        # Antenna
        ConditionalField(_RadiotapReversePadField(ByteField("Antenna", 0)),
                         lambda pkt: pkt.present and pkt.present.Antenna),
        # RX Flags
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("RXFlags", None, -16, _rt_rxflags)),
            lambda pkt: pkt.present and pkt.present.RXFlags),
        # TX Flags
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("TXFlags", None, -16, _rt_txflags)),
            lambda pkt: pkt.present and pkt.present.TXFlags),
        # ChannelPlus
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("ChannelPlusFlags", None, -32, _rt_channelflags2)),
            lambda pkt: pkt.present and pkt.present.ChannelPlus),
        ConditionalField(LEShortField("ChannelPlusFrequency", 0),
                         lambda pkt: pkt.present and pkt.present.ChannelPlus),
        ConditionalField(ByteField("ChannelPlusNumber", 0),
                         lambda pkt: pkt.present and pkt.present.ChannelPlus),
        # MCS
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("knownMCS", None, -8, _rt_knownmcs)),
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitField("Ness_LSB", 0, 1),
                         lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitField("STBC_streams", 0, 2),
                         lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitEnumField("FEC_type", 0, 1, {
            0: "BCC",
            1: "LDPC"
        }), lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("HT_format", 0, 1, {
                0: "mixed",
                1: "greenfield"
            }), lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(
            BitEnumField("guard_interval", 0, 1, {
                0: "Long_GI",
                1: "Short_GI"
            }),  # noqa: E501
            lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(BitEnumField("MCS_bandwidth", 0, 2, _rt_bandwidth),
                         lambda pkt: pkt.present and pkt.present.MCS),
        ConditionalField(ByteField("MCS_index", 0),
                         lambda pkt: pkt.present and pkt.present.MCS),
        # A_MPDU
        ConditionalField(_RadiotapReversePadField(LEIntField("A_MPDU_ref", 0)),
                         lambda pkt: pkt.present and pkt.present.A_MPDU),
        ConditionalField(
            FlagsField("A_MPDU_flags", None, -32, _rt_a_mpdu_flags),
            lambda pkt: pkt.present and pkt.present.A_MPDU),
        # VHT
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("KnownVHT", None, -16, _rt_knownvht)),
            lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(FlagsField("PresentVHT", None, -8, _rt_presentvht),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(ByteEnumField("VHT_bandwidth", 0, _rt_vhtbandwidth),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(StrFixedLenField("mcs_nss", 0, length=5),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(ByteField("GroupID", 0),
                         lambda pkt: pkt.present and pkt.present.VHT),
        ConditionalField(ShortField("PartialAID", 0),
                         lambda pkt: pkt.present and pkt.present.VHT),
        # timestamp
        ConditionalField(_RadiotapReversePadField(LELongField("timestamp", 0)),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(LEShortField("ts_accuracy", 0),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(ByteField("ts_position", 0),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        ConditionalField(ByteField("ts_flags", 0),
                         lambda pkt: pkt.present and pkt.present.timestamp),
        # HE - XXX not complete
        ConditionalField(_RadiotapReversePadField(ShortField("he_data1", 0)),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data2", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data3", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data4", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data5", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        ConditionalField(ShortField("he_data6", 0),
                         lambda pkt: pkt.present and pkt.present.HE),
        # HE_MU
        ConditionalField(
            _RadiotapReversePadField(LEShortField("hemu_flags1", 0)),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(LEShortField("hemu_flags2", 0),
                         lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(
            FieldListField("RU_channel1", [],
                           ByteField,
                           count_from=lambda x: 4),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        ConditionalField(
            FieldListField("RU_channel2", [],
                           ByteField,
                           count_from=lambda x: 4),
            lambda pkt: pkt.present and pkt.present.HE_MU),
        # HE_MU_other_user
        ConditionalField(
            _RadiotapReversePadField(LEShortField("hemuou_per_user_1",
                                                  0x7fff)),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            LEShortField("hemuou_per_user_2", 0x003f),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            ByteField("hemuou_per_user_position", 0),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        ConditionalField(
            FlagsField("hemuou_per_user_known", 0, -16,
                       _rt_hemuother_per_user_known),
            lambda pkt: pkt.present and pkt.present.HE_MU_other_user),
        # L_SIG
        ConditionalField(
            _RadiotapReversePadField(
                FlagsField("lsig_data1", 0, -16, ["rate", "length"])),
            lambda pkt: pkt.present and pkt.present.L_SIG),
        ConditionalField(BitField("lsig_length", 0, 12),
                         lambda pkt: pkt.present and pkt.present.L_SIG),
        ConditionalField(BitField("lsig_rate", 0, 4),
                         lambda pkt: pkt.present and pkt.present.L_SIG),
        # Remaining
        StrLenField(
            'notdecoded',
            "",
            length_from=lambda pkt: max(pkt.len - pkt._tmp_dissect_pos, 0))
    ]

    def guess_payload_class(self, payload):
        if self.present and self.present.Flags and self.Flags.FCS:
            return Dot11FCS
        return Dot11

    def post_build(self, p, pay):
        if self.len is None:
            p = p[:2] + struct.pack("!H", len(p))[::-1] + p[4:]
        return p + pay
Exemple #3
0
class SAPDiagDyntAtomItem(PacketNoPadded):
    name = "SAP Diag Dynt Atom item"
    fields_desc = [
        ShortField("atom_length", 0),
        ByteField("dlg_flag_1", 0),
        ByteField("dlg_flag_2", 0),
        ByteEnumKeysField("etype", 0, diag_atom_etypes),
        ByteField("area", 0),
        ByteField("block", 0),
        ByteField("group", 0),
        ShortField("row", 0),
        ShortField("col", 0),
        # Attr flags
        BitField("attr_DIAG_BSD_COMBOSTYLE", 0, 1),  # 80
        BitField("attr_DIAG_BSD_YES3D", 0, 1),  # 40
        BitField("attr_DIAG_BSD_PROPFONT", 0, 1),  # 20
        BitField("attr_DIAG_BSD_MATCHCODE", 0, 1),  # 10
        BitField("attr_DIAG_BSD_JUSTRIGHT", 0, 1),  # 08
        BitField("attr_DIAG_BSD_INTENSIFY", 0, 1),  # 04
        BitField("attr_DIAG_BSD_INVISIBLE", 0, 1),  # 02
        BitField("attr_DIAG_BSD_PROTECTED", 0, 1),  # 01

        # DIAG_DGOTYP_FNAME
        ConditionalField(
            StrLenField("name_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype == 114),
        # DIAG_DGOTYP_PUSHBUTTON_2 */
        ConditionalField(ByteField("pushbutton_v_length", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ByteField("pushbutton_v_height", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ShortField("pushbutton_function_code_offset", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(ShortField("pushbutton_text_offset", 0),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(StrField("pushbutton_text", ""),
                         lambda pkt: pkt.etype in [115]),
        ConditionalField(StrField("pushbutton_function_code", ""),
                         lambda pkt: pkt.etype in [115]),
        # DIAG_DGOTYP_TABSTRIP_BUTTON
        ConditionalField(ByteField("tabstripbutton_v_length", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ByteField("tabstripbutton_v_height", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ByteField("tabstripbutton_page_id", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_function_code_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_text_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(ShortField("tabstripbutton_id_offset", 0),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_text", ""),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_function_code", ""),
                         lambda pkt: pkt.etype in [116]),
        ConditionalField(StrNullField("tabstripbutton_id", ""),
                         lambda pkt: pkt.etype in [116]),
        # DIAG_DGOTYP_XMLPROP
        ConditionalField(
            StrLenField("xmlprop_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype == 120),
        # DIAG_DGOTYP_EFIELD_1 or DIAG_DGOTYP_OFIELD_1 or DIAG_DGOTYP_KEYWORD_1
        ConditionalField(ByteField("field1_flag1", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(
            FieldLenField("field1_dlen",
                          None,
                          fmt="B",
                          length_of="field1_text"),
            lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(ByteField("field1_mlen", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(ShortField("field1_maxnrchars", 0),
                         lambda pkt: pkt.etype in [121, 122, 123]),
        ConditionalField(
            StrLenField("field1_text",
                        "",
                        length_from=lambda pkt: pkt.field1_dlen),
            lambda pkt: pkt.etype in [121, 122, 123]),
        # DIAG_DGOTYP_FRAME_1
        ConditionalField(ShortField("frame_drows", 0),
                         lambda pkt: pkt.etype in [127]),
        ConditionalField(ShortField("frame_dcols", 0),
                         lambda pkt: pkt.etype in [127]),
        ConditionalField(
            StrLenField("frame_text",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 17),
            lambda pkt: pkt.etype in [127]),
        # DIAG_DGOTYP_RADIOBUTTON_3
        ConditionalField(ByteField("radiobutton_button", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_visible_label_length", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_event_id_off", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ByteField("radiobutton_event_id_len", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_text_off", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(ShortField("radiobutton_text_length", 0),
                         lambda pkt: pkt.etype in [129]),
        ConditionalField(
            StrLenField("radiobutton_text",
                        "",
                        length_from=lambda pkt: pkt.radiobutton_event_id_len +
                        pkt.radiobutton_text_length),
            lambda pkt: pkt.etype in [129]),
        # DIAG_DGOTYP_EFIELD_2 or DIAG_DGOTYP_OFIELD_2 or DIAG_DGOTYP_KEYWORD_2
        ConditionalField(ShortField("field2_flag1", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(
            FieldLenField("field2_dlen",
                          None,
                          fmt="B",
                          length_of="field2_text"),
            lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(ByteField("field2_mlen", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(ShortField("field2_maxnrchars", 0),
                         lambda pkt: pkt.etype in [130, 131, 132]),
        ConditionalField(
            StrLenField("field2_text",
                        "",
                        length_from=lambda pkt: pkt.field2_dlen),
            lambda pkt: pkt.etype in [130, 131, 132]),
        # Remaining types
        ConditionalField(
            StrLenField("value",
                        "",
                        length_from=lambda pkt: pkt.atom_length - 13),
            lambda pkt: pkt.etype not in
            [114, 115, 116, 120, 121, 122, 123, 127, 129, 130, 131, 132]),
    ]

    def post_build(self, p, pay):
        if pay is None:
            pay = ''
        # Update the atom_length field (first 2 bytes) with the packet length
        p = pack("!H", len(p)) + p[2:]
        return p + pay
Exemple #4
0
class LLTDAttributeSeesList(LLTDAttribute):
    name = "LLTD Attribute - Sees List Working Set"
    fields_desc = [
        ByteField("len", 2),
        ShortField("max_entries", 0),
    ]
Exemple #5
0
        return min(14, max(1, (x - 2407) / 5))


class PresentFlagField(ConditionalField):
    """Utility field for use by RadioTap"""
    def __init__(self, field, flag_name):
        ConditionalField.__init__(
            self, field, lambda pkt: pkt.hasflag('present', flag_name))


# TODO(ivanlei): This fields_desc does not cover chained present flags decode will fail in this cases
scapy.layers.dot11.RadioTap.name = '802.11 RadioTap'

# Greatly improved fields_desc for RadioTap which parses known present flags
scapy.layers.dot11.RadioTap.fields_desc = [
    ByteField('version', 0),
    ByteField('pad', 0),
    LEShortField('RadioTap_len', 0),
    FlagsField('present', None, -32, [
        'TSFT', 'Flags', 'Rate', 'Channel', 'FHSS', 'dBm_AntSignal',
        'dBm_AntNoise', 'Lock_Quality', 'TX_Attenuation', 'dB_TX_Attenuation',
        'dBm_TX_Power', 'Antenna', 'dB_AntSignal', 'dB_AntNoise', 'b14', 'b15',
        'b16', 'b17', 'b18', 'b19', 'b20', 'b21', 'b22', 'b23', 'b24', 'b25',
        'b26', 'b27', 'b28', 'b29', 'b30', 'Ext'
    ]),
    PresentFlagField(LELongField('TSFT', 0), 'TSFT'),
    PresentFlagField(ByteField('Flags', 0), 'Flags'),
    PresentFlagField(ByteField('Rate', 0), 'Rate'),
    PresentFlagField(ChannelFromMhzField('Channel', 0), 'Channel'),
    PresentFlagField(LEShortField('Channel_flags', 0), 'Channel'),
    PresentFlagField(ByteField('FHSS_hop_set', 0), 'FHSS'),
Exemple #6
0
class LLTDAttribute80211MaxRate(LLTDAttribute):
    name = "LLTD Attribute - 802.11 Max Rate"
    fields_desc = [
        ByteField("len", 2),
        ShortField("rate", 0),
    ]
Exemple #7
0
class LLTDAttributeLinkSpeed(LLTDAttribute):
    name = "LLTD Attribute - Link Speed"
    fields_desc = [
        ByteField("len", 4),
        IntField("speed", 0),
    ]
class ISIS_BufferSizeTlv(ISIS_GenericTlv):
    name = "ISIS Buffer Size TLV"
    fields_desc = [ByteEnumField("type", 14, _isis_tlv_names),
                   ByteField("len", 2),
                   ShortField("lspbuffersize", 1497)]
class ISIS_ChecksumTlv(ISIS_GenericTlv):
    name = "ISIS Optional Checksum TLV"
    fields_desc = [ByteEnumField("type", 12, _isis_tlv_names),
                   ByteField("len", 2),
                   XShortField("checksum", None)]
Exemple #10
0
class IE_QoS(IE_Base):
    name = "QoS"
    fields_desc = [
        ByteEnumField("ietype", 135, IEType),
        ShortField("length", None),
        ByteField("allocation_retention_prioiry", 1),
        ConditionalField(XBitField("spare", 0x00, 2),
                         lambda p: p.length and p.length > 1),
        ConditionalField(XBitField("delay_class", 0x000, 3),
                         lambda p: p.length and p.length > 1),
        ConditionalField(XBitField("reliability_class", 0x000, 3),
                         lambda p: p.length and p.length > 1),
        ConditionalField(XBitField("peak_troughput", 0x0000, 4),
                         lambda p: p.length and p.length > 2),
        ConditionalField(BitField("spare", 0, 1),
                         lambda p: p.length and p.length > 2),
        ConditionalField(XBitField("precedence_class", 0x000, 3),
                         lambda p: p.length and p.length > 2),
        ConditionalField(XBitField("spare", 0x000, 3),
                         lambda p: p.length and p.length > 3),
        ConditionalField(XBitField("mean_troughput", 0x00000, 5),
                         lambda p: p.length and p.length > 3),
        ConditionalField(XBitField("traffic_class", 0x000, 3),
                         lambda p: p.length and p.length > 4),
        ConditionalField(XBitField("delivery_order", 0x00, 2),
                         lambda p: p.length and p.length > 4),
        ConditionalField(XBitField("delivery_of_err_sdu", 0x000, 3),
                         lambda p: p.length and p.length > 4),
        ConditionalField(ByteField("max_sdu_size", None),
                         lambda p: p.length and p.length > 5),
        ConditionalField(ByteField("max_bitrate_up", None),
                         lambda p: p.length and p.length > 6),
        ConditionalField(ByteField("max_bitrate_down", None),
                         lambda p: p.length and p.length > 7),
        ConditionalField(XBitField("redidual_ber", 0x0000, 4),
                         lambda p: p.length and p.length > 8),
        ConditionalField(XBitField("sdu_err_ratio", 0x0000, 4),
                         lambda p: p.length and p.length > 8),
        ConditionalField(XBitField("transfer_delay", 0x00000, 6),
                         lambda p: p.length and p.length > 9),
        ConditionalField(XBitField("traffic_handling_prio", 0x000, 2),
                         lambda p: p.length and p.length > 9),
        ConditionalField(ByteField("guaranteed_bit_rate_up", None),
                         lambda p: p.length and p.length > 10),
        ConditionalField(ByteField("guaranteed_bit_rate_down", None),
                         lambda p: p.length and p.length > 11),
        ConditionalField(XBitField("spare", 0x000, 3),
                         lambda p: p.length and p.length > 12),
        ConditionalField(BitField("signaling_indication", 0, 1),
                         lambda p: p.length and p.length > 12),
        ConditionalField(XBitField("source_stats_desc", 0x0000, 4),
                         lambda p: p.length and p.length > 12),
        ConditionalField(ByteField("max_bitrate_down_ext", None),
                         lambda p: p.length and p.length > 13),
        ConditionalField(ByteField("guaranteed_bitrate_down_ext", None),
                         lambda p: p.length and p.length > 14),
        ConditionalField(ByteField("max_bitrate_up_ext", None),
                         lambda p: p.length and p.length > 15),
        ConditionalField(ByteField("guaranteed_bitrate_up_ext", None),
                         lambda p: p.length and p.length > 16),
        ConditionalField(ByteField("max_bitrate_down_ext2", None),
                         lambda p: p.length and p.length > 17),
        ConditionalField(ByteField("guaranteed_bitrate_down_ext2", None),
                         lambda p: p.length and p.length > 18),
        ConditionalField(ByteField("max_bitrate_up_ext2", None),
                         lambda p: p.length and p.length > 19),
        ConditionalField(ByteField("guaranteed_bitrate_up_ext2", None),
                         lambda p: p.length and p.length > 20)
    ]
Exemple #11
0
class LL_MIN_USED_CHANNELS_IND(Packet):
    name = "LL_MIN_USED_CHANNELS_IND"
    fields_desc = [
        BTLEPhysField('phys', 0),
        ByteField("min_used_channels", 2),
    ]
Exemple #12
0
class IE_Recovery(IE_Base):
    name = "Recovery"
    fields_desc = [
        ByteEnumField("ietype", 14, IEType),
        ByteField("restart_counter", 24)
    ]
Exemple #13
0
class GTP_PDCP_PDU_ExtensionHeader(GTP_ExtensionHeader):
    fields_desc = [
        ByteField("length", 0x01),
        ShortField("pdcp_pdu", None),
        ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
    ]
Exemple #14
0
class GTP_UDPPort_ExtensionHeader(GTP_ExtensionHeader):
    fields_desc = [
        ByteField("length", 0x40),
        ShortField("udp_port", None),
        ByteEnumField("next_ex", 0, ExtensionHeadersTypes),
    ]
Exemple #15
0
class HCI_Event_Number_Of_Completed_Packets(Packet):
    name = "Number Of Completed Packets"
    fields_desc = [ByteField("number", 0)]
Exemple #16
0
class SAPRouter(Packet):
    """SAP Router packet

    This packet is used for general SAP Router packets. There are (at least)
    five types of SAP Router packets:

        1. Route packets. For requesting the routing of a connection to a
        remote hosts. The packet contains some general information and a
        connection string with a list of routing hops (:class:`SAPRouterRouteHop`).

        2. Administration packets. This packet is used for the SAP Router to
        send administrative commands. It's suppose to be used only from the
        hosts running the SAP Router or when an specific route is included in
        the routing table. Generally administration packets are not accepted
        from the external binding.

        3. Error Information packets. Packets sent when an error occurred.

        4. Control Message packets. Used to perform some control activities,
        like retrieving the current SAPRouter version or to perform the SNC
        handshake. They have the same structure that error information
        packets.

        5. Route accepted packet. Used to acknowledge a route request
        ("NI_PONG").


    Routed packets and some responses doesn't fill in these five packet
    types. For identifying those cases, you should check the type using the
    function :class:`router_is_known_type`.

    NI Versions found (unconfirmed):
        - 30: Release 40C
        - 36: Release <6.20
        - 38: Release 7.00/7.10
        - 39: Release 7.11
        - 40: Release 7.20/7.21
    """

    # Default router version to use
    SAPROUTER_DEFAULT_VERSION = 40

    # Constants for router types
    SAPROUTER_ROUTE = "NI_ROUTE"
    """ :cvar: Constant for route packets
        :type: C{string} """

    SAPROUTER_ADMIN = "ROUTER_ADM"
    """ :cvar: Constant for administration packets
        :type: C{string} """

    SAPROUTER_ERROR = "NI_RTERR"
    """ :cvar: Constant for error information packets
        :type: C{string} """

    SAPROUTER_CONTROL = "NI_RTERR"
    """ :cvar: Constant for control messages packets
        :type: C{string} """

    SAPROUTER_PONG = "NI_PONG"
    """ :cvar: Constant for route accepted packets
        :type: C{string} """

    router_type_values = [
        SAPROUTER_ADMIN,
        SAPROUTER_ERROR,
        SAPROUTER_CONTROL,
        SAPROUTER_ROUTE,
        SAPROUTER_PONG,
    ]
    """ :cvar: List of known packet types
        :type: ``list`` of C{string} """

    name = "SAP Router"
    fields_desc = [
        # General fields present in all SAP Router packets
        StrNullField("type", SAPROUTER_ROUTE),
        ConditionalField(
            ByteField("version", 2),
            lambda pkt: router_is_known_type(pkt) and not router_is_pong(pkt)),

        # Route packets
        ConditionalField(
            ByteField("route_ni_version", SAPROUTER_DEFAULT_VERSION),
            router_is_route),
        ConditionalField(ByteField("route_entries", 0), router_is_route),
        ConditionalField(
            ByteEnumKeysField("route_talk_mode", 0,
                              router_ni_talk_mode_values), router_is_route),
        ConditionalField(ShortField("route_padd", 0), router_is_route),
        ConditionalField(ByteField("route_rest_nodes", 0), router_is_route),
        ConditionalField(
            FieldLenField("route_length", 0, length_of="route_string",
                          fmt="I"), router_is_route),
        ConditionalField(IntField("route_offset", 0), router_is_route),
        ConditionalField(
            PacketListField("route_string",
                            None,
                            SAPRouterRouteHop,
                            length_from=lambda pkt: pkt.route_length),
            router_is_route),

        # Admin packets
        ConditionalField(
            ByteEnumKeysField("adm_command", 0x02, router_adm_commands),
            router_is_admin),
        ConditionalField(
            ShortField("adm_unused", 0x00), lambda pkt: router_is_admin(pkt)
            and pkt.adm_command not in [10, 11, 12, 13]),

        # Info Request fields
        ConditionalField(
            StrNullFixedLenField("adm_password", "", 19),
            lambda pkt: router_is_admin(pkt) and pkt.adm_command in [2]),

        # Cancel Route fields
        ConditionalField(
            FieldLenField("adm_client_count",
                          None,
                          count_of="adm_client_ids",
                          fmt="H"),
            lambda pkt: router_is_admin(pkt) and pkt.adm_command in [6]),
        # Trace Connection fields
        ConditionalField(
            FieldLenField("adm_client_count",
                          None,
                          count_of="adm_client_ids",
                          fmt="I"),
            lambda pkt: router_is_admin(pkt) and pkt.adm_command in [12, 13]),

        # Cancel Route or Trace Connection fields
        ConditionalField(
            FieldListField("adm_client_ids", [0x00],
                           IntField("", 0),
                           count_from=lambda pkt: pkt.adm_client_count), lambda
            pkt: router_is_admin(pkt) and pkt.adm_command in [6, 12, 13]),

        # Set/Clear Peer Trace fields  # TODO: Check whether this field should be a IPv6 address or another proper field
        ConditionalField(
            StrFixedLenField("adm_address_mask", "", 32),
            lambda pkt: router_is_admin(pkt) and pkt.adm_command in [10, 11]),

        # Error Information/Control Messages fields
        ConditionalField(
            ByteEnumKeysField("opcode", 0, router_control_opcodes),
            lambda pkt: router_is_error(pkt) or router_is_control(pkt)),
        ConditionalField(
            ByteField("opcode_padd", 0),
            lambda pkt: router_is_error(pkt) or router_is_control(pkt)),
        ConditionalField(
            SignedIntEnumField("return_code", 0, router_return_codes),
            lambda pkt: router_is_error(pkt) or router_is_control(pkt)),

        # Error Information fields
        ConditionalField(
            FieldLenField("err_text_length",
                          None,
                          length_of="err_text_value",
                          fmt="!I"),
            lambda pkt: router_is_error(pkt) and pkt.opcode == 0),
        ConditionalField(
            PacketField("err_text_value", SAPRouterError(),
                        SAPRouterError), lambda pkt: router_is_error(pkt) and
            pkt.opcode == 0 and pkt.err_text_length > 0),
        ConditionalField(IntField("err_text_unknown", 0),
                         lambda pkt: router_is_error(pkt) and pkt.opcode == 0),

        # Control Message fields
        ConditionalField(
            IntField("control_text_length", 0),
            lambda pkt: router_is_control(pkt) and pkt.opcode != 0),
        ConditionalField(
            StrField("control_text_value", "*ERR"),
            lambda pkt: router_is_control(pkt) and pkt.opcode != 0),

        # SNC Frame fields
        ConditionalField(
            PacketField("snc_frame", None, SAPSNCFrame),
            lambda pkt: router_is_control(pkt) and pkt.opcode in [70, 71])
    ]
Exemple #17
0
class LLTDAttributeIPv6Address(LLTDAttribute):
    name = "LLTD Attribute - IPv6 Address"
    fields_desc = [
        ByteField("len", 16),
        IP6Field("ipv6", "::"),
    ]
Exemple #18
0
class PCO_SOF(PCO_Option):
    name = "PCO MS Support of Network Requested Bearer Control indicator"
    fields_desc = [
        ShortEnumField("type", None, PCO_PROTOCOL_TYPES),
        ByteField("length", 0),
    ]
Exemple #19
0
class LLTDAttributePerformanceCounterFrequency(LLTDAttribute):
    name = "LLTD Attribute - Performance Counter Frequency"
    fields_desc = [
        ByteField("len", 8),
        LongField("freq", 0),
    ]
Exemple #20
0
class PNIORealTime(Packet):
    """PROFINET cyclic real-time"""
    name = "PROFINET Real-Time"
    fields_desc = [
        NotionalLenField("len", None, length_from=lambda p, s: len(s)),
        NotionalLenField(
            "dataLen",
            None,
            length_from=lambda p, s: len(s[:-4].rstrip(b"\0"))),  # noqa: E501
        LowerLayerBoundPacketListField(
            "data", [],
            _pnio_rtc_guess_payload_class,
            length_from=lambda p: p.dataLen),  # noqa: E501
        StrFixedLenField("padding",
                         "",
                         length_from=lambda p: p[PNIORealTime].padding_length(
                         )),  # noqa: E501
        ShortField("cycleCounter", 0),
        FlagsField("dataStatus", 0x35, 8, _PNIO_DS_FLAGS),
        ByteField("transferStatus", 0)
    ]
    overload_fields = {
        ProfinetIO: {
            "frameID": 0x8000
        },  # RT_CLASS_1
    }

    def padding_length(self):
        """Compute the length of the padding need for the ethernet frame"""
        fld, val = self.getfield_and_val("data")

        # use the len field if available to define the padding length, eg for
        # dissected packets
        pkt_len = self.getfieldval("len")
        if pkt_len is not None:
            return max(0, pkt_len - len(fld.addfield(self, b"", val)) - 4)

        if isinstance(self.underlayer, ProfinetIO) and \
                isinstance(self.underlayer.underlayer, UDP):
            return max(0, 12 - len(fld.addfield(self, b"", val)))
        else:
            return max(0, 40 - len(fld.addfield(self, b"", val)))

    @staticmethod
    def analyse_data(packets):
        """Analyse the data to find heuristical properties and determine
        location and type of data"""
        loc = PNIORealTime.find_data(packets)
        loc = PNIORealTime.analyse_profisafe(packets, loc)
        pnio_update_config(loc)
        return loc

    @staticmethod
    def find_data(packets):
        """Analyse a packet list to extract data offsets from packets data."""
        # a dictionary to count data offsets (ie != 0x80)
        # It's formatted: {(src, dst): (total, [count for offset in len])}
        heuristic = {}

        # Counts possible data locations
        # 0x80 are mainly IOxS and trailling 0x00s are just padding
        for pkt in packets:
            if PNIORealTime in pkt:
                pdu = bytes(pkt[PNIORealTime])[:-4].rstrip(b"\0")

                if (pkt.src, pkt.dst) not in heuristic:
                    heuristic[(pkt.src, pkt.dst)] = (0, [])

                total, counts = heuristic[(pkt.src, pkt.dst)]

                if len(counts) < len(pdu):
                    counts.extend([0 for _ in range(len(pdu) - len(counts))])

                for i in range(len(pdu)):
                    if orb(pdu[i]) != 0x80:
                        counts[i] += 1

                comm = (pkt.src, pkt.dst)
                heuristic[comm] = (total + 1, counts)

        # Determine data locations
        locations = {}
        for comm in heuristic:
            total, counts = heuristic[comm]
            length = len(counts)
            loc = locations[comm] = []
            start = None
            for i in range(length):
                if counts[
                        i] > total // 2:  # Data if more than half is != 0x80  # noqa: E501
                    if start is None:
                        start = i
                else:
                    if start is not None:
                        loc.append((start - length, PNIORealTimeRawData, {
                            "length": i - start
                        }))
                        start = None

        return locations

    @staticmethod
    def analyse_profisafe(packets, locations=None):
        """Analyse a packet list to find possible PROFISafe profils.

        It's based on an heuristical analysis of each payload to try to find
        CRC and control/status byte.

        locations: possible data locations. If not provided, analyse_pn_rt will
        be called beforehand. If not given, it calls in the same time
        analyse_data which update the configuration of the data field"""
        # get data locations and entropy of bytes
        if not locations:
            locations = PNIORealTime.find_data(packets)
        entropies = PNIORealTime.data_entropy(packets, locations)

        # Try to find at least 3 high entropy successive bytes (the CRC)
        for comm in entropies:
            entropy = dict(entropies[comm])  # Convert tuples to key => value

            for i in range(len(locations[comm])):
                # update each location with its value after profisafe analysis
                locations[comm][i] = \
                    PNIORealTime.analyse_one_profisafe_location(
                    locations[comm][i], entropy
                )

        return locations

    @staticmethod
    def analyse_one_profisafe_location(location, entropy):
        """Analyse one PNIO RTC data location to find if its a PROFISafe

        :param location: location to analyse, a tuple (start, type, config)
        :param entropy: the entropy of each byte of the packet data
        :returns: the configuration associated with the data
        """
        start, klass, conf = location
        if conf["length"] >= 4:  # Minimal PROFISafe length
            succ_count = 0
            for j in range(start, start + conf["length"]):
                # Limit for a CRC is set to 6 bit of entropy min
                if j in entropy and entropy[j] >= 6:
                    succ_count += 1
                else:
                    succ_count = 0
            # PROFISafe profiles must end with at least 3 bytes of high entropy
            if succ_count >= 3:  # Possible profisafe CRC
                return (start, Profisafe, {
                    "CRC": succ_count,
                    "length": conf["length"]
                })
        # Not a PROFISafe profile
        return (start, klass, conf)

    @staticmethod
    def data_entropy(packets, locations=None):
        """Analyse a packet list to find the entropy of each data byte

        locations: possible data locations. If not provided, analyse_pn_rt will
        be called beforehand. If not given, it calls in the same time
        analyse_data which update the configuration of the data field"""
        if not locations:
            locations = PNIORealTime.find_data(packets)

        # Retrieve the entropy of each data byte, for each communication
        entropies = {}
        for comm in locations:
            if len(locations[comm]) > 0:  # Doesn't append empty data
                entropies[comm] = []
                comm_packets = []

                # fetch all packets from the communication
                for pkt in packets:
                    if PNIORealTime in pkt and (pkt.src, pkt.dst) == comm:
                        comm_packets.append(
                            bytes(pkt[PNIORealTime])[:-4].rstrip(b"\0"))

                # Get the entropy
                for start, dummy, config in locations[comm]:
                    for i in range(start, start + config["length"]):
                        entropies[comm].append(
                            (i, entropy_of_byte(comm_packets, i)))

        return entropies

    @staticmethod
    def draw_entropy(packets, locations=None):
        """Plot the entropy of each data byte of PN RT communication"""
        import matplotlib.pyplot as plt
        import matplotlib.cm as cm
        entropies = PNIORealTime.data_entropy(packets, locations)

        rows = len(entropies)
        cur_row = 1
        for comm in entropies:
            index = []
            vals = []
            for i, ent in entropies[comm]:
                index.append(i)
                vals.append(ent)

            # Offsets the indexes to get the index from the beginning
            offset = -min(index)
            index = [i + offset for i in index]

            plt.subplot(rows, 1, cur_row)
            plt.bar(index, vals, 0.8, color="r")
            plt.xticks([i + 0.4 for i in index], index)
            plt.title("Entropy from %s to %s" % comm)
            cur_row += 1
            plt.ylabel("Shannon Entropy")

        plt.xlabel("Byte offset")  # x label only on the last row
        plt.legend()

        plt.tight_layout()
        plt.show()
Exemple #21
0
class LLTDAttributeLargeTLV(LLTDAttribute):
    name = "LLTD Attribute - Large TLV"
    fields_desc = [
        ByteField("len", 0),
    ]
Exemple #22
0
class LACP(Packet):
    name = "LACP"
    deprecated_fields = {
        "actor_port_numer": ("actor_port_number", "2.4.4"),
        "partner_port_numer": ("partner_port_number", "2.4.4"),
        "colletctor_reserved": ("collector_reserved", "2.4.4"),
    }
    fields_desc = [
        ByteField("version", 1),
        ByteField("actor_type", 1),
        ByteField("actor_length", 20),
        ShortField("actor_system_priority", 0),
        MACField("actor_system", None),
        ShortField("actor_key", 0),
        ShortField("actor_port_priority", 0),
        ShortField("actor_port_number", 0),
        ByteField("actor_state", 0),
        XStrFixedLenField("actor_reserved", "", 3),
        ByteField("partner_type", 2),
        ByteField("partner_length", 20),
        ShortField("partner_system_priority", 0),
        MACField("partner_system", None),
        ShortField("partner_key", 0),
        ShortField("partner_port_priority", 0),
        ShortField("partner_port_number", 0),
        ByteField("partner_state", 0),
        XStrFixedLenField("partner_reserved", "", 3),
        ByteField("collector_type", 3),
        ByteField("collector_length", 16),
        ShortField("collector_max_delay", 0),
        XStrFixedLenField("collector_reserved", "", 12),
        ByteField("terminator_type", 0),
        ByteField("terminator_length", 0),
        XStrFixedLenField("reserved", "", 50),
    ]
Exemple #23
0
class SAPDiag(PacketNoPadded):
    """SAP Diag packet

    This packet holds the Diag Header and serve as a container for
    :class:`SAPDiagItem` items. It handles compression/decompression, adding the
    appropriate Compression Header when necessary.
    """
    name = "SAP Diag"
    fields_desc = [
        ByteField("mode", 0),

        # Communication flags
        BitField("com_flag_TERM_GRA", 0, 1),
        BitField("com_flag_TERM_NNM", 0, 1),
        BitField("com_flag_TERM_CAS", 0, 1),
        BitField("com_flag_TERM_INI", 0, 1),
        BitField("com_flag_TERM_EOP", 0, 1),
        BitField("com_flag_TERM_NOP", 0, 1),
        BitField("com_flag_TERM_EOC", 0, 1),
        BitField("com_flag_TERM_EOS", 0, 1),
        ByteField("mode_stat", 0),
        ByteField("err_no", 0),
        ByteField("msg_type", 0),
        ByteField("msg_info", 0),
        ByteField("msg_rc", 0),
        ByteEnumKeysField("compress", 0, diag_compress_values),

        # Compression Header
        ConditionalField(LEIntField("uncompress_length", None),
                         lambda pkt: pkt.compress == 1),
        ConditionalField(
            ByteEnumField("algorithm", 0x12, {
                0x12: "LZH",
                0x10: "LZC"
            }), lambda pkt: pkt.compress == 1),
        ConditionalField(StrFixedLenField("magic_bytes", "\x1f\x9d", 2),
                         lambda pkt: pkt.compress == 1),
        ConditionalField(ByteField("special", 2),
                         lambda pkt: pkt.compress == 1),

        # SNC Frame
        ConditionalField(PacketField("snc_frame", None, SAPSNCFrame),
                         lambda pkt: pkt.compress in [2, 3]),

        # Message info
        ConditionalField(StrEncodedPaddedField("info", None),
                         lambda pkt: pkt.err_no != 0),

        # Payload
        PacketListField("message", None, SAPDiagItem)
    ]

    def do_compress(self, s):
        """Compress a string using SAP compression C++ extension.

        :param s: string to compress
        :type s: C{string}

        :return: string compression header plus the compressed string
        :rtype: C{string}

        :raise pysapcompress.Error: when a compression error is raised
        """
        if len(s) > 0:
            # Compress the payload and return the output
            (_, _, outbuffer) = pysapcompress.compress(s,
                                                       pysapcompress.ALG_LZH)
            return outbuffer

    def do_decompress(self, s, length):
        """Decompress a string using SAP compression C++ extension.

        :param s: compression header plus compressed string
        :type s: C{string}

        :param length: reported compressed length
        :type length: ``int``

        :return: decompressed string
        :rtype: C{string}

        :raise pysapcompress.Error: when a decompression error is raised
        """
        if len(s) > 0:
            # Decompress the payload and return the output
            (_, _, outbuffer) = pysapcompress.decompress(s, length)
            return outbuffer

    def pre_dissect(self, s):
        """Prepares the packet for dissection. If the compression flag is set,
        decompress the payload.
        """
        # If the compression flag is set, decompress everything after the headers
        if s[7] == "\x01":
            # First need to get the reported decompressed length
            (reported_length, ) = unpack("<I", s[8:12])

            # Then return the headers (Diag and Compression) and the payload (message field)
            try:
                return s[:16] + self.do_decompress(s[8:], reported_length)
            except DecompressError:
                return s
        # Uncompressed packet, just return them
        return s

    def post_build(self, p, pay):
        """Compress the payload. If the compression flag is set, compress both
        the message field and the payload.
        """
        if pay is None:
            pay = ''
        if self.compress == 1:
            payload = "".join([str(item) for item in self.message]) + pay
            if len(payload) > 0:
                try:
                    return p[:8] + self.do_compress(payload)
                except CompressError:
                    return p + pay
        return p + pay

    def get_item(self, item_type=None, item_id=None, item_sid=None):
        """Get an item from the packet's message. Returns None if the message
        is not found, or a list if the item is found multiple times.

        :param item_type: item type byte or string value
        :type item_type: ``int`` or C{string} or ``list``

        :param item_id: item ID byte or string value
        :type item_id: ``int`` or C{string} or ``list``

        :param item_sid: item SID byte or string value
        :type item_sid: ``int`` or C{string} or ``list``

        :return: list of items found on the packet or None
        :rtype: ``list`` of :class:`SAPDiagItem`
        """
        # Expand list lookups
        items = []
        if item_type is not None and type(item_type) == list:
            for itype in item_type:
                items.extend(self.get_item(itype, item_id, item_sid))
            return items
        if item_id is not None and type(item_id) == list:
            for iid in item_id:
                items.extend(self.get_item(item_type, iid, item_sid))
            return items
        if item_sid is not None and type(item_sid) == list:
            for isid in item_sid:
                items.extend(self.get_item(item_type, item_id, isid))
            return items

        # Perform name lookups
        if item_type is not None and isinstance(item_type, str):
            item_type = list(diag_item_types.keys())[list(
                diag_item_types.values()).index(item_type)]
        if item_id is not None and isinstance(item_id, str):
            item_id = list(diag_appl_ids.keys())[list(
                diag_appl_ids.values()).index(item_id)]
        if item_sid is not None and isinstance(item_sid, str):
            item_sid = list(diag_appl_sids[item_id].keys())[list(
                diag_appl_sids[item_id].values()).index(item_sid)]

        # Filter and return items
        if item_sid is None and item_id is None:
            items = [
                item for item in self.message
                if hasattr(item, "item_type") and item.item_type == item_type
            ]
        elif item_sid is None:
            items = [
                item for item in self.message if hasattr(item, "item_type")
                and item.item_type == item_type and item.item_id == item_id
            ]
        else:
            items = [
                item for item in self.message
                if hasattr(item, "item_type") and item.item_type == item_type
                and item.item_id == item_id and item.item_sid == item_sid
            ]

        return items
Exemple #24
0
class SAPLPSCipher(Packet):
    """SAP LPS cipher packet. This is the data stored inside an LPS encrypted blob
    (credential or PSE file). It contains all the required data to decrypt and validate
    the stored context.

    Context length should be <28h
    Restriction length should be <400h
    """
    name = "SAP LPS Cipher"

    LPS_FALLBACK = 0
    LPS_DPAPI = 1
    LPS_TPM = 2

    lps_types = {
        LPS_FALLBACK: "FALLBACK",
        LPS_DPAPI: "DPAPI",
        LPS_TPM: "TPM",
    }
    """LPS types"""

    fields_desc = [
        ByteField("version", 2),
        ByteEnumField("lps_type", 0, lps_types),
        ShortField("context_length", 0),
        StrLenField("context", None, length_from=lambda x: x.context_length),
        ShortField("restriction_length", 0),
        StrLenField("restriction",
                    None,
                    length_from=lambda x: x.restriction_length),
        ShortField("encrypted_key_length", 0),
        StrLenField("encrypted_key",
                    None,
                    length_from=lambda x: x.encrypted_key_length),
        ShortField("unknown_length", 0),
        StrLenField("unknown", None, length_from=lambda x: x.unknown_length),
        ShortField("encrypted_data_length", 0),
        StrLenField("encrypted_data",
                    None,
                    length_from=lambda x: x.encrypted_data_length),
        StrFixedLenField("hmac", None, 0x14),
        LEIntField("checksum", None),
    ]

    def decrypt(self):
        """Decrypt a blob using LPS. Implements FALLBACK and DP methods to derive
        or obtain the encryption key from the one stored in the PSE/credential file and then uses
        that encryption key to decrypt the credential using the AES cipher.

        LPS-protected PSEs/credentials are verified with both a CRC32 checksum and an HMAC.
        Validation of the checksum and HMAC is not implemented.

        :return: decrypted object
        :rtype: string

        :raise NotImplementedError: if the LPS method is not implemented
        :raise SAP_LPS_Decryption_Error: if there's an error decrypting the object
        """

        # Validate supported version
        if self.version != 2:
            log_lps.error("Version not supported")
            raise SAPLPSDecryptionError("Version not supported")

        # TODO: Calculate and validate CRC32

        # Decrypt the encryption key using the LPS method
        if self.lps_type in lps_encryption_key_decryptor:
            encryption_key = lps_encryption_key_decryptor[self.lps_type](self)
        else:
            log_lps.error("Invalid LPS decryption method")
            raise SAPLPSDecryptionError("Invalid LPS decryption method")

        # Decrypt the cipher text with the encryption key
        iv = "\x00" * 16
        decryptor = Cipher(algorithms.AES(encryption_key),
                           modes.CBC(iv),
                           backend=default_backend()).decryptor()
        plain = decryptor.update(self.encrypted_data) + decryptor.finalize()

        # TODO: Calculate and validate HMAC

        return plain

    def decrypt_encryption_key_dpapi(self):
        """Decrypts the encryption key using the DP API. The key is encrypted using
        the DP API without any additional entropy.

        :return: Encryption key decrypted
        :rtype: string
        """
        log_lps.debug("Obtaining encryption key with DPAPI LPS mode")

        return dpapi_decrypt_blob(self.encrypted_key)

    def decrypt_encryption_key_fallback(self):
        """Decrypts the encryption key using the FALLBACK method. In this method, the
        context string, usually "CredEncryption" or "PSEEncryption", is encrypted using
        a derivation of a fixed key hardcoded in CommonCryptoLib, and used as key to
        encrypt the actual encryption key used in the file with the AES cipher.

        :return: Encryption key decrypted
        :rtype: string
        """
        log_lps.debug("Obtaining encryption key with FALLBACK LPS mode")

        digest = Hash(SHA1(), backend=default_backend())
        digest.update(cred_key_lps_fallback)
        hashed_key = digest.finalize()

        hmac = HMAC(hashed_key, SHA1(), backend=default_backend())
        hmac.update(self.context)
        default_key = hmac.finalize()[:16]

        iv = "\x00" * 16
        decryptor = Cipher(algorithms.AES(default_key),
                           modes.CBC(iv),
                           backend=default_backend()).decryptor()
        encryption_key = decryptor.update(
            self.encrypted_key) + decryptor.finalize()

        return encryption_key

    def decrypt_encryption_key_tpm(self):
        """Decrypts the encryption key using the TPM method.

        :return: Encryption key decrypted
        :rtype: string
        """
        log_lps.error("LPS TPM decryption not implemented")
        raise NotImplementedError("LPS TPM decryption not implemented")
Exemple #25
0
class Dot11EltRSN(Packet):
    """The enc, cipher, and auth members contain the decoded 'security' details"""

    name = '802.11 RSN Information Element'

    cipher_suites = {
        '\x00\x0f\xac\x00': 'GROUP',
        '\x00\x0f\xac\x01': 'WEP',
        '\x00\x0f\xac\x02': 'TKIP',
        '\x00\x0f\xac\x04': 'CCMP',
        '\x00\x0f\xac\x05': 'WEP'
    }

    auth_suites = {'\x00\x0f\xac\x01': 'MGT', '\x00\x0f\xac\x02': 'PSK'}

    fields_desc = [
        ByteField('ID', 0),
        FieldLenField("len", None, "info", "B"),
        LEShortField('version', 1),
        StrFixedLenField('group_cipher_suite', '', length=4),
        LEFieldLenField('pairwise_cipher_suite_count',
                        1,
                        count_of='pairwise_cipher_suite'),
        FieldListField('pairwise_cipher_suite',
                       None,
                       StrFixedLenField('', '', length=4),
                       count_from=lambda pkt: pkt.pairwise_cipher_suite_count),
        LEFieldLenField('auth_cipher_suite_count',
                        1,
                        count_of='auth_cipher_suite'),
        FieldListField('auth_cipher_suite',
                       None,
                       StrFixedLenField('', '', length=4),
                       count_from=lambda pkt: pkt.auth_cipher_suite_count),
        BitField('rsn_cap_pre_auth', 0, 1),
        BitField('rsn_cap_no_pairwise', 0, 1),
        BitField('rsn_cap_ptksa_replay_counter', 0, 2),
        BitField('rsn_cap_gtksa_replay_counter', 0, 2),
        BitField('rsn_cap_mgmt_frame_protect_required', 0, 1),
        BitField('rsn_cap_mgmt_frame_protect_capable', 0, 1),
        BitField('rsn_cap_reserved_1', 0, 1),
        BitField('rsn_cap_peer_key_enabled', 0, 1),
        BitField('rsn_cap_reserved_2', 0, 6),
    ]

    def post_dissection(self, pkt):
        """Parse cipher suites to determine encryption, cipher, and authentication methods"""

        self.enc = 'WPA2'  # Everything is assumed to be WPA
        self.cipher = ''
        self.auth = ''

        ciphers = [
            self.cipher_suites.get(pairwise_cipher)
            for pairwise_cipher in self.getfieldval('pairwise_cipher_suite')
        ]
        if 'GROUP' in ciphers:
            ciphers = [
                self.cipher_suites.get(group_cipher, '')
                for group_cipher in self.getfieldval('group_cipher_suite')
            ]
        for cipher in ['CCMP', 'TKIP', 'WEP']:
            if cipher in ciphers:
                self.cipher = cipher
                break

        if 'WEP' == self.cipher:
            self.enc = 'WEP'

        for auth_cipher in self.getfieldval('auth_cipher_suite'):
            self.auth = self.auth_suites.get(auth_cipher, '')
            break
Exemple #26
0
class LLTD(Packet):
    name = "LLTD"
    answer_hashret = {
        # (tos, function) tuple mapping (answer -> query), used by
        # .hashret()
        (1, 1): (0, 0),
        (0, 12): (0, 11),
    }
    fields_desc = [
        ByteField("version", 1),
        ByteEnumField("tos", 0, {
            0: "Topology discovery",
            1: "Quick discovery",
            2: "QoS diagnostics",
        }),
        ByteField("reserved", 0),
        MultiEnumField("function",
                       0, {
                           0: {
                               0: "Discover",
                               1: "Hello",
                               2: "Emit",
                               3: "Train",
                               4: "Probe",
                               5: "Ack",
                               6: "Query",
                               7: "QueryResp",
                               8: "Reset",
                               9: "Charge",
                               10: "Flat",
                               11: "QueryLargeTlv",
                               12: "QueryLargeTlvResp",
                           },
                           1: {
                               0: "Discover",
                               1: "Hello",
                               8: "Reset",
                           },
                           2: {
                               0: "QosInitializeSink",
                               1: "QosReady",
                               2: "QosProbe",
                               3: "QosQuery",
                               4: "QosQueryResp",
                               5: "QosReset",
                               6: "QosError",
                               7: "QosAck",
                               8: "QosCounterSnapshot",
                               9: "QosCounterResult",
                               10: "QosCounterLease",
                           },
                       },
                       depends_on=lambda pkt: pkt.tos,
                       fmt="B"),
        MACField("real_dst", None),
        MACField("real_src", None),
        ConditionalField(ShortField("xid", 0),
                         lambda pkt: pkt.function in [0, 8]),
        ConditionalField(ShortField("seq", 0),
                         lambda pkt: pkt.function not in [0, 8]),
    ]

    def post_build(self, pkt, pay):
        if (self.real_dst is None or self.real_src is None) and \
           isinstance(self.underlayer, Ether):
            eth = self.underlayer
            if self.real_dst is None:
                pkt = (pkt[:4] + eth.fields_desc[0].i2m(eth, eth.dst) +
                       pkt[10:])
            if self.real_src is None:
                pkt = (pkt[:10] + eth.fields_desc[1].i2m(eth, eth.src) +
                       pkt[16:])
        return pkt + pay

    def mysummary(self):
        if isinstance(self.underlayer, Ether):
            return self.underlayer.sprintf(
                'LLTD %src% > %dst% %LLTD.tos% - %LLTD.function%')
        else:
            return self.sprintf('LLTD %tos% - %function%')

    def hashret(self):
        tos, function = self.tos, self.function
        return b"%c%c" % self.answer_hashret.get((tos, function),
                                                 (tos, function))

    def answers(self, other):
        if not isinstance(other, LLTD):
            return False
        if self.tos == 0:
            if self.function == 0 and isinstance(self.payload, LLTDDiscover) \
               and len(self[LLTDDiscover].stations_list) == 1:
                # "Topology discovery - Discover" with one MAC address
                # discovered answers a "Quick discovery - Hello"
                return other.tos == 1 and \
                    other.function == 1 and \
                    LLTDAttributeHostID in other and \
                    other[LLTDAttributeHostID].mac == \
                    self[LLTDDiscover].stations_list[0]
            elif self.function == 12:
                # "Topology discovery - QueryLargeTlvResp" answers
                # "Topology discovery - QueryLargeTlv" with same .seq
                # value
                return other.tos == 0 and other.function == 11 \
                    and other.seq == self.seq
        elif self.tos == 1:
            if self.function == 1 and isinstance(self.payload, LLTDHello):
                # "Quick discovery - Hello" answers a "Topology
                # discovery - Discover"
                return other.tos == 0 and other.function == 0 and \
                    other.real_src == self.current_mapper_address
        return False
Exemple #27
0
class IGMP(Packet):
    """IGMP Message Class for v1 and v2.

This class is derived from class Packet. You  need call "igmpize()"
so the packet is transformed according the RFC when sent.
a=Ether(src="00:01:02:03:04:05")
b=IP(src="1.2.3.4")
c=IGMP(type=0x12, gaddr="224.2.3.4")
x = a/b/c
x[IGMP].igmpize()
sendp(a/b/c, iface="en0")

    Parameters:
      type    IGMP type field, 0x11, 0x12, 0x16 or 0x17
      mrcode  Maximum Response time (zero for v1)
      gaddr   Multicast Group Address 224.x.x.x/4

See RFC2236, Section 2. Introduction for definitions of proper
IGMPv2 message format   http://www.faqs.org/rfcs/rfc2236.html

  """
    name = "IGMP"

    igmptypes = {
        0x11: "Group Membership Query",
        0x12: "Version 1 - Membership Report",
        0x16: "Version 2 - Membership Report",
        0x17: "Leave Group"
    }

    fields_desc = [
        ByteEnumField("type", 0x11, igmptypes),
        ByteField("mrcode", 20),
        XShortField("chksum", None),
        IPField("gaddr", "0.0.0.0")
    ]

    def post_build(self, p, pay):
        """Called implicitly before a packet is sent to compute and place IGMP checksum.

        Parameters:
          self    The instantiation of an IGMP class
          p       The IGMP message in hex in network byte order
          pay     Additional payload for the IGMP message
        """
        p += pay
        if self.chksum is None:
            ck = checksum(p)
            p = p[:2] + chb(ck >> 8) + chb(ck & 0xff) + p[4:]
        return p

    @classmethod
    def dispatch_hook(cls, _pkt=None, *args, **kargs):
        if _pkt and len(_pkt) >= 4:
            from scapy.contrib.igmpv3 import IGMPv3
            if orb(_pkt[0]) in [0x22, 0x30, 0x31, 0x32]:
                return IGMPv3
            if orb(_pkt[0]) == 0x11 and len(_pkt) >= 12:
                return IGMPv3
        return IGMP

    def igmpize(self):
        """Called to explicitly fixup the packet according to the IGMP RFC

        The rules are:
        General:
            1.  the Max Response time is meaningful only in Membership Queries and should be zero
        IP:
            1. Send General Group Query to 224.0.0.1 (all systems)
            2. Send Leave Group to 224.0.0.2 (all routers)
            3a.Otherwise send the packet to the group address
            3b.Send reports/joins to the group address
            4. ttl = 1 (RFC 2236, section 2)
            5. send the packet with the router alert IP option (RFC 2236, section 2)
        Ether:
            1. Recalculate destination

        Returns:
            True    The tuple ether/ip/self passed all check and represents
                    a proper IGMP packet.
            False   One of more validation checks failed and no fields
                    were adjusted.

        The function will examine the IGMP message to assure proper format.
        Corrections will be attempted if possible. The IP header is then properly
        adjusted to ensure correct formatting and assignment. The Ethernet header
        is then adjusted to the proper IGMP packet format.
        """
        gaddr = self.gaddr if hasattr(
            self, "gaddr") and self.gaddr else "0.0.0.0"  # noqa: E501
        underlayer = self.underlayer
        if self.type not in [0x11, 0x30]:  # General Rule 1  # noqa: E501
            self.mrcode = 0
        if isinstance(underlayer, IP):
            if (self.type == 0x11):
                if (gaddr == "0.0.0.0"):
                    underlayer.dst = "224.0.0.1"  # IP rule 1  # noqa: E501
                elif isValidMCAddr(gaddr):
                    underlayer.dst = gaddr  # IP rule 3a  # noqa: E501
                else:
                    warning("Invalid IGMP Group Address detected !")
                    return False
            elif ((self.type == 0x17) and isValidMCAddr(gaddr)):
                underlayer.dst = "224.0.0.2"  # IP rule 2  # noqa: E501
            elif (
                (self.type == 0x12) or
                (self.type == 0x16)) and (isValidMCAddr(gaddr)):  # noqa: E501
                underlayer.dst = gaddr  # IP rule 3b  # noqa: E501
            else:
                warning("Invalid IGMP Type detected !")
                return False
            if not any(
                    isinstance(x, IPOption_Router_Alert)
                    for x in underlayer.options):  # noqa: E501
                underlayer.options.append(IPOption_Router_Alert())
            _root = self.firstlayer()
            if _root.haslayer(Ether):
                # Force recalculate Ether dst
                _root[Ether].dst = getmacbyip(
                    underlayer.dst)  # Ether rule 1  # noqa: E501
        from scapy.contrib.igmpv3 import IGMPv3
        if isinstance(self, IGMPv3):
            self.encode_maxrespcode()
        return True

    def mysummary(self):
        """Display a summary of the IGMP object."""
        if isinstance(self.underlayer, IP):
            return self.underlayer.sprintf(
                "IGMP: %IP.src% > %IP.dst% %IGMP.type% %IGMP.gaddr%"
            )  # noqa: E501
        else:
            return self.sprintf("IGMP %IGMP.type% %IGMP.gaddr%")
Exemple #28
0
class LLTDAttributePhysicalMedium(LLTDAttribute):
    name = "LLTD Attribute - Physical Medium"
    fields_desc = [
        ByteField("len", 4),
        IntEnumField(
            "medium",
            6,
            {
                # https://www.iana.org/assignments/ianaiftype-mib/ianaiftype-mib
                1: "other",
                2: "regular1822",
                3: "hdh1822",
                4: "ddnX25",
                5: "rfc877x25",
                6: "ethernetCsmacd",
                7: "iso88023Csmacd",
                8: "iso88024TokenBus",
                9: "iso88025TokenRing",
                10: "iso88026Man",
                11: "starLan",
                12: "proteon10Mbit",
                13: "proteon80Mbit",
                14: "hyperchannel",
                15: "fddi",
                16: "lapb",
                17: "sdlc",
                18: "ds1",
                19: "e1",
                20: "basicISDN",
                21: "primaryISDN",
                22: "propPointToPointSerial",
                23: "ppp",
                24: "softwareLoopback",
                25: "eon",
                26: "ethernet3Mbit",
                27: "nsip",
                28: "slip",
                29: "ultra",
                30: "ds3",
                31: "sip",
                32: "frameRelay",
                33: "rs232",
                34: "para",
                35: "arcnet",
                36: "arcnetPlus",
                37: "atm",
                38: "miox25",
                39: "sonet",
                40: "x25ple",
                41: "iso88022llc",
                42: "localTalk",
                43: "smdsDxi",
                44: "frameRelayService",
                45: "v35",
                46: "hssi",
                47: "hippi",
                48: "modem",
                49: "aal5",
                50: "sonetPath",
                51: "sonetVT",
                52: "smdsIcip",
                53: "propVirtual",
                54: "propMultiplexor",
                55: "ieee80212",
                56: "fibreChannel",
                57: "hippiInterface",
                58: "frameRelayInterconnect",
                59: "aflane8023",
                60: "aflane8025",
                61: "cctEmul",
                62: "fastEther",
                63: "isdn",
                64: "v11",
                65: "v36",
                66: "g703at64k",
                67: "g703at2mb",
                68: "qllc",
                69: "fastEtherFX",
                70: "channel",
                71: "ieee80211",
                72: "ibm370parChan",
                73: "escon",
                74: "dlsw",
                75: "isdns",
                76: "isdnu",
                77: "lapd",
                78: "ipSwitch",
                79: "rsrb",
                80: "atmLogical",
                81: "ds0",
                82: "ds0Bundle",
                83: "bsc",
                84: "async",
                85: "cnr",
                86: "iso88025Dtr",
                87: "eplrs",
                88: "arap",
                89: "propCnls",
                90: "hostPad",
                91: "termPad",
                92: "frameRelayMPI",
                93: "x213",
                94: "adsl",
                95: "radsl",
                96: "sdsl",
                97: "vdsl",
                98: "iso88025CRFPInt",
                99: "myrinet",
                100: "voiceEM",
                101: "voiceFXO",
                102: "voiceFXS",
                103: "voiceEncap",
                104: "voiceOverIp",
                105: "atmDxi",
                106: "atmFuni",
                107: "atmIma",
                108: "pppMultilinkBundle",
                109: "ipOverCdlc",
                110: "ipOverClaw",
                111: "stackToStack",
                112: "virtualIpAddress",
                113: "mpc",
                114: "ipOverAtm",
                115: "iso88025Fiber",
                116: "tdlc",
                117: "gigabitEthernet",
                118: "hdlc",
                119: "lapf",
                120: "v37",
                121: "x25mlp",
                122: "x25huntGroup",
                123: "transpHdlc",
                124: "interleave",
                125: "fast",
                126: "ip",
                127: "docsCableMaclayer",
                128: "docsCableDownstream",
                129: "docsCableUpstream",
                130: "a12MppSwitch",
                131: "tunnel",
                132: "coffee",
                133: "ces",
                134: "atmSubInterface",
                135: "l2vlan",
                136: "l3ipvlan",
                137: "l3ipxvlan",
                138: "digitalPowerline",
                139: "mediaMailOverIp",
                140: "dtm",
                141: "dcn",
                142: "ipForward",
                143: "msdsl",
                144: "ieee1394",
                145: "if-gsn",
                146: "dvbRccMacLayer",
                147: "dvbRccDownstream",
                148: "dvbRccUpstream",
                149: "atmVirtual",
                150: "mplsTunnel",
                151: "srp",
                152: "voiceOverAtm",
                153: "voiceOverFrameRelay",
                154: "idsl",
                155: "compositeLink",
                156: "ss7SigLink",
                157: "propWirelessP2P",
                158: "frForward",
                159: "rfc1483",
                160: "usb",
                161: "ieee8023adLag",
                162: "bgppolicyaccounting",
                163: "frf16MfrBundle",
                164: "h323Gatekeeper",
                165: "h323Proxy",
                166: "mpls",
                167: "mfSigLink",
                168: "hdsl2",
                169: "shdsl",
                170: "ds1FDL",
                171: "pos",
                172: "dvbAsiIn",
                173: "dvbAsiOut",
                174: "plc",
                175: "nfas",
                176: "tr008",
                177: "gr303RDT",
                178: "gr303IDT",
                179: "isup",
                180: "propDocsWirelessMaclayer",
                181: "propDocsWirelessDownstream",
                182: "propDocsWirelessUpstream",
                183: "hiperlan2",
                184: "propBWAp2Mp",
                185: "sonetOverheadChannel",
                186: "digitalWrapperOverheadChannel",
                187: "aal2",
                188: "radioMAC",
                189: "atmRadio",
                190: "imt",
                191: "mvl",
                192: "reachDSL",
                193: "frDlciEndPt",
                194: "atmVciEndPt",
                195: "opticalChannel",
                196: "opticalTransport",
                197: "propAtm",
                198: "voiceOverCable",
                199: "infiniband",
                200: "teLink",
                201: "q2931",
                202: "virtualTg",
                203: "sipTg",
                204: "sipSig",
                205: "docsCableUpstreamChannel",
                206: "econet",
                207: "pon155",
                208: "pon622",
                209: "bridge",
                210: "linegroup",
                211: "voiceEMFGD",
                212: "voiceFGDEANA",
                213: "voiceDID",
                214: "mpegTransport",
                215: "sixToFour",
                216: "gtp",
                217: "pdnEtherLoop1",
                218: "pdnEtherLoop2",
                219: "opticalChannelGroup",
                220: "homepna",
                221: "gfp",
                222: "ciscoISLvlan",
                223: "actelisMetaLOOP",
                224: "fcipLink",
                225: "rpr",
                226: "qam",
                227: "lmp",
                228: "cblVectaStar",
                229: "docsCableMCmtsDownstream",
                230: "adsl2",
                231: "macSecControlledIF",
                232: "macSecUncontrolledIF",
                233: "aviciOpticalEther",
                234: "atmbond",
                235: "voiceFGDOS",
                236: "mocaVersion1",
                237: "ieee80216WMAN",
                238: "adsl2plus",
                239: "dvbRcsMacLayer",
                240: "dvbTdm",
                241: "dvbRcsTdma",
                242: "x86Laps",
                243: "wwanPP",
                244: "wwanPP2",
                245: "voiceEBS",
                246: "ifPwType",
                247: "ilan",
                248: "pip",
                249: "aluELP",
                250: "gpon",
                251: "vdsl2",
                252: "capwapDot11Profile",
                253: "capwapDot11Bss",
                254: "capwapWtpVirtualRadio",
                255: "bits",
                256: "docsCableUpstreamRfPort",
                257: "cableDownstreamRfPort",
                258: "vmwareVirtualNic",
                259: "ieee802154",
                260: "otnOdu",
                261: "otnOtu",
                262: "ifVfiType",
                263: "g9981",
                264: "g9982",
                265: "g9983",
                266: "aluEpon",
                267: "aluEponOnu",
                268: "aluEponPhysicalUni",
                269: "aluEponLogicalLink",
                271: "aluGponPhysicalUni",
                272: "vmwareNicTeam",
                277: "docsOfdmDownstream",
                278: "docsOfdmaUpstream",
                279: "gfast",
                280: "sdci",
            }),
    ]
Exemple #29
0
class SAPDiagMenuEntry(PacketNoPadded):
    name = "SAP Diag Menu Entry"
    fields_desc = [
        ShortField("length", 0),
        ByteField("position_1", 0),
        ByteField("position_2", 0),
        ByteField("position_3", 0),
        ByteField("position_4", 0),
        # Menu Entry Flags
        BitField("flag_TERM_??8", 0, 1),  # 80
        BitField("flag_TERM_??7", 0, 1),  # 40
        BitField("flag_TERM_??6", 0, 1),  # 20
        BitField("flag_TERM_VKEY", 0, 1),  # 10
        BitField("flag_TERM_SEP", 0, 1),  # 8
        BitField("flag_TERM_MEN", 0, 1),  # 4
        BitField("flag_TERM_SEL", 0, 1),  # 2
        BitField("flag_TERM_??1", 0, 1),  # 1
        ByteField("virtual_key", 0),
        ByteField("return_code_1", 0),
        ByteField("return_code_2", 0),
        ByteField("return_code_3", 0),
        ByteField("return_code_4", 0),
        ByteField("return_code_5", 0),
        ByteField("return_code_6", 0),
        ByteField("function_code_1", 0),
        ByteField("function_code_2", 0),
        ByteField("function_code_3", 0),
        ByteField("function_code_4", 0),
        ByteField("function_code_5", 0),
        ByteField("function_code_6", 0),
        StrNullField("text", ""),
        StrNullField("accelerator", ""),
        StrNullField("info", ""),
    ]
Exemple #30
0
class LLTDAttributeIPv4Address(LLTDAttribute):
    name = "LLTD Attribute - IPv4 Address"
    fields_desc = [
        ByteField("len", 4),
        IPField("ipv4", "0.0.0.0"),
    ]
Exemple #31
0
 def getfield(self, pkt, s):
     if pkt.with_padding:
         return ByteField.getfield(self, pkt, s)
     return s, None
Exemple #32
0
class HCI_Event_Hdr(Packet):
    name = "HCI Event header"
    fields_desc = [
        XByteField("code", 0),
        ByteField("length", 0),
    ]