21

文件解压引发的Getshell

 4 years ago
source link: https://www.freebuf.com/articles/others-articles/229928.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

声明

本文仅供学习和研究,由于传播、利用此文所提供的信息而造成的任何直接或者间接的后果及损失,均由使用者本人负责,海青实验室及文章作者不承担任何责任。

安全狗海青实验室拥有此文章的修改和解释权,如欲转载或传播,必须保证此文的完整性,包括版权声明在内的全部内容,未经海青实验室同意,不得任意修改或者增减此文章内容,不得以任何方式将其用于商业目的。

攻击者可以快速的从文件上传功能点获得一个网站服务器的权限,所以一直是红蓝对抗中的“兵家必争之地”。而随着对抗不断升级,开发人员的安全意识的不断提高,多多少少也学会了使用黑名单或者白名单等一些手段进行防御,但刁钻的攻击者,依然发现了疏忽之处。本文以两个实例,简单介绍文件解压功能导致的getshell问题。

PHPOK CMS后台任意文件上传

首先,准备一个zip文件里,里面包含了一个PHP文件。然后,在导入模块中将zip文件上传。

fQVBVnF.jpg!web

在尝试的时候发现,导入模块失败了,但是查看文件夹内容,可以发现文件已经成功被写入了。

zMziuiJ.jpg!web

z6nyAnN.jpg!web

流程分析

从代码层面来看看整个流程是怎样的?

qAzEZrU.jpg!web

当我们点击导入模块时,浏览器会发送两条请求。先看第一条POST请求。根据PHPOK CMS路由分发的规则,可以定位到upload控制器中的zip方法。

JvEZJ3Z.jpg!web

而在43行处,引入了libs\upload.php文件并且调用zipfile()函数。

vEBfamV.jpg!web

在第135行处,设定了文件后缀类型为zip,由于137行处的if条件不成立,流程进入140行,调用_save()方法。继续跟进_save()方法。

nuyUBzM.jpg!web

_save()方法在276行处使用file_ext()方法对传入的name参数也就是文件名进行后缀判断,而如果判断通过,则会在之后将压缩文件保存下来。跟进一下file_ext()方法。

V3M7N3M.jpg!web

在该方法中,设置了一个白名单,文件名只能是jpg,gif,png,zip中的其中一种。为什么包含zip呢?不管是程序执行到第186或者189行处,在前面就已经给这两个变量设置值为zip了,所以在白名单中自然包含了zip。 目前到此为止,整个上传流程没有什么问题,并且使用了白名单来限制后缀,所以只能上传zip压缩文件。接着再来看第二处请求

admin.php?c=module&f=import&zipfile=_cache%2Fa9414ae41044fc5a.zip&_=1570603538199

同样根据路由规则,可以定位到module控制器下的import方法

QfuY7jU.jpg!web

程序会接受到zipfile参数,是刚刚压缩包保存在缓存文件夹里的文件名。在第705行处判断了是不是存在这个压缩包,如果存在则在708行处进行解压。其中引入了libs/phpzip.php中的unzip函数进行解压。跟进unzip函数,程序实例化了ZipArchive类进行解压,而目标路径$to则是缓存文件夹。

MRNbqa3.jpg!web

到此不难看出问题,程序将压缩包中的文件解压出来之后,并未进一步的进行判断,以至于里面包含的 PHP文件可以绕过上传文件的限制,使得原本建立的安全防御土崩瓦解。

Jspxcms后台的zip解压功能目录穿越漏洞导致getshell

由于这套CMS做了相关防御配置,压缩包里像上文中直接加入JSP文件是无法执行的,会报403错误。因而想到使用目录穿越的方式,跳出JspxCM的根目录,并根据war包会自动解压的特点,从而getshell。

首先,建立一个恶意的war包,并且打成压缩包,如图所示。

eENBZrf.jpg!web

然后点击“上传文件”按钮,上传test5.zip,如图所示。

ArAfYbY.jpg!web

紧接的使用解压功能,将上传的压缩包解压出来。点击“ZIP解压按钮”,如图所示。

EzMN3iI.jpg!web

此时,在服务器端查看webapps目录的变化,可以发现safedog.html和vul.war文件被解压到了网站根目录“webapps/ROOT”之外,如图所示。

FjYreub.jpg!web

访问上传的webshell,效果如下。

http://192.168.114.132:8080/vul/webshell.jsp?pwd=023&cmd=calc

MjQ3yei.jpg!web

流程分析

在后台登录之后,找到ZIP解压功能,通过BurpSuite进行抓包可以发现“解压文件”的接口调用情况,如图所示。

AvMFZfY.jpg!web

该接口对应了jspxcms-9.5.1-release-src/src/main/java/com/jspxcms/core/web/back/WebFileUploadsController.java的unzip方法,如图所示。

Rvau63F.jpg!web

对unzip方法进行跟进,发现它的具体实现在/jspxcms-9.5.1-release-src/src/main/java/com/jspxcms/core/web/back/WebFileControllerAbstractor.java中。可以发现,在对zip文件进行解压的时候,调用了AntZipUtil类的unzip方法,如图所示。

i6NbQba.jpg!web

对AntZipUtil类的unzip方法进行跟进,可发现该方法未对ZIP压缩包里的文件名进行参数校验,就进行文件的写入。这样的代码写法会引发“目录穿越漏洞”,如图所示。

B36ryuR.jpg!web

总结

从上述两则实例来看,压缩包里包含着webshell颇有些特洛伊木马的味道。当程序对上传后缀限制的相当严格,例如上文提到的PHPOK CMS,已经使用白名单的机制只能上传四种后缀的文件,却依然因为对压缩文件的处理不当,导致整个防御机制的失效。在ZZZCMS中的实例,猜测开发者的本意是zip文件夹内的内容应该别可控的,但在目录穿越的加持下,超出了开发者的预期从而防御机制土崩瓦解。

那么如何防御呢?建议开发者在实现文件解压功能时考虑以下要点:

1)限制文件的扩展名(如采用白名单的方式);
2)限制文件的名称(以较为严谨的黑名单约束文件名);
3)限制文件的大小(以免遭受压缩包**的DDoS攻击)。

因此,在开发的各个环节,都要将安全意识贯彻其中。千里之堤毁于蚁穴,也正是这种细微之处的小问题,才使得攻击者有机可乘。

*本文作者:安全狗safedog,转载请注明来自FreeBuf.COM


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK