本帖最后由 梦幻的彼岸 于 2021-6-8 10:29 编辑
备注
原文地址:https://evasions.checkpoint.com/techniques/human-like-behavior.html
原文标题:Evasions: Human-like behavior
更新日期:2021年6月8日
此文后期:根据自身所学进行内容扩充
因自身技术有限,只能尽自身所能翻译国外技术文章,供大家学习,若有不当或可完善的地方,希望可以指出,用于共同完善这篇文章。
目录
- 类似人类的行为检测方法
- 1. 通过注册表的一般检测方法
- 1.1. 检查最近打开的文件的数量
- 1.2. 检查浏览器历史记录是否包含至少10个URLs
- 1.3. 检查是否安装了某些软件包
- 1.4. 反制措施
- 2. 在执行进程的时候检查用户是否存在
- 2.1. 检查鼠标的移动
- 2.2. 通过对用户互动的请求进行检查
- 2.3. Cuckoo人机互动模块的规避技术
- 2.4. 在文件被向下滚动之前没有可疑的行动
- 2.5. 通过GetLastInputInfo检查用户活动
- 反制措施
- 识别标志
- 归功于
类似人类的行为检测方法
这一组描述的所有技术都利用了这样一个事实,即某些动作由用户和虚拟环境以不同方式执行。
1. 通过注册表的一般检测方法
注册表是一个存储不同信息的地方。例如,最近打开的URL和文档,以及软件安装说明都存储在这里。所有这些都可以用来确定机器是否由人类用户操作,而不是一个沙盒。
1.1. 检查最近打开的文件的数量
很难想象一个典型的主机系统,用户不打开任何文件。因此,缺乏最近打开的文件表明这可能是一个虚拟环境。
代码样本 (VB):
[Visual Basic] 纯文本查看 复制代码 Public Function DKTxHE() As Boolean
DKTxHE = RecentFiles.Count < 3
End Function
这个代码样本取自SentinelOne文章
1.2. 检查浏览器历史记录是否包含至少10个URLs
很难想象一个典型的主机系统的用户不浏览互联网。因此,如果浏览器历史中的URL少于10个,这很可能是一个沙盒或虚拟机。
代码样本 (for Chrome):
[C++] 纯文本查看 复制代码 bool chrome_history_evasion(int min_websites_visited = 10)
{
sqlite3 *db;
int rc;
bool vm_found = false;
rc = sqlite3_open("C:\\Users\\<USER_NAME>\\AppData\\Local\\Google\\Chrome\\User Data\\Default\\History", &db);
if (!rc)
{
char **results = nullptr;
char *error = nullptr;
int rows, columns;
rc = sqlite3_get_table(db, "SELECT DISTINCT title FROM urls;", &results, &rows, &columns, &error);
if (!rc)
vm_found = rows < min_websites_visited;
sqlite3_free_table(results);
}
sqlite3_close(db);
return vm_found;
}
1.3. 检查是否安装了某些软件包
如果系统只用于伪装目的,那么它所安装的软件包可能比一般用户的工作机少很多。所安装的软件包可能是专门用于仿真目的的,而不是人类操作员通常使用的软件包。因此,可以将安装的软件包列表与常用的应用程序列表进行比较,以确定它是否是一个沙盒。
代码样本 (PowerShell):
[C++] 纯文本查看 复制代码 Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Format-Table -AutoSize | Measure-Object -Line
1.4. 反制措施
反制措施很简单:
- 打开一些文件以更新最近的历史
- 打开几个互联网网址,创建一个浏览记录
- 安装一些轻量级软件
2. 在执行进程的时候检查用户是否存在
下面的分组利用了用户与机器的互动和虚拟环境的行动之间的差异。
2.1. 检查鼠标的移动
这种方法依靠的是用户在实际工作中经常移动鼠标的事实。
一些沙盒和防病毒虚拟机有一个静态的光标位置,因为它们在自动运行文件时不模拟任何用户活动。
代码样本:
[C++] 纯文本查看 复制代码 int gensandbox_mouse_act() {
POINT position1, position2;
GetCursorPos(&position1);
Sleep(2000);
GetCursorPos(&position2);
if ((position1.x == position2.x) && (position1.y == position2.y))
// No mouse activity during the sleep.
return TRUE;
else
return FALSE;
}
这个代码样本取自pafish项目
如此短的延迟只有2秒,意味着用户在感染的时候应该是活跃的。
反制措施:
在样本模拟过程中实施鼠标移动的模块。
2.2. 通过对用户互动的请求进行检查
一些恶意软件样本包含一个GUI安装程序,需要用户互动。例如,用户必须点击 "安装 "或 "下一步 "按钮。因此,除非按钮被点击,否则恶意软件可能不会采取任何行动。像Cuckoo这样的标准沙盒有一个模拟用户活动的模块。它搜索并点击具有上述标题的按钮。
为了防止自动点击,恶意软件样本可能会创建一个类名称不同于 "按钮 "的按钮,或有不同的标题(不是 "安装 "或 "下一步")。这样,沙盒就无法检测和点击按钮。
代码样本:
[C++] 纯文本查看 复制代码 // we use extended style flags to make a static look like a button
HWND hButton = CreateWindowExW(
WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE, // extended style flags
TEXT("static"), // class "static" instead of "button"
TEXT("Real next"), // caption different from “Install” or “Next”
WS_VISIBLE | WS_CHILD | WS_GROUP | SS_CENTER, // usual style flags
10, 10, 80, 25, // arbitrary position and size, may be any
hWnd, // parent window
NULL, // no menu
NULL, // a handle to the instance of the module to be associated with the window
NULL); // pointer to custom value is not required
反制措施:
检查按钮以外的控件,并检查它们的属性。例如,如果 "安装 "文本与 "静态 "控件(而不是 "按钮")相连,这可能表明应用了规避技术。因此,这样的静态控件可能被点击。
2.3. Cuckoo人机互动模块的规避技术
假设恶意软件安装程序窗口有一个带有 "安装 "标题的按钮或类似的东西。它可以被沙盒的人机交互模块发现,但对于实际用户来说,它是不可见的(一像素大小,隐藏等)。
真正的安装按钮有一个空的或假的标题和窗口类 "静态",所以它不能被自动点击模块发现。此外,如果不可见的按钮被点击,恶意软件可能会采取一些模拟行动。
代码样本:
[C++] 纯文本查看 复制代码 HWND hWnd = CreateWindow(
TEXT("Button"), // class "button"
TEXT("Next"), // caption is “Install” or “Next”
NULL, // style flags are not required, the control is invisible
1, 1, 1, 1, // the control is created of 1x1 pixel size
hParentWnd, // parent window
NULL, // no menu
NULL, // a handle to the instance of the module to be associated with the window
NULL); // pointer to custom value is not required
反制措施:
检查除按钮以外的其他控件并检查其属性。如果有一个1×1像素大小的按钮或按钮是不可见的,这可能是应用了规避技术的一个迹象。因此,这样的控件不应该被点击。
2.4. 在文件被向下滚动之前没有可疑的行动
驻扎在Office文档(即*.docm *.docx)中的恶意软件有效载荷在文档被滚动到某一页(第二页、第三页等)之前不会做任何事情。人类用户通常会滚动浏览文档,而虚拟环境可能不会执行这一步骤。
FireEye报告中的例子(第6-7页)。
RTF文档由正常文本、控制词和组组成。微软的RTF规范包括一个形状绘制功能,它又包括一系列使用以下语法的属性。
[C++] 纯文本查看 复制代码 {\sp{\sn propertyName}{\sv propertyValueInformation}}
在这段代码中,\sp是绘图属性的控制词,\sn是属性名称,\sv包含关于属性值的信息。下图中的代码片段利用了CVE-2010-3333漏洞,该漏洞在为pFragments形状属性使用无效的\sv值时发生:
如下图所示,仔细查看利用漏洞代码,会发现一系列出现在利用漏洞代码之前的段落标记(./par):
重复的段落标记将漏洞代码推到RTF文档的第二页。因此,恶意代码不会执行,除非文档向下滚动,使漏洞代码进入活动窗口--更可能是人类用户的故意行为,而不是虚拟机中的模拟运动。
当RTF向下滚动到第二页时,才会触发漏洞代码并下载有效载荷。
在沙盒中,任何鼠标活动都是随机的或预先编程的,RTF文档的第二页永远不会出现。因此,恶意代码永远不会执行,在沙盒分析中似乎没有什么不妥。
反制措施:
找到一个有文档的窗口,在那里发送WM_VSCROLL消息。或者,如这里所述,发送WM_MOUSEWHEEL消息。
2.5. 通过GetLastInputInfo检查用户活动
用户活动可以通过调用GetLastInputInfo函数来检查
尽管Agent Tesla v3执行了这个检查,但它的做法是不正确的。比较一下Agent Tesla v3的代码和下面正确的技术实现。
Agent Tesla v3中实现的规避技术。 该函数在延迟30秒后被调用:
由于测量的时间值是以毫秒为单位,它们之间的差异不能大于30000(30秒)。这意味着,除以1000.0,所得的值不能大于30。反过来,这表明与600的比较总是导致沙盒未被检测到的结果。
下面提供了正确的实现方法。
代码样本:
[C++] 纯文本查看 复制代码 bool sandbox_detected = false;
Sleep(30000);
DWORD ticks = GetTickCount();
LASTINPUTINFO li;
li.cbSize = sizeof(LASTINPUTINFO);
BOOL res = GetLastInputInfo(&li);
if (ticks - li.dwTime > 6000)
{
sandbox_detected = true;
}
反制措施:
在样本模拟过程中实施鼠标移动的模块。
反制措施
第1章的反制措施在相应章节中给出。第2章的反制措施在相应章节中给出。
识别标志
对于这类技术没有提供签名建议,因为本章所描述的方法并不意味着它们被用于规避目的。很难区分用于规避的代码和为非规避目的设计的代码。
归功于
开源项目,代码样本取自该项目。
某些例子来自的公司:
|