High Severity
Attachment: Suspicious PDF Created With Headless Browser
Description
Detects PDF documents containing a table of contents that were generated using HeadlessChrome, Chromium with Skia/PDF, or QT with empty metadata fields - common characteristics of automated malicious document creation.
References
No references.
Sublime Security
Created May 28th, 2025 • Last updated Jun 30th, 2025
Feed Source
Sublime Core Feed
Source
type.inbound
and (
// directly attached PDF
any(filter(attachments, .file_type == "pdf"),
any(file.explode(.), strings.contains(.scan.ocr.raw, 'TABLE OF CONTEN'))
// the Table of contents can be on another page
and any(file.explode(.),
regex.icontains(.scan.ocr.raw,
'(?:[\r\n]|^)+(?:\s*1\s*(?:\.|:))?\s*Introduction'
)
or strings.icontains(.scan.ocr.raw,
'marked in red'
)
)
and (
(
(
strings.icontains(beta.parse_exif(.).creator, 'HeadlessChrome')
or strings.icontains(beta.parse_exif(.).creator, 'Chromium')
)
and strings.icontains(beta.parse_exif(.).producer, 'Skia/PDF')
)
or (
any(beta.parse_exif(.).fields,
.key == "Creator"
and (.value == "" or strings.istarts_with(.value, 'wkhtmltopdf'))
)
and any(beta.parse_exif(.).fields,
.key == "Title"
and (.value == "" or .value in ('Company HandBook'))
)
and strings.istarts_with(beta.parse_exif(.).producer, 'QT ')
)
)
)
// or within an attached EML
or any(filter(attachments,
.content_type == "message/rfc822" or .file_extension == "eml"
),
any(filter(file.parse_eml(.).attachments, .file_type == "pdf"),
any(file.explode(.),
strings.contains(.scan.ocr.raw, 'TABLE OF CONTEN')
)
// the Table of contents can be on another page
and any(file.explode(.),
regex.icontains(.scan.ocr.raw,
'(?:[\r\n]|^)+1\s*(\.|:)\s*Introduction'
)
)
and (
(
(
strings.icontains(beta.parse_exif(.).creator,
'HeadlessChrome'
)
or strings.icontains(beta.parse_exif(.).creator, 'Chromium')
)
and strings.icontains(beta.parse_exif(.).producer, 'Skia/PDF')
)
or (
any(beta.parse_exif(.).fields,
.key == "Creator"
and (
.value == ""
or strings.istarts_with(.value, 'wkhtmltopdf')
)
)
and any(beta.parse_exif(.).fields,
.key == "Title"
and (.value == "" or .value in ('Company HandBook'))
)
and strings.istarts_with(beta.parse_exif(.).producer, 'QT ')
)
)
)
)
)
Playground
Test against your own EMLs or sample data.