建瓯最坏的YARA - APT | 病毒检测 | 常用模块和字段
建瓯最坏的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模块
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 -d
或sort Data1.txt Data2.txt | uniq -d
。
编写好后,使用YARA规则命令复查一下是否有无法匹配的样本:
yara.exe .\YaraRule.txt -r -n [存放需要匹配样本的目录]
导出表
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)
此类函数,需要传入创建的名字:
如Create
DirectoryA:
设置(Set)
如RegSet
ValueExA
获取(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 | 病毒检测 | 常用模块和字段相关推荐
- 【建瓯最坏】APT的YARA规则
分类 地区 亚洲 中东 StrongPity 初始载荷 Exfiltrate模块(全版本) 未知 地区 亚洲 中东 StrongPity 初始载荷 Exfiltrate模块(全版本) import & ...
- 基于深度学习的病毒检测技术无需沙箱环境,直接将样本文件转换为二维图片,进而应用改造后的卷积神经网络 Inception V4 进行训练和检测...
话题 3: 基于深度学习的二进制恶意样本检测 分享主题:全球正在经历一场由科技驱动的数字化转型,传统技术已经不能适应病毒数量飞速增长的发展态势.而基于沙箱的检测方案无法满足 APT 攻击的检测需求,也 ...
- 一文读懂测序技术在新冠病毒检测中的应用(文末附FAQ)
来源:生物探索 随着世界疫情的发展,多个国家进入公共卫生紧急状态,全球科学家都在抓紧研究更好的检测.治疗.防控手段.从最初未知β属冠状病毒的快速鉴定到病毒序列的完整破译,再到病毒序列的变异监测,高通量 ...
- 奇安信病毒检测中心 2022年第二季度App收集个人信息检测报告 学习笔记 附下载地址
奇安信 2022年第二季度App收集个人信息检测报告 下载地址 2022年第二季度 APP收集个人信息 检测报告 奇安信 病毒响应中心 研究背景 随着互联网和移动设备的发展,手机已成为人人都拥有的设备 ...
- BZOJ1966: [Ahoi2005]VIRUS 病毒检测
BZOJ1966: [Ahoi2005]VIRUS 病毒检测 Description 科学家们在Samuel星球上的探险仍在继续. 非常幸运的,在Samuel星球的南极附近,探险机器人发现了一个巨大的 ...
- PHP文件在线检测病毒,VIRSCAN 在线病毒检测客户端
/**** 本程序以及提供的源码仅供技术交流使用. 作者不作任何类型担保,在任何情况下都不对使用本软件造成的任何损失或任何相应而生. 间接.附带的损失承担任何责任. ****/importwin.ui ...
- 马斯克再次进行新冠病毒检测 预计今天出结果
11月15日消息,特斯拉CEO埃隆·马斯克周六时间表示,自己"很有可能"感染了中等程度的新冠肺炎,但继续对测试的准确性表示怀疑,称"不同实验室的结果大相径庭". ...
- 互联网奠基人:温顿·瑟夫自曝新冠病毒检测呈阳性
By 超神经 场景描述:互联网奠基人之一:温顿·瑟夫(Vinton G. Cerf) ,3 月 30 日在自己的推特上发布自己冠状病毒检测呈阳性. 关键词:新冠病毒 TCP/IP TCP/IP 协议 ...
- KMP算法之病毒检测
什么是KMP算法? KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特--莫里斯--普拉特操作(简称KMP算法).KMP ...
最新文章
- CVM2021| PCT: Point cloud transformer(分类+分割任务SOTA)
- 如何用openvr api打开vive前置摄像头
- 【单页应用巨坑之History】细数History带给单页应用的噩梦
- Xcode的简单使用
- poj 3411 1724
- 01-复杂度2 Maximum Subsequence Sum (25 分)
- Android系统架构图
- 13 FI配置-财务会计-输入全局参数
- C#利用NI VAS采集图片
- SAP License:SAP CO ML 物料帐配置
- 卸载驱动出现:rmmod: can't change directory to '/lib/modules': No such file or directory
- 手游接入Facebook的那些坑
- 解决pip install 库 下载速度慢的问题
- html怎么自动过度,HTML与CSS中的过渡模块
- 《动手深度学习》4.5 权重衰减Weight Decay
- 在计算机上知道手机密码,不知道密码查手机通话记录:傻瓜式教程
- 债券价格和到期收益率的关系_债券价格与到期收益率之间的关系.PPT
- 2019“智汇科学城”光明区创新企业投融资路演在招商局智慧城顺利举办
- php面试题和答案整理
- js获取最近12个月
热门文章
- 什么是瑞士加密谷Crypto Valley、CV Labs
- 网吧无盘系统服务器安装,网吧网络无盘系统的安装方法
- Win10开始菜单打不开怎么办?
- v20超级计算机,荣耀v20正式发布 成为首款通过泰尔实验室的综合游戏体验五星手机...
- Python列表实现矩阵的创建、输入输出、转化转置、加减乘运算并设计一个矩阵计算器GUI界面
- 全栈开发-Python的介绍
- oracle database各个版本地址
- HTML怎么把按钮往下移,css按钮固定在底部
- 测角误差估计算法matlab,Harris角点检测 及 Matlab实验
- 单片机消抖c语言程序,基于单片机定时器软件消抖C51程序研究