吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 16275|回复: 18
收起左侧

[PC样本分析] 魔改CobaltStrike:二开及后门生成分析

  [复制链接]
mai1zhi2 发表于 2021-2-21 10:04
使用论坛附件上传样本压缩包时必须使用压缩密码保护,压缩密码:52pojie,否则会导致论坛被杀毒软件等误报,论坛有权随时删除相关附件和帖子!
病毒分析分区附件样本、网址谨慎下载点击,可能对计算机产生破坏,仅供安全人员在法律允许范围内研究,禁止非法用途!
禁止求非法渗透测试、非法网络攻击、获取隐私等违法内容,即使对方是非法内容,也应向警方求助!
本帖最后由 mai1zhi2 于 2021-3-19 21:05 编辑

一、概述:
这次文章主要介绍下Cobalt Strike 4.1相关功能的二开和后门(artifact.exe\beacon.exe)的生成方式,Cobalt Strike的jar包我已反编译,并改了下反编译后的bug,teamserver与agressor均能正常调试使用,附反编译后项目地址: https://github.com/mai1zhi2/CobaltstrikeSource。若有不对的地方希望大伙指出,谢谢。后续将会再分享通讯协议与自定义客户端(后门)。PS:感谢Moriarty的分享课。
二、常用二开的方式:
2.1RDI,反射型DLL注入
添加反射型Dll:
在default.can文件中添加自定义的菜单项,其中传入参数$1为beaconID:
1.png

在AggressorBridge.java的scriptLoaded()方法中增加自定义的dialog:
2.png

在evaluate()方法添加相应的事件处理,来打开自定义的对话框:
3.png

自定义的对话框的构造方法传入client和beaconID的数组,以便后续构造TaskBeacon实例,再调用TaskBeacon实例中新增的RDITest()方法,:
4.png
下图为在TaskBeacon.java中的TaskBeacon类中新增的RDITest(),在该方法中生成RDITestJob类对象并调用其spawn()方法:
5.png
所增加的RDITestJob类,该类继承Job类,并实现所需的虚函数,其中getDLLName()函数要返回所需dll的路径:
6.png
8.png
另外在该类中重写了父类的spawn()方法,因为父类的spawn()方法会调用decrypt()函数解密后相应的资源后再去读取,而我们的dll没有进行加密,所以直接读取即可:
9.png
测试运行:
10.png
11.png
2.2 BOF,Beacon Object File,加载运行obj File
先生成 bof文件,这里以netstat功能为例子
新建自定义的BOF类,并继承PostExInlineObject类,重写类中的getObjectFile()方法,该方法的作用是返回要加载的BOF文件路径:
12.png

其中在父类PostExInlineObject中的getFunction()方法可以修改BOF文件的入口方法名,不一定为go:
13.png
然后在TaskBeacon增加其BOF类的调用:
14.png

最后在自定义dialog中调用:
15.png
测试运行:
16.png

三、简介相关后门的生成:
3.1、stager(artifact.exe)
17.png

跟进show(),首先设置windowsexecute对话框里面的相应信息,其中DialogManager var1为窗口管理对象,再调用addDialogListener(this)将当前的窗口加入链表,然后调用它的action()方法:
18.png
跟入action()方法,里面再调用action_noclose()方法:
19.png
跟入action_noclose(),首先找到Generate的按钮,然后为其添加事件监听:
20.png

选择listener,点击Generate:
21.png
点击按钮后就新建线程,通过listeners2属性获得一个窗口迭代器,然后迭代窗口对象,调用该窗口对象所实现DialogListener接口中的dialogAction()方法:
22.png

因为WindowsExecutableDialog实现了DialogListener的接口:
23.png
即调用该类中的dialogAction()方法:
24.png

跟入getPayloadStager(),该方法主要负责生成相关的shellcode:
25.png

跟入 shellcode (),该方法三个参数分别为listener、payload名称、payload的位数:
26.png
继续跟入resolve(),判断传入的payload名称var2是否在系统自带的payload链表var4里:
27.png
返回相应payload 的GenericStager对象,并genericStager.generate()方法,该方法为主要shellcode的生成方法:首先传入"resources/httpstager.bin"路径通过CommUtils.resource()获得相关的shellcode:
28.png 先拼接了teamserver地址和端口号:
29.png

30.png
31.png
再回填EXIT_FUNK_PROCESS:
32.png
33.png
回填SkipOffset和isSSL
34.png

回填User-agent:
35.png
回填URI:
36.png
这里注意这个getURI()生成URI的函数,现在有网络空间测绘进行网络上的扫描,该生成的URI就是其主要特征,跟入这个函数:
82.png
因为GenericHTTPStagerX86是父类,看ForeignHTTPStagerX86子类里面的函数实现,里面调用了MSFURI(32),继续跟入: 83.png 这个函数是URI有大写字母+小写字母+数字组合而成,然后经过checksum()函数计算与92相等则成功生成,跟入checksum(): 84.png

在webserver端认证URI来下载beacon时也是通过checksum8()函数来认证:
85.png

86.png 最后函数执行完后返回shellcode,回到dialogAction()方法,后续判断需要生成的是exe还是dll,调用savefile()来保存,再在该函数中调用post(),里面新开线程,调用窗口对象的dialogResult()方法: 37.png
跟入dialogResult()方法,先获取了相关的信息:
38.png
根据信息调用patchArtifact()方法:
39.png
跟进patchArtifact():
40.png
再跟进patchArtifact(),函数中主要调用_patchArtifact(),传入shellcode内容和相应文件名,先读取出在resources/中artfict32的内容:
41.png

再生成四个随机数放在数组var6中,然后将shellcode跟该数组进行异或处理后存放在var7:
42.png
在artfact.exe找到1024个‘A’的位置:
43.png

44.png
然后把相应的位置、异或所需的数组、异或后的shellcode内容及长度等信息填入var10:
45.png
然后把artfact32.exe的1024个’A’进行替换,并返回artfact32.exe内容:
46.png
接着把artfact32.exe内容传入fixChecksum()做校验和:
47.png

最后调用writetofile()把数据写入文件:
481.png
482.png

对比文件,1024个‘A’被替换成异或后的shellcode:
48.png
生成Stage(Beacon.exe)分析:
49.png

前面流程都一样,主要分析WindowsExecuteStageDialog.java
50.png
跟入getListener(),里面主要做配置信息:
51.png
再跟入new ScListener():
52.png
先看DataUtils.getProfile(var1),主要获取c2profile通信设置:
53.png
54.png
再看DataUtils.getPublicKey(var1),获取pubkey的值:
55.png
56.png
返回listener var4后,调用var4的export()方法,跟入,函数里判断payload的类型:
57.png
58.png
获得相关host和port后调用exportBeaconStageHTTP():
59.png
再跟入exportBeaconStage(),先获得当前的系统时间,然后读取resource/beacon.dll:
60.png
跟入readResource(String s),先把resource/替换成sleeve/,然后调用decrypt()解密读取到的相应资源:
61.png
跟入decrypt(),里面做相应的解密处理,先分别获取内容0到length-16的字节存入var2和length-16到length的字节存入var3:
62.png
计算var2的消息摘要:
63.png
取消息摘要的前16位与var3对比,相等则执行do_decrypt()解密操作:
64.png
然后读出数组的长度,跟进长度申请空间,再存入空间并返回:
65.png
接着后面读取c2配置文件的规则信息user-agent、sleep间隔、dns配置等:
66.png
67.png
注意:这里传入RSA的pubKey,用后续AES密钥传递通信:
68.png
把信息传入beacon_obfuscate()进行异或处理后,回填到解密后内容的"AAAABBBBCCCCDDDDEEEEFFFF"的位置,并返回:
69.png
返回后的内容传入process(),里面有前后两个处理pe文件的方法:
70.png
先跟进pre_process(),首先调用string()方法,传入pe内容即var1:
71.png
跟入string(),函数主要是读取默认配置文件default.profile里面的stage内容:
72.png
73.png
再获取配置文件stage标签里的image_size、entrypoint等基本信息,再进行设置:
74.png
75.png
跟入post_process(),主要判断生成的Beacon位数,然后修改其里面的DOS头,作为RDI调用:
76.png
硬编码修改DOS头,其中var1为需要跳转执行方法的位置:
77.png

78.png

返回修改好的内容,至此export()方法执行完毕,后续根据是否生成x64位程序和是否为.exe\.dll去修改。
81.png
跟入patchArtifact():
481.png
再跟入_patchArtifact():
482.png
可见后面所调用的方法作用均与上面stager一致,不再赘述。

谢谢大家观看。祝大家新春快乐。

7.png
17_1.png

免费评分

参与人数 20吾爱币 +21 热心值 +20 收起 理由
wisejay + 1 + 1 我很赞同!
crisislal + 1 + 1 我很赞同!
timego + 1 我很赞同!
jilley409 + 1 + 1 就是需要这种带逻辑过程的教程,才能让小白细细琢磨,加油~~!!
s1mple. + 1 + 1 用心讨论,共获提升!
CXM~ + 1 + 1 鼓励转贴优秀软件安全工具和文档!
努力加载中 + 1 + 1 谢谢@Thanks!
alpt6285 + 1 + 1 用心讨论,共获提升!
zsq + 1 + 1 谢谢@Thanks!
L1ngFeng + 1 + 1 谢谢@Thanks!
着迷59 + 1 + 1 谢谢@Thanks!
boy666 + 1 + 1 谢谢@Thanks!
antiol + 3 + 1 我很赞同!
By丿安之若素 + 1 + 1 用心讨论,共获提升!
legendary666 + 1 + 1 我很赞同!
寒枫雨雪 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
魔道书生 + 2 + 1 打开 拉到评分 评分666 关闭 感觉又进步了
woshicp + 1 + 1 热心回复!
xqmyuliyue + 1 谢谢@Thanks!
okgjkk + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

okgjkk 发表于 2021-2-21 10:28
很详细  很牛  适合我这种小白学习
junmajun 发表于 2021-2-21 14:06
whngomj 发表于 2021-2-22 07:51
江男 发表于 2021-2-22 11:12
学习了,感谢大神分享~~~
louchen94 发表于 2021-3-4 10:58
感谢大神分享
孤客浮舟 发表于 2021-3-4 13:57
这帖子竟然不火
ht4266394 发表于 2021-3-5 11:12
大佬啊,写的好详细,感谢大佬的奉献
纯洁小白 发表于 2021-3-8 09:39
楼主功力深厚 有耐心走完一遍逻辑代码
忆秋暝枫 发表于 2021-3-11 09:05
这么详细,学习了,感谢分享
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-11-15 11:52

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表