java代码审计-网校在线系统
本文章仅供学术研究
首先分析下这个网站使用的是哪些框架组件
pom.xml
通过pom.xml文件可以看得出是一个Spring+Springmvc+mybatis框架
dependency-check-maven
我们可以一个一个组件找版本漏洞也可以使用dependency-check-maven进行组件的安全检测

web.xml
查找filter和拦截器,发现并没有对其进行安全的过滤和拦截

applicationContext.xml
我们可以看到大部分是一些数据库配置、数据库事务等配置

这里可以看到mapper与entity目录位置

spring-mvc.xml
可以看到下面后台拦截器的配置,排除/admin/main/login路径

后台bean注入的类,首先判断是否登录

后台是通过cookie来获取管理用户

前台拦截器

通过搜索@RequestMapping,发现/webapp不在拦截的范围,也可以使用正则表达式:@(.*?)Mapping\(

仔细看了下这些控制器大部分是app前端的显示并无意义,有用的是下面的video可以用来上传影片


源代码扫描
我们将源代码放到Fortify下进行扫描,获取结果
我们可以根据扫描结果找对应文件,也可以搜索关键字定位漏洞

网站目录结构


SQL注入
首先我们知道该持久层框架是mybatis,我们重点搜索的就是带${的xml文件

我们接着搜索dao接口

找到dao实现类

接着通过service接口找到了实现接口

最后才是我们的Controller层

该功能点是在后台的文章管理里

尝试进行注入,成功注入

XSS
存储型XSS
找存储型xss有两种方式:
- 可以先找controller也可以先从jsp找到表达式渲染位置(<%=或者是${)
 - 也可以先找jsp再去找到controller判断过滤
 
我们找xss存储型可以先去找controller
通过搜索model.addObject或request.setAttribute,都是将对象添加到view中
一般找一些list的controller

找到对应的模型,如果没有路径则是通过setViewName方法来添加路径

可以看到pojo层, 返回显示的数据,7个是String类型


首先是找service层

找到service实现类从而找到dao层

再找到dao层的实现类,从而找到mapper文件的方法

可以看到查询questions表的所有字段,及其其他表的一些字段也可以存在xss

通读了下从控制层到数据访问层,并没有对xss进行过滤,而且也没有过滤器和拦截器进行过滤,所以我们就可以回到jsp页面,因为我们是要找当前功能点增删改查的xss,所以其他联合表的字段就不看,主要看content和title
由于是在回答问题的主页,所以没有显示content

这里也有坑点,如果遇到了<c:out>标签输出的,是有对尖括号进行实体编码

之后我们就通过查找update或者是add的方式一步步一跟踪判断是否在添加到数据库中是否存在实体和过滤来插入我们的payload

最终通过add的方法插入xss

并且渲染到页面

反射型XSS

可以看的传入了courseName,并且是在form表单下

传到接口去处理,传入了courseName参数
找到controller

通过一系列的service到dao层查询并返回controller,我们可以直接在这里可以知道后端并没有做过滤,直接将值返回

成功在后端进行渲染

文件上传
搜索upload等关键字

找到controller,发现该功能点不会被后台拦截,路径是在/video下,而我们后台只拦截admin下的文件


用来视频上传功能的方法

我们看下需要构造哪些参数,可以看到这里有三个参数,两个是必须的

并且fileType是可以控制的

这也就可以造成文件上传,并且路径还返回给我们

构造poc
 | 
上传页面

成功上传

逻辑漏洞
首先就是逻辑漏洞最大原因是因为后端没有对该用户的身份进行判断,或者是用户身份可控导致执行了功能点,这就是漏洞成因
搜索@RequestParam(value=”user或者是getParameter(“user还可以用@ModelAttribute(“user”)等方法

绑定请求参数到指定User对象,User下有userId,所以我们可以搜索

可以看下这个,传入了user对象,但是并没有对UserI等进行判断,我们继续跟进下service的updateUser方法

service实现层也并没有对用户进行判断,我们继续找下dao实现层,一般校验是在service实现下

找到dao实现层

mapper对用户id进行判断,但是忽略了用户id可以控制

造成了我们可以修改用户id来实现对其用户信息修改

正确应该从cookie或者是session提取userId来辨别用户身份,并且数据库要对用户身份进行判断
