这是[信安成长计划]的第 25 篇文章
0x00 目录
0x01 CS自带方案
0x02 自定义流程实现
0x03 自定义Patch实现
按照之前对RDI功能发布的分析《RDI 任务发布流程分析》,当添加新功能时,只要实现了对应的几个方法便可以完成,但是这样的方法并不便于团队对新功能的增加,功能增加只掌握在了编译的人手中。
0x01 CS自带方案
在CS中有一个类似的方法,可以支持用户对RDI功能的自定义 DllSpawnJob
它是由cna脚本来执行的,通过 bdllspawn
方法来完成,在解析完参数之后会调用 DllSpawn
方法
DllSpawnJob
当中,根据已有的名字可以推断出,它可以支持用户自定义几个关键函数的信息然后进行 Spawn
就目前来说,有几个比较有局限的地方
首先当前只支持 Spawn 操作,实际对于 Inject 还是有一定需求的,比如注入自身等情况
其次 DllSpawnJob
是继承自 JobSimple
,处理流程与 execute-assembly
是一致的,你所想要追加的内容信息都是通过参数的方式来进行追加的,并不支持进行我们想要的后续 Patch 操作,所有的信息在你编译好 DLL 的时候就需要完成
0x02 自定义流程实现
虽然上面的方案有缺陷,但是我们可以借鉴这样的方式来完成我们自己的处理
我们选择继承 Job
,在实现以后,可以更方便使用 Spawn 和 Inject 两种逻辑,接着实现 abstract
方法, 并且其中的信息通过外部传参获得
以 Inject 为例,添加一个 bjobinject
方法,为了能够为上面的几个方法提供内容,先获取这些关键信息,同时因为是注入的关系,也需要有 PID
到这里所需要的最基本参数也就完成了,已经可以在 cna 脚本中来进行调用了,当然为了方便,对于 PipeName
、CallbackType
等不太会做变动的内容可以设置默认值,如果传入为空就默认使用
bjobinject(%options['bid'], "desc", "shortdesc", "test", "", 0, 0,%options["pid"]);
同理来实现 Spawn 操作时,直接在 new 完以后调用 Spawn 就可以了
0x03 自定义Patch实现
然后就是增加 Patch 操作了,在 CS 中 Patch 的操作还是非常多的
根据 Job
的处理流程可以发现有一个地方能够让我们进行操作,我们可以自己来实现 fix
方法,然后再通过参数来达到控制任务执行流程的目的
再这里可以有很多种处理方案,刚开始想偷懒,想在外部直接传入 Python 脚本,内部来执行并替换调返回
但是后来想了想,这样做会带来的风险将直线上升,除非你愿意每次使用前,都看一眼所有的 Python 代码有没有恶意操作
为了安全起见,只能是自己来实现了,所以这里也就只支持简单的 Patch 操作(后来发现,再加上CS自带的一些辅助函数,可操作性还是蛮大的)
因为 Patch 主要就需要一个原始字符串和一个新字符串,所以只要一个 Key-Value 格式的数据就足以处理了,将文件中的 Key 值替换为 Value 值
偷懒,直接使用 Java 的 Properties
来完成
依旧通过 cna 脚本将文件名传入,然后我们来获取进行读取
接下来就需要讨论参数该如何获得了,因为所有的参数都是从 cna 脚本当中传入的,而我们并不知道调用者会传入多少个参数进来,所以最好的方案就是拿到一个数组,然后传入我们自己的方法里,在 fix 中进行获取,并和文件中所需要的进行匹配
对于 cna 参数的处理就非常简单了,如果一直能获取到参数那就一直取,最后将整个数组都传回来即可
对于文件中的信息匹配的话,可能有两种情况,一种是纯字符串的替换,另一种是需要根据实际传入的参数来进行处理
对于第一种就没有什么操作了,直接写就可以了
AAAAAAAAA=balabala
对于第二种需要约定一个方案,以 $arg[x]
为例,如有有就说明想要从参数中来获取
AAAAAAAAA=$arg[0]
然后我们在遍历 Key 的时候,判断一下对应的 Value 是不是包含了这样的字符,如果存在的话,就说明需要进行对应的替换
这样就完成了对 DLL 的 Patch 处理操作
但是有个问题,这样岂不是只能直接替换明文在文件中了,刚开始我还在想该怎么去处理这样的问题,后来发现 cna 脚本有一些自带的处理方法能够便于我们进行一些其他的操作,比如 base64
、gzip
等等
虽然不多,但是也足够我们去做一些基本的处理了,这样我们就可以直接在 cna 脚本中来使用了
bjobinject(%options['bid'], "desc", "shortdesc", "test", "", 0, 0,%options["pid"], "config.prop", %options["arg1"]);
bjobinject(%options['bid'], "desc", "shortdesc", "test", "", 0, 0,%options["pid"], "config.prop", %options["arg0"], %options["arg1"],base64_encode(%options["arg2"]));
如果还想有其他的一些操作,去添加对应的方法,然后在 cna 脚本中直接调用就好了
-----文章到此结束,欢迎继续探讨-----
往 期 文 章
1. RDI 任务发布流程分析
2. RDI 任务执行流程分析
原文始发于微信公众号(信安成长计划):CobaltStrike逆向学习系列(番外篇)-自定义RDI功能添加
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论