freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

渗透测试 | 通读审计之HadSky
2024-04-19 14:56:45

前言

距离上次编写文章已经过了很久很久... 本篇文章是从去年七月份挖掘后提交CNVD通过, 并等待厂商修复漏洞后, 时隔9月, 才分享出来的. 因为笔者在其中挖掘到多处前台漏洞, 并成功申请了CNVD编号.

image


那么回头望首, 今天我们所分析的系统是HadSky, 该系统具有一定的安全性, 几乎站点从外部接收上采用的全局性白名单过滤, 那么接下来聊一下笔者与该CMS之间的小故事.

本次分析是HadSky v7.12.10.20230702 Latest (2023年7月2日)版本, 笔者会在文末附上该版本的链接, 方便笔者进行复盘.

image

官网安装渠道:

https://www.hadsky.com/hadsky-download.html

该框架使用puyuetian轻量级框架进行开发, 笔者会在此分析出框架的运行原理, 以及分析过程中所遇到的安全隐患问题.

安装口存在的安全隐患&&开发模式分析

安装部分给大家一个小小的引子.

image

这里“创始人信息填写”则是后台的账号密码设置, 这里默认填写上很明显是存在一些安全隐患的, 但并不是什么大的问题, 这里不细说.

下面有一个“云服务信息初始化”, 这个点在我当前测试时功能已经失效了, 但安装完毕后可以正常使用, 后面该功能模块会引出高危漏洞, 这里先给大家提前剧透一下.

安全的密钥

WEB 界面其实并没有什么发现, 而重点关注的代码层面到底干了什么, 我们查看\install\phpscript\install.php文件会发现该站点在数据库中存在两种密钥, 如图:

image

通过观察代码, 我们可以知道该数据库的password字段只经过了一次md5加密, 但其实第124行的 $s_t 变量则类似于数据库安全中的“盐”, 它在后面的COOKIE用户身份校验中起了非常大的作用. 到下面MVC分析我们会进行刨析. 下面可能出现漏洞的地方则是CreateRandomString方法.

image

CreateRandomString函数则使用了非常安全的rand()函数, 以避免了Dz论坛某版本曾爆出的key泄露情况.

参考链接:

https://www.jianshu.com/p/592d336adfe3

所以这里并不存在漏洞, 接下来就是重点了.

配置项存放形式

image

通过这个信息我们可以得到两点:

  1. 该站点的配置信息都在数据库里, 则是$mysql_prefix . 'set'这张表

image

setname是配置项, 而setvalue则是配置项的值. 这里可以简单理解为一个简单的键值对.

  1. 该站点存在第二个密钥, 该密钥目前的用途不知, 但与官方网站是存在握手行为的.

MVC 路由 && 框架运行原理分析

那么聊完一些有的没的, 下面我们从index.php开始分析, 深入浅出一些开发上存在缺陷的code, 并理解它的网站架构.

image

22行之前都是一些版本定义, debug默认开启, 安装检测. 我们重点关注22行引入的puyuetian.php文件.

image

这里定义了一个全局数据$_G, 以存放WEB应用系统层面的信息, 并且19~31行的if判断中, 不允许直接访问puyuetian.php文件, 接下来我们继续跟进35行的puyuetian/vars.php文件.

站点全局变量存放

image

这里重点关注上面的$_G['STRING']变量的定义(安全机制), 以及下面$_G['SYSTEM']['CLIENTIP'] = $IPaddress;可以进行IP伪造, 并且没有过滤机制,$_G['SYSTEM']['REFERER'] = $_SERVER['HTTP_REFERER'];未经任何判断, 直接放入$_G['SYSTEM']中, 这里可能也会触发漏洞, 特意留意一下, 那么接下来回到puyuetian.php文件中, 继续往下读取.

image

后面引入了一个function.php文件, 这里都是一些函数的定义, 等分析到再看, 17行的firewall.php看似是一个防火墙配置, 但该站点默认未开启, 所以不用分析. 回到puyuetian.php文件继续分析.

image

47~55行禁止了/index.php/.../...的写法, 那么接着往下看.

全局GET过滤 (*)

image

从这里我们可以发现,$_GET的所有内容全部经过了Cstr函数处理, 随后都给了$G, 这里Cstr函数的过滤还是比较严格的, 强制白名单只允许A-Za-z0-9_字符, 不允许其他任何字符出现, 否则函数返回false, 算是一个全局的外部GET参数过滤, 那么接着往下看.

IP黑名单 (被修复的XFF头)

image

ips.php文件的主要内容则是通过\puyuetian\ips\config.hst的IP设置来进行某某IP, 这里看到一个点, 而是$_G['SYSTEM']['CLIENTIP']之前是没有任何过滤的, 但包含了ips.php后则有了htmlspecialchars + strip_tags过滤, 并且使用htmlspecialcharsENT_QUOTES模式, 完全过滤了一些引号, 尖括号等攻击语句.

所以, 这里本应该存在的XFF头注入, 目前被修复了, 只留下了$_SERVER[REFERER]目前还没有被修复.

缓存机制

image

这里缓存机制的配置比较简单, 若发现/cache/html/目录中有关于当前$_G[SYSTEM][LOCATION]的缓存, 则只使用file_get_contents进行读取内容, 缓存文件的末尾会有CacheFile的注释结尾.

MySQL机制 (*)

image

80以及81行的代码比较简单, 对$_G进行数据库的定义, 以及定义Data类, 我们下面仔细分析一下第82行做的事情.

image

puyuetian/mysql/install.php文件的前半部分主要是增加了mysql_query方法, 但是从这里可以看出来$_G[PDO]未经过任何过滤直接调用了PDO::query方法,mysql_query && sqlQuery方法使用不当会造成SQL注入问题.

第19行因为$_G[PDO]PDO类的实例, 而PDO默认支持堆叠形式, 这也是一个需要留意的点.

再往下面的$_G[SET]则是我们的pk_set表中的各个配置项了.

那么知道上半部分在做什么事情之后, 我们来分析下半部分所做的事情.

image

再往下的核心思想则是, 将本数据库下的所有以pk_打头的表, 全部实例化一个Data对象, 并特别指明了Data对象的table成员属性就是表名. 随后依次存入到$_G[TABLE]中去.

Data 类的下可注入的函数 (!)

为什么说该系统比较安全, 其实也有这里Data类的死亡过滤原因, 我们来仔细分析一下Data类做了一些什么事情.

看一下它的getSql方法:

image

可以看到这个if分支中, 只有$field传入字符串, 并且$str未传入任何内容才不会经过mysqlstr函数的过滤, 所以这里的利用条件是比较苛刻的. 我们再看一下其他函数的定义.

image

这里其他任何函数, 几乎都是封装了getSql方法, 要么调用getSql方法时只传递了一个字符串, 要么调用了自定义的mysql_query方法, 否则, 几乎都无法注入成功.

puyuetian/mysql/notfound.php中没什么框架核心思想||安全方面的问题, 就不细说了.

业务逻辑 (用户校验核心文件)

image

/puyuetian/ext/preload.php文件只需要着重注意一下$_G[TEMP\LATE]变量即可, 因为它与后面的模板输出环环相扣.

/puyuetian/ext/function.php又引入了一系列业务逻辑函数, 例如: 发帖, 消息回复等函数.

/puyuetian/ext/uia.php这里不介绍, 因为在文章下文会详细描述该文件所导致的问题缺陷.

image

查看/puyuetian/ext/normal.php这里其实用来记录你的$_SERVER[REQUEST_URI]是否存在恶意语句等, 这里默认值为0, 所以一带而过.

接下来我们看一下/puyuetian/ext/loadapps.php

image

主要应用于插件是否开启, 这里我们刚安装的系统可以发现自带了这么多插件, 并且app_filesmanager_load,app_mysqlmanager_load等插件都是默认开启的.

INDEX 层路由分析 (*)

安全的外部路由

跌跌撞撞, 终于到达了我们路由分析的点, 这一部分是整个运行原理分析中最重要的一部分了, 再努努力, 把代码读下去.

image

这里我们发现了$_G['GET']['C'], 用于接收外部c参数, 也就是GET请求的c. 如果外部参数c存在, 那么则直接使用, 但是我们知道, $_G的所有参数在全局GET过滤 (*)分析部分已经经过Cstr所处理, 故, 该站点的路由安全是没问题的, 因为$_G['STRING']['SAFECHARS']并不包含..等字符, 通过白名单的手段白名单过滤了目录跳跃漏洞.

而不存在外部的参数c时, 在正常业务逻辑中, 数据库中的select * from pk_set where setname like 'CHKCSRFPAGES';, 默认返回了list. 那么我们继续往下看.

未打开的CSRF开关

image

这里的CSRF配置项默认被关闭了, 也不知道为何关闭该功能, 它里面的$_G['CHKCSRFVAL']大家可能一脸懵, 它是在业务逻辑 (用户校验核心文件)中笔者忽略的UIA.PHP文件, 后面在安全漏洞部分会详细说明.

XSS可能利用点

在接下来就会包含我们的./phpscript/$_GET[c].php文件了, 只是不能跳路径罢了. 因为我们$G['GET']['C']默认是list, 我们跟进list.php给大家看一下.

image

可以看到, 已经进入到正常的业务逻辑当中去了, 这里成功理解了我们外部参数C的作用. 我们继续多个phpscript目录下的文件中的文件末尾的代码, 看一下模板解析部分是如何处理的, 如图:

image

在本张图片的分析中, 我们会发现, 每个控制器下的最后一行代码的处理方式都不同, 有调用PkPopUp函数返回弹窗的, 有返回JSON的, 有直接exit暂停程序运行的, 有经过temp\late函数处理的.

在这里笔者提到一些点, 可能会存在安全隐患.

JsonData函数中, 使用了json_encode函数进行返回, 当函数第三个参数为null时直接返回json_decode出来的数据, 若将该函数返回结果直接抛出到浏览器身上, 可能会存在XSS漏洞,

ExitJson中, 若函数第三个参数指定了false, 则不会输出Content-Type: application/json前缀, 这里可能也会在处理上产生XSS漏洞.

PkPopUp函数中直接拼接了JS代码, 也就是我们的可控点若是在该函数中, 并且传入的数据没有被正确消毒, 即可产生一个XSS漏洞.

当然, 笔者会在本篇文章的安全部分详细介绍出来一些实例.

temp\late函数详细解读

# 代码审计
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者
文章目录