Threat hunting with Osquery, Part 1 – Persistence

  • Thursday, Jul 8, 2021
Singel-post cover image

Part 1 – Persistence

In the following three-part series, we will show a number of examples using Osquery for hunting of cyber threats on Windows machines. For testing and demonstration of the information retrievable by Osquery, it is enough to run the queries on a single endpoint. Keep in mind though, that the full power of Osquery manifests itself when deployed widely and managed centrally, when a single query retrieves data from the entire environment. In this first part, we will show a few queries that help in discovering persistence created by attacker or malware.

You can read more about Osquery in our short blog post.

Scheduled Tasks

Notorious technique for achieving malicious code execution or persistence is creation of a scheduled task or tampering with a legitimate one (MITRE ATT&CK T1053.005). In the output of the query listed below, we look for unusual names of the scheduled tasks, paths to executables and their command line arguments. There can never be enough skepticism – Attackers often invent very convincing names for their scheduled tasks, but for obvious reasons one cannot find any documentation about them on the internet.

SELECT 
    name, 
    action, 
    path, 
    state, 
    datetime(last_run_time, "unixepoch") AS last_run_time, 
    datetime(next_run_time, "unixepoch") AS next_run_time
FROM scheduled_tasks; 

Services

Achieving persistence by creating or modifying a legitimate Windows service is listed as T1543.003 in the MITRE ATT&CK matrix and attackers often use it. Just as with the scheduled tasks, attackers often create plausible-looking service names, which easily fool the unprepared. We should investigate services, whose executable are located in an unusual folder, AppData and its subfolders are a notorious example. Additionally, arguments for the svchost process can contain the && characters, which causes execution of any appended command during interpretation of the command line.

SELECT 
    name, 
    display_name, 
    status, 
    start_type, 
    path, 
    module_path 
FROM services

Startup Items

After the user logs in, the operating system launches programs linked in Startup folders, be it user-specific or system-wide. Also, the system automatically runs commands written in Windows registry keys Run, RunOnce, RunServices and RunServicesOnce. Abuse of this functionality by attackers is listed in MITRE ATT&CK as technique T1547.001. In the data retrieved by the query listed below, we must look for unusual executable locations and unusual commands in their arguments, especially if any command interpreter is being launched.

SELECT 
    name, 
    path, 
    args, 
    source, 
    username 
FROM startup_items; 

WMI

WMI (Windows Management Instrumentation) contains functionality for code execution, that is conditioned by occurrence of a pre-defined event. It works by linking three components: event filter – binding – consumer. The event filter defines the event that triggers the execution signal. This signal is then passed via the bindings to the event consumers, which contain the definition of the action that gets executed at that instant. Attackers use the creation of such WMI object trio to establish persistence, described as MITRE ATT&CK technique T1546.003. Osquery helps us look into these objects using the four queries listed below. First thing to notice are suspicious commands and unusual paths to scripts and executable files in event consumer objects. Then, the binding objects will lead us to the event filters, which will tell us what triggers the suspicious activity.

SELECT 
    name, 
    command_line_template, 
    executable_path, 
    relative_path 
FROM wmi_cli_event_consumers; 
SELECT 
    name, 
    scripting_engine, 
    script_file_name, 
    script_text, 
    relative_path 
FROM wmi_script_event_consumers; 
SELECT 
    consumer, 
    filter,
    relative_path 
FROM wmi_filter_consumer_binding; 
SELECT 
    name, 
    query, 
    relative_path 
FROM wmi_event_filters;