yara 实验

yara 实验


免责声明

本文档仅供学习和研究使用,请勿使用文中的技术源码用于非法用途,任何人造成的任何负面影响,与本人无关.


什么是 yara

YARA 是一款旨在帮助恶意软件研究人员识别和分类恶意软件样本的开源工具,使用 YARA 可以基于文本或二进制模式创建恶意软件家族描述信息,当然也可以是其他匹配信息。

这款工具配备一个短小精悍的命令行搜索引擎,它由纯C语言编写,优化了执行的效率。该引擎可以跨平台使用,能够运行 Windows,Linux 及Mac OS X 系统上。同时,这款工具提供 python 扩展,允许通过 python 脚本访问搜索引擎。

YARA 的功能非常丰富,尤其是与模块的集成。模块可以在保持规则可读性的基础上开启了非常精细的扫描。


安装

linux 下可以直接用包管理器进行安装

apt install -y yara

windows 下访问项目的 releases 页面下载 https://github.com/VirusTotal/yara/releases

为了方便,这里重命名 yara64.exe 为 yara.exe

在当前目录下打开 CMD, 输入 help

yara.exe --help


语法

       --atom-quality-table=FILE        path to a file with the atom quality table
  -C,  --compiled-rules                 加载已编译的规则
  -c,  --count                          只打印匹配的数量
  -d,  --define=VAR=VALUE               定义外部变量
       --fail-on-warnings               警告失败
  -f,  --fast-scan                      快速匹配模式
  -h,  --help                           显示此帮助并退出
  -i,  --identifier=IDENTIFIER          print only rules named IDENTIFIER
  -l,  --max-rules=NUMBER               匹配多个规则后中止扫描
       --max-strings-per-rule=NUMBER    设置每条规则的最大字符串数(默认=10000)
  -x,  --module-data=MODULE=FILE        pass FILE's content as extra data to MODULE
  -n,  --negate                         仅打印不满足的规则 (negate)
  -w,  --no-warnings                    禁用警告
  -m,  --print-meta                     打印元数据
  -D,  --print-module-data              打印模块数据
  -e,  --print-namespace                打印规则的名称空间
  -S,  --print-stats                    打印规则的统计信息
  -s,  --print-strings                  打印匹配的字符串
  -L,  --print-string-length            打印匹配字符串的长度
  -g,  --print-tags                     打印标签
  -r,  --recursive                      递归搜索目录(遵循符号链接)
       --scan-list                      扫描FILE中列出的文件,每行一个
  -k,  --stack-size=SLOTS               设置最大堆栈大小(默认=16384)
  -t,  --tag=TAG                        只打印标记为TAG的规则
  -p,  --threads=NUMBER                 使用指定的线程数来扫描一个目录
  -a,  --timeout=SECONDS                在给定的秒数后中止扫描。
  -v,  --version                        显示版本信息

示例

基本使用

rule silent_banker : banker
{
    meta:
        description = "This is just an example"
        thread_level = 3
        in_the_wild = true
    strings:
        $a = {6A 40 68 00 30 00 00 6A 14 8D 91}
        $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
        $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
    condition:
        $a or $b or $c
}
  • 第一行的 rule silent_banker : banker 是声明该规则用于检出 banker 类型的样本。
  • meta 后面的是一些描述信息,比如规则说明、作者信息等。
  • strings 定义了 $a $b $c 两个十六进制字符串(十六进制字符串用大括号括起来)和一个文本字符串(文本字符串直接用双引号括起来)
  • condition 规定了匹配的条件,这里写的是 or,表明样本中只要匹配到了 $a $b $c 三个字符串中的任意一个,那么样本就会被识别为 banker

新建一个 test.yara,内容同上,同时新建一个文件夹,文件夹中随机复制几个文件进去,进行识别

yara.exe test.yara 111/

没有任何反应, 因为我们的 yara 规则没有命中 111 文件夹下的任何文件。

修改下规则

rule silent_banker : banker
{
    meta:
        description = "This is just an example"
        thread_level = 3
        in_the_wild = true
    strings:
        $a = {6A 40 68 00 30 00 00 6A 14 8D 91}
        $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
        $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"
        $d = {4D 5A}
    condition:
        $a or $b or $c or $d
}

增加了一个十六进制字符串 $d 所匹配的值是 4D 5A。 而 4D 5A 是 PE 文件(包括 exe、dll 等)的文件头,也就是说一个正常的 PE 文件中是一定会包含 4D 5A 这个十六进制的数据的。

且我们在最后的 condition 中加入了 or $d,表示如果 $d 条件满足,样本也可以成功识别。

重新对111文件夹下的文件进行扫描

这里识别了多个文件,并命中自定义的 yara 特征。

如果要识别子目录下的文件需要 -r 参数

识别 python

新建 test.yara

rule python_test : python
{
    strings:
        $a="if __name__ == '__main__':" nocase
    condition:
        $a
}

nocase 关键字代表不区分大小写

测试


匹配 CS

Win32_PE

这里生成多个 cs 马,分析提取一些特征。

可以看到大小区分的比较明显,要么 20kb 以下,要么 300kb 以下,这是因为小的是 Staged 大的是 Stageless。

yara 规则是会全文扫描的,那么这样将会大大降低扫描效率,如果我们能够写一些 filter 过滤掉大部分的不相关样本,那么 yara 在扫描的时候将会只对疑似的文件进行有效的扫描而不会浪费资源。

那这里可以过滤文件大小

rule CS : win32
{
    condition:
        filesize < 400KB
}

用 IDA 分析2个exe

来到 start 函数之后,我们可以发现多个 CobaltStrike 样本的入口点是完全一致的,程序入口点都是 004014B0

用 exeinfo pe 获取入口点,需要注意的是,这里是获取到的文件偏移,也就是offset,并不是我们在IDA中看到的entry_point

使用pe.entry_point来获取入口点

import "pe"

rule CS : win32
{
    condition:
        pe.entry_point == 0x8b0 and filesize < 400KB
}

接下来继续找特征,静态查看 main 函数

这里调用了 sub_402A60 和 sub_401795 ,跟进查看,这里 sub_401795 比较关键

在 sub_401795 函数中,程序会通过 CreateThread 创建一个新线程

并且可以看到有一个 %c%c%c%c%c%c%c%c%cMSSE-%d-server 看起来像是通信协议。

这里 CreateThread 的 lpStartAddress 是 sub_401685, 在 sub_401685 的 sub_4015D0 函数中可以看到通过 CreateNamedPipeA 的方式创建管道准备通信。

那么接下来直接匹配这个字符串

import "pe"

rule CS : win32
{
    strings:
        $comm="%c%c%c%c%c%c%c%c%cMSSE-%d-server"
    condition:
        pe.entry_point == 0x8b0 and filesize < 400KB and $comm
}

最后再加上一个 PE 文件的判断

import "pe"

rule CS : win32
{
    strings:
        $comm="%c%c%c%c%c%c%c%c%cMSSE-%d-server"
    condition:
        uint16(0)==0x5A4D and pe.entry_point == 0x8b0 and filesize < 400KB and $comm
}

powershell

生成不同位数下的 powershell 后门

32位

64位

32 位和 64 位结构相似, 32 位使用 $DoIt = @''@方式定义两个函数. 程序关键执行的内容被 base64 编码

比较相似的就是这个 [Byte[]]$var_code = [System.Convert]::FromBase64String

匹配这种类似的字符串

rule powershell
{
    strings:
        $string1="[Byte[]]$var_code = [System.Convert]::FromBase64String"
        $string2="$var_runme.Invoke([IntPtr]::Zero)"
    condition:
        filesize < 20KB and $string1 and $string2
}


html_pe

CobaltStrike 提供 3 种生成 html 木马的方式 exe,powershell,vba,依次生成如下

exe

简单粗暴,直接包含一个 PE 文件在其中,

文件最后将 shellcode 释出为 evil.exe 并执行,这里文件名不一定是固定值,尝试通过正则进行匹配。

rule html_exe
{
    strings:
        $string="evil.exe"
        $string2="var_shellcode"
        $reg1= /var_tempexe = var_basedir & \"\\\" & \"[A-z]{1,20}.exe\"/
    condition:
        filesize < 100KB and $string and $string2 and $reg1
}

vba

查看 vba 版的html马

中间一大段为混淆的 vba 代码

通过 & 符号拼接由 chr 函数转换的 ascii

&Chr(10)&

这里比较容易找到特征,比如 myAr"&"ray

rule html_vba
{
    strings:
        $string="Wscript.Shell"
        $string2= "myAr\"&\"ray \"&Chr(61)&\" Array\"&Chr(40)&Chr(45)&\"4\"&Chr(44)&Chr(45)&\"24\"&Chr(44)&Chr(45)&"
    condition:
        filesize < 100KB and $string and $string2
}

powershell

查看结构

同样的 base64 编码命令, 解码查看

这里 $s=New-Object IO.MemoryStream 结合下文是将数据加载到内存中执行

在 cs3.14中是$s=New-Object IO.Memor

rule html_ps
{
    strings:
        $string= "Wscript.Shell"
        $string2= "var_shell.run \"powershell -nop -w hidden -encodedcommand"
        $string3= "var_func"
    condition:
        filesize < 100KB and $string and $string2 and $string3
}


Source & Reference

点击关注,共同学习!
安全狗的自我修养

github haidragon

https://github.com/haidragon

posted @ 2022-10-30 14:12  syscallwww  阅读(216)  评论(0编辑  收藏  举报