JEE服务器端执行远程目标代码实现
2014-10-30 11:44
274 查看
相信不少开发员在测试环境时经常会遇到这类情形: 排查问题过程中,想查看内存运行详细参数,或定位运行环境一些问题,要处理这些问题,只能一次次地重新发布新的代码来作进一步调试,以排查确定问题。本文会向开发人员展示另一种简单的服务器调用执行远程目标Class的方法,以更高效地排查定位测试服务器问题。
一. 实现目标功能:
界面简介:
1. 在 "远程class地址" 栏位输入 目标需要执行的class地址
2. 点击"执行" 按钮,便会执行目标类,并将目标类的输出结果打印到页面。
二. 实现原理
1. 入口invokeRemoteClass.jsp页面
b). 将inputStream转化为byte[].
c). JavaClassExecuter.execute()方法通过SwapClassLoader将class 字节码加载到类加载器中,并执行。
2. HttpInputStreamUtil类示例
3. JavaClassExecuter 远程class执行类
4. SwapClassLoader类加载器
5. WebConsole 目标执行Class类与web之间的桥梁
6. 测试类TestRemotInvoke
注:
JEE服务器端执行远程目标代码功能不推荐在正式服务器使用,仅用于测试开发即可,否则会有安全问题。
本文章力图以最简单的方法实现服务器端远程执行目标代码,欢迎读者进一步进行功能扩展。
liantian.wu/吴炼钿
一. 实现目标功能:
界面简介:
1. 在 "远程class地址" 栏位输入 目标需要执行的class地址
2. 点击"执行" 按钮,便会执行目标类,并将目标类的输出结果打印到页面。
二. 实现原理
1. 入口invokeRemoteClass.jsp页面
<%@page import="java.io.FileInputStream,web.WebConsole,util.HttpInputStreamUtil,java.io.InputStream,loader.JavaClassExecuter"%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>远程调用类测试</title> </head> <body> <% String remoteClassUrl = request.getParameter("remoteClassUrl"); String result = ""; byte[] b = null; if(remoteClassUrl!=null){ try{ InputStream is = HttpInputStreamUtil.readInputStreamFromUrl(remoteClassUrl); b = new byte[is.available()]; is.read(b); result = JavaClassExecuter.execute(b); is.close(); }catch(Exception e){ result = e.getMessage(); } } %> <form action="invokeRemoteClass.jsp" method="post"> <fieldset> <legend>远程调用类信息:</legend> <table> <tr><td>远程class地址:</td><td><input size="100" name="remoteClassUrl" value="<%if(remoteClassUrl!=null){out.print(remoteClassUrl);}%>"/></td></tr> <tr><td>输出:</td><td><div><pre><%=result%></pre></div> </td></tr> <tr><td></td><td><input type="submit" value="执行"/></td></tr> </table> </fieldset> </form> </body> </html>a). 主要执行逻辑为通过HttpInputStreamUtil类读取目标执行类的InputStream
b). 将inputStream转化为byte[].
c). JavaClassExecuter.execute()方法通过SwapClassLoader将class 字节码加载到类加载器中,并执行。
2. HttpInputStreamUtil类示例
package util; import java.io.InputStream; import java.net.HttpURLConnection; import java.net.URL; /** * 根据url读取相应文件流 * @author wult * */ public class HttpInputStreamUtil { /** * 根据url,读取出其inputstream * @param classUrl * @return * @throws RuntimeException */ public static InputStream readInputStreamFromUrl(String classUrl) throws RuntimeException{ InputStream result = null; URL url = null; HttpURLConnection httpConn = null; try { url = new URL(classUrl); httpConn = (HttpURLConnection) url.openConnection(); httpConn.setRequestMethod("POST"); httpConn.connect(); int code = httpConn.getResponseCode(); if(code == 200){ result = httpConn.getInputStream(); } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } return result; } }
3. JavaClassExecuter 远程class执行类
package loader; import java.lang.reflect.Method; import web.WebConsole; /** * JavaClass执行工具 * @author wult * */ public class JavaClassExecuter { /** * 执行外部传过来的代表一个Java类的Byte数组 * @param classByte 代表一个Java类的Byte数组 * @return 执行结果 */ public static String execute(byte[] classByte) throws RuntimeException{ WebConsole.clean(); SwapClassLoader loader = new SwapClassLoader(); Class clazz = loader.loadByte(classByte); try { Method method = clazz.getMethod("main", new Class[] { String[].class }); method.invoke(null, new String[] { null }); } catch (Throwable e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } return WebConsole.getBufferString(); } }
4. SwapClassLoader类加载器
package loader; /** * 本加载器目的是为了满足重复载入类 * @author wult * */ public class SwapClassLoader extends ClassLoader{ public SwapClassLoader() { super(SwapClassLoader.class.getClassLoader()); } public Class loadByte(byte[] classByte){ return defineClass(null, classByte, 0,classByte.length); } }
5. WebConsole 目标执行Class类与web之间的桥梁
package web; /** * web控制台 * 作为目标执行Class类与web之间的桥梁 * @author wult * */ public class WebConsole { private static StringBuffer sb = new StringBuffer(); /** * 清除buffer */ public static void clean(){ sb.setLength(0); } /** * 打印信息 * @param line */ public static void println(String line){ sb.append(line); sb.append("\n"); } /** * 返回sb内容 * @return */ public static String getBufferString(){ return sb.toString(); } }
6. 测试类TestRemotInvoke
package test; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; import web.WebConsole; public class TestRemotInvoke { public static void main(String[] args) { MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean(); MemoryUsage usage = memorymbean.getHeapMemoryUsage(); WebConsole.println("JVM内存运行情况: "); WebConsole.println("初始的总内存: " + usage.getInit()/(1024*1024)+"MB"); WebConsole.println("最大可用内存: " + usage.getMax()/(1024*1024)+"MB"); WebConsole.println("已使用的内存: " + usage.getUsed()/(1024*1024)+"MB"); } }
注:
JEE服务器端执行远程目标代码功能不推荐在正式服务器使用,仅用于测试开发即可,否则会有安全问题。
本文章力图以最简单的方法实现服务器端远程执行目标代码,欢迎读者进一步进行功能扩展。
liantian.wu/吴炼钿
相关文章推荐
- 利用远程线程将代码注入到目标进程中执行
- 挖洞经验 | 看我如何综合利用4个漏洞实现GitHub Enterprise远程代码执行
- 挖洞姿势:特殊的上传技巧,绕过PHP图片转换实现远程代码执行(RCE)
- 利用远程线程将代码注入到目标进程中执行
- shell脚本实现同时多台远程主机执行命令的代码分享
- 远程线程模板(将执行代码写入目标进程)
- 看我如何利用Atom编辑器的漏洞实现远程代码执行
- linux expect实现登陆远程主机并执行命令示例代码
- python模块paramiko实现上传下载与远程执行命令的代码
- 服务器端Page.ClientScript.RegisterStartupScript实现弹窗,让用户确认后执行后面的代码,否则跳出
- Struts2远程代码执行漏洞检测的原理和代码级实现
- 挖洞姿势:特殊的上传技巧,绕过PHP图片转换实现远程代码执行(RCE)
- 阿里巴巴支付宝远程代码执行漏洞-0DAY
- (转)用.net实现远程获取其他网站页面内容!(核心代码分析)
- 关于模态对话框关闭之后继续执行服务器端代码的问题
- asp.net下模态对话框关闭之后继续执行服务器端代码的问题
- 用.net实现远程获取其他网站页面内容!(核心代码分析)
- 阿里巴巴支付宝远程代码执行漏洞-0DAY
- asp下实现替换远程文件为本地文件并保存远程文件的代码
- 用c#中实现的,调用cmd来执行bcp的代码