detect/csum: add igmp-csum keyword to match checksum

Add rule to decoder-events.rules to match on bad checksums.
pull/14921/head
Victor Julien 9 months ago
parent c54bc8bc8b
commit 190ed2e8ed

@ -120,6 +120,8 @@ alert icmp any any -> any any (msg:"SURICATA ICMPv4 invalid checksum"; icmpv4-cs
alert tcp any any -> any any (msg:"SURICATA TCPv6 invalid checksum"; tcpv6-csum:invalid; classtype:protocol-command-decode; sid:2200077; rev:2;) alert tcp any any -> any any (msg:"SURICATA TCPv6 invalid checksum"; tcpv6-csum:invalid; classtype:protocol-command-decode; sid:2200077; rev:2;)
alert udp any any -> any any (msg:"SURICATA UDPv6 invalid checksum"; udpv6-csum:invalid; classtype:protocol-command-decode; sid:2200078; rev:2;) alert udp any any -> any any (msg:"SURICATA UDPv6 invalid checksum"; udpv6-csum:invalid; classtype:protocol-command-decode; sid:2200078; rev:2;)
alert icmp any any -> any any (msg:"SURICATA ICMPv6 invalid checksum"; icmpv6-csum:invalid; classtype:protocol-command-decode; sid:2200079; rev:2;) alert icmp any any -> any any (msg:"SURICATA ICMPv6 invalid checksum"; icmpv6-csum:invalid; classtype:protocol-command-decode; sid:2200079; rev:2;)
alert igmp any any -> any any (msg:"SURICATA IGMP invalid checksum"; igmp-csum:invalid; classtype:protocol-command-decode; sid:2200126; rev:1;)
# IPv4 in IPv6 rules # IPv4 in IPv6 rules
alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 packet too short"; decode-event:ipv6.ipv4_in_ipv6_too_small; classtype:protocol-command-decode; sid:2200082; rev:2;) alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 packet too short"; decode-event:ipv6.ipv4_in_ipv6_too_small; classtype:protocol-command-decode; sid:2200082; rev:2;)
alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 invalid protocol"; decode-event:ipv6.ipv4_in_ipv6_wrong_version; classtype:protocol-command-decode; sid:2200083; rev:2;) alert pkthdr any any -> any any (msg:"SURICATA IPv4-in-IPv6 invalid protocol"; decode-event:ipv6.ipv4_in_ipv6_wrong_version; classtype:protocol-command-decode; sid:2200083; rev:2;)
@ -158,5 +160,5 @@ alert pkthdr any any -> any any (msg:"SURICATA packet with too many layers"; dec
alert pkthdr any any -> any any (msg:"SURICATA AF-PACKET truncated packet"; decode-event:afpacket.trunc_pkt; classtype:protocol-command-decode; sid:2200122; rev:1;) alert pkthdr any any -> any any (msg:"SURICATA AF-PACKET truncated packet"; decode-event:afpacket.trunc_pkt; classtype:protocol-command-decode; sid:2200122; rev:1;)
alert ipv4 any any -> any any (msg:"SURICATA IPv4 unknown protocol"; decode-event:ipv4.unknown_protocol; threshold: type limit, track by_src, seconds 60, count 1;classtype:protocol-command-decode; sid:2200125;) alert ipv4 any any -> any any (msg:"SURICATA IPv4 unknown protocol"; decode-event:ipv4.unknown_protocol; threshold: type limit, track by_src, seconds 60, count 1;classtype:protocol-command-decode; sid:2200125;)
# next sid is 2200126 # next sid is 2200127

@ -90,6 +90,12 @@ static int DetectICMPV6CsumMatch(DetectEngineThreadCtx *,
static int DetectICMPV6CsumSetup(DetectEngineCtx *, Signature *, const char *); static int DetectICMPV6CsumSetup(DetectEngineCtx *, Signature *, const char *);
static void DetectICMPV6CsumFree(DetectEngineCtx *, void *); static void DetectICMPV6CsumFree(DetectEngineCtx *, void *);
/* prototypes for the "igmp-csum" rule keyword */
static int DetectIGMPCsumMatch(
DetectEngineThreadCtx *, Packet *, const Signature *, const SigMatchCtx *);
static int DetectIGMPCsumSetup(DetectEngineCtx *, Signature *, const char *);
static void DetectIGMPCsumFree(DetectEngineCtx *, void *);
#ifdef UNITTESTS #ifdef UNITTESTS
static void DetectCsumRegisterTests(void); static void DetectCsumRegisterTests(void);
#endif #endif
@ -182,6 +188,12 @@ void DetectCsumRegister (void)
sigmatch_table[DETECT_ICMPV6_CSUM].Setup = DetectICMPV6CsumSetup; sigmatch_table[DETECT_ICMPV6_CSUM].Setup = DetectICMPV6CsumSetup;
sigmatch_table[DETECT_ICMPV6_CSUM].Free = DetectICMPV6CsumFree; sigmatch_table[DETECT_ICMPV6_CSUM].Free = DetectICMPV6CsumFree;
sigmatch_table[DETECT_ICMPV6_CSUM].desc = "match on IPv6/ICMPv6 checksum"; sigmatch_table[DETECT_ICMPV6_CSUM].desc = "match on IPv6/ICMPv6 checksum";
sigmatch_table[DETECT_IGMP_CSUM].name = "igmp-csum";
sigmatch_table[DETECT_IGMP_CSUM].Match = DetectIGMPCsumMatch;
sigmatch_table[DETECT_IGMP_CSUM].Setup = DetectIGMPCsumSetup;
sigmatch_table[DETECT_IGMP_CSUM].Free = DetectIGMPCsumFree;
sigmatch_table[DETECT_IGMP_CSUM].desc = "match on IPv4/IGMP checksum";
} }
/** /**
@ -796,6 +808,86 @@ static void DetectICMPV6CsumFree(DetectEngineCtx *de_ctx, void *ptr)
SCFree(ptr); SCFree(ptr);
} }
/**
* \brief Checks if the packet sent as the argument, has a valid or invalid
* igmp checksum, based on whether igmp-csum option for this rule
* has been supplied with "valid" or "invalid" argument
*
* \param t Pointer to the tv for this detection module instance
* \param det_ctx Pointer to the detection engine thread context
* \param p Pointer to the Packet currently being matched
* \param s Pointer to the Signature, the packet is being currently
* matched with
* \param m Pointer to the keyword_structure(SigMatch) from the above
* Signature, the Packet is being currently matched with
*
* \retval 1 if the Packet contents match the keyword option; 0 otherwise
*/
static int DetectIGMPCsumMatch(
DetectEngineThreadCtx *det_ctx, Packet *p, const Signature *s, const SigMatchCtx *ctx)
{
const DetectCsumData *cd = (const DetectCsumData *)ctx;
if (!PacketIsIPv4(p) || !PacketIsIGMP(p) || p->proto != IPPROTO_IGMP)
return 0;
if (p->flags & PKT_IGNORE_CHECKSUM) {
return cd->valid;
}
const IGMPHdr *igmph = PacketGetIGMP(p);
if (!p->l4.csum_set) {
const IPV4Hdr *ip4h = PacketGetIPv4(p);
p->l4.csum = ICMPV4CalculateChecksum(
(uint16_t *)igmph, IPV4_GET_RAW_IPLEN(ip4h) - IPV4_GET_RAW_HLEN(ip4h));
p->l4.csum_set = true;
}
if (p->l4.csum == igmph->checksum && cd->valid == 1)
return 1;
else if (p->l4.csum != igmph->checksum && cd->valid == 0)
return 1;
else
return 0;
}
/**
* \brief Creates a SigMatch for the icmpv4-csum keyword being sent as argument,
* and appends it to the Signature(s). Accepts 2 values for the
* keyword - "valid" and "invalid", both with and without quotes
*
* \param de_ctx Pointer to the detection engine context
* \param s Pointer to signature for the current Signature being parsed
* from the rules
* \param csum_str Pointer to the string holding the keyword value
*
* \retval 0 on success, -1 on failure
*/
static int DetectIGMPCsumSetup(DetectEngineCtx *de_ctx, Signature *s, const char *csum_str)
{
DetectCsumData *cd = SCCalloc(1, sizeof(DetectCsumData));
if (cd == NULL)
return -1;
if (DetectCsumParseArg(csum_str, cd) == 0)
goto error;
if (SCSigMatchAppendSMToList(
de_ctx, s, DETECT_IGMP_CSUM, (SigMatchCtx *)cd, DETECT_SM_LIST_MATCH) == NULL) {
goto error;
}
return 0;
error:
DetectIGMPCsumFree(de_ctx, cd);
return -1;
}
static void DetectIGMPCsumFree(DetectEngineCtx *de_ctx, void *ptr)
{
SCFree(ptr);
}
/* ---------------------------------- Unit Tests --------------------------- */ /* ---------------------------------- Unit Tests --------------------------- */
#ifdef UNITTESTS #ifdef UNITTESTS

@ -116,6 +116,7 @@ enum DetectKeywordId {
DETECT_UDPV6_CSUM, DETECT_UDPV6_CSUM,
DETECT_ICMPV4_CSUM, DETECT_ICMPV4_CSUM,
DETECT_ICMPV6_CSUM, DETECT_ICMPV6_CSUM,
DETECT_IGMP_CSUM,
DETECT_STREAM_SIZE, DETECT_STREAM_SIZE,
DETECT_DETECTION_FILTER, DETECT_DETECTION_FILTER,

Loading…
Cancel
Save