协同OA文件上传时都调用一个Action,那就是fileUpload.do。
架构使用了Spring,所以,在服务上这个http://***.com/fileUpload.do文件是不存在的,要找到他对应的类,然后反编译才可以看到源码。
通过web.xml,找到了urlMapping.xml,
这个XML中可以找到一系类的URL映射文件,比如fileUpload.do映射到了
现在再找到fileUploadController就可以找到与之相对应的类了。文件上传下载一般属于公用组件,所以找到了common-controller.xml。在这个里面找到类。
终于找到类了,下载下来class然后反编译吧,看代码。
com.seeyon.v3x.common.fileupload.FileUploadController 反编译后的源码如下:
关键代码如下:
如果文件名不为空,就生成文件,然后调用this.fileManager.uploadFiles(request, extensions, destFile, maxSize);
这里请注意,在方法一开始的时候使用了
String destFilename = request.getParameter("destFilename"); 接收文件名,
request.getParameter是从http协议GET/POST等方法中接收,而非在httpbody中。比如说以下请求:
Content-Disposition: form-data; name="file1"; filename="1.jpg"
Content-Type: image/jpeg
这个1.jpg是无效的,不管用,这就可以说,我们可以随意的给上传的文件传递文件名,比如说JSP。
那么问题来了,程序是怎么过来的?上传文件后,放在什么地方?
destFile = new File(FilenameUtils.separatorsToSystem(destFilename));
这句话,就代表着生成一个文件,在Java中可以使用相对路径比表示。比如
File file = new File("./webapps/seeyon/x.jsp");
这样也是合法的,那么最终会生成到哪里呢?一般会根据Web容器的Context上下文路径来生成,
比如当前上下文路径为:
d:/xxx/xxx/tomcat/ 那么,最终路径就是d:/xxx/xxx/tomcat/./webapps/seeyon/x.jsp,由此可以得知,如果存在上传漏洞,那么不用知道绝对路径,就可以到指定目录了。不用担心上传文件后找不到路径了。
但继续还得看下去,看最后是如何过滤的。但是这个方法没过滤,而是调用了this.fileManager类的uploadFiles方法,并传入了file,request,扩展名。
this.fileManager是类外一个类,在去找这个类。
import com.seeyon.v3x.common.filemanager.manager.FileManager;
找这个类可真是曲折,在classes目录了根本就没有这个类,程序员将部分代码分离了,放在了lib里面的v3x-common.jar中,继续反编译,找到类。
最终的调用方法如下:
最终过滤的关键代码: