0x01 关于 phpgithub
1
2
3
4
5
|
其历史相对已经比较久远了,这里也就不废话了,属弱类型中一种解释型语言
除了web开发以及写些简单的exp,暂未发现其它牛逼用途,暂以中小型web站点开发为主
另外,低版本的php自身漏洞就比较多,建议,从如今开始就在新项目中使用php
5.6.x 日后的版本
好在官方维护的一直比较勤奋,主次版本都迭代的比较快,最新版已经到
7.2.0
哼哼……是,
'最好的语言'... :)
|
0x02 这次演示环境web
1
2
|
CentOS6.8 x86_64 最小化,带基础库安装 eth0: 192.168.3.42 eth1: 192.168.4.14 eth2: 192.168.5.14
php-5.6.32.tar.gz 官方提供的源码包
|
0x03 下载 php-5.6.32.tar.gz
,并安装好php所需的各类依赖库sql
1
2
3
4
5
6
7
8
9
|
# yum install epel-release -y
# yum install -y zlib-devel libxml2-devel freetype-devel
# yum install -y libjpeg-devel libpng-devel gd-devel curl-devel libxslt-devel
# yum install openssl openssl-devel libmcrypt libmcrypt-devel mcrypt mhash mhash-devel -y
# tar xf libiconv-1.15.tar.gz
# cd libiconv-1.15
# ./configure --prefix=/usr/local/libiconv-1.15 && make && make install
# ln -s /usr/local/libiconv-1.15/ /usr/local/libiconv
# ll /usr/local/libiconv/
|
0x04 开始编译安装php5.6.32,要带的编译参数比较多,你们下去之后,能够仔细了解下这些参数都是干什么用的,其实,都是一些php内置功能模块,这里默认就已经启用了一些比较经常使用的模块,如,pdo,mysqli,关于下面的模块,并不用所有都装,根据你本身实际的开发业务需求,用什么装什么便可,切记,不要一上来无论用不用就先装一大堆,你不用,极可能就会被别人利用
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
# wget http://au1.php.net/distributions/php-5.6.32.tar.gz
# tar xf php-5.6.32.tar.gz
# cd php-5.6.32
# ./configure --help
# ./configure \
-
-prefix=/usr/local/php-5.6.32 \
-
-with-config-file-path=/usr/local/php-5.6.32/etc \
-
-with-mysql=/usr/local/mysql \
-
-with-mysqli=/usr/local/mysql/bin/mysql_config \
-
-with-pdo-mysql=/usr/local/mysql \
-
-with-iconv-dir=/usr/local/libiconv \
-
-with-freetype-dir \
-
-with-jpeg-dir \
-
-with-png-dir \
-
-with-zlib \
-
-with-libxml-dir=/usr \
-
-with-curl \
-
-with-mcrypt \
-
-with-gd \
-
-with-openssl \
-
-with-mhash \
-
-with-xmlrpc \
-
-with-xsl \
-
-with-fpm-user=nginx \
-
-with-fpm-group=nginx \
-
-enable-xml \
-
-disable-rpath \
-
-enable-bcmath \
-
-enable-shmop \
-
-enable-sysvsem \
-
-enable-inline-optimization \
-
-enable-mbregex \
-
-enable-fpm \
-
-enable-mbstring \
-
-enable-gd-native-ttf \
-
-enable-pcntl \
-
-enable-sockets \
-
-enable-soap \
-
-enable-short-tags \
-
-enable-static \
-
-enable-ftp \
-
-enable-opcache=no
|
1
2
3
|
# make && make install
# ln -s /usr/local/php-5.6.32/ /usr/local/php
# cp php.ini-production /usr/local/php/etc/php.ini 建立php解释器的配置文件
|
0x05 编辑,配置并优化php-fpm.conf
,即 fastcgi 的服务端
,以下
让php进程以一个系统伪用户的身份起来,在能知足实际业务需求的状况下,最大程度上下降php进程权限
1
2
3
4
5
|
# useradd -s /sbin/nologin -M phpfpm
# cp /usr/local/php/etc/php-fpm.conf.default /usr/local/php/etc/php-fpm.conf
# vi /usr/local/php/etc/php-fpm.conf
# mkdir /usr/local/php/logs
# egrep -v "^$|;" /usr/local/php/etc/php-fpm.conf 简化php-fpm配置文件
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
|
[global]
pid = /usr/local/php/logs/php-fpm.pid
error_log = /usr/local/php/logs/php-fpm.log
log_level =
error
rlimit_files = 32768
events.mechanism = epoll
[www]
user = phpfpm
group = phpfpm
listen = 127.0.0.1:9000
listen.owner = phpfpm
listen.group = phpfpm
pm = dynamic
pm.max_children = 1024
pm.start_servers = 16
pm.min_spare_servers = 5
pm.max_spare_servers = 20
pm.max_requests = 2048
slowlog = /usr/local/php/logs/
$pool.log.slow
request_slowlog_timeout = 10
php_admin_value[sendmail_path] = /usr/sbin/sendmail -t -i -f klion@protonmail.com
security.limit_extensions = .php
|
1
2
3
4
5
|
# /usr/local/php/sbin/php-fpm 启动php-fpm
# ps -le | grep "php-fpm"
# netstat -tulnp | grep ":9000"
# echo "/usr/local/php/sbin/php-fpm" >> /etc/rc.local && cat /etc/rc.local
# killall php-fpm 若是想关闭php-fpm,直接把它进程kill掉便可
|
尝试让php与mysql,nginx 进行联动,看看php能不能被正常解析
1
2
3
4
5
6
7
8
|
<?php
$link = mysql_connect(
"localhost","root","admin") or die(mysql_error());
if($link){
echo "yeah , mysql connect succeed!";
}
else{
echo mysql_error();
}
?>
|
0x06 最后,咱们就来好好关注下php解析器自身的安全,php解析器的设置所有依靠php.ini
文件来实现,因此,下面就来详细说明一下针对php.ini的安全配置
1
|
# vi /usr/local/php/etc/php.ini
|
将 register_globals 项设为Off
,自己的意思就是注册为全局变量,也就是说,设置为On的时候,从客户端传过来的参数值会被直接注册到php全局变量中,在后端能够直接拿到该变量到脚本中使用,若是为Off,则表示只能到特定的全局数组中才能取到该数据,建议关闭,容易形成变量覆盖问题,不过在php高版本中 如,> 5.6.x
,已经去除对此项的设置,官方给的说明是这样的本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除
,若是你用的仍是低版本的php就须要注意把此项关闭
1
2
3
4
5
6
7
|
<?php
if($mark){
echo "login succeed! ";
}
else{
echo "login failed!";
}
?>
|
将 cgi.fix_pathinfo的值设为 0
,默认cgi.fix_pathinfo 项是开启的,即值为1,它会对文件路径自动进行修正,咱们要把它改为0,不要让php自动修正文件路径,防止入侵者利用此特性构造解析漏洞来配合上传webshell
建议同时关闭如下两项,若是实在有业务需求,请在代码中严格限制检查用户传过来的数据
1
2
3
4
5
6
|
allow_url_fopen = Off
allow_url_include = Off
|
禁用各类高危函数
,尽量让各类 webshell [ 一句话,大马 ]
没法再靠php内置函数来执行各类系统命令,说实话,禁用这些函数也并不能很好的防住什么,利用各类拆分拼装变形,依然很容易逃逸
,下面是一些比较常见的命令和代码执行函数,若是你还发现有其它的一些不经常使用的高危函数,也能够一并加进来,防止被入侵者率先发现并利用,此项默认为空,即关闭,另外,并非下面全部的函数都必定要禁用掉,务必要根据本身实际的开发业务来进行,实在用不到的,也不必让它留着,由于有些函数,开发可能会用,因此也不能盲注的去禁用,那就只能靠在代码中作更为严格的检查,中间的利害还要靠你们本身去定夺,这里仅仅只是个参考
1
|
disable_functions = dl,
eval,assert,popen,proc_close,gzinflate,str_rot13,base64_decode,exec,system,ini_alter,readlink,symlink,leak,proc_open,pope,passthru,chroot,scandir,chgrp,chown,escapeshellcmd,escapeshellarg,shell_exec,proc_get_status,max_execution_time,opendir,readdir,chdir,dir,unlink,delete,copy,rename,ini_set
|
转义开关
,主要用来转义各类特殊字符,如,单引号,双引号,反斜线和空字符...
我的建议,在这里先把它关闭,由于它并不能很好的防住sql注入,或者说,基本是防不住的,好比,利用宽字节 说到这儿,顺便再补充一句,对付宽字节的最好办法就是全站统一使用 utf-8
,这里仍是建议你们采用sql语句预编译和绑定变量的方式来预防sql注入,这也是目前为止比较切实有效的预防手段,对于从客户端过来的各类其它数据,能够单独写个检查类,若是你想安全就不要对这些开关寄予太大的但愿,可能php官方也发现,这个开关实质就是个摆设,因此给出了这样的说明本特性已自 PHP 5.3.0 起废弃并将自 PHP 5.4.0 起移除
1
2
|
magic_quotes_gpc = Off
magic_quotes_runtime = Off
|
关闭php自身的各类错误回显
,反正只要记得,在项目上线后,全部的程序错误一概接收到咱们本身事先准备好的地方[通常是日志]
,一旦被入侵者在前端看到,极易形成敏感信息泄露,高版本的php,默认这些危险项就是处于关闭状态的,另外,有条件的状况下务必把线上环境和测试开发环境隔离
,不要把过多但愿寄托于程序员,毕竟,你我都知道,那是根本不靠谱的 ^_^
1
2
3
4
5
6
7
|
display_errors = Off
error_reporting = E_WARING & ERROR
log_errors = On
error_log = /usr/local/php/logs/php_errors.log
log_errors_max_len = 2048
ignore_repeated_errors = Off
display_startup_errors = Off
|
隐藏php的详细版本号
,即X-Powered-By
中显示的内容,不得再也不次强调,有些漏洞只能针对特定的类型版本,在实际渗透过程当中,若是让入侵者看到详细的版本号,他极可能就会直接去尝试利用该版本所具备的一些漏洞特性再配合着其它漏洞一块儿使用
限制php对本地文件系统的访问
,即把全部的文件操做都限制指定的目录下,让php其实就是限制了像fopen()
这类函数的访问范围,通常主要用来防止旁站跨目录,把webshell死死控制在当前站点目录下,此项默认为空,不建议直接写到php.ini中,能够参考前面nginx安所有署中的,直接在每一个站点目录下新建一个.user.ini
而后再把下面的配置写进去便可,这样相对比较灵活
1
|
open_basedir = "/usr/local/nginx/html/bwapp/bWAPP:/usr/local/nginx/html/dvws/"
|
关于对服务端session的一些安全处理方式
隐藏后端使用的真正脚本类型,扰乱入侵者的渗透思路,另外,切记不要把敏感数据直接明文存在session中,有泄露风险
1
|
session
.name = JSESSIONID 表示jsp程序,php的则是PHPSESSID
|
修改session文件存放路径,最好不要直接放在默认的/tmp
目录下,实际中多是一台单独的session服务器,好比,memcached
1
2
|
session
.save_handler = memcache
session
.save_path = "tcp://192.168.3.42:11211"
|
安全模式
可根据实际业务需求选择性开启,安全模式的意思就是操做文件的函数只能操做与php进程UID相同的文件,但php进程的uid并不必定就是web服务用户的uid,这也就形成了麻烦,也就是说,你想避免这种麻烦,可能就须要在最开始配置时就让php进程和web服务使用同一个系统用户身份,但这又正好跟我前面说的相背了,咱们在前面说过,最好把php进程用户和web服务用户分开,这样更容易进行权限控制,另外,高版本的php[ > php5.4 ]
已再也不支持安全模式,由于官方可能也以为它并没什么卵用,并且低版本php的安全模式,还可被绕过,因此,若是你用的是低版本的php,请根据自身实际业务作取舍
1
2
|
safe_mode = On
safe_mode_gid = off
|
限制php单脚本执行时长,防止服务器资源被长期滥用而产生拒绝服务的效果
1
2
3
|
max_execution_time = 30
max_input_time = 60
memory_limit = 8M
|
关于上传,若是实际的业务根本不涉及到上传,直接把上传功能关掉便可,若是须要上传,再根据需求作出调整便可,对防入侵来说,这里对咱们意义并非很是大
1
2
3
4
|
file_uploads = On
upload_tmp_dir =
upload_max_filesize = 8M
post_max_size = 8M
|
0x07 利用 chattr
锁定一些不须要常常改动的重要配置文件,如,php-fpm.conf,php.ini,my.cnf…,为了防止chattr工具被别人滥用,你能够把它更名隐藏到系统的某个角落里,用的时候再拿出来
锁定
1
2
3
|
# chattr +i /usr/local/php/etc/php.ini
# chattr +i /usr/local/php/etc/php-fpm.conf
# chattr +i /etc/my.cnf
|
解锁
1
2
3
|
# chattr -i /usr/local/php/etc/php.ini
# chattr -i /usr/local/php/etc/php-fpm.conf
# chattr -i /etc/my.cnf
|
0x08 务必勤于关注php官方的高危补丁发布及说明,和其它工具不一样,php 自身bug多,由于关注的人多,搞的人也多,因此暴露出来的各类安全问题也就更多
0x09 最后,告诉你们一个怎么把曾经yum下来的包保留着的办法,在系统断网的状况下也许用的着,只需到yum配置里面去调整下便可,保留的包的路径也在yum配置中定义好了
小结:
至此为止,关于整套LNMP架构
的安所有署及优化,也就差很少完成了,咱们关注的点,更多可能仍是集中在防护入侵上,捎带了一点性能优化,这里所给的参数选项基本所有均可直接用于实战部署,但并非全部的参数配置都是必须的,还须要你好好根据本身实际的业务需求作出适当取舍,或者在此基础进行定制改进,有些地方都是基于本身平时实战经验的考量来的,并不必定彻底是对的,若是有性能更好,更安全的方案,也很是欢迎你们一块儿来私信交流 ^_^