bt未授权访问phpmyadmin

宝塔面板未授权访问phpmyadmin

关于宝塔

之前是用过一段时间的宝塔的,感觉很方便,功能也很齐全。

但是宝塔一直被披露有很多安全漏洞。

今天看了源码才知道是用flask写的。

这次的未授权访问phpmyadmin影响的版本:

Linux正式版7.4.2
Linux测试版7.5.13
Windows正式版6.8

环境搭建

docker pull tim2docker/baota2:v1
sudo docker run -d -it --name="pma" -p 8888:8888 -p 888:888 -p 2279:2279 tim2docker/baota2:v1
sudo docker exec -it pma bt restart
sudo docker exec -it pma bt default

使用docker简单方便快速的搭建出环境

初始化完成后访问他给定的url,使用账号密码登录进入宝塔面板

并进入软件管理启动php,mysql,nginx

至此,环境搭建完毕!

漏洞复现

直接访问http://192.168.112.129:888/pma

可以很清楚的看到已经成功的进入到了phpmyadmin,并且已经是登录状态了,绕过了权限认证!

简单叙述一下原理

1. 关于宝塔中用户进入phpmyadmin的认证

在7.4.2点击访问phpmyadmin有两种方式:

  • 通过安全面板授权访问
    • 这种方式访问的url为:http://192.168.112.129:2279/phpmyadmin/index.php
    • 可以看到是通过宝塔的端口以及认证实现的
  • 通过Nginx/Apache访问
    • 这种方式访问的url为:http://192.168.112.129:888/phpmyadmin_c8483cecf22859f0/index.php
    • 这是为phpmyadmin服务单独开放的888端口

然而在之前的版本只有一种方式:

  1. 通过Nginx/Apache访问

这不得不归功于7.4.2版本的升级:

更新日志:
1、增加phpMyAdmin安全访问模块
2、调整面板自带PHP解释器的可靠性
3、修复因增加ols环境导致的一些问题
4、修复小程序扫码登录和绑定问题
5、修改sessionid为通用key

然后贴一下phpmyadmin本身的认证机制:

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

2. 新版本宝塔7.4.2通过安全面板授权访问phpmyadmin的流程

在第一次点击安全面板授权登录的时候,bt前段会把数据库的账号密码发送到phpmyadmin,然后经过下面的代码处理,把账号密码写到配置文件,这样就不需要输入账号密码登录了。

核心代码在这里

                if request.method == 'POST':
                   #登录phpmyadmin
                   if puri in ['index.php','/index.php']:
                       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('pma_username')
                       if username:
                           password = request.form.get('pma_password')
                           if not self.write_pma_passwd(username,password):
                               return Resp('未安装phpmyadmin')

如果尝试登录phpmyadmin,并且请求附带pma_usernamepma_password会执行self.write_pma_passwd(username,password)

    def write_pma_passwd(self,username,password):
       '''
          @name 写入mysql帐号密码到配置文件
          @author hwliang<2020-07-13>
          @param username string(用户名)
          @param password string(密码)
          @return bool
      '''

       self.check_phpmyadmin_phpversion()
       pconfig = 'cookie'
       if username:
           pconfig = 'config'
       pma_path = '/www/server/phpmyadmin/'
       pma_config_file = os.path.join(pma_path,'pma/config.inc.php')
       conf = public.readFile(pma_config_file)
       if not conf: return False
       rep = r"/\* Authentication type \*/(.|\n)+/\* Server parameters \*/"
       rstr = '''/* Authentication type */
$cfg['Servers'][$i]['auth_type'] = '{}';
$cfg['Servers'][$i]['host'] = 'localhost';
$cfg['Servers'][$i]['port'] = '{}';
$cfg['Servers'][$i]['user'] = '{}';
$cfg['Servers'][$i]['password'] = '{}';
/* Server parameters */'''.format(pconfig,self.get_mysql_port(),username,password)
       conf = re.sub(rep,rstr,conf)
       public.writeFile(pma_config_file,conf)
       return True

很清楚的可以看到直接把账号密码写死在了config.inc.php

但是,这样的话未授权的用户无论访问哪个url都是不能绕过授权的,第一个url没有授权的话会直接重定向到主页,第二个会让你填写账号密码

3. 错误的文件放置目录

根据2的叙述,使用bt面板进行流量转发的时候转发到的肯定是某个目录下存放的phpmyadmin应用,那么

只要能找到phpmyadmin的根目录就可以完成未授权访问了

很遗憾,bt的开发人员把新的pma目录放到了/www/server/phpmyadmin

这是老版本访问phpmyadmin的根路径

可以看到这个目录放了2个文件夹

  • phpmyadmin_c8483cecf22859f0
  • pma

第一个里面的config.inc.php并没有写账号密码

而之前的代码刚好是写到了pma里面这个配置文件里面的:

pma_config_file = os.path.join(pma_path,'pma/config.inc.php')
public.writeFile(pma_config_file,conf)

所以访问http://192.168.112.129:888/pma即可成功访问phpmyadmin

这就导致了最后的未授权访问。

思考

其实宝塔这个不需要用户密码访问phpmyadmin想法真的挺不错的

给了用户很大的用户体验,有时候安全固然重要,但是用户体验也是一个很重要的指标

但是,这个漏洞的发生,确实给各大bt使用者,包括国家机关,政府企业以及个人用户带来了很大的损失,希望开发者多思考这些看似很愚蠢的很细小的逻辑错误。

Reference

来自p神的文章https://www.anquanke.com/post/id/215288

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇