文章为匿名投稿,该文章仅限提供思路,具体实现请自行研究使用。

文章内用到的代码源码 详见末尾


由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,文章作者不为此承担任何责任。

RedCode Team 拥有对此文章的修改和解释权如欲转载或传播此文章,必须保证此文章的完整性,包括版权声明等全部内容。未经作者允许,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。


CobaltStrike魔改与增强

写这篇文档的目的在于记录CS客户端和服务器的魔改过程,因为有些点随着时间的过去会逐渐淡忘,有这么一篇详实的魔改过程记录文档,无疑对团队和个人来说都是件益事。这篇文档将记录CS4.4版本的破解使用,特征消除,功能改造增强的实现过程。

第一部分-破解使用

网上已经有人公开了4.4版本的原版jar包和破解方法,见CobaltStrike 4.4原版+通用白嫖破解及汉化加载器[1]。对于别人的公开不便评论,原本这个版本的原版jar包应该在一个小圈子里流传,后面被传出来了,也无所谓,反正迟早都要发生的。4.4版本由于class之间有循环校验文件完整性,导致4.3及之前版本的暴力替换class文件的破解方法失效,于是有师傅用java agent注入的形式动态替换内存当中的license实现白嫖。这位师傅就是Twi1ight[2]。CSAgent实现了CS 4.X的通杀白嫖,实在牛逼,膜。

上面是CS4.4相关的有趣故事,接下来是如何使用破解补丁的具体过程。首先clone CSAgent[3]到本地,然后IDEA打开。等待IDEA完成项目加载后,点击右侧maven选项,先执行compile,再执行single打包,生成破解补丁jar包。

执行完成后,生成jar包。

接下来复制一份完整的cs 4.x的目录,重命名为cobaltstrike4.4,然后替换该目录下的cobaltstrike.jar为cs4.4的原版jar包。将上面生成的破解补丁复制到目录下,重命名为CSAgent.jar。

替换cobaltstrike、teamserver、agscript、c2lint、cobaltstrike.bat文件中的解密key,cs4.4版本替换后的文件可以从release的1.2版本中下载。

#!/bin/bash
#
# Start Cobalt Strike Aggressor Script
# 文件 agscriptjava -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -classpath ./cobaltstrike.jar -javaagent:CSAgent.jar=5e98194a01c6b48fa582a6a9fcbb92d6 -Duser.language=en aggressor.headless.Start $*
#!/bin/bash
#
# Check a Malleable C&C Profile
# 文件 c2lintjava -XX:ParallelGCThreads=4 -XX:+UseParallelGC -classpath ./cobaltstrike.jar -javaagent:CSAgent.jar=5e98194a01c6b48fa582a6a9fcbb92d6 -Duser.language=en c2profile.Lint $1
#!/bin/bash
#
# Start Cobalt Strike Client
# 文件 cobaltstrikejava -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -javaagent:CSAgent.jar=5e98194a01c6b48fa582a6a9fcbb92d6 -Duser.language=en -jar cobaltstrike.jar $*
; 文件 cobaltstrike.batjava -XX:ParallelGCThreads=4 -XX:+AggressiveHeap -XX:+UseParallelGC -javaagent:CSAgent.jar=5e98194a01c6b48fa582a6a9fcbb92d6 -Duser.language=en -jar cobaltstrike.jar
#!/bin/bash
#
# Start Cobalt Strike Team Server
# 文件 teamserver# make pretty looking messages (thanks Carlos)
function print_good () {echo -e "\x1B[01;32m[+]\x1B[0m $1"
}function print_error () {echo -e "\x1B[01;31m[-]\x1B[0m $1"
}function print_info () {echo -e "\x1B[01;34m[*]\x1B[0m $1"
}# check that we're r00t
if [ $UID -ne 0 ]; thenprint_error "Superuser privileges are required to run the team server"exit
fi# check if java is available...
if [ $(command -v java) ]; thentrue
elseprint_error "java is not in \$PATH"echo "    is Java installed?"exit
fi# check if keytool is available...
if [ $(command -v keytool) ]; thentrue
elseprint_error "keytool is not in \$PATH"echo "    install the Java Developer Kit"exit
fi# generate a certificate# naturally you're welcome to replace this step with your own permanent certificate.# just make sure you pass -Djavax.net.ssl.keyStore="/path/to/whatever" and# -Djavax.net.ssl.keyStorePassword="password" to java. This is used for setting up# an SSL server socket. Also, the SHA-1 digest of the first certificate in the store# is printed so users may have a chance to verify they're not being owned.
if [ -e ./cobaltstrike.store ]; thenprint_info "Will use existing X509 certificate and keystore (for SSL)"
elseprint_info "Generating X509 certificate and keystore (for SSL)"keytool -keystore ./cobaltstrike.store -storepass Microsoft -keypass Microsoft -genkey -keyalg RSA -alias cobaltstrike -dname "CN=*.microsoft.com, OU=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=WA, C=US"
fi# start the team server.
java -XX:ParallelGCThreads=4 -Dcobaltstrike.server_port=50050 -Dcobaltstrike.server_bindto=0.0.0.0 -Djavax.net.ssl.keyStore=./cobaltstrike.store -Djavax.net.ssl.keyStorePassword=Microsoft -server -XX:+AggressiveHeap -XX:+UseParallelGC -classpath ./cobaltstrike.jar -javaagent:CSAgent.jar=5e98194a01c6b48fa582a6a9fcbb92d6 -Duser.language=en server.TeamServer $*

现在已经破解完成,可以启动teamserver和client查看效果。

生成木马上线测试。

成功上线。

测试执行命令。

可开启汉化选项,复制CSAgent提供的resources和script目录到cs4.4的目录下,关闭客户端重新启动即可汉化。

第二部分-特征消除

逆向环境搭建

  • idea pro

  • java-decompiler

使用idea安装目录下的plugins/java-decompiler/lib/java-decompiler.jar文件反编译cobaltstrike.jar,反编译完成得到cs的java源码,需要注意的是,得到的源码是一个jar的压缩包,解压即可得到源码。

java -cp IDEA_HOME/plugins/java-decompiler/lib/java-decompiler.jar  org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler -dgs=true <src.jar> <dest dir>

接下来新建一个IDEA项目,jdk版本选择1.8。

下一步勾选Create Project from template.

创建完成项目之后,解压缩源码jar包中的代码到项目的src目录下。完成这些,初步的逆向分析环境就搭建好了。

teamserver登录接口

启动CS TeamServer的过程中,会看到其日志打印提示信息

[*] SHA256 hash of SSL cert is: d1a004dba75db4c313f6d6ce33181418112c4186a6cf1c58b4c12bf4a427ba46

可以通过前面的提示信息SHA256 hash of SSL cert is在代码中搜索,定位到TeamServer启动的位置(server/TeamServer/A)。

其中SecureServerSocket var4 = new SecureServerSocket(var3, this.port)这行代码正是简历TCP TLS监听的代码。var3是程序监听的IP地址,如果在启动teamserver时没有指定,那么默认监听绑定的地址就是0.0.0.0。代码接下来便是对新连接的客户端请求进行处理的过程(server/TeamServer/A)。

对于每个连接的客户端请求,都会调用acceptAndAuthenticate方法去验证身份(ssl/SecureServerSocket/acceptAndAuthenticate)。跟进这个方法,继续分析。

最终调用了authenticate方法对新创建的连接进行认证,第一个参数是连接的socket对象,第二个参数是当前服务端设置的连接密码,第三个参数的客户端的IP地址(ssl/SecureServerSocket/authenticate)。跟进该方法,继续分析。

首先从socket请求中读取4字节的int型变量。如果读取到的数据与48879相等,那么继续后面的处理过程,否则就直接返回false,身份认证失败,关闭客户端的连接。因此,我们这里可以修改这一字段的值,改为我们自定义的其他值,以避免teamserver口令爆破和指纹识别的风险

上面是teamserver端的处理过程,与之相对应的,客户端也有一段登录请求包的构造过程(ssl/SecureSocket/authenticate),在修改服务端的同时,也要修改客户端,才能在修改完成之后,正常的用户通过修改后的客户端登录。

设置连接密码为admin123,启动teamserver。使用网上开源的cs登录密码爆破脚本分别爆破修改前和修改后的teamserver。

修改前的teamserver被爆破出密码为admin123。

修改后的teamserver无法被爆破出密码。

使用修改后的客户端可正常登录TeamServer。

分段beacon下载路径特征

使用分段的木马上线,木马会请求一个随机URI路径下载第二阶段的beacon文件,这个beacon文件就是CS的控制功能所在。

根据网上师傅们分享的URI检测的代码所在位置(cloudstrike/WebServer/checksum8),按照师傅们提到的,修改这一部分的校验逻辑。

与之相对应,还需要修改另一处生成stager时获取URI的代码(common/CommonUtils/MSFURI)。

修改前手动下载beacon文件。

IDA中可打开查看shellcode内容。

修改后手动下载beacon文件。

生成默认的分段上线exe,执行上线成功。

64位程序上线成功。

另外还有一种方法,就是在不需要分段模式上线的时候kill掉管理站点下的stager,在需要的时候再开起来,这也是一种规避stager uri扫描的方法。

修改beacon配置信息的默认密钥

参考网上其他师傅公开的资料,beacon/BeaconPayload的beacon_obfuscate方法对beacon的配置信息进行了异或混淆,异或的key是固定的,3.x是0x69,4.x为0x2e。

这里的46的16进制就是0x2E。修改完服务端beacon的混淆密钥,与之对应,需要修改sleeve目录下的dll文件。这些DLL文件默认是加密的,使用ca3tie1[4]师傅开发的 **CrackSleeve[5]**程序解密这些DLL,在修改完密钥之后再加密回去即可。需要注意的是,在解密的时候需要将程序中默认的密钥改成4.4版本的。

其中以x64结尾的是64位文件,x86或者没有后缀名的为32位文件。使用IDA打开beacon.dll,搜索0x2e,找到之后修改成与服务端相同的密钥即可。

修改完成之后,选择Edit->Patch Program -> Apply patches to input file保存文件修改即可。类似的,其他dll文件也需要修改密钥。修改完成密钥之后,执行encode加密操作,重新将修改后的dll加密回去,然后替换原来jar包中的DLL文件即可。需要修改的文件有beacon、dnsb、extc2、pivot以及这些文件的x64版本。

注意,在替换jar包中的sleeve文件时,需要提前备份原来的文件,防止修改之后,出现错误,导致程序无法使用。

修改混淆密钥前,使用CobaltStrikeParser[6]解析beacon的配置信息。

修改混淆密钥后再次解析。

生成32位、64位的分段exe程序上线成功。

其他一些特征修改

•.cobaltstrike.beacon_keys和cobaltstrike.store这两个文件不要使用默认的文件,删除后生成新的。•profile文件要换新的,启动服务端时记得加载,或者直接把jar包里面的默认配置给改了•开在公网的teamserver不要使用默认端口

第三部分-改造增强

shellcode自定义

ShellCode开发框架参考自快乐鸡哥[7]师傅和鬼手[8]师傅,两位师傅YYDS。之所以参考两位师傅的,是因为快乐鸡哥师傅的shellcode框架里没有生成x64的,而鬼手师傅的代码里有64位的。

两位师傅写的代码搜索API的算法区别也比较大,笔者觉得这里应该参考快乐鸡哥师傅的。快乐鸡哥师傅的搜索算法是先定位函数所在DLL模块,再在模块内搜索,当调用函数较多时,这个方法效率比鬼手师傅的全局搜索效率要高,并且hash冲突的可能性也会比较低。

笔者的目标是先搜寻内存当中的DLL模块的基址,再从基址遍历导出表计算导出函数HASH并对比获取导出函数的内存地址。为了得到Shellcode,需要首先分别计算出DLL模块名称的HASH和导出函数的HASH。

将生成的HASH数据导出到文件中保存。接下来将上线的C代码写好,生成shellcode,分别上线测试。

32位ShellCode上线成功。

64位ShellCode上线成功。

接下来分析CS的ShellCode生成替换过程。首先定位到ShellCode生成过程代码入口(aggressor/dialogs/PayloadGeneratorDialog)。

首先判断格式,每个格式对应不同的语言代码模板。这里直接看原始的payload如何构造。

根据前端用户的选项选择payload架构和监听器,然后将选项传入getListener函数,返回后调用getPayloadStager函数,继续跟进分析。

getListener通过监听器的名字从全局注册的监听器中搜索,并返回监听器对象。跟进ScListener对象的getPayloadStager函数分析。

getPayloadStager直接调用了Stagers.shellcode函数,跟进。

shellcode是个单例方法,最终会调用Stagers的对象方法resolve根据选择的监听器类型生成GenericStager,再调用generate方法生成shellcode。

笔者这里自定义的ShellCode是reverse http,因此会进入GenericHTTPStagerX64和GenericHTTPStagerX86。

最终都会进入GenericHTTPStager的generate方法。

public byte[] generate() {try {// 获取stager模板文件InputStream var1 = CommonUtils.resource(this.getStagerFile());// 读取模板文件到内存byte[] var2 = CommonUtils.readAll(var1);String var3 = CommonUtils.bString(var2);var1.close();// 获取监听器的host信息,最后添加一个unicode的0结尾,放到模板代码的最后var3 = var3 + this.getListener().getStagerHost() + '\u0000';// 创建一个packer对象Packer var4 = new Packer();// 设置为小端字节序var4.little();// 添加监听器的端口var4.addShort(this.getListener().getPort());AssertUtils.TestPatchS(var2, 4444, this.getPortOffset());// 替换shelllcode模板中端口偏移处的信息var3 = CommonUtils.replaceAt(var3, CommonUtils.bString(var4.getBytes()), this.getPortOffset());var4 = new Packer();var4.little();// 设置exit代码var4.addInt(1453503984);AssertUtils.TestPatchI(var2, 1453503984, this.getExitOffset());var3 = CommonUtils.replaceAt(var3, CommonUtils.bString(var4.getBytes()), this.getExitOffset());var4 = new Packer();var4.little();var4.addShort(this.getStagePreamble());AssertUtils.TestPatchS(var2, 5555, this.getSkipOffset());var3 = CommonUtils.replaceAt(var3, CommonUtils.bString(var4.getBytes()), this.getSkipOffset());var4 = new Packer();var4.little();// 设置连接选项var4.addInt(this.getConnectionFlags());AssertUtils.TestPatchI(var2, this.isSSL() ? -2069876224 : -2074082816, this.getFlagsOffset());var3 = CommonUtils.replaceAt(var3, CommonUtils.bString(var4.getBytes()), this.getFlagsOffset());String var5;// 搜索303个X,搜索到的话,替换成headers信息if (CommonUtils.isin(CommonUtils.repeat("X", 303), var3)) {var5 = this.getConfig().pad(this.getHeaders() + '\u0000', 303);var3 = CommonUtils.replaceAt(var3, var5, var3.indexOf(CommonUtils.repeat("X", 127)));}// 搜索79个Y,然后替换成URIint var6 = var3.indexOf(CommonUtils.repeat("Y", 79), 0);var5 = this.getConfig().pad(this.getURI() + '\u0000', 79);var3 = CommonUtils.replaceAt(var3, var5, var6);// 最终在尾部添加水印信息后返回return CommonUtils.toBytes(var3 + this.getConfig().getWatermark());} catch (IOException var7) {MudgeSanity.logException("HttpStagerGeneric: " + this.getStagerFile(), var7, false);return new byte[0];}}

这里以32位shellcode为例,通过代码,模板文件为resources/httpstager.bin。在反编译jar包的源码中,找到该文件,用010Editor打开,再打开生成的shellcode文件,对比两者的差别。

第一处区别偏移是0xBF,十进制就是191,这个偏移正是GenericHTTPStagerX86类中定义的端口数据的偏移,teamserver监听端口为8088,16进制正是0x1f98,这里是小端存储,即981F。第三处区别的偏移是0x143,对比文件内容,正是替换Y的地方。前面是占位80字节的URI信息,后面是headers信息。

这里水印信息为499602D2。这些便是根据监听器配置生成的ShellCode数据。

经过上面的处理流程之后,最后通过common/CommonUtils.writeToFile将ShellCode直接写入文件。

写在最后

其实前面这些魔改只是做的表面功夫,真正到实战当中还是会被实力强的杀软秒杀,比如卡巴斯基等。遇到这些对手,需要让beacon和其他后渗透模块高度自定义,这里面涉及到很多方面,静态和行为都需要改造,所以单从魔改CS的客户端、服务端和控制端已经远远不够了,并且灵活度太低,参考快乐鸡哥师傅用C#重写的SharpBeacon(师傅YYDS)。另外,鉴于改造CS的客户端这么麻烦,不如在搞清楚CS的内部原理之后,在外部建设一个Stager生成服务,通过CS的配置动态生成各种语言版本的Stager,这样省去了通过Agent动态替换JAVA指令的麻烦,灵活度大大增加。

参考资料

•https://github.com/Twi1ight/CSAgent•https://github.com/ryanohoro/csbruter•https://mp.weixin.qq.com/s/HibtLfikI_0ezcLVCRxqaA•https://mp.weixin.qq.com/s/0MPM3bysJJYr5jbRnES_Vg•https://github.com/Sentinel-One/CobaltStrikeParser•https://github.com/CCob/BeaconEye•https://mp.weixin.qq.com/s/_gSPWVb1b-xuvhU6ynmw0Q•https://wbglil.gitbook.io/cobalt-strike/cobalt-strike-gong-ji-fang-yu/untitled-1•https://github.com/TonyChen56/ShellCodeFrame•https://gitee.com/stemmm/CobaltstrikeSource

References

[1] CobaltStrike 4.4原版+通用白嫖破解及汉化加载器: https://www.ddosi.org/cobaltstrike-4-4-csagent/
[2] Twi1ight: https://github.com/Twi1ight
[3] CSAgent: https://github.com/Twi1ight/CSAgent
[4] ca3tie1: https://github.com/ca3tie1
[5] CrackSleeve: https://github.com/ca3tie1/CrackSleeve
[6] CobaltStrikeParser: https://github.com/Sentinel-One/CobaltStrikeParser
[7] 快乐鸡哥: https://github.com/mai1zhi2
[8] 鬼手: https://github.com/TonyChen56


知识星球人员介绍

知识星球二维码

文章内用到的代码源码已同步更新在知识星球

CobaltStrike魔改与增强相关推荐

  1. Cobaltstrike 魔改需要改哪些

    1.上线的默认证书 2.生成出的shellcode 3.defender查杀截图 4.kaspersky 查杀shell运行 5.主动防御之--如何识别恶意Cobalt Strike服务器 6.关于C ...

  2. 魔改GPT自动写网文,速度一秒十字,还能给太监作品无限续更 | 开源

    博雯 发自 凹非寺 量子位 报道 | 公众号 QbitAI 如果一个人只看网文,那会写出来怎样的文字? 看了100G网文后,这个AI模型帮你试了一下. 先来一段自由创作: 乍眼看去很有内味,而且基本是 ...

  3. 【网络结构】小议如何跳出魔改网络结构的火坑

    公众号关注 "ML_NLP" 设为 "星标",重磅干货,第一时间送达! 机器学习算法与自然语言处理出品 @公众号原创专栏作者 纵横 知乎专栏 | 机器不学习 引 ...

  4. 用最简单的方式训练史上最强ResNet-50,性能超过魔改结构的ResNeSt

    近日,CMU 的研究人员在 arXiv 上放出了一份技术报告,介绍他们如何通过蒸馏(distillation)训练一个强大的小模型.所提出方法使用相同模型结构和输入图片大小的前提下,在 ImageNe ...

  5. 推荐!小议如何跳出魔改网络结构的火坑(完整版)

    点击我爱计算机视觉标星,更快获取CVML新技术 本文原载于知乎,已获作者授权转载,请勿二次转载, https://zhuanlan.zhihu.com/p/108838471 昨天发布过上半部分,不少 ...

  6. 苹果又魔改安卓?有人说,还不如看鸿蒙……

    ‍ ‍ 来源| 网易科技<态℃>栏目组 文|御柳 7天前,华为发布了面向未来万物互联的.全新的操作系统鸿蒙OS. 昨天,苹果更新了OS全家桶.然而,新功能升级却处处"似曾相识&q ...

  7. 联想魔改BIOS详细最优设置

    为什么我会买M710q 租的房子不大,而且我不太喜欢很大的塔式机箱,加上我也不玩 Steam 这些,所以非常迷你的电脑对我来说显得简直不要太棒了! 先前有一台 DeskMini 被我的好(sun)朋( ...

  8. 关于Typecho的主题魔改记录

    本站使用handsome主题魔改的折腾过程 本文记录博主在使用该款主题时进行的一系列魔改,也就是你现在看到的一系列效果 本站[http://www.cyz4531.top]使用的是handsome主题 ...

  9. 文本生成魔改方案汇总!

    文 | 三和厂妹 编 | zenRRan 文本生成是NLP中较难的点,应用场景多且广泛.本篇笔记录一下文本生成的应用场景和主流方案,主要是基础的学习汇总和解决方案的梳理,相关学习资料在文中有链接或者文 ...

最新文章

  1. SAP PP CS01使用ECR去创建BOM主数据,报错:System status: ECR is not yet approved.
  2. Python 字符串操作方法大全
  3. leetcode35 插入的位置
  4. Tensorboard详解(下篇)
  5. maven 集成 CXF
  6. Arm 与中国联通成功部署物联网设备管理平台解决方案
  7. 快速上手系列:传智播客Java基础笔记
  8. 浏览器渲染页面的原理及流程---------重绘与重排(回流)--优化
  9. Java多线程编程 深入详解
  10. 进销存设计之——进销存和财务软件的对接
  11. 国内 OA 办公自动化系统 现状
  12. 欲戴王冠,必承其重。
  13. 简析发送手机验证码原理
  14. 利用树制作的简易家谱
  15. 成都传智播客11月20日就业班开班啦
  16. 业界红包玩法与技术方案总结
  17. 自定义View | 仿QQ运动步数进度效果
  18. 人工智能的发展,主要经历哪几个阶段?
  19. 直流无刷电机仿真分析——基于simulink官方例程BLDC Speed Control
  20. ftp上传文件 严重文件传输错误

热门文章

  1. 神经网络基础知识第一章
  2. react-dom.development.js:6202 Unable to preventDefault inside passive event listener invocation 错误
  3. php+摩尔斯电码,如何在Symfony 3中使用PHP编码和解码摩尔斯电码(翻译摩尔斯电码)...
  4. 无忧无盘服务器内存,无忧无盘安装以及配置教材.doc
  5. 公式自动编号/居中对齐、插入脚注、文献引用等,让恼人的文章格式从此有据可循
  6. spring cloud 2020
  7. 用MATLAB对图形进行水平和垂直灰度投影
  8. 怎么用计算机算20次方,一个数的几次方怎么算,有简便方法吗?比如2的20次方,怎么算快?...
  9. Vin码/车架号OCr识别
  10. 红帽第四季度订阅的强劲增长 整体表现超预期