Cobalt Strike快乐星球
2022-7-12 23:50:28 Author: mp.weixin.qq.com(查看原文) 阅读量:144 收藏

前言

    感谢<<安全的矛与盾>>星球大佬让我白嫖了许多东西,知识、思路等等。没有这些白嫖,不可能完成快乐星球的构建。本人是一个脚本小子,大佬们轻喷。

快乐星球

Patch CVE-2021-36798

漏洞描述

image.png

漏洞影响范围

    CS <= 4.3

漏洞成因分析

    漏洞存在在beacon.BeaconC2.process_beacon_callback_decrypted中对beacon端发送过来的任务处理结果的长度进行判断,直接按照beacon端的结果进行分配内存,导致teamserver端崩溃。

image.png


    该函数为common.DataParser.readCountedBytes

image.png
image.png


    可以看到,readCountedBytes函数首先读取一个4字节的数据并转换为int类型,然后根据这个int类型的变量申请内存buffer用来读取接下来的数据,这里就存在一个问题,如果攻击者可以控制这个4字节的数据,就可以控制接下来申请的buffer的长度,从而导致teamserver端申请过大内存导致陷入僵死。

漏洞缓解方案

    之所以叫做缓解方案,是因为并没有真正的修复,而是对beacon行为进行了判断,限制如果是新session,拒绝其直接发送截屏和键盘记录的结果。之所以只对这俩分支进行判断,是因为只有这俩分支调用了readCountedBytes这个函数。判断的关键代码为denyFirstAttack。

image.png
private byte[] denyFirstAttack(String var1, DataInputStream var4, int var16) {
        byte[] var17;
        if (this.data.isNewSession(var1)) {
            this.getCheckinListener().output(BeaconOutput.Error(var1, "Dropped responses from session. Didn't expect " + var16 + " prior to first task."));
            CommonUtils.print_error("Dropped responses from session " + var1 + " [type: " + var16 + "] (no interaction with this session yet)");
            return null;
        }
        var17 = CommonUtils.readAll(var4);
        return var17;
    }

    data.isNewSession判断当前任务队列里,是否包含该session,如果没有,就直接发任务处理数据,那这里就存在问题。

image.png


    然后就是把这段判断放到截屏和键盘记录处理分支里面。

image.png
image.png

修复效果验证

    这里贴下4.3版本的验证效果。未修复前使用poc测试https://github.com/M-Kings/CVE-2021-36798

image.png
image.png


    可以看到直接把teamserver打宕机了。修改完后再测试,防护生效,teamserver没有崩溃。

image.png
image.png

Patch CVE-2022-23317

漏洞描述

image.png

漏洞影响范围

    CS <= 4.5

漏洞复现

beacon.http-get

image.png


beacon.http-post

image.png


stager

image.png


stager64

image.png

漏洞缓解方案

    对请求uri进行判断,不是/开头都直接返回400 Bad Request。具体修复位置在cloudstrike.WebServer._serce

image.png
if (!(uri.startsWith("/"))) {
    return this.processResponse(uri, method, header, param, falsenull,
         new Response("400 Bad Request""text/plain"""));
}

修复效果验证

beacon.http-get

image.png


beacon.http-post

image.png


stager

image.png


stager64

image.png

Bypass beacon-eye

绕过原理

image.png


    绕过原理这里简单记录下:cs在填充profile数据时,数据格式:x64为8字节+8字节,x86为4字节+4字节,前面的字节是数据长度类型,后面的字节是数据,由于数据长度类型这里只使用了一个字节,剩下7个或3个字节都为0。这个就是beaconEye的yara规则,据此绕过只需要把前面没用的字节设置为非0即可。

绕过BeaconEye

    IDA中打开beaconx64.dll,来到DLLMain,找到profile解析的函数,函数位置为sub_180018694。

image.png


    跟进该函数,首先申请profile数据所在堆内存块,然后赋值为0,这里可以对这个0进行修改,让他不为0,即可绕过beaconEye的yara规则。

image.png
image.png


    这里测试用mov edx, eax,其机器指令为89 C2,正好为2字节,经测试,使用mov edx, ebx patch,仍然会被检测到。

image.png
image.png


    patch之后,再看下反编译效果。

image.png


    没什么问题。x86的dll修改,可以改成push eax,1字节指令,原push 0是2字节,这样不会影响原指令长度。使用其他寄存器可能还会被检测到,这里测试eax的值不会被检测到。

image.png
image.png
image.png
image.png

    需要修改的DLL如下,修改位置和原理是类似的,不再赘述。
beacon.dll、beacon.x64.dll -- http listener的beacon
dnsb.dll、dnsb.x64.dll -- dns listener的beacon
extc2.dll、extc2.x64.dll -- external listener的beacon
pivot.dll、pivot.x64.dll -- bind tcp、smb listener的beacon

测试效果

    绕过前使用beaconeye扫描进程内存,成功发现beacon所在进程。

image.png


    在patch过beacon之后,再次进行测试,发现已无法找到beacon进程,成功绕过。

image.png

Modify xor key

    这个比较简单,就不多写了,记录下修改位置在beacon/BeaconPayload的beacon_obfuscate方法。

image.png

Modify team server authentication header

    这个比较简单,就不多写了,记录下修改位置在ssl/SecureServerSocket的authenticate方法和ssl/SecureSocket的authenticate方法。

image.png
image.png

Beauty UI

    这个比较简单,就不多写了,记录下修改位置在aggressor.Aggressor的A方法。

image.png

Bypass 360

    bypass 360核晶的思路借鉴星球大佬分享的一篇文章的思路,就是将DLL注入beacon所在进程执行。在CS 4.4版本需要对DLL导入表进行Patch,但在CS 4.5版本不需要,具体原因没有分析,原因是太菜了。。。
    这里需要对Java端进行修改,主要修改的地方是beacon/TaskBeacon.java,界面功能实现原理与下个小节的setchar类似。
Desktop command

image.png


logonpasswords command

image.png


hashdump command

image.png


printscreen command

image.png


screenshot command

image.png

Setchar

    思路来源于先知上深蓝实验室一篇文章,不得不说先知这个社区还是不错的。https://xz.aliyun.com/t/11055

出现问题

    首先按照原文给的思路,在增加了修改按钮和功能后确实可以修改BeaconEntry对象的chst属性数据,但是使用扫描工具扫描的输出结果还是乱码的。暂时陷入困局,这时候去看了下cs的注册编码的过程,发现了问题。

image.png


    调试teamserver端,在上图当中注册beacon对象编码信息处下断点,发现每次beacon callback回来都会经过process_beacon_metadata这个函数,也就是说每次都要重新生成BeaconEntry对象,这里生成的BeaconEntry对象会保存在teamserver端,与client端的BeaconEntry对象是不同的。由于每次都要从beacon的metadata里解析编码信息,就会导致每一次callback回来都是目标环境的编码,这就是只修改client chst属性的数据无法完成编码切换的原因。

修复过程

    只需要在每次注册编码信息前,判断当前BeaconID的编码有没有被修改就行,没有从全局维护的customCharsets中找到或者为空字符串,那就按照目标环境的编码进行注册,否则注册client自定义的编码数据。

实现效果

console设置命令: setchar [charset]

image.png


界面的下拉框选择

image.png
image.png


扫描输出UTF-8数据,显示正常

image.png

破解补丁

    此处省略1w字。

image.png

使用方法

    beacon的右键菜单中选择Soldier,Setchar可以设置返回数据的编码,EnableBypass360开启绕过核晶模式,DisableBypass360切换回一般模式。

image.png
image.png

下个版本

Last Soldier<Memory Evasion>

参考资料

https://www.sentinelone.com/labs/hotcobalt-new-cobalt-strike-dos-vulnerability-that-lets-you-halt-operations/https://github.com/Sentinel-One/CobaltStrikeParserhttps://hosch3n.github.io/2021/08/06/%E5%85%B3%E4%BA%8E%E4%BF%AE%E5%A4%8DHotcobalt%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%83%B3%E6%B3%95/https://github.com/M-Kings/CVE-2021-36798https://xz.aliyun.com/t/10832https://github.com/CCob/BeaconEyehttps://donghuangt1.com/writings/Stager/


文章来源: http://mp.weixin.qq.com/s?__biz=MzU5NTg1NzIzNg==&mid=2247484007&idx=1&sn=8ba1369043e1f4d25a86651c69c75f3b&chksm=fe6ad85cc91d514a3898fb03d203c6865091c7b6c689c77240d6db0f7cad2a8674a01333cf40&mpshare=1&scene=1&srcid=0712bBnCnBN4Xvp7HsqWCnkM&sharer_sharetime=1657641023466&sharer_shareid=205c037363a9188e37dfb6bb4436f95b#rd
如有侵权请联系:admin#unsafe.sh