2024-09-23 01:54阅读: 173评论: 1推荐: 1

Java代码审计篇 - ofcms系统审计思路讲解 - 篇3 - 文件上传漏洞审计

Java代码审计篇 | ofcms系统审计思路讲解 - 篇3 | 文件上传漏洞审计

1 文件上传代码审计【有1处】

文件上传漏洞我们需要着重关注的是文件在被java代码解析到保存下来之间有无验证过滤,因此什么样的上传方式,什么样的保存方式都不重要,大家着重关注代码对文件的验证过滤手段即可。

文件上传代码审计常搜索的关键字如下:

file
upload
write
fileName
filePath
getPart
FileOutputStream
transferTo
getRealPath
FileItem
ServletFileUpload
DiskFileItemFactory
....

1.1 可疑点1【无漏洞】

1.1.1 直接搜索upload关键字

1.1.2 选择第一个,点进去分析一下

类名为UeditorAction

可以在当前页面搜索upload关键字,也可以同时参考该类的所有方法名称。

大概看一下,四个方法的写法是差不多的:

  • getFile()方法的第2个参数不太相同,通过参数名称uploadPath可以大概判断出来,这个参数表示的是文件上传路径,也就是说调用不同的方法会保存到不同的目录。

通过下方的msg.put("url", "/upload/image/" + file.getFileName())也可以大体确定这一点;

当然msg.put不是用来保存文件用的,只是返回的信息而已。

uploadImage()方法为例进行分析,可以看到,这个方法内部与保存文件相关的代码就前面两行(后面的都是关于返回的消息相关了),即

UploadFile file = this.getFile("file", "image");
file.getFile().createNewFile();

我们先分析下this.getFile()方法

1.1.3 分析this.getFile()方法

点击进入看一下:

getFile()方法,首先调用了getFiles(uploadPath),跟进之下:就在上面

可以看到这里先做了个判断,判断request对象是否是MultipartRequest类型的对象,如果不是则创建一个新的MultipartRequest类型的对象,总之就是保证request对象是MultipartRequest类型的对象。

然后调用.getFiles()方法。

额外的:其中request对象就是HttpServletRequest,相关代码如下:

这里目前来看,需要有两个点需要分析:

  • 1)new MultipartRequest(request, uploadPath)
  • 2)request.getFiles()

接下来先分析new MultipartRequest(request, uploadPath)

1.1.4 分析new MultipartRequest(request, uploadPath)

点击进入:

一个构造方法,先调用了父类,然后调用了wrapMultipartRequest()

  • 父类可以点击去看看,其实没啥
  • 着重看下wrapMultipartRequest()

点击进入wrapMultipartRequest(),代码比较长,大概意思已标注:

其中我们需要关注的是文件的过滤代码,也就是图中红框位置:

if (isSafeFile(uploadFile)) {
uploadFiles.add(uploadFile);
}

这里面调用了一个isSafeFile()方法,进去看一看:

1.1.5 分析isSafeFile()方法

发现这里有了验证过滤:

  • 首先是对文件名去空白字符,然后转成小写
  • 其次是文件名如果是.jsp或者.jspx结尾则删除,返回false

师傅们可以想一下有无绕过手段

如果没有问题,则将文件add进入uploadFiles列表中。

1.1.6 分析request.getFiles()方法

然后接下来点进2.1.3步骤中的this.getFile()方法中的getFiles()方法进行分析

进来之后,发现方法中没有太多语句,只是直接返回了uploadFiles,也就是上一步所说的uploadFiles列表,这里面存放的是经过过滤的文件。

到此为止,其实已经差不多了,已经找到了文件的过滤方式:

  • 首先是对文件名去空白字符,然后转成小写
  • 其次是文件名如果是.jsp或者.jspx结尾则删除,返回false

刚开始所说的uploadImage()方法中的第2条语句 file.getFile().createNewFile();这里没什么,就是通过返回的经过过滤的file对象来创建一个新的文件。

那么接下来可以验证一下:

1.1.7 验证文件的过滤方式,并尝试找到绕过之法(毕竟是黑名单[\偷笑])

根据前面所说的路由机制,可以确定此uploadImage()方法的调用需要访问admin/ueditor/uploadImage.json

前端找一下呗。怎么找?搜呗...哎真麻烦,说实话好难找啊

根据路径大致判断范围:ueditor,貌似在哪见过这个词?

原来是个富文本编辑器,还好我“见多识广”哈哈

那就在前端找一下哪里有富文本,同时在控制台搜索着ueditor:

经过了九九八十一天,终于找到了。

admin/ueditor/uploadImage.json应该就是在富文本上传图片时触发的吧:尝试一下

uploadImage()方法打上断点,yakit也开启抓包拦截

先来个普通图片试一试

大事不妙!之前分析的路由机制不太对,这里怎么是/admin/ueditor/handler.html?action=uploadImage

  • 这里我懒得分析了,懂的师傅可以留个言~么么哒

不过没关系,放包!uploadImage()方法触发了。也就是功能和方法对上了!

在下面也可以看到上传路径在:D:\Program Files\tomcat\apache-tomcat-8.0.17\webapps\ofcms_admin_war\upload\image

当然在返回包中,也可以看到上传路径

访问一下,可以访问到。

接下来尝试绕过一下,已知文件过滤方式

  • 首先是对文件名去空白字符,然后转成小写
  • 其次是文件名如果是.jsp或者.jspx结尾则删除,返回false

绞尽脑汁~貌似只有一个方式:文件名后面加.绕过,但是这种好像只适用于windows。

来都来了,试一下吧,谁让我现在用的电脑是windows。

这里我直接修改了数据包,将文件名改成了.jsp.,文件内容用的是冰蝎生成的jsp马子。

这里idea就先不debug了,直接放包,上传成功。

可以到目录中看一下,有没有上传成功:

嘿嘿,成功,同时后缀是.jsp。

接下来就是看看能不能连接了...

测试了下,不太行,虽然能上传,但是不能解析。

这里为了避免中文问题,我改成了webshell.jsp

怎么办?目录穿越试一试,哈哈哈

经过三天三夜的调试,找到了文件名处理的源码(这里过程就不粘出来了,自己可以调一下,如果想看过程,评论区留个言,给兄弟们安排上[\狗头])

  • 先计算/的位置
  • 然后进行原始文件名的截取

即文件名为../../../webshell.jsp.,最终文件名也将变为webshell.jsp.

1.1.8 这里,这个点就到此结束,总结一下:

  • 该位置的文件上传可以任意上传除.jsp.jspx的文件,但是没什么luan用。
  • 当然如果是windows是可以通过加.绕过的,不过解析不了。
  • 尝试目录穿越,有代码会将路径接取掉。

成果:0day无,分析经验+1

1.2 可疑点2【无漏洞】

分析第二个ComnController类中的:

进来之后发现,写法和之前是差不多的,同样使用了getFile()方法,怎么办?放弃!

后面使用了getFile()方法的,直接放弃就好了。

换目标!

这里多说一下,其实我们搜的这些,都是jfinal组件中的upload,漏洞基本没有,如果有,那就是组件0Day了。不过分析分析源码也是好的,赞同请点赞。

1.3 可疑点3【跑偏的漏洞-路径遍历读取.xml文件】

通过upload搜索的,翻了一圈,不是UeditorAction类,就是ComnController类,没有别的可疑的了。换关键字搜索。

1.3.1 搜索file关键字

找到一个TemplateController类中导入了File。进入看看

文件中搜索下file,85个,真不少

进来之后,大概浏览一遍,该类中其中两个方法getTemplates() save()方法中存在文件相关的功能代码,所以这里分开来分析下。先分析getTemplates()

【其实这里不需要分析的,因为它是获取文件用的,没有写入文件保存文件的功能,和文件上传无关】。
既然来都来了,看一下吧~

1.3.2 分析getTemplates()方法

方法代码如下:

首先看前面三行,getPara()方法获取参数值,获取不到,会有默认值:

点进getPara()方法,进来一看:欣喜若狂啊

直接通过request.getParameter(name)获取参数值,也就是说,目录可控啊~

继续往下分析

这一块就没啥了,就是将String类型的路径,封装一下,变成对象。顺便还做了一下验证处理。

  • 其中画红框位置表示:pathFile.listFiles表示目录下的文件或目录,然后通过FileFilter做了一下验证,判断是否是目录,是目录的放入dirs列表中。

  • 其中的setAttr()方法,是将目录对象保存到request对象中。

继续向下分析:这里和之前的差不多,只不过是通过FileFilter限制了白名单文件,即将.html.xml.css.js的文件放入到了files列表中。

继续向下分析:这段代码作用就是页面上默认显示的模版文件,传入的文件名如果没有则显示files列表中的第一个(所以没有任意文件读取~哈哈哈)

最后返回resource.html或者是index.html

没有文件上漏洞!

1.3.3 柳暗花明又一村

但是别急,回想下,最开始说该方法获取的前端参数可控,即目录可控,那我们能不能不去获取默认路径下的.html.xml.css.js文件。

直接验证了,前端找到对应功能点,还是那个熟悉的模版~

随便点个模版,yakit拦截下~

默认参数是这样的:

  • file_name=contact.html
  • dir=/
  • dir_name=/

对照下源码,dir是当前目录,file_name是查看的文件

那么修改一下,读取网站下的web.xml试一试

而默认读取的根目录是webapps\ofcms_admin_war\WEB-INF\page\default

所以我们构造dir=../../../../ROOT/WEB-INFfile_name=web.xml

成功读取!经验+1

1.3.4 多点脑洞

既然这里可以读取web.xml,并且下方可以保存,那我们是不是就可以修改web.xml文件了呢?

尝试修改保存一下,出现请求异常~

直接调试下,在save()方法处打个断点,发现是因为dirs参数值即dirName中存在../因此被拒绝了。

这里其实很好绕过,聪明的你一点发现了,前面还有个参数:res_path

我们可以修改res_path的值和dirs参数的值,来达到修改web.xml的目的。

这里师傅们可以自己尝试下,因为这里和下面的save()方法的分析是一样的,就放一起说了。

1.4 可疑点4【有漏洞】

从上一个分析,发现save()方法其实是有问题的,接下来着重分析一下。

1.4.1 分析save()方法

代码就这么长:

首先看:

这里从前端获取“res_path”的参数值,前面也说过,getPara()获取的值是可控的。

然后通过res_path的值决定pathFile是什么内容,这里其实不用管,因为不管res_path是什么,pathFile都是固定的,不是SystemUtile.getSiteTemplateResourcePath()就是SystemUtile.getSiteTemplatePath(),没有可变的地方。

接下来是这段,也是核心:

首先从前端获取“dirs”参数的值,不过这个值中不能存在../,也就是说这个参数不能是利用点了。

然后从前端获取“file_name”参数的值,没有任何限制。

最后从前端获取“file_content”参数的值,仅仅对<>做了转义。

然后就是新建文件,调用FileUtils.writeString(file, fileContent)写入内容。

writeString方法如下:直接调用FileOutputStream.write()写的,没有别的过滤。

分析下来之后,可以利用的点为:file_name和file_content。

文件名和文件内容都可控,这不就是妥妥的任意文件写入(可以理解为任意文件上传)。

1.4.2 利用漏洞写入jsp马

那直接写个jsp马进去!当然,可能解析不了。

file_name和file_content都替换掉,最后别忘了file_content的值使用URL编码一下

  • 这里我用的是冰蝎jsp马

成功写入:

访问连接:但是会发现连接失败,看来当前目录下不能直接访问,或者是jsp不解析

继续尝试别的目录:file_name=../../../webshell.jsp

也是失败。

这里尝试在static目录,是可以的。file_name=../../../static/webshell.jsp

小tips:static目录是静态目录,一般文件是可以直接访问。

命令成功执行!撒花~

1.5 最后结尾

最后搜索了其他的类和关键字,没有可以分析利用的点了。师傅们看看就好。

1.5.1 例1:SystemUtile类下

1.5.2 例2:GenUtils类下,都是创建固定名称的文件,并非文件上传

1.5.3 例3:换关键字write搜索,基本都是分析过的,要不就是无用的

文件上传漏洞代码审计到此为止,希望师傅们有所收获,如有问题,评论区留言~
也可扫码加好友,一起进步~

posted @   leyilea  阅读(173)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
💬
评论
📌
收藏
💗
关注
👍
推荐
🌜
深色
🚀
回顶
收起
🔑
点击右上角即可分享
微信分享提示
  1. 1 忽冷忽热 沈以诚
忽冷忽热 - 沈以诚
00:00 / 00:00
An audio error has occurred.

作曲 : Reol

作词 : Reol

fade away...do over again...

fade away...do over again...

歌い始めの一文字目 いつも迷ってる

歌い始めの一文字目 いつも迷ってる

どうせとりとめのないことだけど

伝わらなきゃもっと意味がない

どうしたってこんなに複雑なのに

どうしたってこんなに複雑なのに

噛み砕いてやらなきゃ伝わらない

ほら結局歌詞なんかどうだっていい

僕の音楽なんかこの世になくたっていいんだよ

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.

目の前 広がる現実世界がまた歪んだ

目の前 広がる現実世界がまた歪んだ

何度リセットしても

僕は僕以外の誰かには生まれ変われない

「そんなの知ってるよ」

気になるあの子の噂話も

シニカル標的は次の速報

麻痺しちゃってるこっからエスケープ

麻痺しちゃってるこっからエスケープ

遠く遠くまで行けるよ

安定なんてない 不安定な世界

安定なんてない 不安定な世界

安定なんてない きっと明日には忘れるよ

fade away...do over again...

fade away...do over again...

そうだ世界はどこかがいつも嘘くさい

そうだ世界はどこかがいつも嘘くさい

綺麗事だけじゃ大事な人たちすら守れない

くだらない 僕らみんなどこか狂ってるみたい

本当のことなんか全部神様も知らない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.