建瓯最坏的YARA

  • YARA规则
    • 推荐YARA相关文章
    • 通用
      • 文件属性
        • SIZE(如66KB)
    • 条件(Condition)
      • 字符串多次出现
      • 字符串位置
        • 地址
          • 具体位置
          • 位置区间
        • 偏移
    • PE模块
      • 文件类型判断
      • 导入表
        • 延迟导入表
      • 导出表
      • PDB
      • 资源
  • YARA规则思路
    • IDA导出表窗口
    • 字符串
    • IDA的字符串窗口
      • PDB
      • 字符型格式符
    • 函数参数
      • 创建(Create)
      • 设置(Set)
      • 获取(Get)
      • 文件(File)
    • 字符串
      • 字符串操作(str)
      • 格式化输出函数(printf)
  • 实例
    • 字符串多次出现
    • 特殊函数
      • 函数多次出现
    • 特殊代码
      • 分离赋值-StrongPity

YARA规则

下载地址

推荐YARA相关文章

《看雪 - [翻译]编写Yara规则检测恶意软件 》

通用

文件属性

SIZE(如66KB)

文件大小判断:filesize < 100KB
文件大小区间:(33KB < filesize and filesize < 99KB)
33KB < filesize < 99KB,会报错,YARA官方文档没有搜到区间怎么写,加了括号(33KB < filesize < 99KB)也不行

 condition:filesize < 66KB(33KB < filesize and filesize < 99KB)

条件(Condition)

字符串多次出现

字符串出现的次数可以由一个变量表示,变量名是用#代替$的字符串标识符

 condition://包含String$String//String出现2次以上,字符串符号$改为变量符号##String > 2

字符串位置

地址

注意数值默认是十进制的,如果是十六进制的需要在数字前加上“0x”。

具体位置

有时知道字符串是否位于特定的位置,或偏移量在文件或进程地址空间内的某个虚拟地址上时,可通过at进行匹配:

rule AtAddress
{strings:$Address0x100 = "Address0x100"condition:$Address0x100 at 0x100
}
位置区间

当字符串Digits2串偏移量在0到100之间,而字符串Digits2串偏移量在0到100之间,而字符串Digits2串偏移量在0到100之间,而字符串Above100位于100到文件末尾之间的偏移量处时:

rule InInterval
{strings:$Digits2= "0-99"$Above100 = "100<"condition:$Digits2 in (0..100) and $Above100 in (100..filesize)
}

偏移

如果确定某字符串出现在另一字符串固定位置的偏移处,可以通过@取得地址值表示,格式为@String1[Num],[Num]表示的是,对应字符串第一次出现的位置,并且Num计数是从1开始的
当字符串String1地址往后偏移0x11处为String1地址往后偏移0x11处为String1地址往后偏移0x11处为String2时:

 condition:@String1[1] + 0x11 == @String2[1]

除此之外,也可以通过加减运算和比较运算符表示。如:

 condition://取值是支持负数的(@String1[1] - @String2[1] == -0x11)//或者也可以写为(@String2[1] - @String1[1] > 0x11)

PE模块

使用该模块之前需要导入PE模块(注意PE必须小写)

import "pe"condition:pe.is_dll()pe.is_32bit()pe.is_64bit()pe.pdb_path == "Y:\建瓯最坏\ProjectName\2021\Project2021RAT.pdb"pe.imphash() == "b8bb385806b89680e13fc0cf24f4431e"pe.imports("kernel32.dll", "WriteProcessMemory")pe.exports("ExportTableName")

文件类型判断

Dll文件:pe.is_dll()
32位:pe.is_32bit()
64位:pe.is_64bit()

导入表

导入表哈希值:pe.imphash() == “b8bb385806b89680e13fc0cf24f4431e”,注意要小写
导入表中的函数:pe.imports(“kernel32.dll”, “WriteProcessMemory”),尽量找比较特殊的函数
导入表Library的个数:pe.number_of_imports == 6

延迟导入表

在编写海莲花后门Salgorea发现一个比较特殊的情况,有个样本的导入表函数条件匹配不上:

pe.imports( "Shell32.dll" , "ShellExecuteW" )

IDA的导入表内却又有“ShellExecuteW”,定位来源发现不同处为,匹配不上的函数显示来自延迟导入表(Delayed imports from SHELL32.dll):

搜了很久都没有找到YARA怎么匹配延迟导入表中函数的写法,换个思路,暂时选择通过增加其他的函数条件来检测。方式为:对比两种样本的函数,找到相同且比较特殊的函数、
从导入表中,复制所有列:

利用Excel或其他方式(如文本对比工具,Linux的命令uniq),选中范围后,设置高亮Name列的重复项:

我个人还是更倾向于Excel:

Office的Excel好像没有提取重复数据,WPS这个功能要钱,那么推荐安装Git或者在Linux下执行命令求交sort Data.txt | uniq -dsort Data1.txt Data2.txt | uniq -d
编写好后,使用YARA规则命令复查一下是否有无法匹配的样本:

yara.exe .\YaraRule.txt -r -n [存放需要匹配样本的目录]

导出表

导出表中的函数名:pe.exports(“ExportTableName”)
导出表中的函数个数等于明确数字:pe.number_of_exports == [导出表最下方的数字减去1]

导出表中的函数个数处于某个区间:(200 < pe.number_of_exports and pe.number_of_exports < 300)
还可以匹配正则等,检测单个用名称匹配比较多,预测性用正则

PDB

PDB:pe.pdb_path == "Y:\建瓯最坏\ProjectName\2021\Project2021RAT.pdb"
只单个样本可以考虑
但是从APT跟踪角度来说,一般以字符串的方式+正则匹配用来预测可能变化的情况。
分解上面的PDB分别是:
盘符:一个大写英文,[A-Z]{1}
用户名:固定长度的中文, [\u4e00-\u9fa5]{4}
项目名:不定长(暂取Max50)大小写英文,[a-zA-Z]{,50}
年份:定长数字,20XX年,20[0-9]{2};201X年,201[0-9]{1};202X年,202[0-9]{1}
源文件名称:当做是随机搭配的数字和大小写英文,[\w]{,50}
可以写成以下几种格式搭配,一般建议写宽松写,或者根据历史样本的变化规律可以对应的修改。

rule PDB
{strings://如果以“建瓯最坏”不变匹配:建瓯最坏\([路径(包括大小写英文和\)]).pdb$StringsPDB_JianOu = /[\u4e00-\u9fa5]{4}[\w\\]{,50}.pdb///ProjectName\[不同年份]\Project2021RAT.pdb$StringsPDB_Year = /ProjectName\\20[0-9]{2}\\Project2021RAT.pdb///[不同项目名]\2021\[不同源文件名].pdb$StringsPDB_ProjectName = /[a-zA-Z]{,50}\\20[0-9]{2}\\[\w]{,50}.pdb/condition:all of them
}

资源

如ICON:

import "pe"
import "hash"condition:for any i in (0..pe.number_of_resources) : (( pe.resources[i].type == pe.RESOURCE_TYPE_ICON )and( hash.md5(pe.resources[i].offset,pe.resources[i].length) == "834c709455bfefb9b0e8976bad13a8f4" ))

YARA规则思路

IDA导出表窗口

 condition:pe.exports("ExportTableName")

除非是比较特殊,而且长期大量的样本都是同一个名称,不然其实检测的精度比较高,但是通用性较低

字符串

IDA的字符串窗口

PDB

在IDA的字符串窗口搜索PDB,没有就算了
有的话参考上述的规则,判断PDB路径结构,对一些变量(如年份2018和日期/版本号0328)替换为正则

这里这种通用性较低,没有比较特殊的字符串,勉强可以写一个,条件判断里可能也不会作为主要逻辑:

 strings:$StringsPDB = /F:\\[\w\\]{36,60}\\Doc.pdb/

字符型格式符

在IDA的字符串窗口搜索字符型格式符,如%s,基本会有一些比较自定义的字符串

函数参数

还有部分函数的参数需要传入字符串,可以试着从这里面看看有无比较特殊的字符串或者格式

创建(Create)

此类函数,需要传入创建的名字:

CreateDirectoryA:

设置(Set)

如RegSetValueExA

获取(Get)

大多数获取功能的函数是没有什么参数,但是要处理获取到的数据,此时会有一些参与处理的字符串:

文件(File)

文件操作类大多数需要带文件路径或者文件名,如打开某文件,或者遍历某文件等

字符串

字符串操作(str)

字符串操作那必然是有字符串了,找找有无比较特殊的字符串

格式化输出函数(printf)

和字符串操作同理

实例

字符串多次出现

考虑到误报率和检测率,可以增加一些检测条件,下图中的“%ls”可以看出有多次出现:

但是需要通过Hex十六进制窗口确认一下字符串的类型,此部分一共有1个“%ls”和两个宽字节的“%ls”:
或者通过浮IDA提示的字符串类型判断,char为普通字符串:
wchar为宽字符。需要将字符串加上wide 定义:

可以写字符串多次出现的规则检测如下:

 strings:$LS = "%ls" nocase$LS_Wide = "%ls" nocase widecondition:$LS and #LS_Wide > 1//或者如果字符串多,可以://all of them and #LS_Wide > 1


不过大于小于的偏差值可能会比较大,YARA有一参数-s:

-s, --print-strings print matching strings
打印出匹配的字符串

在数量不多的情况下,可以作为计数方式使用:


上图可知“%ls”出现3次,宽字节的“%ls”出现5次,加上精确数字,规则可以写为:

 strings:$LS = "%ls" nocase$LS_Wide = "%ls" nocase widecondition:#LS ==3 and #LS_Wide == 5

特殊函数

有些恶意软件,可能字符串常见,但是用的函数很特殊,或者这两个叠加的集合比较准确,可以考虑在条件处增加函数条件,格式为:imports(dll_name, function_name),如:pe.imports(“Kernel32.dll”, “Sleep”)
恶意软件常通过创建互斥体,保持运行的唯一性,这本质是通过创建锁来形成的,故除了互斥体外,还有其他的方式,如:临界区,事件和信号量。
比如APT蔓灵花的常用下载器使用的方式是调用“CreateSemaphoreA”创建信号量:

import "pe"rule APT_Bitter_ArtraDownloader_Jul20
{meta:author = "建瓯最坏"description = "蔓灵花ArtraDownloader - 2020.07新变种"sampleMD5 = "cgc.exe - 808849DE500179EC0FBC82C862F62333"strings:$Strings = "ExRng" nocase$StringsPost1 = "info" nocase$StringsPost2 = "Test" nocase$StringsPHP = ".php" nocase$StringsFile = "wb" nocase$StringsFileOpen = "Open" nocasecondition:all of themand pe.is_32bit()and pe.imports("Kernel32.dll","CreateSemaphoreA")  //创建信号量and pe.imports("SHLWAPI.dll","PathAddBackslashA")    //比较特殊and pe.imports("WS2_32.dll","connect")and pe.imports("SHELL32.dll","ShellExecuteA")
}

函数多次出现

竟然木有这种语法,希望后续版本中会有

特殊代码

分离赋值-StrongPity

APT组织StrongPity常用的Exfiltrate模块中有字符串分离赋值的特殊代码如下:

上面截图中是一个很有特殊性的代码,Exfiltrate模块会拼接卷序列号和分离赋值的版本字符串。在后续载荷中,代码的具体实现稍有不同,直接通过“GetVolumeInformationW”快速定位到了此处:

可以发现有规律为通过分离赋值的方式,拼接处“v[1-9][0-9]{2}kt[0-9]{2}p[0-9]”,那么一定有对“v”“_”“kt”“p”的赋值,对应着二进制代码如下:

 strings://v赋值,push 0x76$HexVerNumV = { 6A 76 }//下划线$HexVerNumUnderscore = { 6A 5F }//k$HexVerNumK = { 6A 6B }//p$HexVerNumP = { 6A 70 }

对目前已知发现的版本检测率为100%:

又考虑到赋值都在一定范围的代码处,可以再加上字符串地址取值和偏移量判断,但又不是非常固定,是处于一个比较临近的区间,比如“v”和“_”偏移,在V20版本为0xD的,在V21版本为0x11的,所以取一个比较宽松的值为0x33(3是我的幸运数字):

import "pe"rule APT_StrongPity_Exfiltrate_Dec20
{meta:author = "建瓯最坏"description = "2020-12-25,StrongPity联网插件"sample = "81390CE601D34F384BFF9198EEF793A9"strings://版本号标识,格式如"v33_kt33p3"$HexVerNumV = { 6A 76 }$HexVerNumUnderscore = { 6A 5F }$HexVerNumK = { 6A 6B }$HexVerNumP = { 6A 70 }$StringsName = "name=%ls" nocase$StringsDel = "delete=" nocase//有些版本SFT字符串被加密处理了,无法通用//$StringsSFT = "*.sft" nocase widecondition:all of themand ( @HexVerNumUnderscore[1] - @HexVerNumV[1] < 0x33 )and pe.imports("Kernel32.dll","GetVolumeInformationW")and pe.imports("Kernel32.dll","ReadFile")and pe.imports("Kernel32.dll","CreateProcessW")and pe.imports("WinHTTP.dll","WinHttpSendRequest")
}

如果仅根据上面两个版本的偏移数字,甚至可以写作:

 condition:( 0xD <= @HexVerNumUnderscore[1] - @HexVerNumV[1] )and( @HexVerNumUnderscore[1] - @HexVerNumV[1] <= 0x11 )
}

但是对于示例的这个样本,不是很有必要,因为这些分离赋值的Hex值都比较特殊,每个在IDA里面搜索后的结果都只有一个:

通过定义String,同时多个即可以扫描到几乎100%的对应样本。
对特殊的字符串意义不大,不过对于搭配通用的字符串,可以大大的提高准确率。可惜分析早先过这个样本却不记得具体样本,无法展示,但道理如此。

建瓯最坏的YARA - APT | 病毒检测 | 常用模块和字段相关推荐

  1. 【建瓯最坏】APT的YARA规则

    分类 地区 亚洲 中东 StrongPity 初始载荷 Exfiltrate模块(全版本) 未知 地区 亚洲 中东 StrongPity 初始载荷 Exfiltrate模块(全版本) import & ...

  2. 基于深度学习的病毒检测技术无需沙箱环境,直接将样本文件转换为二维图片,进而应用改造后的卷积神经网络 Inception V4 进行训练和检测...

    话题 3: 基于深度学习的二进制恶意样本检测 分享主题:全球正在经历一场由科技驱动的数字化转型,传统技术已经不能适应病毒数量飞速增长的发展态势.而基于沙箱的检测方案无法满足 APT 攻击的检测需求,也 ...

  3. 一文读懂测序技术在新冠病毒检测中的应用(文末附FAQ)

    来源:生物探索 随着世界疫情的发展,多个国家进入公共卫生紧急状态,全球科学家都在抓紧研究更好的检测.治疗.防控手段.从最初未知β属冠状病毒的快速鉴定到病毒序列的完整破译,再到病毒序列的变异监测,高通量 ...

  4. 奇安信病毒检测中心 2022年第二季度App收集个人信息检测报告 学习笔记 附下载地址

    奇安信 2022年第二季度App收集个人信息检测报告 下载地址 2022年第二季度 APP收集个人信息 检测报告 奇安信 病毒响应中心 研究背景 随着互联网和移动设备的发展,手机已成为人人都拥有的设备 ...

  5. BZOJ1966: [Ahoi2005]VIRUS 病毒检测

    BZOJ1966: [Ahoi2005]VIRUS 病毒检测 Description 科学家们在Samuel星球上的探险仍在继续. 非常幸运的,在Samuel星球的南极附近,探险机器人发现了一个巨大的 ...

  6. PHP文件在线检测病毒,VIRSCAN 在线病毒检测客户端

    /**** 本程序以及提供的源码仅供技术交流使用. 作者不作任何类型担保,在任何情况下都不对使用本软件造成的任何损失或任何相应而生. 间接.附带的损失承担任何责任. ****/importwin.ui ...

  7. 马斯克再次进行新冠病毒检测 预计今天出结果

    11月15日消息,特斯拉CEO埃隆·马斯克周六时间表示,自己"很有可能"感染了中等程度的新冠肺炎,但继续对测试的准确性表示怀疑,称"不同实验室的结果大相径庭". ...

  8. 互联网奠基人:温顿·瑟夫自曝新冠病毒检测呈阳性

    By 超神经 场景描述:互联网奠基人之一:温顿·瑟夫(Vinton G. Cerf) ,3 月 30 日在自己的推特上发布自己冠状病毒检测呈阳性. 关键词:新冠病毒  TCP/IP TCP/IP 协议 ...

  9. KMP算法之病毒检测

    什么是KMP算法? KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特--莫里斯--普拉特操作(简称KMP算法).KMP ...

最新文章

  1. CVM2021| PCT: Point cloud transformer(分类+分割任务SOTA)
  2. 如何用openvr api打开vive前置摄像头
  3. 【单页应用巨坑之History】细数History带给单页应用的噩梦
  4. Xcode的简单使用
  5. poj 3411 1724
  6. 01-复杂度2 Maximum Subsequence Sum (25 分)
  7. Android系统架构图
  8. 13 FI配置-财务会计-输入全局参数
  9. C#利用NI VAS采集图片
  10. SAP License:SAP CO ML 物料帐配置
  11. 卸载驱动出现:rmmod: can't change directory to '/lib/modules': No such file or directory
  12. 手游接入Facebook的那些坑
  13. 解决pip install 库 下载速度慢的问题
  14. html怎么自动过度,HTML与CSS中的过渡模块
  15. 《动手深度学习》4.5 权重衰减Weight Decay
  16. 在计算机上知道手机密码,不知道密码查手机通话记录:傻瓜式教程
  17. 债券价格和到期收益率的关系_债券价格与到期收益率之间的关系.PPT
  18. 2019“智汇科学城”光明区创新企业投融资路演在招商局智慧城顺利举办
  19. php面试题和答案整理
  20. js获取最近12个月

热门文章

  1. 什么是瑞士加密谷Crypto Valley、CV Labs
  2. 网吧无盘系统服务器安装,网吧网络无盘系统的安装方法
  3. Win10开始菜单打不开怎么办?
  4. v20超级计算机,荣耀v20正式发布 成为首款通过泰尔实验室的综合游戏体验五星手机...
  5. Python列表实现矩阵的创建、输入输出、转化转置、加减乘运算并设计一个矩阵计算器GUI界面
  6. 全栈开发-Python的介绍
  7. oracle database各个版本地址
  8. HTML怎么把按钮往下移,css按钮固定在底部
  9. 测角误差估计算法matlab,Harris角点检测 及 Matlab实验
  10. 单片机消抖c语言程序,基于单片机定时器软件消抖C51程序研究