java内存马查杀工具
java-memshell-scanner:扫描java内存马
<%@ page import="java.net.URL" %>
<%@ page import="java.lang.reflect.Field" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="com.sun.org.apache.bcel.internal.Repository" %>
<%@ page import="java.net.URLEncoder" %>
<%@ page import="java.util.Map" %>
<%@ page import="org.apache.catalina.core.StandardWrapper" %>
<%@ page import="java.lang.reflect.Method" %>
<%@ page import="java.util.ArrayList" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.concurrent.CopyOnWriteArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head><title>tomcat-memshell-killer</title>
</head>
<body>
<center><div><%!public Object getStandardContext(HttpServletRequest request) throws NoSuchFieldException, IllegalAccessException {Object context = request.getSession().getServletContext();Field _context = context.getClass().getDeclaredField("context");_context.setAccessible(true);Object appContext = _context.get(context);Field __context = appContext.getClass().getDeclaredField("context");__context.setAccessible(true);Object standardContext = __context.get(appContext);return standardContext;}public HashMap<String, Object> getFilterConfig(HttpServletRequest request) throws Exception {Object standardContext = getStandardContext(request);Field _filterConfigs = standardContext.getClass().getDeclaredField("filterConfigs");_filterConfigs.setAccessible(true);HashMap<String, Object> filterConfigs = (HashMap<String, Object>) _filterConfigs.get(standardContext);return filterConfigs;}// FilterMap[]public Object[] getFilterMaps(HttpServletRequest request) throws Exception {Object standardContext = getStandardContext(request);Field _filterMaps = standardContext.getClass().getDeclaredField("filterMaps");_filterMaps.setAccessible(true);Object filterMaps = _filterMaps.get(standardContext);Object[] filterArray = null;try { // tomcat 789Field _array = filterMaps.getClass().getDeclaredField("array");_array.setAccessible(true);filterArray = (Object[]) _array.get(filterMaps);} catch (Exception e) { // tomcat 6filterArray = (Object[]) filterMaps;}return filterArray;}/*** 遗留问题,getFilterConfig()依然存在2个* @param request* @param filterName* @throws Exception*/public synchronized void deleteFilter(HttpServletRequest request, String filterName) throws Exception {Object standardContext = getStandardContext(request);// org.apache.catalina.core.StandardContext#removeFilterDefHashMap<String, Object> filterConfig = getFilterConfig(request);Object appFilterConfig = filterConfig.get(filterName);Field _filterDef = appFilterConfig.getClass().getDeclaredField("filterDef");_filterDef.setAccessible(true);Object filterDef = _filterDef.get(appFilterConfig);Class clsFilterDef = null;try {// Tomcat 8clsFilterDef = Class.forName("org.apache.tomcat.util.descriptor.web.FilterDef");} catch (Exception e) {// Tomcat 7clsFilterDef = Class.forName("org.apache.catalina.deploy.FilterDef");}Method removeFilterDef = standardContext.getClass().getDeclaredMethod("removeFilterDef", new Class[]{clsFilterDef});removeFilterDef.setAccessible(true);removeFilterDef.invoke(standardContext, filterDef);// org.apache.catalina.core.StandardContext#removeFilterMapClass clsFilterMap = null;try {// Tomcat 8clsFilterMap = Class.forName("org.apache.tomcat.util.descriptor.web.FilterMap");} catch (Exception e) {// Tomcat 7clsFilterMap = Class.forName("org.apache.catalina.deploy.FilterMap");}Object[] filterMaps = getFilterMaps(request);for (Object filterMap : filterMaps) {Field _filterName = filterMap.getClass().getDeclaredField("filterName");_filterName.setAccessible(true);String filterName0 = (String) _filterName.get(filterMap);if (filterName0.equals(filterName)) {Method removeFilterMap = standardContext.getClass().getDeclaredMethod("removeFilterMap", new Class[]{clsFilterMap});removeFilterDef.setAccessible(true);removeFilterMap.invoke(standardContext, filterMap);}}}public synchronized void deleteServlet(HttpServletRequest request, String servletName) throws Exception {HashMap<String, Object> childs = getChildren(request);Object objChild = childs.get(servletName);String urlPattern = null;HashMap<String, String> servletMaps = getServletMaps(request);for (Map.Entry<String, String> servletMap : servletMaps.entrySet()) {if (servletMap.getValue().equals(servletName)) {urlPattern = servletMap.getKey();break;}}if (urlPattern != null) {// 反射调用 org.apache.catalina.core.StandardContext#removeServletMappingObject standardContext = getStandardContext(request);Method removeServletMapping = standardContext.getClass().getDeclaredMethod("removeServletMapping", new Class[]{String.class});removeServletMapping.setAccessible(true);removeServletMapping.invoke(standardContext, urlPattern);// Tomcat 6必须removeChild 789可以不用// 反射调用 org.apache.catalina.core.StandardContext#removeChildMethod removeChild = standardContext.getClass().getDeclaredMethod("removeChild", new Class[]{org.apache.catalina.Container.class});removeChild.setAccessible(true);removeChild.invoke(standardContext, objChild);}}public synchronized HashMap<String, Object> getChildren(HttpServletRequest request) throws Exception {Object standardContext = getStandardContext(request);Field _children = standardContext.getClass().getSuperclass().getDeclaredField("children");_children.setAccessible(true);HashMap<String, Object> children = (HashMap<String, Object>) _children.get(standardContext);return children;}public synchronized HashMap<String, String> getServletMaps(HttpServletRequest request) throws Exception {Object standardContext = getStandardContext(request);Field _servletMappings = standardContext.getClass().getDeclaredField("servletMappings");_servletMappings.setAccessible(true);HashMap<String, String> servletMappings = (HashMap<String, String>) _servletMappings.get(standardContext);return servletMappings;}public synchronized List<Object> getListenerList(HttpServletRequest request) throws Exception {Object standardContext = getStandardContext(request);Field _listenersList = standardContext.getClass().getDeclaredField("applicationEventListenersList");_listenersList.setAccessible(true);List<Object> listenerList = (CopyOnWriteArrayList) _listenersList.get(standardContext);return listenerList;}public String getFilterName(Object filterMap) throws Exception {Method getFilterName = filterMap.getClass().getDeclaredMethod("getFilterName");getFilterName.setAccessible(true);return (String) getFilterName.invoke(filterMap, null);}public String[] getURLPatterns(Object filterMap) throws Exception {Method getFilterName = filterMap.getClass().getDeclaredMethod("getURLPatterns");getFilterName.setAccessible(true);return (String[]) getFilterName.invoke(filterMap, null);}String classFileIsExists(Class clazz) {if (clazz == null) {return "class is null";}String className = clazz.getName();String classNamePath = className.replace(".", "/") + ".class";URL is = clazz.getClassLoader().getResource(classNamePath);if (is == null) {return "在磁盘上没有对应class文件,可能是内存马";} else {return is.getPath();}}String arrayToString(String[] str) {String res = "[";for (String s : str) {res += String.format("%s,", s);}res = res.substring(0, res.length() - 1);res += "]";return res;}%><%out.write("<h2>Tomcat memshell scanner 0.1.0</h2>");String action = request.getParameter("action");String filterName = request.getParameter("filterName");String servletName = request.getParameter("servletName");String className = request.getParameter("className");if (action != null && action.equals("kill") && filterName != null) {deleteFilter(request, filterName);} else if (action != null && action.equals("kill") && servletName != null) {deleteServlet(request, servletName);} else if (action != null && action.equals("dump") && className != null) {byte[] classBytes = Repository.lookupClass(Class.forName(className)).getBytes();response.addHeader("content-Type", "application/octet-stream");String filename = Class.forName(className).getSimpleName() + ".class";String agent = request.getHeader("User-Agent");if (agent.toLowerCase().indexOf("chrome") > 0) {response.addHeader("content-Disposition", "attachment;filename=" + new String(filename.getBytes("UTF-8"), "ISO8859-1"));} else {response.addHeader("content-Disposition", "attachment;filename=" + URLEncoder.encode(filename, "UTF-8"));}ServletOutputStream outDumper = response.getOutputStream();outDumper.write(classBytes, 0, classBytes.length);outDumper.close();} else {// Scan filterout.write("<h4>Filter scan result</h4>");out.write("<table border=\"1\" cellspacing=\"0\" width=\"95%\" style=\"table-layout:fixed;word-break:break-all;background:#f2f2f2\">\n" +" <thead>\n" +" <th width=\"5%\">ID</th>\n" +" <th width=\"10%\">Filter name</th>\n" +" <th width=\"10%\">Patern</th>\n" +" <th width=\"20%\">Filter class</th>\n" +" <th width=\"20%\">Filter classLoader</th>\n" +" <th width=\"25%\">Filter class file path</th>\n" +" <th width=\"5%\">dump class</th>\n" +" <th width=\"5%\">kill</th>\n" +" </thead>\n" +" <tbody>");HashMap<String, Object> filterConfigs = getFilterConfig(request);Object[] filterMaps1 = getFilterMaps(request);for (int i = 0; i < filterMaps1.length; i++) {out.write("<tr>");Object fm = filterMaps1[i];Object appFilterConfig = filterConfigs.get(getFilterName(fm));if (appFilterConfig == null) {continue;}Field _filter = appFilterConfig.getClass().getDeclaredField("filter");_filter.setAccessible(true);Object filter = _filter.get(appFilterConfig);String filterClassName = filter.getClass().getName();String filterClassLoaderName = filter.getClass().getClassLoader().getClass().getName();// ID Filtername 匹配路径 className classLoader 是否存在file dump killout.write(String.format("<td style=\"text-align:center\">%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td style=\"text-align:center\"><a href=\"?action=dump&className=%s\">dump</a></td><td style=\"text-align:center\"><a href=\"?action=kill&filterName=%s\">kill</a></td>", i + 1, getFilterName(fm), arrayToString(getURLPatterns(fm)), filterClassName, filterClassLoaderName, classFileIsExists(filter.getClass()), filterClassName, getFilterName(fm)));out.write("</tr>");}out.write("</tbody></table>");// Scan servletout.write("<h4>Servlet scan result</h4>");out.write("<table border=\"1\" cellspacing=\"0\" width=\"95%\" style=\"table-layout:fixed;word-break:break-all;background:#f2f2f2\">\n" +" <thead>\n" +" <th width=\"5%\">ID</th>\n" +" <th width=\"10%\">Servlet name</th>\n" +" <th width=\"10%\">Patern</th>\n" +" <th width=\"20%\">Servlet class</th>\n" +" <th width=\"20%\">Servlet classLoader</th>\n" +" <th width=\"25%\">Servlet class file path</th>\n" +" <th width=\"5%\">dump class</th>\n" +" <th width=\"5%\">kill</th>\n" +" </thead>\n" +" <tbody>");HashMap<String, Object> children = getChildren(request);Map<String, String> servletMappings = getServletMaps(request);int servletId = 0;for (Map.Entry<String, String> map : servletMappings.entrySet()) {String servletMapPath = map.getKey();String servletName1 = map.getValue();StandardWrapper wrapper = (StandardWrapper) children.get(servletName1);Class servletClass = null;try {servletClass = Class.forName(wrapper.getServletClass());} catch (Exception e) {Object servlet = wrapper.getServlet();if (servlet != null) {servletClass = servlet.getClass();}}if (servletClass != null) {out.write("<tr>");String servletClassName = servletClass.getName();String servletClassLoaderName = null;try {servletClassLoaderName = servletClass.getClassLoader().getClass().getName();} catch (Exception e) {}out.write(String.format("<td style=\"text-align:center\">%d</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td>%s</td><td style=\"text-align:center\"><a href=\"?action=dump&className=%s\">dump</a></td><td style=\"text-align:center\"><a href=\"?action=kill&servletName=%s\">kill</a></td>", servletId + 1, servletName1, servletMapPath, servletClassName, servletClassLoaderName, classFileIsExists(servletClass), servletClassName, servletName1));out.write("</tr>");}servletId++;}out.write("</tbody></table>");List<Object> listeners = getListenerList(request);if (listeners == null || listeners.size() == 0) {return;}out.write("<tbody>");List<ServletRequestListener> newListeners = new ArrayList<>();for (Object o : listeners) {if (o instanceof ServletRequestListener) {newListeners.add((ServletRequestListener) o);}}// Scan listenerout.write("<h4>Listener scan result</h4>");out.write("<table border=\"1\" cellspacing=\"0\" width=\"95%\" style=\"table-layout:fixed;word-break:break-all;background:#f2f2f2\">\n" +" <thead>\n" +" <th width=\"5%\">ID</th>\n" +" <th width=\"20%\">Listener class</th>\n" +" <th width=\"30%\">Listener classLoader</th>\n" +" <th width=\"35%\">Listener class file path</th>\n" +" <th width=\"5%\">dump class</th>\n" +" <th width=\"5%\">kill</th>\n" +" </thead>\n" +" <tbody>");int index = 0;for (ServletRequestListener listener : newListeners) {out.write("<tr>");out.write(String.format("<td style=\"text-align:center\">%d</td><td>%s</td><td>%s</td><td>%s</td><td style=\"text-align:center\"><a href=\"?action=dump&className=%s\">dump</a></td><td style=\"text-align:center\"><a href=\"?action=kill&servletName=%s\">kill</a></td>", index + 1, listener.getClass().getName(), listener.getClass().getClassLoader(), classFileIsExists(listener.getClass()), listener.getClass().getName(), listener.getClass().getName()));out.write("</tr>");index++;}out.write("</tbody></table>");}%></div><br/>code by c0ny1
</center>
</body>
</html>
java内存马查杀工具相关推荐
- Java内存马查杀GUI工具
注意:请勿在生产环境使用,存在打崩业务的风险,目前适用于自己搭建靶机分析学习 功能: 关于Java Web内存马查杀的文章和工具已经有不少,不过大都不够完善,各有缺点:于是我做了一款GUI版本的实时内 ...
- 内存马查杀工具FindShell试用
首先使用冰蝎创建一个内存马 成功进入内存马界面 接下来尝试使用findshell查杀,项目主页为 https://github.com/4ra1n/FindShell 服务器上首先部署代码,执行 gi ...
- 【应急响应】网站入侵篡改指南Webshell内存马查杀漏洞排查时间分析
网站入侵篡改指南&Webshell内存马查杀&漏洞排查&时间分析 章节内容点: IIS&.NET-注入-基于时间配合日志分析 Apache&PHP-漏洞-基于漏 ...
- 内存马查杀copagent研究
项目简介 copagent主要用于内存马查杀. 项目编译 1.生成agent.jar 2.将其拷贝进入cop的resources文件夹中 3.生成cop.jar 将刚才的agent.jar,拷贝到re ...
- 应急响应 -162天:webshell和内存马查杀
首要任务: 获取当前WEB环境的组成架构(语言,数据库,中间件,系统等) #IIS&.NET-注入-基于时间配合日志分析 背景交代:某公司在某个时间发现网站出现篡改或异常 应急人员:通过时间节 ...
- 初识Java内存马检测
近些年,无文件攻击技术越来越流行.本文旨在介绍无文件攻击中最为流行的一种技术--Java内存马,让企业.用户了解和重视其危害性,提高防范意识,降低安全风险. - 全文约1500字,预计阅读时间为4分钟 ...
- Java内存马攻防实战——攻击基础篇
在红蓝对抗中,攻击方广泛应用webshell等技术在防守方提供的服务中植入后门,防守方也发展出各种技术来应对攻击,传统的落地型webshell很容易被攻击方检测和绞杀.而内存马技术则是通过在运行的 ...
- dll 源码_【技术分享】 | 一个JAVA内存马的源码分析
前言 偶然接触到了这样一个JAVA内存马,其作者也是冰蝎的作者,项目地址: https://github.com/rebeyond/memShell 正好最近在接触JAVA,借此机会学习下大佬的代码, ...
- java filesearcher_Java Object Searcher | java内存对象搜索辅助工具
Java Object Searcher | java内存对象搜索辅助工具 0x01 工具简介 #################################################### ...
最新文章
- Cacti Nagios Squid三个工具的一些区别
- html文件钓起始标志,关于html页面head标签顺序
- python爬虫接口_python爬虫之百度API调用方法
- css 根据宽度适应
- linux下的gdb调试
- 30天扣篮训练计划_明日之后:网易CH用心良苦?狼人画出“辐射高校30天计划”,绝了...
- 【数据仓库】数据集市
- c#初学者记录(1)
- Text Classification with BERT using Transformers for long text inputs
- [Android]RapidFloatingActionButton框架正式出炉
- GUI(图形用户界面)
- android 实现广告弹窗,Android实现自适应屏幕的弹窗广告
- node.js-医院预约挂号系统的设计与实现毕业设计源码141041
- [云原生]~云原生简介
- python格式和JSON格式转换
- 新手如何零基础操作让亚马逊无货源店铺如何单月3-5万
- 区块链产业发展面临的挑战、发展建议以及趋势丨2021中国区块链产业发展报告...
- 用pip给python安装matplotlib库-windows
- 极大似然估计、极大似然函数
- 鼠标右键新建菜单没了怎么办