0x00 简介

感觉遇到的jfinal框架也不算少,在较早一些的版本中

jfinal框架存在上传问题,后面进行了修复,但是修复并不算完整

这里看一下,什么情况下存在上传

测试版本

  • 4.9

0x01 上传流程跟踪

测试代码,根据一下全过程

1
2
3
4
public void upload() {
String prefix = BaseUtil.getDate();
getFile("file", prefix);
}

1657096377650

继续跟进,这里会判断是否是上传的数据包格式

1657096413348

调用wrapMultipartRequest方法,这里有个点需要注意就是参数中的filepath,后面会提到

1657096483062

继续跟进后会发现,在最下面会调用isSafefile

1657096612509

关于isSafefile方法,这个是新老版本都存在的一个方法,这里只检测了jsp和jspx

1
2
3
4
5
6
7
8
9
private boolean isSafeFile(UploadFile uploadFile) {
String fileName = uploadFile.getFileName().trim().toLowerCase();
if (!fileName.endsWith(".jsp") && !fileName.endsWith(".jspx")) {
return true;
} else {
uploadFile.getFile().delete();
return false;
}
}

比如在windows下1.jsp.是不被检测的

但是这并不是老版本的绕过方式

因为在上层代码中,getfile之后会进一步进行处理,而原来的文件相当于一个缓存,在进一步处理之后会被删除

所以这里如果使用1.jsp.的形式,可以使用条件竞争

当然既然谈到绕过那在老版本中自然是存在让文件驻留的方式

上图中可以看到,所有代码都在try…catch中,也就是当出现异常的时候不会将文件删除

所以这里可以构造畸形的上传数据包

这里不做过多的解释,因为新版本已经针对性修复

修复方式如下,当出现异常时,会将数据包中缓存的文件删除

1657097061371

继续跟进,可以发现其实无论怎么样都是先写,后删除

1657097193904

所以条件竞争,将一直存在,先生成文件

1657097304229

再把内容写入

看一下数据包异常的时候

在抓取到异常的时候,比如下面的数据包,正常的文件,已经写入,由于异常是在写入文件时候产生的

1657097708193

所以异常的文件知识一个空文件,接下来会进入文件删除的流程

而且很明显这里删除的是正常的文件

1657097794661

最后异常的文件会被留下来

但是没啥用因为这是一个空文件

所以这里无可厚非的用到了条件竞争

所以接下来需要看看怎么才能让文件驻留的更久一些

从代码上来看,可以循环9999次,但是不能传这么多文件啊

1657098774887

看看是否存在其他的方式

可以看到当return 是false的时候,不需要其他条件,哪怕只有一个文件也会循环9999次

1657098864763

而返回false条件就是捕获到异常

跟进代码

1657098915685

继续跟进后,可以看到应该是不让00截断

1657098940257

试一下,成功

1657099079430

上传目录

再就是关于上传目录的问题了

既然要进行条件竞争那上传目录肯定要在web目录下才行

跟进一下上传目录的配置,需要关注的就是baseuploadpath

1657099194781

此参数是在初始化的时候被设置的

1657099248475

在框架中默认的上传路径就是upload

1657099453033

但是这个其实可以通过上层应用进行设置

1657099476842

1657099539717

1657099570342

当然如果没有进行配置

那么就直接在web目录下了

可以直接访问

0x02 end

就这些吧