使用yara防御恶意软件

  • A+
所属分类:安全工具
本文将分享本人在学习yara时的一些心得,并在后面给出使用yara来防御CobaltStrike的方法。
 

yara简介

 
yara是一个基于规则的恶意样本分析工具,旨在帮助蓝队或安全研究员防御和分析恶意软件,其官网地址为https://virustotal.github.io/yara/。你可以使用yara基于文本或二进制来标记恶意软件家族来达到各种目的。
 
yara的安装也是十分的简单,如win下已有独立文件,下载使用即可。
使用yara防御恶意软件
下面是一个简单的yara规则的demo:
rule silent_banker : banker {          meta:                        description = "This is just an example"                       threat_level = 3                                 in_the_wild = true              strings:                                 $a = {640 68 00 30 00 00 614 891}                                 $b = {84D B0 2B C1 83 C0 27 99 6459 F7 F9}                      $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"              condition:                                  $a or $b or $c }
yara规则不需要太多知识要求,规则本身十分简单, 真正的技巧和细节都在分析部分


yara规则

 
yara的规则跟许多语言的语法颇为类似,学习起来也没有那么的困难。下面就是一个基础的yara规则框架:
rule RuleName {             meta:             strings:                 condition: }
然后将其保存为yara文件即可。当然该规则没有进行任何操作。一般一个yara文件分为上述的三个部分,meta、strings、condition,并以rule包裹。rule后跟rule名字。关于rule名字有以下要求:
  •  英文或字母组成的字符串

  •  可以使用下划线

  •  第一个字符禁止为数字

  • 大小写敏感

  • 不可以大于128个字符长度


meta部分:主要为该规则的基础信息,如作者信息、创建时间、样本内容等
strings部分:主要用来定义字符串支持正则表达式,用来配合下面的部分使得规则生效。
condition部分:主要来编写表达式来处理strings部分的字符串。


yara关键词

 
在yara中有一些词不可作为标识符,因为在yara中有特殊用途。
all、and、or、at、int32、wide、not....
具体的可以去查找yara文档,这里不再赘述。

字符串
 
在yara中字符串的表示主要由十六进制与文本字符串组成。
 
十六进制字符串:
 
在十六进制字符串中可以使用通配符表示,通配符为“?”.demo如下:
rule RuleName {             meta:                     author = "lengyi"             strings:                      $hex1 = { EF 44 ?? D8 A? FB}               condition:                     $hex1  }
则它可以匹配以下字符串:
EF 44 01 D8AA FB
使用yara防御恶意软件
不定长字符串可以用[4-6]这类形式表示,而无限长的字符串可以用[-]表示
rule RuleName {             meta:                     author = "lengyi"             strings:                     $hex1 = { EF 44 [-] D8 A2 FB}                      $hex2 = { EF 44 [4-6] D8 A2 FB}                 condition:                     $hex1 or $hex2  }

文本字符串:
 
这个就没啥好说的了,利用文本来匹配字符串,比如mimikatz的logonpasswords等
rule RuleName {             meta:                     author = "lengyi"             strings:                      $hex1 = "honghe"                condition:                     $hex1 }
使用yara防御恶意软件
注:转义字符依旧适用。
 
修饰符
 
yara提供了丰富的修饰符来方便匹配,如不区分大小写的nocase:
rule RuleName {         meta:                 author = "lengyi"         strings:                  $hex1 = "honghe"  nocase          condition:                 $hex1 }
宽字符的wide:
rule RuleName {             meta:                     author = "lengyi"             strings:                      $hex1 = "honghe" wide             condition:                     $hex1 }
匹配base64的base64:
rule RuleName {         meta:                 author = "lengyi"         strings:                  $hex1 = "honghe" base64         condition:                 $hex1 }
它将会匹配下面的字符串: 
aG9uZ2hl 
全词匹配的fullword:
rule RuleName {             meta:                     author = "lengyi"             strings:                      $hex1 = "facebook" fullword             condition:                     $hex1 }
将匹配:
www.facebook.com www.xor.facebook.com https://www.facebook.com/

正则表达式
 
这个就不再多说了,唯一要注意的就是使用//来包裹正则表达式,类似于perl语法。
 

条件
 
布尔运算
 
使用and or not等关键字来使字符串充当布尔变量
rule RuleName {             meta:                     author = "lengyi"             strings:                      $hex1 = "facebook"                     $hex2 = "book"                     $hex3 = "face"             condition:                         ($hex1 and $hex2) or $hex3 }
文件大小
 
yara使用filesize来进行文件大小的匹配,大小以字节为单位
rule RuleName {             meta:                     author = "lengyi"             condition:                     filesize > 200KB }
可执行程序入口点
 
假如你扫描的文件是一个pe文件或者是一个elf文件时,你可以使用entry_point来进行表示程序的入口点。新版本中已将它归入了PE模块当中,不再单独使用。
 
访问指定位置的数据
 
如果你想从特定偏移位置读取数据, 并将其存为一个变量. 那么你可以使用以下任何一个方式:
 
int8(<offset or virtual address>) int16(<offset or virtual address>) int32(<offset or virtual address>)   uint8(<offset or virtual address>) uint16(<offset or virtual address>) uint32(<offset or virtual address>)   int8be(<offset or virtual address>) int16be(<offset or virtual address>) int32be(<offset or virtual address>)  uint8be(<offset or virtual address>) uint16be(<offset or virtual address>) uint32be(<offset or virtual address>)
rule RuleName {            meta:                     author = "lengyi"             condition:                         unint16(0) and unit32(unit32(0x3c)) == 0x00004550 }
使用yara防御恶意软件
以上就是基本的yara规则的语法了,而在正式的编写中呢,可能并不需要这么负责的内容,比如我们以某rat的规则为例:
使用yara防御恶意软件
就是简单的三条url地址,然后使用or进行匹配,而这些url地址也可以使用pestudio来查看:
使用yara防御恶意软件
并不需要太多的逆向知识,除此之外vt也有相关的功能:
使用yara防御恶意软件
唯一的难点就是需要大量的样本来确定,该家族的样本都是使用的该url。
更简单的可能就像下面这样
rule hacktool_windows_mimikatz_copywrite {         meta:                  description = "Mimikatz credential dump tool: Author copywrite"         reference = "https://github.com/gentilkiwi/mimikatz"          author = "@fusionrace"                  md5_1 = "0c87c0ca04f0ab626b5137409dded15ac66c058be6df09e22a636cc2bcb021b8"                  md5_2 = "0c91f4ca25aedf306d68edaea63b84efec0385321eacf25419a3050f2394ee3b"                  md5_3 = "0fee62bae204cf89d954d2cbf82a76b771744b981aef4c651caab43436b5a143"                  md5_4 = "004c07dcd04b4e81f73aacd99c7351337f894e4dac6c91dcfaadb4a1510a967c"                 md5_5 = "09c542ff784bf98b2c4899900d4e699c5b2e2619a4c5eff68f6add14c74444ca"                  md5_6 = "09054be3cc568f57321be32e769ae3ccaf21653e5d1e3db85b5af4421c200669"         strings:                 $s1 = "Kiwi en C" fullword ascii wide                 $s2 = "Benjamin DELPY `gentilkiwi`" fullword ascii wide                  $s3 = "http://blog.gentilkiwi.com/mimikatz" fullword ascii wide                  $s4 = "Build with love for POC only" fullword ascii wide                 $s5 = "gentilkiwi (Benjamin DELPY)" fullword wide                 $s6 = "KiwiSSP" fullword wide                $s7 = "Kiwi Security Support Provider" fullword wide                 $s8 = "kiwi flavor !" fullword wide          condition:                  any of them         }
但对于mimikatz来说,的确简单有效
 

yara编写

 
我们以CobaltStrike为例,从分析开始一步步的编写一个yara规则出来。
 
首先就是文件大小,CobaltStrike生成的马一般都很小,所以我们第一条规则便可以针对马的大小来做限制:
rule CobaltStrike4_1:beacon { meta: description = "This rule is used to detect CobaltStrike4.1 Trojan" author = "lengyi" condition:      filesize > 10KB and filesize < 24KB  }
使用yara防御恶意软件
然后便是分析阶段,将cs的马子放入cutter进行分析,发现入口点基本一样:
使用yara防御恶意软件
将其转换为汇编代码,发现入口点的main的结构相同
使用yara防御恶意软件
继续跟进,发现入口点为0x004014b0 ,然后减去0xc,那么入口点基本就是14B0的位置:
使用yara防御恶意软件
在这里也可以印证我们的猜想
使用yara防御恶意软件
之前说过可以使用pe模块来标识文件的入口点,不过不是使用我们这里的地址,而是需要文件偏移:
使用yara防御恶意软件
即000008B0也就是0x8b0
import"pe" rule CobaltStrike4_1:beacon {        meta:                 description ="This rule is used to detect CobaltStrike4.1 Trojan"          author = "lengyi"       condition:               pe.entry_point ==0x8b0 and filesize >10KB and filesize < 24KB }
使用yara防御恶意软件
那么这样简单的规则就算写完了,我们继续编写,在查看PE的过程中,我发现其中有一些奇奇怪怪的字符串:
使用yara防御恶意软件
看起来像是一些通信协议,我们回到cutter,查看main函数;
使用yara防御恶意软件
跳到401840,在该地址中可以看到我们的字符串,以及使用CreateThread来新建线程
使用yara防御恶意软件
这里CreateThread的地址为406148,在401648中可以看到正在使用CreateNamedPipeA进行管道通信:
使用yara防御恶意软件
通过附加多个线程,发现均存在该字符串,则在规则中匹配即可:
import "pe" rule CobaltStrike4_1:beacon { meta: description = "This rule is used to detect CobaltStrike4.1 Trojan" author = "lengyi" strings: $name = "%c%c%c%c%c%c%c%c%cMSSE-%d-server" condition: pe.entry_point ==0x8b0 and filesize > 10KB and filesize < 24KB and $name }
使用yara防御恶意软件
最后使用uint16来判断一下是否为pe文件即可,最后的yara规则如下:
import "pe" rule CobaltStrike4_1:beacon { meta: description = "This rule is used to detect CobaltStrike4.1 Trojan" author = "lengyi"     strings:          $name = "%c%c%c%c%c%c%c%c%cMSSE-%d-server"     condition:           uint16(0) == 0x5A4D and pe.entry_point ==0x8b0 and filesize > 10KB and filesize < 24KB and $name }
然后在一些威胁情报网站随便下了几个样本,三个检出了两个:
使用yara防御恶意软件
还是很不错的。


参考文章:
 
https://yara.readthedocs.io/en/stable/writingrules.html#more-about-rules
https://www.youtube.com/watch?v=35Exd9GrR5I&ab_channel=HackerSploit
https://www.anquanke.com/post/id/211501#h3-8

声明: 文章初衷仅为攻防研究学习交流之用,严禁利用相关技术去从事一切未经合法授权的入侵攻击破坏活动,因此所产生的一切不良后果与本文作者及该公众号无任何关联。


发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: