Complex Detections Made Simple


Customized detections are a critical capability for any serious monitoring team. Being able to create your own detections is the difference between being at the mercy of a vendor and being able to fill in the detection gaps that are specific to your organization.

Detections can be grouped into three types.

  1. Lookup Detection

  2. Stateless Detection

  3. Stateful Detection


The first two categories are the most commonly found throughout the information security industry.

A Lookup detection is the most simple form of detection and is often referred to as black-listing. An example of this would be checking traffic against a threat feed of "bad domain names". These threat feeds can be purchased from a vendor and track which domains are known sources of malicious activity. So in Lookup detection you look up each DNS resolution on your network against the list provided by the threat feed. Easy peasy.

A lookup rule in looks like this:
Domain names matching the public "malwaredomains" list:

op: lookup
resource: lcr://lookup/malwaredomains
path: event/DOMAIN_NAME

Stateless detections are a bit more interesting but still very simple in their application. This type of detection is called "stateless" because it does not keep any "state" between evaluations.

An example of a Stateless detection could be "look for any executable running from the Recycler Bin on Windows". It's a bit more involved than a one-to-one Lookup, but every process execution can be evaluated disjointly from anything external to it.

A stateless rule in looks like this:
Detect file system Access Control List modifications

op: and
- event: NEW_PROCESS
  op: is windows
- case sensitive: false
  op: ends with
  path: event/FILE_PATH
  value: icacls.exe
- case sensitive: false
  op: contains
  path: event/COMMAND_LINE
  value: grant

Stateful rules are more complex. Here you want to keep track of some state and information over time in order to evaluate future events. In security these commonly fall into two categories:

  • Time-based detections

  • Descendance detections

The time-based detections are something along the lines of "if you see event ABC more than X times in Y seconds".

The descendance detections revolve around the parent-child relationships of various events. For example, "if you see event X as a descendant of event Z".

Those Stateful detections are usually difficult to make accessible to non-developers. Today, we're introducing a new capability in LimaCharlie, on top of having Lookup and Stateless detections, we now have easy Stateful detections available.

The in-depth documentation can be found here, but these examples should give you a taste:

Detect 4 reconnaissance tools executed within 5 seconds:

op: process burst
re: .*/((ifconfig)|(arp)|(route)|(ping)|(traceroute)|(nslookup)|(netstat)|(wget)|(curl))
count: 4
time: 5

Detect "cmd.exe" executing as a descendant of "notepad.exe":

op: process descendant
parent: .*notepad.exe
child: .*cmd.exe

The actual operators have more functionality than demonstrated above like descendance with with types of file created, it's worth a look!

All of those detections, Lookup, Stateless and Stateful run in the LimaCharlie cloud on all the data from all your agents, no infrastructure necessary.


Hunting Code Injection


Today we are going to explore how we can see the NEW_REMOTE_THREAD event on Windows using LimaCharlie. This event gets emitted every time a process creates a remote thread in another process.

Those familiar with Windows malware will recognize this as a basic element of many code injection methods, such as Reflective DLL Injection.

This event will provide the originating and target process id as well as atoms (our globally unique identification and relationship id) and thread id.

Begin looking at these events by doing a simple detect and report. Once the detection is reported we do the following:

  1. Get the detailed history of the last few minutes (file writes, network, etc).

  2. Get the memory map of the source and target process where we may be able to get a confirmation that we can see some injected code as Read+Write+Execute memory.

  3. List the strings in memory of the source and destination process. If there was anything obfuscated like domains, files, Command and Control servers, we may be able to get them from memory right away.

And that is hunting code injection with LimaCharlie. Documentation along with the detection and response rules can be found below. Please do not hesitate to contact us if you have any questions.

Happy hunting!


Rules documentation:

Commands documentation:

The Detection Rule:

op: is windows

The Response Rule:

- action: report
name: remote_thread
- action: task
command: history_dump
- action: task
- mem_map
- --processatom
- <<routing/parent>>
- action: task
- mem_map
- --processatom
- <<event/TARGET_ATOM>>
- action: task
- mem_strings
- --processatom
- <<routing/parent>>
- action: task
- mem_strings
- --processatom
- <<event/TARGET_ATOM>>