Detection rules › Sublime MQL

Attachment: ICS calendar with embedded file from internal sender with SPF failure

Severity
high
Type
rule
Source
github.com/sublime-security/sublime-rules

Detects calendar invitations (ICS files) from internal domains that fail SPF authentication and contain embedded attachments, with single attendee and organizer both from organizational domains.

Threat classification

Sublime's own taxonomy (not MITRE ATT&CK).

CategoryValues
Attack typesCredential Phishing
Tactics and techniquesSpoofing, Evasion, ICS Phishing

Event coverage

Rule body MQL

type.inbound
and sender.email.domain.domain in $org_domains
and not coalesce(headers.auth_summary.dmarc.pass, false)
// has an ICS file
and any(attachments,
        .file_extension == "ics" or .content_type == "text/calendar"
)
// and a single other attachment that isn't an ICS but is embedded in the ICS
and length(filter(attachments,
                  not (
                    .file_extension == "ics"
                    or .content_type == "text/calendar"
                    or .file_type in $file_types_images
                  )
                  and any(filter(attachments,
                                 .file_extension == "ics"
                                 or .content_type == "text/calendar"
                          ),
                          strings.contains(file.parse_text(.).text,
                                           ..content_id
                          )
                  )
           )
) == 1
// exlode the ics file and look at the VEVENT file
and any(filter(attachments,
               .file_extension == "ics" or .content_type == "text/calendar"
        ),
        any(file.explode(.),
            // attendees and org are both within org_domains
            any(.scan.ics.calendars,
                any(.components,
                    .type == "VEVENT"
                    and length(.attendees) == 1
                    and all(.attendees,
                            .mailbox.email.domain.domain in $org_domains
                    )
                    and any(.organizers,
                            .mailbox.email.domain.domain in $org_domains
                    )
                    and length(.attachments) > 0
                    and all(.attachments,
                            .type == "uri" and strings.starts_with(.uri, "CID:")
                    )
                )
            )
        )
)

Detection logic

Scope: inbound message.

Detects calendar invitations (ICS files) from internal domains that fail SPF authentication and contain embedded attachments, with single attendee and organizer both from organizational domains.

  1. inbound message
  2. sender.email.domain.domain in $org_domains
  3. not:
    • coalesce(headers.auth_summary.dmarc.pass)
  4. any of attachments where any holds:
    • .file_extension is 'ics'
    • .content_type is 'text/calendar'
  5. length(filter(attachments, not .file_extension == 'ics' or .content_type == 'text/calendar' or .file_type in $file_types_images and any(filter(attachments, .file_extension == 'ics' or .content_type == 'text/calendar'), strings.contains(file.parse_text(.).text, ..content_id)))) is 1
  6. any of filter(attachments) where:
    • any of file.explode(.) where:
      • any of .scan.ics.calendars where:
        • any of .components where all hold:
          • .type is 'VEVENT'
          • length(.attendees) is 1
          • all of .attendees where:
            • .mailbox.email.domain.domain in $org_domains
          • any of .organizers where:
            • .mailbox.email.domain.domain in $org_domains
          • length(.attachments) > 0
          • all of .attachments where all hold:
            • .type is 'uri'
            • .uri starts with 'CID:'

Inspects: attachments[].content_id, attachments[].content_type, attachments[].file_extension, attachments[].file_type, headers.auth_summary.dmarc.pass, sender.email.domain.domain, type.inbound. Sensors: file.explode, file.parse_text, strings.contains, strings.starts_with. Reference lists: $file_types_images, $org_domains.

Indicators matched (5)

FieldMatchValue
attachments[].file_extensionequalsics
attachments[].content_typeequalstext/calendar
file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].typeequalsVEVENT
file.explode(filter(attachments)[])[].scan.ics.calendars[].components[].attachments[].typeequalsuri
strings.starts_withprefixCID: