Skip to content

CirklAI/dactyl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Dactyl

Dactyl is a fast rule engine written in Zig.

TUI

Using Dactyl

Writing a rule

The basic anatomy of a rule

Here are the parts of a rule

  • Imports (if using regex, etc)
  • Metadata
  • Strings
  • Conditions

Imports

Imports allow the use of features disabled by default, for example, to use Regex you must write:

imports: [
    "regex"
],

Regex is disabled by default for performance reasons.

Metadata

Metadata contains the following fields:

  • Name
  • Author
  • Date
  • Severity
  • Labels

Here is how you would write a metadata statement:

meta: {
	name: "Name-Of-Rule",
    author: "[User] name or email",
    date: "Date of rule creation",
    severity: 10, // severity of rule as int/float (i hope decimal numbers aren't too hard for you)
    labels: ["ransomware", "wnry", "eternalblue", "apt"]
},

Strings

As Dactyl is a pattern matching language, here is how to define strings:

strings: {
    $kill_switch: { "text": "www.iuqerfsodpifjposifjposdfjhgosurijfaewrwergwea.com" },
    $nocase: { "text": "hEllO", "nocase": true },
    $name_1: { "text": "Hello" },
    $some_magic: { "hex": "FF 00 10 30 AE AB" },
    $some_regex: { "regex": `/\.he(l|l)o$/i` }
},

Condition

To execute matching, you need to tell Dactyl what conditions to accept Here is how to define the conditions:

condition: {
  any: {
    of: ["$some_string", "$maybe_magic"],
    any: ["$could", "$be", "$any", "$of", "$these"]
  }
}

Complete example

Here is an example of a working WanaCry rule you can test:

{
  imports: [
    "regex"
  ],

  meta: {
    name: "WannaCry-Ransomware-Dropper",
    author: "user@example.com",
    date: "2025-12-21",
    severity: 10,
    labels: ["ransomware", "wnry", "eternalblue", "apt"]
  },

  strings: {
    $kill_switch: { "text": "www.iuqerfsodpifjposifjposdfjhgosurijfaewrwergwea.com" },

    $dropper: { "text": "Tasksche.exe", "nocase": true },
    $msg_header: { "text": "WanaCrypt0r", "nocase": true },
    $btc_1: { "text": "13AM4VW2dhxYgXeQepoHkHSQuy6NgaEb94" },
    $btc_2: { "text": "12t9YDPgwueZ9NyMgw519p7AA8isjr6SMw" },
    $btc_3: { "text": "115p7UMMngoj1pMvkghijcRdfJNXj6LrLn" },
    $wncry_magic: { "hex": "57 41 4E 41 43 52 59 21" },
    $ext_regex: { "regex": `/\.wn(cry|ry)$/i` }
  },

  condition: {
    any: {
      of: ["$kill_switch", "$wncry_magic"],
      any: ["$dropper", "$msg_header", "$btc_1", "$btc_2", "$btc_3"]
    }
  }
}

The CLI

Compiling a rule

dactyl <file.dlt> # this command compiles the rules and checks for issues

Using a rule

dactyl <file.dlt> <sample.exe> # this command will compile the rule then run it on an executable

Running a rule will check the rule against the exe, this is useful when demoing or developing a rule.

Example output:

 ⌬ Dactyl v0.0.1
────────────────────────────────

MATCH FOUND » WannaCry-Ransomware-Dropper
Time: 87.058ms | Matches: 4

┌─ $dropper at 0xF4D8
0x0000F4D8  74 61 73 6B 73 63 68 65  2E 65 78 65 00 00 00 00  |tasksche.exe....|
0x0000F4E8  54 61 73 6B 53 74 61 72  74 00 00 00 74 2E 77 6E  |TaskStart...t.wn|

┌─ $btc_1 at 0xF488
0x0000F488  31 33 41 4D 34 56 57 32  64 68 78 59 67 58 65 51  |13AM4VW2dhxYgXeQ|
0x0000F498  65 70 6F 48 6B 48 53 51  75 79 36 4E 67 61 45 62  |epoHkHSQuy6NgaEb|

┌─ $btc_2 at 0xF464
0x0000F464  31 32 74 39 59 44 50 67  77 75 65 5A 39 4E 79 4D  |12t9YDPgwueZ9NyM|
0x0000F474  67 77 35 31 39 70 37 41  41 38 69 73 6A 72 36 53  |gw519p7AA8isjr6S|

┌─ $wncry_magic at 0xEB7C
0x0000EB7C  57 41 4E 41 43 52 59 21  00 00 00 00 25 00 73 00  |WANACRY!....%.s.|
0x0000EB8C  5C 00 25 00 73 00 00 00  43 6C 6F 73 65 48 61 6E  |\.%.s...CloseHan|

Converting from YARA?

You can convert YARA to Dactyl like so:

dactyl convert <file.yara> # will parse all rules and create the necessary files

Library?

Library documentation will be available soon™

Disabled Modules

These modules are disabled by default, but can be re-enabled via the imports

disabled module reason
Regex Performance

Releases

No releases published

Packages

No packages published

Languages