这是[信安成长计划]的第 26 篇文章
0x00 目录
0x01 BEACON_RDLL_GENERATE
0x02 Sleep
0x03 总结
在 CS 当中提供了很多自定义 Hook 的操作,允许用户对原始的一些流程进行修改,比如自定义 RDI,修改 SleepMask,修改 Artifact 等,但是这些又是如何通过 cna 脚本就可以完成这些处理流程的替换
这里的最终目的也是为了能跟上一篇文章一样,为功能添加增加便利性,不必受限于特定的开发人员
0x01 BEACON_RDLL_GENERATE
这里以自定义 RDI 为例分析,直接在反编译后的代码里进行搜索,能够看到主要有两个文件中存在
default.cna 是默认的 cna 脚本,界面当中的很多流程处理都是由这个脚本中的内容处理的
ScListener 是生成 Beacon 时所进行流程处理的地方
首先看 cna 脚本,默认是直接返回 null 的
这里的内容与手册中的描述是完全一致的
然后看 ScListener 中的内容,可以发现在处理了 format 之后,如果有值,则最终会返回这里获取的内容
也就说明最核心的内容就是下面这一块,而且从上面的 SleepUtils 取值的操作可以推断出,这里是进行参数传递的操作,同时也可以看到这里上面 push 了三个参数,这与文档中所说明的情况也刚好相同
getScriptEngine().format(
"BEACON_RDLL_GENERATE"
, var5)
这里的 format 最终会调用到 cortana.core.FormatManager
var1 就是前面所传入的 BEACON_RDLL_GENERATE,var2 就是所传入的参数
可以看到先用名字来 get,这里可以推测,在加载 cna 的时候会将所有的函数都存储起来,然后这里会进行获取,拿到具体的方法之后,就调用 SleepUtils.runCode,最后会将执行的结果返回回去
到这里基本理清楚了执行的流程处理,当 cna 脚本加载时,会将函数等内容都解析出来,当具体执行时,会通过判断函数名是否存在,来决定是否需要执行其他的代码
0x02 Sleep
流程分析明白后,再深入一点点 cna 的流程处理,因为这里是调用了 SleepUtils.runCode,通过搜索可以看到具体的解释
对于 SleepClosure 是什么,可以向上再追一下,可以发现,具体的注册是在 bindFunction 中处理和获取的
通过调用堆栈发现是从默认 cna 中获取的
可以看到这里解析了 set 方法,并且注册了 EVENT_PUBLIC 函数,最终解析出的代码是一个类似的结构体
通过 cna 可以发现这里的代码与上面所解析出来的结构是一样的,也就说明实际在注册的时候,会将 Sleep 的代码进行类似序列化的操作,最后在需要的时候进行调用
既然一切都是通过 cna 来进行的,那参考上一篇文章所碰到的处理方案,这里可以有两种使用的函数,一种是 Sleep 自带的函数,另一种就是 CS 自己实现的一整套处理流程,比如说 base64_encode 等
从官网给出的例子中也能够看出来
这些是 Sleep 自带的函数
具体可以从 Sleep 的官网来看 http://sleep.dashnine.org/manual/index.html
还有一些是由 CS 自己实现的
可以在 CS 中找到注册信息
同时在具体的实现中也能看到这里对返回值也是需要进行一些小的处理,最终需要通过 byte[] 的方式回传,然后调用 SleepUtils.getScalar 将数据回传给 cna 脚本中的代码,之后继续往下执行
0x03 总结
通过上面的分析整个的流程已经很清楚了,cna 加载时会进行解析,将函数和具体的代码都处理后存储到 Map 中,然后在实际执行时就可以专门进行处理了
对于 cna 来说,我们也可以增加自己想要的一些处理流程,只要增加对应的方法并且在最后通过 SleepUtils.getScalar 返回就可以了
按实际需求来进行对应的修改即可
-----文章到此结束,欢迎继续探讨-----
原文始发于微信公众号(信安成长计划):CobaltStrike逆向学习系列(番外篇)-Hooks处理流程分析
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论