Retrospection
In the previous steps, you deployed test scenarios and uploaded test files to observe Contextal Platform's detection capabilities. Here, we’ll break down the underlying mechanics that triggered specific actions.
Test File Overview
Let’s first examine the structure of the test file. It appears to be a standard PDF file with visible text. However, when analyzing the graph generated by the platform, the structure reveals a more complex nature.
First of all, this PDF file doesn't contain traditional plain text data, that's why the PDF
object data shows a NOTEXT
symbol. The document has a single page and its content is image-based with embedded text. The platform’s Optical Character Recognition (OCR) processing enables the extraction of text from the graphical page, hence the associated Text
object data includes an OCR
symbol.
Furthermore, an HTML
object named invoice.html
is embedded within the PDF, accessible as an attachment by typical tools like Adobe Reader. When opened, it suggests downloading a file named invoice.iso
, which is a CDFS
object that holds PE
and LNK
objects (named hello.dll
and invoice.lnk
respectively). This simulates a malware-delivery setup where the invoice.lnk
file could be executed after navigating through the file structure on a Windows system.
BLOCK Action Analysis
Upon the first upload, the test file was immediately flagged with a BLOCK
action due to a scenario named Test-Scenario-PDF-Unsafe-Attachment
. The triggering ContexQL query for this scenario is as follows:
object_type == "PDF"
&& @has_descendant(object_type == "PE" || object_type == "LNK")
This query looks for a PDF
object with descendant objects of type PE
or LNK
in the graph generated from the input object. In this case, the test file's graph met these conditions, triggering the BLOCK
action.
ALERT Action Analysis
A second scenario, Test-Scenario-PDF-Campaign
, was designed to trigger an ALERT
action when specific conditions were met. This scenario involves both a local query (focused on the current input object) and a global query (evaluated across multiple recently processed objects globally), creating a powerful approach to detecting broader patterns.
Local Query Conditions
The local query is applied only to the current input object, in our case the uploaded file’s graph, with the following conditions:
object_type == "PDF" &&
@has_child(
object_type == "Text"
&& @has_symbol("OCR")
&& @match_object_meta($natural_language_sentiment.compound < -0.5)
)
This query matches if the PDF
object has a Text
child with the OCR
symbol assigned and if the text was recognized as natural language showing a negative sentiment. The test file was crafted to meet these criteria.
Global Query Conditions
The global query, part of the global context structure works in a different way. It's never applied to the input's object graph and instead applies across recent graphs in the platform’s database. Additionally, the global context defines a minimum number of graphs that must satisfy the global query for it to be considered successful. This query’s minimum match requirement is set to two instances, and its code is as follows:
object_type == "PDF" &&
@has_descendant(
object_type == "Text"
&& @match_object_meta($natural_language_sentiment.compound < -0.5)
)
For simplicity and educational purposes, we kept it similar to the local query, with some conditions relaxed to make it look just a bit different.
Action Trigger
On the first upload, the local query matched, but the global query did not yet meet its match requirement, as there were no previously processed graphs satisfying the conditions. Only after submitting the file a third time did the global query’s match count reach two, fulfilling the global condition and triggering the ALERT
action.
The global context query is a powerful tool, enabling you to ask platform a broad question like "Have you seen specific characteristics in recently processed objects, and in how many?" This technique is useful for validating local queries before triggering actions or for detecting large-scale phishing, malware, or spam campaigns. In fact, in this tutorial we simulated such a campaign!