二进制明文字符串加密:还原与反还原

一颗小胡椒2023-10-30 15:07:30

上一篇文章介绍了xorstr的原理和最小化验证概念的代码,这篇文章来看下这种已经被广泛应用于各恶意样本以及安全组件中的技术如何还原,如果还没看上篇建议先看下了解其实现后再看本篇文章。

一
xorstr的现状

随着相关技术的应用越来越广,各种攻击样本都用上了这一工具,威胁样本分析变得越来越耗时。这就是为什么需要一个对抗上述混淆技术的还原工具的原因,两个开源的还原工具flare-floss(https://github.com/mandiant/flare-floss)和AntiXorstr(https://github.com/lstaroth/AntiXorstr),工具的应用让这种二进制隐藏的字符串还原难度大幅降低。

二
还原方案分析

flare-floss是mandiant公司开发并开源出来的针对病毒分析的自动化二进制字符串启发式查找工具,针对此类加密方式flare-floss提供了两种还原逻辑(stack string & tight string),两者基于不同的假设,但都可以用来处理上述加密,下面给出他的实现原理的简要分析摘要。

stack string:flare-floss的这种还原方式基于一种非常宽的假设,即这种字符串必须基于栈,在栈上构造并解密。所以他使用模拟执行的方式对每个函数逐汇编代码的进行模拟执行,并在遇到函数调用指令时对当前栈进行全dump,最后使用字符串明文算法在dump中查找疑似的明文字符串,保存结果。

由于其假设过宽,致使其几乎拥有对当前开源的xorstr类似项目拥有100%的覆盖率,但过宽的假设导致大量的误报,对安全分析来说过多的垃圾信息反而干扰了正确的判断,这个误报在其代码中特别标注为“don't run this on functions with tight loops as this will likely result in FPs”

tight string:而flare-floss为了解决上述解决方案过宽假设带来的大量False Postive的问题,在去年更新了floss2加入tight string还原模式,这种模式基于这样的假设:存在栈加密字符串的函数存在一个循环Block块,这个Block块出去时栈为解密状态,也即他瞄准的时上述代码中的decrypt内联函数部分,decrypt中的for循环结构即为tight string关注的循环Block,而他也从每个函数调用转为每个循环block出口时对函数栈进行dump并搜索明文字符串。

AntiXorstr:去年写这个工具的时候并没有关注到floss项目因此实现的逻辑和他完全不同。区别于tightstring对decrypt特征的关注,该工具关注的是类构造函数。基于这样的假设:“栈加密字符串的加密数值必须是编译期计算出来的”。工具会对函数的栈进行预分析,并对栈进行立即数染色,被非0立即数染色过的联通区域标记为高可疑区域,并在后续的模拟执行过程中关注此类区域的读写并输出结果。

三
tight string的绕过

在对floss的tight string逻辑分析的过程中发现他的假设实际上并非是栈字符串的必须的,但确实是当前几乎所有开源的实现一定会存在的特征,即解密函数流程图中表现为环的形式。所以对floss-tight string的绕过即实现一个不会成环的字符串解密函数。首先我们先看下当前常规字符串的解密逻辑的反汇编流程图特征,demo如下:

这里的loc_1400010A0即为一个循环的Block,Block中的代码就是for循环中解密原始数据的decrypt函数的汇编码。这里让decrypt函数内部不生成循环即可实现对此还原方式的绕过,那么如何消环呢?这里用模板编程的思路去考虑一下,可以把循环使用模板递归展开的方式在编译期给消除掉,最终需要的效果如下:

__forceinline char* decrypt()
{
    for (auto index = 0; index < N; index++)
    {
        encBuffer[index] -= 1;
    }
    return encBuffer;
}
//N = 5
__forceinline char* decrypt_noloop()
{
    encBuffer[0] -= 1;
    encBuffer[1] -= 1;
    encBuffer[2] -= 1;
    encBuffer[3] -= 1;
    encBuffer[4] -= 1;
    return encBuffer;
}

剩下就是如何使用C++模板生成decrypt_noloop代码,使用递归展开的方式生成并对N=0做个特化终止即可消除loop环,并且还有一些细节这里限于篇幅不做展开,实现DEMO已开源:xorstr_s.h(https://github.com/lstaroth/xorstr-security/blob/main/xorstr_s.h)

测试demo

void test()
{
    printf(Enc("Samsung\n"));
    wprintf(Enc(L"Apple\n"));
    printf(Enc("Xiaomi\n"));
    wprintf(Enc(L"Oppo Group\n"));
    printf(Enc("vivo\n"));
    wprintf(Enc(L"Transsion\n"));
    std::cout << Enc("Honor") << std::endl;
    std::wcout << Enc(L"Realme") << std::endl;
    std::cout << Enc("Motorola") << std::endl;
    std::wcout << Enc(L"Huawei") << std::endl;
    std::cout << Enc("Others") << std::endl;
}

测试结果:STACK & TIGHT 绕过,DECODED模式还原出一部分。

 ─────────────────────
  FLOSS STACK STRINGS
 ─────────────────────
 ─────────────────────
  FLOSS TIGHT STRINGS
 ─────────────────────
 ───────────────────────
  FLOSS DECODED STRINGS
 ───────────────────────
Samsung
Apple
Xiaomi
Oppo Group
vivo
Transsion
Honor


四
更鲁棒的绕过策略

上述通过详细分析floss还原策略写的xorstr_s似乎显得不是很鲁棒,仅仅针对一个开源的工具去实现定制化的绕过方案显得成本过高,那么是否有更鲁棒的反还原方式呢,暂时有两种方式,其中一种的核心原理是:”基于堆的明文展开“,使得Floss这样对堆明文做监控的模式彻底失效。

读过上一篇文章的应该可以知道栈中保存了字符串密文,但并不是一定要就地解密,完全可以对栈数据只读而解密后的明文写入堆中,并利用临时对象的析构函数完成堆的释放即可。实现DEMO已开源:xorstr_h.h(https://github.com/lstaroth/xorstr-security/blob/main/xorstr_h.h),测试FLOSS的效果如下:

FLOSS STACK STRINGS
 ─────────────────────
o]QOIR[6<
}<L<L<P<Y<6<<<
dU]SQU6<
s<L<L<S<
<{<N<S<I<L<6<<<
JUJS6
h<N<]<R<O<O<U<S<R<6<<<
tSRSN
n<Y<]<P<Q<Y<<<
qSHSNSP]<
t<I<]<K<Y<U<<<
sHTYNO<
 ─────────────────────
  FLOSS TIGHT STRINGS
 ─────────────────────
 ───────────────────────
  FLOSS DECODED STRINGS
 ───────────────────────
o]QOIR[6<
字符串函数string
本作品采用《CC 协议》,转载必须注明作者和本文链接
近期,Unit 42的研究人员在分析Medusa(美杜莎)勒索软件活动时,发现该活动的升级和勒索策略发生了很大变化。
脱敏前电话号码,CONCAT(LEFT(mobilePhone,3),?身份证号码脱敏sql:. 根据定义的策略类型,对数据进行脱敏,当然策略可以自定义。请添加微信wx153666购买授权,不白嫖从我做起!?测试证书会失效,请勿正式环境使用
利用wirkeshake抓包初步分析配置本地PC的ip为192.168.5.150并在上面运行server,然后在pixel手机上安装client_连接192.168.5.150服务器.apk,手机ip为192.168.5.221,在PC上通过wireshake进行抓包。如下所示,看到No.14是手机发给server的HTTP GET包,No.17为server发给手机的HTTP报文。
这似乎又是一个0 day漏洞,这个漏洞与pif文件有关,是我在研究pif文件的时候发现的。
mysql提权总结
2021-09-17 15:04:08
使用过MySQL的人都知道,MySQL有很多内置函数提供给使用者,包括字符串函数、数值函数、日期和时间函数等,给开发人员和使用者带来了很多方便。
随着Web应用攻击手段变得复杂,基于请求特征的防护手段,已经不能满足企业安全防护需求。在2012年的时候,Gartner引入了“Runtime application self-protection”一词,简称为RASP,属于一种新型应用安全保护技术,它将防护功能“ 注入”到应用程序中,与应用程序融为一体,使应用程序具备自我防护能力,当应用程序遭受到实际攻击伤害时,能实时检测和阻断安全攻击,而不需要进行人工干预。实现了在攻击链路最关键的地方阻断攻击。
刚好404之前有一篇博客写过这个漏洞,我在它的参考资料里面找到了github上面提供的poc生成代码,以及j00sean在twitter上面发的6行代码,以这两者为基础对该漏洞进行分析。
二进制程序分析
2021-09-25 17:18:46
分析恶意软件的第一步是收集二进制程序在主机上执行的行为事件,研究人员根据这些行为大体形成一个思路来描述恶意软件的功能。 这包含应用释放或者从互联网下下载的文件,写入什么样的注册表、访问了什么网络地址,修改读写本地的什么文件等等。那么研究人员通过行为会确定恶意样本的类型。通常类型如下:
上一篇文章介绍了xorstr的原理和最小化验证概念的代码,这篇文章来看下这种已经被广泛应用于各恶意样本以及安全组件中的技术如何还原,如果还没看上篇建议先看下了解其实现后再看本篇文章。
一颗小胡椒
暂无描述