CHALLENGE INFORMATION

Description

Learn how YARA rules can be used to detect anomalies.

Summary

Here we start with a quick YARA 101, where we discuss what YARA rules are, what they are used for, what problems they solve, and, lastly, how exactly to build and use them.

In the practical part, we build a YARA rule to identify files containing a specific hidden string, then assemble the hidden pieces to find McSkidy’s hidden message and potential location.

AOC25 - Day-13 Hero

Storyline

McSkidy, missing from TBFC, sent a hidden message to the blue team embedded in Easter-themed images. The team must create a YARA rule to scan the directory, detect a keyword paired with code words, and extract those code words in ascending order to decode her message.

Theory

YARA is a malware detection tool that identifies threats by searching for unique patterns and digital fingerprints in code, files, and memory.

Advantages

  • Speed: Quickly scans large file sets.
  • Flexibility: Detects text, binary patterns, and complex logic.
  • Control: Analysts define what is malicious.
  • Shareability: Rules are reusable across organizations.
  • Visibility: Connects scattered clues into attack patterns.

Common Use Cases

  • Post-incident analysis: Verifies malware presence across the environment.
  • Threat hunting: Searches for known or related malware families.
  • Intelligence scans: Applies shared rules to detect new indicators.
  • Memory analysis: Examines active processes for malicious code.

YARA Rules

A YARA rule consists of three key elements:

  • Metadata: Information about the rule itself; who created it, when, and why.
  • Strings: What to search for (text, byte sequences, regular expressions).
  • Conditions: Logic deciding when the rule triggers.

YARA rule example: Looking for specific URLs and executable names.

rule TBFC_KingMalhare_Trace
{
    meta:
        author = "Defender of SOC-mas"
        description = "Detects traces of King Malhare's malware"
        date = "..."
    strings:
        $s1 = "rundll32.exe" fullword ascii
        $s2 = "msvcrt.dll" fullword wide
        $url1 = /http:\/\/.*malhare.*/ nocase
    condition:
        any of them
}

YARA rule example: Specific header binary, malicious binary fragment, restrict by file size.

rule TBFC_Simple_MZ_Detect
{
    meta:
        author = "TBFC SOC L2"
        description = "IcedID Rule"
        date = "..."
        confidence = "low"

    strings:
        $mz   = { 4D 5A }                        // "MZ" header (PE file)
        $hex1 = { 48 8B ?? ?? 48 89 }            // malicious binary fragment
        $s1   = "malhare" nocase                 // story / IOC string

    condition:
        all of them and filesize < 10485760      // < 10MB size
}

Execution syntax.

: -r : scan directories recursively and follow symlinks
: -s : prints the strings found within files that match the rule
yara -r icedid_starter.yar C:\

Rule Extension: .yar

Strings

Strings represent the signatures of malicious activity in fragments of text, bytes, or patterns.

Text Strings

# TEXT STRINGS - words or short text fragments

# ASCII and case-sensitive (default)
$TBFC_string = "Christmas"

# Case-insensitive
$xmas = "Christmas" nocase
        
# Wide-character - searching for both here
# many windows executables use two-byte Unicode characters - ***ascii*** enforces single-byte search
$xmas = "Christmas" wide ascii

# XOR strings - checks all possible single-byte XOR variations of the string
$hidden = "Malhare" xor

# Base64 strings - decodes the content and searches for the original pattern even if hidden in encoded form
$b64 = "SOC-mas" base64

Hexadecimal Strings

# Hexadecimal strings - search for specific byte patterns written in hexadecimal notion
# - useful for file headers, shellcode, binary signatures

rule TBFC_Malhare_HexDetect
{
    strings:
        $mz = { 4D 5A 90 00 }   // MZ header of a Windows executable
        $hex_string = { E3 41 ?? C8 G? VB }

    condition:
        $mz and $hex_string
}

Regular Expression Strings

# Regular expression strings - flexible search patterns, spotting URLs, encoded commands, dynamic filenames
# BEWARE: can match wide range of data > SLOW down scans if too broad

rule TBFC_Malhare_RegexDetect
{
    strings:
        $url = /http:\/\/.*malhare.*/ nocase
        $cmd = /powershell.*-enc\s+[A-Za-z0-9+/=]+/ nocase

    condition:
        $url and $cmd
}

Conditions

  • Match single string: $xmas.
  • Match any string: any of them.
  • Match all strings: all of them – trigger only if every indicator matches.
  • Combined logic: and, or, not – ($s1 or $s2) and not $benign.
  • Comparisons: Check file properties, not just contents – filesize, entrypoint, hash – any of them and (filesize < 700KB)

Questions and Answers

First, we navigate to the /home/ubuntu/Downloads/easter directory on the VM and take a quick look around.

ubuntu@tryhackme:~$ cd /home/ubuntu/Downloads/
ubuntu@tryhackme:~/Downloads$ ls -hla easter/
...
-rw-r--r-- 1 ubuntu ubuntu  695K ... easter1.jpg
-rw-r--r-- 1 ubuntu ubuntu  1.3M ... easter10.jpg
...
-rw-r--r-- 1 ubuntu ubuntu   462 ... embeds
ubuntu@tryhackme:~/Downloads$

That is a lot of pictures – sixty-one, to be exact:

ubuntu@tryhackme:~/Downloads$ cd easter
ubuntu@tryhackme:~/Downloads/easter$ ls | wc -l
61
ubuntu@tryhackme:~/Downloads/easter$

We create a YARA rule named tbfc-string_detect.yar with a bare-bones YARA rule structure, then add one simple text string search with $keyword = "TBFC:" ascii:

rule TBFC_STRING_DETECT
{
    meta:
        author = "DefinitelyNotTheEasterBunny"
        description = "Detect keywords 'TBFC:' followed by an ASCII alphanumeric keyword"
        date = "Once-Upon-A-Time"
        confidence = "very-low"

    strings:
        $keyword = "TBFC:" ascii

    condition:
        $keyword
}

The rule is very simple; it looks for the string ‘TBFC:’ and assumes that it is ASCII encoded, which is the default setting.

As for the condition, it only has to match that simple keyword we defined – therefore, it will only trigger when the searched object (text, file, etc.) contains the specified keyword.

Let us try running it:

ubuntu@tryhackme:~/Downloads/easter$ cd ..
ubuntu@tryhackme:~/Downloads$ ls -hla
...
drwxr-xr-x  2 ubuntu ubuntu 4.0K ... easter
-rw-r--r--  1 ubuntu ubuntu  320 ... tbfc-string-detect.yar
ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/
TBFC_STRING_DETECT easter//easter46.jpg
0x2f78a:$keyword: TBFC:
TBFC_STRING_DETECT easter//embeds
0x18f:$keyword: TBFC:
0x1bf:$keyword: TBFC:
TBFC_STRING_DETECT easter//easter10.jpg
0x137da8:$keyword: TBFC:
TBFC_STRING_DETECT easter//easter16.jpg
0x3bb7f7:$keyword: TBFC:
TBFC_STRING_DETECT easter//easter52.jpg
0x2a2ad2:$keyword: TBFC:
TBFC_STRING_DETECT easter//easter25.jpg
0x42c778:$keyword: TBFC:
ubuntu@tryhackme:~/Downloads$

Great, it worked. Let us move on to the questions.

Question-1: How many images contain the string TBFC?

5

We are almost already there to answer this question. Yeah, we could simply count them… But we can do better; let us play with Linux a bit:

ubuntu@tryhackme:~/Downloads$ yara -r tbfc-string-detect.yar easter/
TBFC_STRING_DETECT easter//easter46.jpg
TBFC_STRING_DETECT easter//embeds
TBFC_STRING_DETECT easter//easter16.jpg
TBFC_STRING_DETECT easter//easter10.jpg
TBFC_STRING_DETECT easter//easter52.jpg
TBFC_STRING_DETECT easter//easter25.jpg
ubuntu@tryhackme:~/Downloads$ yara -r tbfc-string-detect.yar easter/ | grep .jpg
TBFC_STRING_DETECT easter//easter46.jpg
TBFC_STRING_DETECT easter//easter16.jpg
TBFC_STRING_DETECT easter//easter10.jpg
TBFC_STRING_DETECT easter//easter52.jpg
TBFC_STRING_DETECT easter//easter25.jpg
ubuntu@tryhackme:~/Downloads$ yara -r tbfc-string-detect.yar easter/ | grep .jpg | wc -l
5
ubuntu@tryhackme:~/Downloads$

First we remove the unnecessary string outputs that come with -s, then we focus only on .jpg files. Lastly, we count them.

Question-2: What regex would you use to match a string that begins with TBFC: followed by one or more alphanumeric ASCII characters?

/TBFC:[A-Za-z0-9]+/

Let us modify our keyword from $keyword = "TBFC:" ascii to $keyword = /TBFC:[A-Za-z0-9]+/ ascii.

The part [A-Za-z0-9] denotes an alphanumeric character, + indicates that there is at least one or more of them, and ascii makes sure that this regular expression will search for one-byte ASCII encoded versions of the specified keyword.

This is how our new modified rule might look:

rule TBFC_STRING_DETECT
{
    meta:
        author = "DefinitelyNotTheEasterBunny"
        description = "Detect keywords 'TBFC:' followed by an ASCII alphanumeric keyword"
        date = "Once-Upon-A-Time"
        confidence = "very-low"

    strings:
        $keyword = /TBFC:[A-Za-z0-9]+/ ascii

    condition:
        $keyword
}

Question-3: What is the message sent by McSkidy?

Find me in Hopsec Island

Running our new rule, specified in the previous question, brings us closer to answering this question.

ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/
TBFC_STRING_DETECT easter//easter46.jpg
0x2f78a:$keyword: TBFC:HopSec
TBFC_STRING_DETECT easter//easter10.jpg
0x137da8:$keyword: TBFC:Find
TBFC_STRING_DETECT easter//easter52.jpg
0x2a2ad2:$keyword: TBFC:Island
TBFC_STRING_DETECT easter//easter16.jpg
0x3bb7f7:$keyword: TBFC:me
TBFC_STRING_DETECT easter//easter25.jpg
0x42c778:$keyword: TBFC:in
ubuntu@tryhackme:~/Downloads$

As we can see, there is a secret message hidden here. Let us try to cut away all the unnecessary words and focus on the hidden message, starting with excluding lines that contain image extensions (.jpg).

ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg 
0x2f78a:$keyword: TBFC:HopSec
0x137da8:$keyword: TBFC:Find
0x2a2ad2:$keyword: TBFC:Island
0x3bb7f7:$keyword: TBFC:me
0x42c778:$keyword: TBFC:in
ubuntu@tryhackme:~/Downloads$

Focusing only on the secret words and trying to sort them brings us to the following: ‘Find’, ‘HopSec’, ‘Island’, ‘in’, ‘me’.

ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg | cut -d " " -f 2
TBFC:HopSec
TBFC:me
TBFC:Find
TBFC:Island
TBFC:in
ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg | cut -d " " -f 2 | cut -d ":" -f 2
HopSec
me
Find
Island
in
ubuntu@tryhackme:~/Downloads$ yara -s -r tbfc-string-detect.yar easter/ | grep -v .jpg | cut -d " " -f 2 | cut -d ":" -f 2 | sort
Find
HopSec
Island
in
me
ubuntu@tryhackme:~/Downloads$

Assembling them in the correct order gives us the secret message: “Find me in Hopsec Island”.