宝塔迷
经验教程
优惠活动
模板美化
插件模块
脚本命令
实用软件
隐私安全
热门文章
CloudFlare公共优选Cname域名地址
【原创】宝塔海外版aapanel中文语言包
网站使用 CloudFlare 优选域名的方法
宝塔国际版aapanel(宝塔海外版)
【原创】新蓝白配色清新简约宝塔面板模板美化主题
标签搜索
宝塔linux面板
宝塔面板命令
宝塔面板教程
CloudFlare
宝塔面板插件
宝塔面板美化
宝塔面板服务管理
宝塔面板活动
安装宝塔面板
宝塔windows面板
AAPanel
宝塔面板模板
宝塔面板主题
宝塔面板降级
宝塔面板防火墙
SSH终端
宝塔面板登陆
宝塔面板工具
宝塔Linux面板7.7.0
宝塔面板app
发布
登录
最新发布
2021-09-01
宝塔面板PMA漏洞复现分析
周日晚,某群里突然发布了一则消息,宝塔面板的phpmyadmin存在未授权访问漏洞的紧急漏洞预警,并给出了一大批存在漏洞的URL: 120200829112700781.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。 在恢复代码之前,我们先将服务器断网,或者将宝塔设置成离线模式: 220200829112809930.png图片 这么做的目的是防止宝塔进行自动版本更新,避免好不容易恢复的代码又自动升级了。 宝塔系统代码默认安装完是在/www/server/panel,接着我们直接将将压缩包内的panel目录上传到这里来,覆盖掉已有的文件。重启下宝塔,即可发现系统版本号已经恢复成7.4.2了: 320200829112825497.png图片 还没完,我们使用beyond compare打开7.4.2和7.4.3的压缩包代码,先看看官方是怎么修复的漏洞: 420200829112834350.png图片 比较粗暴,直接判断目录/www/server/phpmyadmin/pma是否存在,如果存在就直接删掉。所以,我们虽然恢复了系统版本代码,但删掉的pma已经不在了,我们还需要恢复一下这个目录。 方法也很简单,/www/server/phpmyadmin下本身存在一个phpmyadmin目录,我们直接复制一下这个目录即可: 520200829112851527.png图片 漏洞究竟是怎么回事 有了环境,我们仍需看看代码。 首先,由于7.4.2是引入漏洞的版本,我们看看官方对7.4.2的更新日志: 620200829112900300.png图片 用beyond compare打开7.4.0和7.4.2的压缩包代码,看看具体增加了哪些代码: 720200829112908390.png图片 可见,在7.4.2版本中增加了两个视图,分别对应着phpmyadmin和adminer。视图中用到了panelPHP#start方法,这个方法其实也是新加的: def start(self,puri,document_root,last_path = ''): ''' @name 开始处理PHP请求 @author hwliang<2020-07-11> @param puri string(URI地址) @return socket or Response ''' ... #如果是PHP文件 if puri[-4:] == '.php': if request.path.find('/phpmyadmin/') != -1: ... 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') if puri in ['logout.php','/logout.php']: 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): ''' @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 这个代码也很好理解了,如果传入了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链接,会访问到这样一个路径: 82020082911312125.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”按钮,会弹出如下模态框: 92020082911322887.png图片 这个里面有两种访问模式,“通过Nginx/Apache/OIs访问”是老版本的访问方式,“通过面板安全访问”就是7.4.2新增加的代理模式。 我们点击“通过面板安全访问”,并抓包,会抓到这样一个数据包: 102020082911323695.png图片 宝塔前端将我们的Mysql账号密码填好了直接发给phpmyadmin。又因为我们前面分析过的那段代码,后台将账号密码直接写入了phpmyadmin配置文件,来做到免认证的逻辑。 如果一个未认证的用户,直接访问http://ip:8888/phpmyadmin/index.php呢?会被直接重定向到登录页面: 1120200829113246497.png图片 如果仅仅是这样,这个过程是不存在漏洞的。但是,官方开发人员犯了一个错误,他将pma应用放在了/www/server/phpmyadmin目录下,而这个目录原本是老的phpmyadmin访问方式所使用的Web根目录。 这意味着,我通过老的888端口+pma目录,可以访问到新的phpmyadmin,而新的phpmyadmin又被官方修改了配置文件,最终导致了未授权访问漏洞: 1220200829113257588.png图片 所以,如何解决这个问题呢?也很简单,只需要将pma移到其他目录去即可。 总结 我们来做个总结。 首先,宝塔面板绝对不是弱智,这个漏洞不是简简单单的放了一个未授权的pma在外面忘记删。这其实会打很多人脸,因为大部分人认为这只是个简单的phpmyadmin未授权访问漏洞,并对宝塔进行了一顿diss,没有想到这后面其实是一个复杂的逻辑错误。 其次,用户体验和安全绝对是不冲突的,我十分不喜欢为了保障安全而阉割用户体验的做法。所以希望宝塔官方不会因为这次的漏洞事件而彻底将代码回滚(据说7.4.3的更新只是临时解决方案),该改进的地方还是要改进。 我有数年不再使用Linux面板了,这次也算重新体验了一下2020年的Linux面板,个人感觉宝塔看外在其实是一个比较注重安全的系统,比如自动生成的用户密码、用户名和密码的策略、默认的Php安全配置、自动的版本更新等等,相比于很多国内其他的商业系统,绝对属于有过之而无不及了。但是看代码其实需要改进的地方还有很多,这个以后有机会再细说吧。
隐私安全
# 宝塔面板漏洞
gacjie
3年前
0
708
0
2021-08-18
宝塔linux面板7.7.0正式版
1、旧版本的面板可能存在未知安全隐患,因此建议仅用于如本地开发测试环境,生产环境使用建议做好如防火墙安全组限制IP访问等安全设置,不要依靠宝塔相关安全服务。 2、由于宝塔将下载站的历史升级包篡改删除,7.7.0版本安装过程少部分文件来自本站,安装后的所有功能均链接官方,因此官方若修改更新一些文件,可能会导致面板无法安装使用(也就是失效)。如遇到可联系我修复。 3、由于7.7.0是旧版本,因版本迭代更新的原因,面板运行环境互不兼容,建议尽可能全新安装而不是降级。
脚本命令
# 宝塔面板教程
# 宝塔linux面板
# 宝塔面板降级
# 宝塔面板登陆
# 宝塔面板版本
# 宝塔Linux面板7.7.0
gacjie
3年前
0
1,384
0
2020-12-01
宝塔Windows面板下载安装教程
宝塔Windows面板是提升运维效率的服务器管理软件,最新面板仅支持Windows Server 2008 R2/2012/2016/2019/2022,64位系统(中文简体),且未安装其它环境,低于08 R2或其它系统(包括家用系统,家用推荐安装方法)不建议安装使用。 支持一键WNMP/WAMP/IIS/SQLServer/集群/监控/网站/FTP/数据库/JAVA/PM2等100多项服务器管理功能。 演示图片 home.png图片 下载地址 https://download.bt.cn/win/panel/BtSoft.zip
经验教程
# 宝塔面板教程
# 安装宝塔面板
# 宝塔windows面板
gacjie
4年前
0
50
0
2020-12-01
宝塔面板app安装使用教程
宝塔App是提升运维效率的服务器管理软件,支持一键LAMP/LNMP/集群/监控/网站/FTP/数据库/JAVA等100多项服务器管理功能。 演示图片 home.png图片 下载地址 https://download.bt.cn/app/apk/BT-App.apk
经验教程
# 宝塔面板教程
# 宝塔面板app
# 宝塔面板手机端
gacjie
4年前
0
330
0
2019-09-03
宝塔Linux面板5.9.2正式版
安装要求 Python版本: 2.6/2.7(安装宝塔时会自动安装) 内存:128M以上,推荐512M以上(纯面板约占系统10M内存) 硬盘:100M以上可用硬盘空间(纯面板约占20M磁盘空间) 系统:CentOS 6.x / 7.x (Ubuntu、Debian、Fedora 请点这里), 确保是干净的操作系统,不支持32位系统,没有安装过其它环境带的Apache/Nginx/php/MySQL(已有环境不可安装) Centos安装命令: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install.sh && sh install.shUbuntu/Deepin安装命令: wget -O install.sh http://download.bt.cn/install/install-ubuntu.sh && sudo bash install.shDebian安装命令: wget -O install.sh http://download.bt.cn/install/install-ubuntu.sh && bash install.shFedora安装命令: wget -O install.sh http://download.bt.cn/install/install.sh && bash install.sh更新命令(仅限3.x - 5.x版本使用!不支持2.X,6.X面板!): wget -O update.sh http://download.bt.cn/install/update.sh && sh update.sh降级命令(以5.9.1为例,请改为你需要降级到的版本。): wget -O update.sh http://download.bt.cn/install/update.sh && sed -i 's/LinuxPanel-${version}/LinuxPanel-5.9.1/g' update.sh && sh update.sh升级专业版 wget -O update.sh http://download.bt.cn/install/update_pro.sh && bash update.sh pro解锁专业版(需要先升级专业版) sed -i 's/panelAuth.panelAuth().get_order_status(None)/{"status" : True,"msg" : {"endtime" : 32503651199 }}/g' /www/server/panel/class/common.py && echo '' > /www/server/panel/data/userInfo.json && /etc/init.d/bt restart恢复免费版 wget -O update.sh http://download.bt.cn/install/update.sh && bash update.sh free
脚本命令
# 安装宝塔面板
# 宝塔面板命令
# 宝塔面板脚本
# 宝塔Linux面板5.9
gacjie
5年前
0
828
2
上一页
1
...
12
13