如果你一路跟着学到这里说明你已经预备一定的实战挖掘能力了,其实我不是很想写一堆公开源码的一些基础分析,
但是想了想就当给自己增加基础经验了,挺长时间没更新了后面我会补回来,实战了那就一周2-3更吧,师傅们一定要慢慢来不要着急,
成为大佬的第一步:承认自己是普通人,我不是天才,所以饭要一口一口吃,路要一步一步走。
GitHub地址:[https://github.com/jeecgboot/jeecg](https://github.com/jeecgboot/jeecg)
后端: Springmvc+Servlet
数据库: Mysql+redis
我会很细的讲就会造成有点啰嗦见谅,搭建也非常简单,导入docs目录下面的数据库文件,dbconfig.properties配置一下数据库账号密码就好了。
说起来未授权访问,基本上都是使用request.getRequestURI()进行路由匹配,然而在低版本spring中存在路由缺陷导致的问题,
不清楚的话看我往期文章《SpringMvc<=5.2.6(<=2.3.0)权限绕过通病》,
首先我们得判断当前使用的什么作为权限验证的过滤器 拦截器还是说使用了组件?首先在web.xml中查看是否存在过滤器,
发现是存在的不过是一些设置编码格式的不是我们想要,那么我们就等考虑拦截器了,我一般都是全局找
implements WebMvcConfigurer但是找不到全局找implements HandlerInterceptor找到了好多这是怎么回事呢?其实就是因为springmvc里面配置了拦截器图一,
看到存在两个先进入第一个org.jeecgframework.jwt.aop.RestAuthTokenInterceptor。
进入之后可以看下面图一,其实就看前两行代码就饶过了,首先通过getContextPath()从上下文开始获取路径,
getRequestURI()获取我们的全路径,在进行substring进行截取字符串,其实就是不要下文路径,再通过
indexOf判断当前路径中有没有/rest/有就返回字符串位置,等于-1是因为找不到,那么很简单只要不出现
/rest/就饶过了,后面的条件是或者,那么只要有一条成立就会是true,但是这并不算绕过,因为我们没有绕过/rest/,
那么再往下走就是request.getHeader("X-AUTH-TOKEN");获取请求头,不等于空的情况下会走到54行进行一个jwt的验证,
没错这个jwt密钥泄露了JYJ5Qv2WF4lA6jPl5GKuAG,那么用密钥加密一下就行了代码一,后面进入63行进行一个封装,主要是64行代码我们跟进去这个方法。
进入下面图一之后可以看到是通过45行进行获取了redis中的key对应的value,之后在对我们传入的jwt和他查询的进行比较,
那么很显然在安装中如果存在默认的key对应的value那么就是未授权了,但是这里在安装中不存在key所以就算有密钥也没用,
那么为什么还要讲呢?因为在刚开始审的时候一定要多看多想,那么在这个拦截器中我们是无法绕过路径中存在/rest/的,下面我们看另一个拦截器。
org.jeecgframework.core.interceptors.AuthInterceptor进入65-74行都是查看我们路由存在不存在
JAuth注解之类的操作但是在这个程序没有复合条件的因为都不存在这个注解,再到下面78里面只获取请求路径截取参数,
80把//和\\替换成一个/,那么关键点来了83行匹配requestPath.substring(0,4)获取我们前面三个字符来进行equals比较,
只需要前面是api就可以,那么如何绕呢?没错../首先我们确认版本是否存在安全问题图二,4.0.9确实存在问题,那么就饶过了。
org/jeecgframework/web/cgform/controller/upload/CgUploadController#ajaxSaveFile方法中存在文件上传,
那么我是如何知道的呢?关于文件操作的操作开源直接使用idea进行全局搜索 new File(就可以了图一,那么176行就是获取所有的上传文件参数存储在Map中,
之后就是183行之前的代码确认文件路径是否存在不存在就创建,后面把上传参数进行遍历,在后面程序都有注释不解释了进入到196行write2Disk方法中图二,
只要扩展名不等于txt就直接使用FileCopyUtils.copy(mf.getBytes(), savefile)方式进行上传了,那么如果就是
txt扩展名就会使用数据流FileOutputStream输出流进行写入,payload图三。
com/jeecg/demo/controller/JeecgFormDemoController#filedeal
首先通过获取bizType参数图一,进入getPath方法图二,可以看到图二其实就是一个枚举类,通过常量给到构造方法,
这个是一个文件路径那我们选择photosucai吧,在回到图一,之后创建完整路径不存在就创建,通过
MultipartHttpServletRequest过去上传在multipartRequest.getFile("file");获取上传中file参数,
772行在获取到了文件名,773行吧我们的文件名通过lastIndexOf从后往前找点在通过substring开始获取扩展名,之后构造最后的路径776行进行复制上传,
但是这里是不会上传到web目录的因为我们在进入getPath之后拼接路径的时候前面还存在一个变量760行从配置文件中获取路径,payload图三。
com/jeecg/demo/controller/JeecgFormDemoController#图一直接一眼洞,payload
/api/../jeecgFormDemoController/filedelete.do?filepath=../../文件
里面还是存在很多安全问题的,我就不一一看了剩下的留给师傅们。