这次文章主要介绍下Cobalt Strike 4.1相关功能的二开和后门(artifact.exe\beacon.exe)的生成方式,Cobalt Strike的jar包我已反编译,并改了下反编译后的bug,teamserver与agressor均能正常调试使用,附反编译后项目地址: b28K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6E0j5h3V1I4P5X3S2A6x3W2)9J5c8V1y4G2j5X3q4D9N6s2y4@1M7X3W2C8k6g2y4G2N6i4u0U0k6b7`.`. 。若文章有不对的地方希望大伙指出,谢谢。后续将会再分享通讯协议与自定义客户端(后门)。PS:感谢Moriarty的分享课。
添加反射型Dll: 在default.can文件中添加自定义的菜单项,其中传入参数$1为beaconID:
在AggressorBridge.java的scriptLoaded()方法中增加自定义的dialog:
在evaluate()方法添加相应的事件处理,来打开自定义的对话框:
自定义的对话框的构造方法传入client和beaconID的数组,以便后续构造TaskBeacon实例,再调用TaskBeacon实例中新增的RDITest()方法,:
下图为在TaskBeacon.java中的TaskBeacon类中新增的RDITest(),在该方法中生成RDITestJob类对象并调用其spawn()方法:
所增加的RDITestJob类,该类继承Job类,并实现所需的虚函数,其中getDLLName()函数要返回所需dll的路径:
另外在该类中重写了父类的spawn()方法,因为父类的spawn()方法会调用decrypt()函数解密后相应的资源后再去读取,而我们的dll没有进行加密,所以直接读取即可: 测试运行:
先生成.Bof文件,这里以netstat功能为例子新建自定义的BOF类,并继承PostExInlineObject类,重写类中的getObjectFile()方法,该方法的作用是返回要加载的BOF文件路径:
其中在父类PostExInlineObject中的getFunction()方法可以修改BOF文件的入口方法名,不一定为go:
然后在TaskBeacon增加其BOF类的调用: 最后在自定义dialog中调用: 测试运行:
跟进show(),首先设置windows execute对话框里面的相应信息,其中DialogManager var1为窗口管理对象,再调用addDialogListener(this)将当前的窗口加入链表,然后调用它的action()方法:
跟入action()方法,里面再调用action_noclose()方法:
跟入action_noclose(),首先找到Generate的按钮,然后为其添加事件监听: 选择listener,点击Generate: 点击按钮后就新建线程,通过listeners2属性获得一个窗口迭代器,然后迭代窗口对象,调用该窗口对象所实现DialogListener接口中的dialogAction()方法: 因为WindowsExecutableDialog实现了DialogListener的接口: 即调用该类中的dialogAction()方法: 跟入getPayloadStager(),该方法主要负责生成相关的shellcode: 跟入 shellcode (),该方法三个参数分别为listener、payload名称、payload的位数: 继续跟入resolve(),判断传入的payload名称var2是否在系统自带的payload链表var4里: 返回相应payload 的GenericStager对象,并genericStager.generate()方法,该方法为主要shellcode的生成方法:首先传入"resources/httpstager.bin"路径通过CommUtils.resource()获得相关的shellcode: 先拼接了teamserver地址和端口号: 再回填EXIT_FUNK_PROCESS: 回填SkipOffset和isSSL 回填User-agent: 回填URI: 这里注意这个getURI()生成URI的函数,现在有网络空间测绘进行网络上的扫描,该生成的URI就是其主要特征,跟入这个函数: 因为GenericHTTPStagerX86是父类,看ForeignHTTPStagerX86子类里面的函数实现,里面调用了MSFURI(32),继续跟入: 这个函数是URI有大写字母+小写字母+数字组合而成,然后经过checksum()函数计算与92相等则成功生成,跟入checksum(): 在webserver端认证URI来下载beacon时也是通过checksum8()函数来认证:
最后函数执行完后返回shellcode,回到dialogAction()方法,后续判断需要生成的是exe还是dll,调用savefile()来保存,再在该函数中调用post(),里面新开线程,调用窗口对象的dialogResult()方法: 跟入dialogResult()方法,先获取了相关的信息: 根据信息调用patchArtifact()方法: 跟进patchArtifact(): 再跟进patchArtifact(),函数中主要调用_patchArtifact(),传入shellcode内容和相应文件名,先读取出在resources/中artfict32的内容: 再生成四个随机数放在数组var6中,然后将shellcode跟该数组进行异或处理后存放在var7: 在artfact.exe找到1024个‘A’的位置: 然后把相应的位置、异或所需的数组、异或后的shellcode内容及长度等信息填入var10: 然后把artfact32.exe的1024个’A’进行替换,并返回artfact32.exe内容: 接着把artfact32.exe内容传入fixChecksum()做校验和: 最后调用writetofile()把数据写入文件: 对比文件,1024个‘A’被替换成异或后的shellcode:
前面流程都一样,主要分析WindowsExecuteStageDialog.java 跟入getListener(),里面主要做配置信息: 再跟入new ScListener(): 先看DataUtils.getProfile(var1),主要获取c2profile通信设置: 再看DataUtils.getPublicKey(var1),获取pubkey的值:
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
顾何 666 好文,感谢分享!
挤蹭菌衣 菜鸟入门求鸡哥带[em_88][em_88]