【Yara】入门

文章目录

概述:Yara 入门,资料、工具整理

GitHub

Yara Style Guide

  1. Neo23x0/YARA-Style-Guide: A specification and style guide for YARA rules
  2. Neo23x0/YARA-Performance-Guidelines: A guide on how to write fast and memory friendly YARA rules

Yara 相关技术文章

Yara 工具

  1. threatexpert/yarchk: 基于yara规则并发扫描Windows终端所有进程(Scan all processes on a Windows terminal quickly based on YARA rules.)
    • 可以一次性检测系统内所有进程,但是不能根据事件检测

快速手册

  1. 帮助命令

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    YARA 4.5.4, the pattern matching swiss army knife.
    Usage: yara [OPTION]... [NAMESPACE:]RULES_FILE... FILE | DIR | PID

    Mandatory arguments to long options are mandatory for short options too.

    --atom-quality-table=FILE path to a file with the atom quality table
    -C, --compiled-rules load compiled rules
    -c, --count print only number of matches
    -E, --strict-escape warn on unknown escape sequences
    -d, --define=VAR=VALUE define external variable
    -q, --disable-console-logs disable printing console log messages
    --fail-on-warnings fail on warnings
    -f, --fast-scan fast matching mode
    -h, --help show this help and exit
    -i, --identifier=IDENTIFIER print only rules named IDENTIFIER
    --max-process-memory-chunk=NUMBER set maximum chunk size while reading process memory (default=1073741824)
    -l, --max-rules=NUMBER abort scanning after matching a NUMBER of rules
    --max-strings-per-rule=NUMBER set maximum number of strings per rule (default=10000)
    -x, --module-data=MODULE=FILE pass FILE's content as extra data to MODULE
    -n, --negate print only not satisfied rules (negate)
    -N, --no-follow-symlinks do not follow symlinks when scanning
    -w, --no-warnings disable warnings
    -m, --print-meta print metadata
    -D, --print-module-data print module data
    -M, --module-names show module names
    -e, --print-namespace print rules' namespace
    -S, --print-stats print rules' statistics
    -s, --print-strings print matching strings
    -L, --print-string-length print length of matched strings
    -X, --print-xor-key print xor key and plaintext of matched strings
    -g, --print-tags print tags
    -r, --recursive recursively search directories
    --scan-list scan files listed in FILE, one per line
    -z, --skip-larger=NUMBER skip files larger than the given size when scanning a directory
    -k, --stack-size=SLOTS set maximum stack size (default=16384)
    -t, --tag=TAG print only rules tagged as TAG
    -p, --threads=NUMBER use the specified NUMBER of threads to scan a directory
    -a, --timeout=SECONDS abort scanning after the given number of SECONDS
    -v, --version show version information
  2. 检测目标进程

    1
    yara32.exe {yara规则文件} {PID}
  3. 检测文件夹

    1
    yara32.exe {yara规则文件} {待检测目录}

libyara

由于我个人 C++ 的偏向,所以需要静态库使用,因此需要 libyara 相关内容。这一部分包括 libyara 的编译、使用、扩展等

下载 Yara 项目,打开 Windows 目录下的 sln 文件即可,编译时所需工具集调整为自己当前环境的工具集即可。

改动

检测所有进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// 如何使用 
// cmd 输入 `yara32.exe {yara规则文件} -1`,即可检测所有进程
if (result == ERROR_COULD_NOT_OPEN_FILE) // 替换这个括号里边的内容即可
{
// Is it a PID? To be a PID it must be made up entirely of digits.
char_t* endptr = NULL;
long pid = _tcstol(argv[argc - 1], &endptr, 10);

if (pid >= -1 && argv[argc - 1] != NULL && *endptr == '\x00')
{
// 扫描所有进程
if (argc == 2 && atoi(argv[1]) == -1)
{
printf("Now will scan all the Process\n");
int count;
int* pids = GetAllProcessPids(&count);

// 不扫描自己,消除误报
DWORD this_pid = GetCurrentProcessId();
if (pids != NULL)
{
printf("Total processes: %d\n", count);
printf("Total processes %d\n", count);
printf("Process PIDs:\n");
printf(stderr, "Now will scan all the Process\n");
for (int i = 0; i < count; i++)
{
printf(stderr, "Now scanning PID is %d\n", pids[i]);
if (this_pid == pids[i])
{
continue;
}
// 复现问题,不能用printf,不清楚为什么会直接崩溃,疑似内存冲突
printf(stderr, "Now scanning PID is %d\n", pids[i]);
result = yr_scanner_scan_proc(scanner, pids[i]);
if (result == 2)
{
printf(
stderr,
"Scanning %d Fail, Maybe You should get to priv level to "
"system or your EDR protect it and you can ignore it \n",
pids[i]);
}
}
free(pids); // 释放内存
}
}
else
{
// 扫描指定进程
result = yr_scanner_scan_proc(scanner, atoi(argv[1]));
}
// result = yr_scanner_scan_proc(scanner, (int) pid);
}
}

TODO

  • [ ] 根据创建进程事件动态检测