CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析

这是[信安成长计划]的第 6 篇文章
关注微信公众号[信安成长计划]
CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第1张图片

0x00 目录

0x01 C2Profile 分析

0x02 set userwx “true”

0x03 set userwx “false”

CobaltStrike 提供了一个内存混淆功能,它会在 Sleep 的时候将自身混淆从而避免一定的检测

0x01 C2Profile 分析

因为 sleep_mask 是从 C2Profile 中设置的,所以就需要先搞清楚 TeamServer 是如何解析的

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第2张图片

很明显它还跟其他的设置项有关,这里我们重点关注一下 rwx 的设置

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第3张图片

首先会将 text 段的结尾地址存储到 index=41 的位置

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第4张图片

接着判断了 text 段与 rdata 段中间的空白位置够不够 256 个字节,推测会将加解密函数放在这里

图片

obfuscate 就让它默认为 false,它不是我们这次关注的重点,接下来就会将 0 和 4096 添加到其中

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第5张图片

再看一眼 text 段的 Virtual Address,这块很明显就是 PE 头的那段内容

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第6张图片

接下来就是循环添加内容了,可以很明显的看到 do while 的循环条件是 text 段且不允许使用 rwx,这也就意味着,当我们不允许使用 rwx 的时候,text 段并不会被添加到 index=42 的项中,应该也就不会被混淆了,在最后还添加了零,用于标示结尾

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第7张图片

0x02 set userwx “true”

为了快速定位到加解密函数所在,可以设置断点来完成,因为按照之前的分析,使用 rwx 的时候,text 段也会被混淆的,所以跟入函数以后,直接滑倒开头下写入断点即可

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第8张图片

接着直接放过也就到达了位置

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第9张图片

接着根据这个位置到 IDA 中进行查找,然后通过回溯也很容易能够找到整个的调用链

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第10张图片

在主循环的最后有一个用于处理 Sleep 的函数

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第11张图片

它通过判断 0x29 来决定是否直接调用 Sleep,如果使用了 sleep_mask,0x29 中存储的就是 text 段的结尾地址

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第12张图片

首先它会将自己当前函数与加解密函数一起传入

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第13张图片

在函数中先计算了两个函数地址的差值,通过对比很明显能够看出这个就是加解密函数的长度

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第14张图片

接着从 0x29 中取出 text 段的结尾地址,并从全局变量中取出 PE 头的位置,相加也就得到了在内存中的 text 的结尾地址,也就是后面要存放加解密函数的地址,接着传统的拷贝也就不提了,重点是后面的赋值操作

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第15张图片

申请了 0x20 的空间,也就是 32 个字节,8 个字节存储 PE 头地址,8 个字节存储 0x2A 的地址

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第16张图片

这个 0x2A 也就是之前构造的那一串结构

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第17张图片

然后将加 16 的位置传入

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第18张图片

第一个使用 CryptoAPI 生成密钥

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第19张图片

如果失败的话,用第二个自己实现的算法生成密钥

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第20张图片

最后就来调用加解密函数了,第一个是构造的结构,第二个是 Sleep 函数,第三个是时间

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第21张图片

接着就来分析加解密函数,根据中间 Sleep 调用可以推断出,上面是加密函数,下面是解密函数

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第22张图片

参数是指针类型,取数组,下标 1,也就是 0x2A 所取到的值了

然后 v6 就是第一个值 sectionAddress,v7 就是第二个值 sectionEnd,然后将 v3 再后移

用来判断跳出规则的就是最后添加的两个零

do while 的混淆条件就是 sectionAddress

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第23张图片

之后的解密也是一样的逻辑就不提了

接下来就是验证的时候了

Sleep 时候的状态

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第24张图片

此时的代码段

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第25张图片

接收命令时候的状态

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第26张图片

此时的代码段

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第27张图片

在允许 RWX 权限的时候,代码段是混淆的

0x03 set userwx “false”

理论在之前也都讲完了,这里就是验证一下最终的效果

Sleep 时候的状态

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第28张图片

此时的代码段

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第29张图片

接收命令时的状态

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第30张图片

此时的代码段

CobaltStrike逆向学习系列(6):Beacon sleep_mask 分析_第31张图片

在禁止 RWX 权限的时候,代码段是不混淆的

你可能感兴趣的:(信息安全,系统安全,web安全,安全,安全架构)