【攻防演练】某OA 任意文件上传1day分析
2023-4-17 11:13:58 Author: 星冥安全(查看原文) 阅读量:41 收藏

通过uploaderOperate.jsp上传,OfficeServer移动实现未授权任意文件上传getshell

接口对应的class为OfficeServer.class,将其反编译,看到代码如下:

(1)首先判断请求方法为POST

(2)然后将this.MsgObj.sendType设置为JSON格式

(3)调用this.MsgObj.Load解析参数,跟进该方法

该方法有两种解析参数的方法,根据函数名可以得知,一种是处理表单数据,另一种是处理文件上传数据,这里我们先看处理表单数据的,因为还没涉及到文件。

从上传的表单中,将数据转化为json格式,并赋值给saveFormParam属性。

(4)获取上传表单的数据,并根据数据执行对应功能

(5)当mOptionINSERTIMAGE时,存在漏洞,我们直接到该循环中,如下:

当传入的参数isInsertImageNew为1时,进入到插入图片的功能,具体实现如下:

(6)根据传入的imagefileid4pic,从数据库查询文件名,如果文件名中存在.则以原后缀名作为后缀,否则以.jpg作为后缀。

(7)获取文件内容并且保存

ImageFileManager.getInputStreamById方法会根据传入的imagefileid4pic从数据库中获取其真实路径,然后读取文件流,返回inputStream对象,如下:

isZip在ecology默认安装的时候为1,如果用户修改设置,不进行压缩时,会直接打开文件,获取文件流。

然后跟进OdocFileUtil.getFileFromByte,如下:

其中var1GCONST.getRootPath(),也就是网站根目录。var2为(6)中计算的文件名。

到这也就实现,任意的文件写入了,但是现在我们需要一个接口,可以将文件上传到服务器,并且写入ecology..iamgefile这个表中。

接口位置:workrelate/plan/util/uploaderOperate.jsp

当传入的secId不为0的时候,调用dev.uploadDocToImg方法,接着往上看一下dev是哪个对象。

找到对应的方法,如下:

直接跳过这一对创建对象,赋值,if条件判断等内容,因为都没有return exit等操作,直接找到下面的关键点(代码位于:classbean/weaver/docs/docs/DocExtUtil.class),如下:

流程如下:

  • 1.创建了RecordSet类,是用来操作数据库的,后面要用到

RecordSet var19 = new RecordSet();
  • 2.获取了当前数据库中存放的文档id的下一位值

int var20 = var12.getNextDocId(var19);
  • 3.调用上传函数

String var21 = var1.uploadFiles(var3); //var3为Filedata

此处传入的值var3Filedata

接着跟进到classbean/weaver/file/FileUpload.class 当中,找到uploadFiles的实现,如下:

然后会调用

该方法中验证this.mpdata是否为空,这里不需要担心,在实例化对象的时候,会给赋值,只需要满足带有上传附件即可,如下:

跟进getAttachment方法,可以看到:

其返回了一个MultipartRequest对象,然后在实例化该对象时,会将文件压缩写入到filesystem目录下,如下:

FilePart.writeTo的核心代码:

到这里我们大概清楚,当文件上传时,会将临时文件以zip的形式保存在D:/WEAVER/ecology/filesystem/

接着回到uploadFiles(String[] var1, String var2),继续跟进逻辑:

  • 先遍历上传文件数组,清除文件名中xss相关payload

  • 判断上传文件数组是否为空

  • 判断this.getParameter("name") 是否不为空

  • 保存文件

int var3 = var1.length; // 因为上一个函数将文件名处理为数组,传入该函数
String[] var4 = new String[var3];
this.filenames = new String[var3];

for(int var5 = 0; var5 < var3; ++var5) { // 遍历var1数组,也就是附件名 ['Filedata']
this.filenames[var5] = SecurityMethodUtil.textXssClean(this.mpdata.getOriginalFileName(var1[var5])); // xss清除
if (this.filenames[var5] == null || "".equals(this.filenames[var5])) { // 判断请求中是否未传入文件
return var4;
}
// var2来源于:this.getParameter("name") 函数,只要不传入name参数,var2即为False
// 所以!StringUtils.isBlank(var2)为False,整个if条件为False
if (!StringUtils.isBlank(var2) && !var2.equals(this.filenames[var5]) && (var2.equals(this.filenames[var5]) || "file".equals(this.filenames[var5]))) {
this.filenames[var5] = var2;
var4[var5] = this.saveFile(var1[var5], var2, this.mpdata);
} else {
// 到这里,调用saveFile保存文件
var4[var5] = this.saveFile(var1[var5], this.mpdata);
}
}

跟进到saveFile当中,看一下逻辑实现:

1、获取文件保存路径:

String var4 = var2.getFilePath(var1); //var4 = D:/WEAVER/ecology/filesystem/

2、获取文件名

String var5 = var2.getFileName(var1); //临时文件名
// 原始文件名
String var6 = SecurityMethodUtil.textXssClean(var2.getOriginalFileName(var1));
String var7 = var2.getContentType(var1);
long var8 = var2.getFileSize(var1);
String var10 = Util.null2String(this.getParameter("imagefilename"));
String var11 = Util.null2String(var6);
String var12 = var11.contains(".") ? var11.substring(var11.indexOf(".")) : "";
// imagefilename不为空,且后缀与原始文件名一致时,优先取imagefilename作为文件名
if (!var10.isEmpty() && ("".equals(var12) || var10.endsWith(var12))) {
var6 = var10;
}

3、进行大小判断和是否允许此类后缀上传的判断

默认配置,任意文件都可以上传。所以,会直接进入下一个else:

首先判断,上传内容是否需要压缩,代码如下:

如果我们不传入needCompressionPic则会直接进入下面,其中this.needzipthis.needzipencrypt存放于数据库SystemSet中,两者默认均为1

然后继续跟进,代码如下:

其逻辑如下:

1.生成插入imagefile表的数据库语句

2.创建OSS对象生成对应的aescode和Tokenkey

3.更新数据库,将文件名等信息写入imagefile数据库

4.上传文件到OSS

到这里,我们就完成了文件的上传,而且imageFilename.jsp格式,然后将imagefileid传给OfficeServer接口即可解压文件,getshell。

pocsuite -u http://127.0.0.1:8082/ -r ~/exp/poc/ecology/ecology_upload_rce_nday.py

转载:https://forum.butian.net/share/1782作者:Alivin欢迎大家关注作者一波

 点击下方小卡片或扫描下方二维码观看更多技术文章

师傅们点赞、转发、在看就是最大的支持


    文章来源: http://mp.weixin.qq.com/s?__biz=MzkxMDMwNDE2OQ==&mid=2247488601&idx=1&sn=c9fa8f5b23c9227f9833a2581051434b&chksm=c12c229ff65bab8936739471226a8fc8e516c42885d5c4a3b6728b81a8bd170e660021c8efe0#rd
    如有侵权请联系:admin#unsafe.sh