冰蝎流程图如下:
冰蝎是先请求服务端,服务端判断请求之后生成一个128位的随机数,并将这个128位的随机数写入到session里面,并将这个128位的随机数返回给客户端,但是客户端并不会使用这个key作为之后的通讯的key,而是会继续重复上面过程,不断获取key,直到满足特定条件之后,才会确定是最终的key。客户端会保存这个key和响应报文里面的set-cookie的值。这个key就是之后客户端和服务端进行通讯的密匙。
获取key和保存cookie之后,获取服务端信息,执行命令,文件操作,数据库操作等都是使用这个key和cookie进行操作,对执行的代码动态生成class字节数组,然后使用key进行aes加密,再进行base64编码,并用post方式发送数据。接收服务端返回的数据时,先使用key进行解密,解密之后的数据一般是使用了base64编码,解码之后就可以获取服务端返回的明文数据。
反编译Behinder.jar包,其核心代码在net.rebeyond.behinder包内
冰蝎的原理为上传一个class字节码,通过调用classloader的defineClass方法,将class字节码,转换为Class。实例化上传的这个类,通过equal方法传递PageContext。获取到PageContext,间接获取到Request、Response、Seesion等对象。如HttpServletRequest request=(HttpServletRequest) pageContext.getRequest()
其核心部分是协商密钥getKeyAndCookie
客户端打开和服务端的连接之后,会先调用BasicInfoUtils类,在BasicInfoUtils类的getBasicInfo方法里,会调用ShellService的构造方法新建ShellService类。而在ShellService类里面的构造方法,会调用Utils的getKeyAndCookie方法。
Utils.getKeyAndCookie方法:
public static Map<String, String> getKeyAndCookie(String getUrl, String password, Map<String, String> requestHeaders) throws Exception {
disableSslVerification();
Map<String, String> result = new HashMap();
StringBuffer sb = new StringBuffer();
InputStreamReader isr = null;
BufferedReader br = null;
URL u