宝塔面板phpMyAdmin未授权访问安全漏洞是个低级错误吗?

wufei123 2024-05-24 阅读:8 评论:0
周日晚,某群里突然发布了一则消息,宝塔面板的phpmyadmin存在未授权访问漏洞的紧急漏洞预警,并给出了一大批存在漏洞的url: 随便点开其中一个,赫然就是一个大大的phpmyadmin后台管理页面,无需任何认证与登录。当然,随后各种神...

周日晚,某群里突然发布了一则消息,宝塔面板的phpmyadmin存在未授权访问漏洞的紧急漏洞预警,并给出了一大批存在漏洞的url:

8ab94b0361e4ccb558061222e3e6cf6.png

随便点开其中一个,赫然就是一个大大的phpmyadmin后台管理页面,无需任何认证与登录。当然,随后各种神图神事也都刷爆了社交网络,作为一个冷静安全研究者,我对此当然是一笑置之,但是这个漏洞的原因我还是颇感兴趣的,所以本文我们就来考证一下整件事情的缘由。

一、我们的问题究竟是什么?

首先,我先给出一个结论:这件事情绝对不是简简单单地有一个pma目录忘记删除了,或者宝塔面板疏忽大意进行了错误地配置,更不是像某些人阴谋论中说到的官方刻意留的后门。

我为什么这么说?首先,根据官方的说法,这个漏洞只影响如下版本:

Linux正式版7.4.2

Linux测试版7.5.13

Windows正式版6.8

这个版本就是最新版(漏洞修复版)的前一个版本。也就是说,这个确定的小版本之前的版本面板是不受影响的。我们试想一下,如果是“后门”或者官方忘记删除的目录,为什么只影响这一个版本呢?况且宝塔面板发展了这么久,积累了400万用户,体系安全性也相对比较成熟,如果存在这么低劣的错误或“后门”,也应该早就被发现了。

经过实际查看互联网上的案例和询问使用了宝塔面板的朋友,我发现在7.4.2以前的版本中没有pma这个目录,并且phpmyadmin默认情况下认证方法是需要输入账号密码的。所以,宝塔出现这个漏洞,一定是做过了下面这两件事:

新增了一个pma目录,内容phpmyadmin

phpmyadmin的配置文件被修改了认证方式

那么,我们的问题就变成了,官方为什么要做这两处修改,目的究竟是什么?

为了研究这个问题,我们需要先安装一个宝塔7.4.2版本。但是,宝塔的安装是一个傻瓜化的一键化脚本:

yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh

并没有给到用户一个可以选择版本号的选项,官方的Git也许久没更新了,我们如何才能安装到一个合适的版本(7.4.2)呢?

二、安装一个合适的版本

这当然难不倒我。首先,我安装了最新版的宝塔面板,用的就是上述一键化脚本。

安装的过程自然没什么问题,安装完成后,系统显示的版本号是最新版7.4.3,因为在爆出这个漏洞以后,官方迅速进行了修复升级。不过没关系,我们仍然可以找到离线升级包:

http://download.bt.cn/install/update/LinuxPanel-7.4.0.zip http://download.bt.cn/install/update/LinuxPanel-7.4.2.zip http://download.bt.cn/install/update/LinuxPanel-7.4.3.zip

分别是7.4.0/7.4.2/7.4.3的版本,我们分别下载并解压,并尝试将自己的服务器版本恢复成漏洞版本7.4.2。

在恢复代码之前,我们先将服务器断网,或者将宝塔设置成离线模式:

3cd084c23abeaaf41f95b9cb6cb799a.png

这么做的目的是防止宝塔进行自动版本更新,避免好不容易恢复的代码又自动升级了。

宝塔系统代码默认安装完是在/www/server/panel,接着我们直接将将压缩包内的panel目录上传到这里来,覆盖掉已有的文件。重启下宝塔,即可发现系统版本号已经恢复成7.4.2了:

83a03bae942e6f71c3617b9ba707c68.png

还没完,我们使用beyond compare打开7.4.2和7.4.3的压缩包代码,先看看官方是怎么修复的漏洞:

04828949f5f39eefbfba453db13b738.png

比较粗暴,直接判断目录/www/server/phpmyadmin/pma是否存在,如果存在就直接删掉。所以,我们虽然恢复了系统版本代码,但删掉的pma已经不在了,我们还需要恢复一下这个目录。

方法也很简单,/www/server/phpmyadmin下本身存在一个phpmyadmin目录,我们直接复制一下这个目录即可:

d7ea051444f1b50c20197487b52fb0e.png

三、漏洞究竟是怎么回事

有了环境,我们仍需看看代码。

首先,由于7.4.2是引入漏洞的版本,我们看看官方对7.4.2的更新日志:

617af739919d57fd7d13e9cf12f6297.png

用beyond compare打开7.4.0和7.4.2的压缩包代码,看看具体增加了哪些代码:

c9a67dd190c79960118bf7cc1a4d5e0.png

可见,在7.4.2版本中增加了两个视图,分别对应着phpmyadmin和adminer。视图中用到了panelPHP#start方法,这个方法其实也是新加的:

def start(self,puri,document_root,last_path = &#39;&#39;): &#39;&#39;&#39; @name 开始处理PHP请求 @author hwliang<2020-07-11> @param puri string(URI地址) @return socket or Response &#39;&#39;&#39; ... #如果是PHP文件 if puri[-4:] == &#39;.php&#39;: if request.path.find(&#39;/phpmyadmin/&#39;) != -1: ... if request.method == &#39;POST&#39;: #登录phpmyadmin if puri in [&#39;index.php&#39;,&#39;/index.php&#39;]: content = public.url_encode(request.form.to_dict()) if not isinstance(content,bytes): content = content.encode() self.re_io = StringIO(content) username = request.form.get(&#39;pma_username&#39;) if username: password = request.form.get(&#39;pma_password&#39;) if not self.write_pma_passwd(username,password): return Resp(&#39;未安装phpmyadmin&#39;) if puri in [&#39;logout.php&#39;,&#39;/logout.php&#39;]: self.write_pma_passwd(None,None) else: ... #如果是静态文件 return send_file(filename)

代码太长,我们不展开分析,只我写出来的部分。在请求的路径是/phpmyadmin/index.php且存在pma_username、pma_password时,则执行self.write_pma_passwd(username,password)。

跟进self.write_pma_passwd:

def write_pma_passwd(self,username,password): &#39;&#39;&#39; @name 写入mysql帐号密码到配置文件 @author hwliang<2020-07-13> @param username string(用户名) @param password string(密码) @return bool &#39;&#39;&#39; self.check_phpmyadmin_phpversion() pconfig = &#39;cookie&#39; if username: pconfig = &#39;config&#39; pma_path = &#39;/www/server/phpmyadmin/&#39; pma_config_file = os.path.join(pma_path,&#39;pma/config.inc.php&#39;) conf = public.readFile(pma_config_file) if not conf: return False rep = r"/\* Authentication type \*/(.|\n)+/\* Server parameters \*/" rstr = &#39;&#39;&#39;/* Authentication type */ $cfg[&#39;Servers&#39;][$i][&#39;auth_type&#39;] = &#39;{}&#39;; $cfg[&#39;Servers&#39;][$i][&#39;host&#39;] = &#39;localhost&#39;; $cfg[&#39;Servers&#39;][$i][&#39;port&#39;] = &#39;{}&#39;; $cfg[&#39;Servers&#39;][$i][&#39;user&#39;] = &#39;{}&#39;; $cfg[&#39;Servers&#39;][$i][&#39;password&#39;] = &#39;{}&#39;; /* Server parameters */&#39;&#39;&#39;.format(pconfig,self.get_mysql_port(),username,password) conf = re.sub(rep,rstr,conf) public.writeFile(pma_config_file,conf) return True

这个代码也很好理解了,如果传入了username和password的情况下,宝塔会改写phpmyadmin的配置文件config.inc.php,将认证方式改成config,并写死账号密码。

这就是为什么7.4.2版本中pma可以直接访问的原因。

补个课:phpmyadmin支持数种认证方法,默认情况下是Cookie认证,此时需要输入账号密码;用户也可以将认证方式修改成Config认证,此时phpmyadmin会使用配置文件中的账号密码来连接mysql数据库,即不用再输入账号密码。

四、官方做这些动作的原因

其实各位看官看到这里肯定脑子里还是一团浆糊,这些代码究竟意味着什么呢?为什么官方要将认证模式改成config模式?

是很多漏洞分析文章的通病,这些文章在出现漏洞后跟一遍漏洞代码,找到漏洞发生点和利用方法就结束了,并没有深入研究开发为什么会这么写,那么下次你还是挖不出漏洞。

所以,这里思考一下,我们现在起码还有下列疑问:

在7.4.2版本以前,用户是如何使用phpmyadmin的?

宝塔为什么要在7.4.2版本增加phpmyadmin有关的视图?

宝塔为什么要将phpmyadmin认证模式改成config?

我们如何复现这个漏洞?

第一个问题,我们其实可以简单找到答案。在正常安装宝塔最新版7.4.3时,我们点击宝塔后台的phpmyadmin链接,会访问到这样一个路径:

b678601f9e10d03b18ed8edf71b63a0.png

7.4.3版本为了修复这个漏洞,回滚了部分代码,所以这种方式其实就是7.4.2以前版本的phpmyadmin的访问方式:通过888端口下的一个以phpmyadmin_开头的文件夹直接访问phpmyadmin。

这种老的访问方法中,888端口是一个单独的Nginx或Apache服务器,整个东西是安全的,访问也需要输入账号密码。

但是这种访问方法有些麻烦,需要额外开放888端口,而且每次登陆都要重新输入密码。所以,官方开发人员提出了一种新的做法,在宝塔后端的python层面转发用户对phpmyadmin的请求给php-fpm。这样有三个好处:

直接在python层面做用户认证,和宝塔的用户认证进行统一,不需要多次输入mysql密码

也不需要再对外开放888端口了

使用phpmyadmin也不再依赖于Nginx/Apache等服务器中间件了

这就是为什么宝塔要在7.4.2增加phpmyadmin有关的视图的原因,这个视图就是一个phpmyadmin的代理,做的事情就是转发用户的请求给php-fpm。

用户在第一次使用这种方式登录时,系统会自动发送包含了Mysql账号密码的数据包,宝塔后端会捕捉到此时的账号密码,填入phpmyadmin的配置文件,并将认证方式改成config。对于用户来说,感受到的体验就是,不再需要输入任何Mysql密码即可使用phpmyadmin了。

这的确给用户的使用带来了更好的体验。

五、漏洞复现

此时我们应该还有个疑问:既然官方目的是“直接在python层面做用户认证,和宝塔的用户认证进行统一”,那么仍然是有认证的呀?为什么会出现未授权访问漏洞呢?

我们可以来复现一下这个漏洞。首先,我们以系统管理员的身份登录宝塔后台,来到数据库页面,点击“phpMyAdmin”按钮,会弹出如下模态框:

7fa30bdf20eab63dd56755d61cee440.png

这个里面有两种访问模式,“通过Nginx/Apache/OIs访问”是老版本的访问方式,“通过面板安全访问”就是7.4.2新增加的代理模式。

我们点击“通过面板安全访问”,并抓包,会抓到这样一个数据包:

6914eecff6f59abcea46f1c3a8522f0.png

宝塔前端将我们的Mysql账号密码填好了直接发给phpmyadmin。又因为我们前面分析过的那段代码,后台将账号密码直接写入了phpmyadmin配置文件,来做到免认证的逻辑。

如果一个未认证的用户,直接访问http://ip:8888/phpmyadmin/index.php呢?会被直接重定向到登录页面:

4598a34ea51d0c500b02406b886a589.png

如果仅仅是这样,这个过程是不存在漏洞的。但是,官方开发人员犯了一个错误,他将pma应用放在了/www/server/phpmyadmin目录下,而这个目录原本是老的phpmyadmin访问方式所使用的Web根目录。

这意味着,我通过老的888端口+pma目录,可以访问到新的phpmyadmin,而新的phpmyadmin又被官方修改了配置文件,最终导致了未授权访问漏洞:

0a30c32ee0fbdf5336685701172e2ac.png

所以,如何解决这个问题呢?也很简单,只需要将pma移到其他目录去即可。

六、总结

我们来做个总结。

首先,宝塔面板绝对不是弱智,这个漏洞不是简简单单的放了一个未授权的pma在外面忘记删。这其实会打很多人脸,因为大部分人认为这只是个简单的phpmyadmin未授权访问漏洞,并对宝塔进行了一顿diss,没有想到这后面其实是一个复杂的逻辑错误。

其次,用户体验和安全绝对是不冲突的,我十分不喜欢为了保障安全而阉割用户体验的做法。所以希望宝塔官方不会因为这次的漏洞事件而彻底将代码回滚(据说7.4.3的更新只是临时解决方案),该改进的地方还是要改进。

我有数年不再使用Linux面板了,这次也算重新体验了一下2020年的Linux面板,个人感觉宝塔看外在其实是一个比较注重安全的系统,比如自动生成的用户密码、用户名和密码的策略、默认的Php安全配置、自动的版本更新等等,相比于很多国内其他的商业系统,绝对属于有过之而无不及了。但是看代码其实需要改进的地方还有很多,这个以后有机会再细说吧。

本文来自公众号:https://mp.weixin.qq.com/s/3ZjwFo5gWlJACSkeYWQLXA

以上就是宝塔面板phpMyAdmin未授权访问安全漏洞是个低级错误吗?的详细内容,更多请关注知识资源分享宝库其它相关文章!

版权声明

本站内容来源于互联网搬运,
仅限用于小范围内传播学习,请在下载后24小时内删除,
如果有侵权内容、不妥之处,请第一时间联系我们删除。敬请谅解!
E-mail:dpw1001@163.com

分享:

扫一扫在手机阅读、分享本文

发表评论
热门文章
  • 华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀

    华为 Mate 70 性能重回第一梯队 iPhone 16 最后一块遮羞布被掀
    华为 mate 70 或将首发麒麟新款处理器,并将此前有博主爆料其性能跑分将突破110万,这意味着 mate 70 性能将重新夺回第一梯队。也因此,苹果 iphone 16 唯一能有一战之力的性能,也要被 mate 70 拉近不少了。 据悉,华为 Mate 70 性能会大幅提升,并且销量相比 Mate 60 预计增长40% - 50%,且备货充足。如果 iPhone 16 发售日期与 Mate 70 重合,销量很可能被瞬间抢购。 不过,iPhone 16 还有一个阵地暂时难...
  • 惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起

    惠普新款战 99 笔记本 5 月 20 日开售:酷睿 Ultra / 锐龙 8040,4999 元起
    本站 5 月 14 日消息,继上线官网后,新款惠普战 99 商用笔记本现已上架,搭载酷睿 ultra / 锐龙 8040处理器,最高可选英伟达rtx 3000 ada 独立显卡,售价 4999 元起。 战 99 锐龙版 R7-8845HS / 16GB / 1TB:4999 元 R7-8845HS / 32GB / 1TB:5299 元 R7-8845HS / RTX 4050 / 32GB / 1TB:7299 元 R7 Pro-8845HS / RTX 2000 Ada...
  • 酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元

    酷凛 ID-COOLING 推出霜界 240/360 一体水冷散热器,239/279 元
    本站 5 月 16 日消息,酷凛 id-cooling 近日推出霜界 240/360 一体式水冷散热器,采用黑色无光低调设计,分别定价 239/279 元。 本站整理霜界 240/360 散热器规格如下: 酷凛宣称这两款水冷散热器搭载“自研新 V7 水泵”,采用三相六极马达和改进的铜底方案,缩短了水流路径,相较上代水泵进一步提升解热能力。 霜界 240/360 散热器的水泵为定速 2800 RPM 设计,噪声 28db (A)。 两款一体式水冷散热器采用 27mm 厚冷排,...
  • Nginx服务器的HTTP/2协议支持和性能提升技巧介绍

    Nginx服务器的HTTP/2协议支持和性能提升技巧介绍
    Nginx服务器的HTTP/2协议支持和性能提升技巧介绍 引言:随着互联网的快速发展,人们对网站速度的要求越来越高。为了提供更快的网站响应速度和更好的用户体验,Nginx服务器的HTTP/2协议支持和性能提升技巧变得至关重要。本文将介绍如何配置Nginx服务器以支持HTTP/2协议,并提供一些性能提升的技巧。 一、HTTP/2协议简介:HTTP/2协议是HTTP协议的下一代标准,它在传输层使用二进制格式进行数据传输,相比之前的HTTP1.x协议,HTTP/2协议具有更低的延...
  • 两个表格切换的快捷键是什么

    两个表格切换的快捷键是什么
    两个表格切换的快捷键是“ctrl+pageup”和“ctrl+pagedown”,按键盘上的“ctrl+pageup”键是向右切换表格,按“ctrl+pagedown”键是向左切换表格。 本教程操作环境:windows7系统、Microsoft Office Excel2010版、Dell G3电脑。 两个工作表之间切换是Ctrl+Tab,两个工作簿之间切换是Ctrl+PageUP和Ctrl+PageDown。 打开Excel表格,打开几个工作簿。 按键盘上的Ctrl+P...