PHP 安全篇|通过给网站植入 WebShell 来加固服务器安全

作为开发者,很多人往往忽略一些安全性问题,无论是业务逻辑,还是代码安全,又或者是服务器安全、数据库安全等等。

本文以攻击者的视角,逐步测试实现可利用的漏洞或者令我们忽视的问题,加固一些安全策略或者设置来让服务器提高一定的安全性。

以 PHP 项目为例,Nginx+MySQL 的基础组件来展开相关工作 ,其他 WEB 端也可以参照。

注:测试时请备份线上环境,或者进行快照操作,避免某些马有残留无法清除。

本机测试机器为 CentOS7,部署了基本的 Nginx、PHP、MySQL、无特殊安全项配置等。

1.手工传马到项目中

手工传一个 PHP 马到项目根目录中,模拟被上传大马后的操作场景。

大马下载地址网上有很多,这里推荐几个,不保证没后门。测试需注意

通过 vi 写入木马到项目根目录中,并保存为 webshell.php

由于是通过 root 用户直接写入的,导致马的权限非常大。

访问大马文件

正确显示如下,输入密码进行登录。

进入后的界面如下

左侧菜单为不同功能类、右边为具体的工作区。

点击上级目录、或者输入系统任何地址,可以直接进行读取。

可以跨站读写

/tmp 可写

/etc/passwd 可读

网卡配置信息可查看

系统命令执行

查看系统监听端口

端口监听情况

常用端口扫描

局域网端口扫描

查看系统进程

解决问题

总结一下,上面存在很多问题,比如跨站读写、系统文件可读、常用 bash 命令执行等。

下面我们逐步进行解决。

1.跨站/目录 读写

解决方案就是设置 PHP 的限制目录参数,可以通过 Nginx 参数配置,也可以通过 php.ini 配置,也可以通过站点下.user.ini 文件进行配置。

这里演示使用 nginx 进行参数设置

fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/tmp/:/proc/";

其允许访问目录为站点目录,以及系统缓存目录(上传文件用到的),以及 proc 目录(PHP 用到的一些系统指针相关操作)。

完整配置如下:

location ~ .*\.(php|php5)?$ {
	fastcgi_pass 127.0.0.1:9000;
	fastcgi_index index.php;
	fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
	fastcgi_param  SCRIPT_NAME $fastcgi_script_name;
	fastcgi_param PHP_ADMIN_VALUE "open_basedir=$document_root:/tmp/:/proc/";
	include fastcgi_params;
}

另外附上 .user.ini 的配置,作用相同

open_basedir=/tmp/:/proc/:./

需要注意的是,.user.ini 需要进行加锁,加锁之后的文件不允许被修改删除,这样防止被上传等漏洞进行修改越权。

# 加锁命令
chattr +i .user.ini

# 解锁命令
chattr -i .user.ini

在测试权限过程中,还需要注意 system 方法不受 open_basedir 配置约束。需要测试越权,可以通过 scandir 进行测试。

2.禁用系统命令

禁用项目中用不到,又比较危险的函数,如 shell_exec、exec、system、popen、passthru。

这里依然使用 Nginx 进行设置、如果站点较多也可在 php.ini 设置全局的限制。

限制常用的 SHELL 命令执行函数,避免通过 shell 获取系统信息,或者执行其他木马。

fastcgi_param PHP_ADMIN_VALUE "disable_functions=shell_exec,exec,system,popen,passthru,popen,proc_open,mail";

如果项目中没有进程管道之类的操作,没有 socket 相关操作,也可以使用如下参数,将其一并禁用。

fastcgi_param PHP_ADMIN_VALUE "disable_functions=system,exec,shell_exec,passthru,proc_open,proc_close, proc_get_status,checkdnsrr,getmxrr,getservbyname,getservbyport, syslog,popen,show_source,highlight_file,dl,socket_listen,socket_create,socket_bind,socket_accept, socket_connect, stream_socket_server, stream_socket_accept,stream_socket_client,ftp_connect, ftp_login,ftp_pasv,ftp_get,sys_getloadavg,disk_total_space, disk_free_space,posix_ctermid,posix_get_last_error,posix_getcwd, posix_getegid,posix_geteuid,posix_getgid, posix_getgrgid,posix_getgrnam,posix_getgroups,posix_getlogin,posix_getpgid,posix_getpgrp,posix_getpid, posix_getppid,posix_getpwnam,posix_getpwuid, posix_getrlimit, posix_getsid,posix_getuid,posix_isatty, posix_kill,posix_mkfifo,posix_setegid,posix_seteuid,posix_setgid, posix_setpgid,posix_setsid,posix_setuid,posix_strerror,posix_times,posix_ttyname,posix_uname,mail";

(吃饭去了,待补充)

Comments