8.7-8.8任务

11.28 限定某个目录禁止解析php

需求:我们某些目录允许用户上传图片、文档等文件,如果有恶意用户上传一些php木马文件,我们的服务器就危险了,所以对于用户能够上传的目录,我们需要限定某个目录禁止解析php。#(sql注入漏洞了解一下)(web安全了解一下)

场景:猜想是SQL漏洞,抓包查询查询数据库的请求,发现某个不寻常的请求来源于某个图片目录下的php文件,里面写有一句话木马。

    <Directory /usr/local/apache2.4/docs/dummy-host2.example.com/upload>
        php_admin_flag engine off
        <FilesMatch (.+)\.php(.*)>
            Order allow,deny
            Deny from all
        </FilesMatch>
    </Directory>

filesmatch可有可无。虽然都不能解析,但是没有filesmatch会被看到源码,不友好。

[root@localhost: ~]# curl -x127.0.0.1:80 'http://dummy-host2.example.com/upload/123.php' -I
HTTP/1.1 403 Forbidden
Date: Mon, 06 Aug 2018 15:31:39 GMT
Server: Apache/2.4.32 (Unix) PHP/5.6.30
Content-Type: text/html; charset=iso-8859-1

我们把filesmatch注释掉之后,

[root@localhost: ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.conf 
[root@localhost: ~]# /usr/local/apache2.4/bin/apachectl graceful
[root@localhost: ~]# curl -x127.0.0.1:80 'http://dummy-host2.example.com/upload/123.php'
<?php 
	echo "123.php";
?>

访问123.php就会变为源码,不会被解析。这种静态文件目录下是不建议放置php文件的。

11.29 限制user_agent

user_agent可以看做一个浏览器的标识。

CC攻击

攻击者借助代理服务器生成指向受害主机的合法请求,实现DDOS和伪装就叫:CC(ChallengeCollapsar)。

CC主要是用来攻击页面的。大家都有这样的经历,就是在访问论坛时,如果这个论坛比较大,访问的人比较多,打开页面的速度会比较慢,访问的人越多,论坛的页面越多,数据库压力就越大,被访问的频率也越高,占用的系统资源也就相当可观。

一个静态页面不需要服务器多少资源,甚至可以说直接从内存中读出来发给你就可以了,但是论坛就不一样了,我看一个帖子,系统需要到数据库中判断我是否有读帖子的权限,如果有,就读出帖子里面的内容,显示出来——这里至少访问了2次数据库,如果数据库的数据容量有200MB大小,系统很可能就要在这200MB大小的数据空间搜索一遍,这需要多少的CPU资源和时间?如果我是查找一个关键字,那么时间更加可观,因为前面的搜索可以限定在一个很小的范围内,比如用户权限只查用户表,帖子内容只查帖子表,而且查到就可以马上停止查询,而搜索肯定会对所有的数据进行一次判断,消耗的时间是相当的大。

CC就是充分利用了这个特点,模拟多个用户(多少线程就是多少用户)不停的进行访问(访问那些需要大量数据操作,就是需要大量CPU时间的页面).这一点用一个一般的性能测试软件就可以做到大量模拟用户并发。

用几千台几万台肉鸡去同时访问一个网站,而这个网站服务器性能不好或者没有高并发处理,就很容易挂掉这个网站。

这些访问都是正常请求,我们可以通过识别这个规律的user_agent来阻止cc攻击。

    <IfModule mod_rewrite.c>
        RewriteEngine on
        RewriteCond %{HTTP_USER_AGENT}  .*curl.* [NC,OR] //这里是两个条件,没有OR默认为AND
        RewriteCond %{HTTP_USER_AGENT}  .*baidu.com.* [NC] //NC标识忽略大小写
        RewriteRule  .*  -  [F] //F为forbidden
    </IfModule>

这样使用curl访问就会被禁止。

[root@localhost: ~]# curl -x127.0.0.1:80 http://dummy-host2.example.com/123.php
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /123.php
on this server.<br />
</p>
</body></html>

但是使用chrome访问就可以。

同样curl -A可以定义user_agent,更换agent就可以了。

[root@localhost: ~]# curl -A "lalala" -x127.0.0.1:80 http://dummy-host2.example.com/123.php
123.php[root@localhost: ~]# 
[root@localhost: ~]# curl -A "baiDU" -x127.0.0.1:80 http://dummy-host2.example.com/123.php
[root@localhost: ~]# vim /usr/local/apache2.4/conf/extra/httpd-vhosts.confst: ~]# 
[root@localhost: ~]# curl -A "baiDU.com" -x127.0.0.1:80 http://dummy-host2.example.com/123.php
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /123.php
on this server.<br />
</p>
</body></html>
[root@localhost: ~]# tail -5 /usr/local/apache2.4/logs/dummy-host2.example.com-access_20180806.log 
192.168.244.1 - - [06/Aug/2018:23:47:31 +0800] "GET /123.php HTTP/1.1" 301 246 "-" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3486.0 Safari/537.36"
192.168.244.1 - - [06/Aug/2018:23:47:31 +0800] "GET /123.php HTTP/1.1" 200 7 "-" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3486.0 Safari/537.36"
127.0.0.1 - - [06/Aug/2018:23:50:07 +0800] "GET http://dummy-host2.example.com/123.php HTTP/1.1" 200 7 "-" "lalala"
127.0.0.1 - - [06/Aug/2018:23:50:23 +0800] "GET http://dummy-host2.example.com/123.php HTTP/1.1" 200 7 "-" "baiDU"
127.0.0.1 - - [06/Aug/2018:23:50:51 +0800] "GET http://dummy-host2.example.com/123.php HTTP/1.1" 403 216 "-" "baiDU.com"

这就是如何过滤user_agent的方法。

11.30/31 php相关配置

查看php的配置文件的路径,

[root@localhost: ~]# /usr/local/php5/bin/php -i | grep -i "loaded configuration file"
Loaded Configuration File => /usr/local/php5/etc/php.ini

当然,这里查看的有可能不是你站点的配置,想查看站点的配置文件应该在站点的根目录写一个带有phpinfo()的页面,去查询配置文件。

在这里我重新编辑了一下host2的主页,

这里的路径就是准确的pho.ini的位置。

打开php.ini,查看一下配置。最重要的就是disable functions,就是列出的函数在php文件中是不能使用的,

disable_functions = eval,assert,popen,passthru,escapeshellarg,escapeshellcmd,passthru,exec,system,chroot,scandir,chgrp,chown,escapeshellcmd,escapeshellarg,shell_exec,proc_get_status,ini_alter,ini_restore,dl,pfsockopen,openlog,syslog,readlink,symlink,leak,popepassthru,stream_socket_server,popen,proc_open,proc_close,phpinfo

一般线上会禁掉phpinfo,因为会暴露自己的目录信息。

[root@localhost: ~]# curl -x192.168.244.128:80 'dummy-host2.example.com/index.php'
host2
[root@localhost: ~]# cat /usr/local/apache2.4/docs/dummy-host2.example.com/index.php
<?php
	echo "host2\n";
	phpinfo();
?>

线下的时候我们还需要使用phpinfo,所以暂时先打开。

data.timezone也需要定义一下,如果不定义会出现警告。

PHP Warning:  Unknown: It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in Unknown on line 0

我们可以把时区定义到上海,重庆,北京等,

date.timezone = Asia/Shanghai

php_error也是在线下显示帮助你查找错误,

; http://php.net/display-errors
display_errors = On

比如打开之后,我把phpinfo禁掉,就会报错,也会泄露目录信息。

[root@localhost: ~]# curl -x192.168.244.128:80 'dummy-host2.example.com/index.php'
host2
<br />
<b>Warning</b>:  phpinfo() has been disabled for security reasons in <b>/usr/local/apache2.4/docs/dummy-host2.example.com/index.php</b> on line <b>3</b><br />

所以线上关闭就好。如果想常闭,那我们配置一下error_log就好了。

; http://php.net/log-errors
log_errors = On

error_log = /tmp/php_errors.log

; Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
; http://php.net/error-reporting
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT

我们重新访问一下,

root@localhost: ~]# curl -x192.168.244.128:80 'dummy-host2.example.com/index.php'
host2
<br />
<b>Warning</b>:  phpinfo() has been disabled for security reasons in <b>/usr/local/apache2.4/docs/dummy-host2.example.com/index.php</b> on line <b>3</b><br />
[root@localhost: ~]# cat /tmp/php
php_errors.log  php-gdtest/     
[root@localhost: ~]# cat /tmp/php_errors.log 
[07-Aug-2018 12:21:04 Asia/Shanghai] PHP Warning:  phpinfo() has been disabled for security reasons in /usr/local/apache2.4/docs/dummy-host2.example.com/index.php on line 3
[root@localhost: ~]# ll /tmp/php_errors.log 
-rw-r--r-- 1 daemon daemon 173 Aug  7 12:21 /tmp/php_errors.log

可以看到日志的属主是httpd进程的用户,如果没有生成日志,一定要查看定义的目录有没有设置权限。

也可以先创建目录文件,然后给一个777的权限。

我们在做一个测试,在php中加一行错误代码。

[root@localhost: ~]# head !$
head /usr/local/apache2.4/docs/dummy-host2.example.com/123.php
<?php 
	echo "123.php\n";
	jaljlsgjl;ag
?>
[root@localhost: ~]# curl -x192.168.244.128:80 'dummy-host2.example.com/123.php'
123.php
<br />
<b>Notice</b>:  Use of undefined constant jaljlsgjl - assumed 'jaljlsgjl' in <b>/usr/local/apache2.4/docs/dummy-host2.example.com/123.php</b> on line <b>3</b><br />
<br />
<b>Notice</b>:  Use of undefined constant ag - assumed 'ag' in <b>/usr/local/apache2.4/docs/dummy-host2.example.com/123.php</b> on line <b>4</b><br />
[root@localhost: ~]# !cat
cat /tmp/php_errors.log 
[07-Aug-2018 12:21:04 Asia/Shanghai] PHP Warning:  phpinfo() has been disabled for security reasons in /usr/local/apache2.4/docs/dummy-host2.example.com/index.php on line 3
[07-Aug-2018 12:27:48 Asia/Shanghai] PHP Notice:  Use of undefined constant jaljlsgjl - assumed 'jaljlsgjl' in /usr/local/apache2.4/docs/dummy-host2.example.com/123.php on line 3
[07-Aug-2018 12:27:48 Asia/Shanghai] PHP Notice:  Use of undefined constant ag - assumed 'ag' in /usr/local/apache2.4/docs/dummy-host2.example.com/123.php on line 4
[root@localhost: ~]# curl -x192.168.244.128:80 'dummy-host2.example.com/123.php' -I
HTTP/1.1 200 OK
Date: Tue, 07 Aug 2018 04:28:20 GMT
Server: Apache/2.4.32 (Unix) PHP/5.6.30
X-Powered-By: PHP/5.6.30
Cache-Control: max-age=0
Expires: Tue, 07 Aug 2018 04:28:20 GMT
Content-Type: text/html; charset=UTF-8

下面再介绍一个安全相关的open_basedir安全选项。

一台服务器上有多个站点,而某一个站点被黑被拿到权限,很有可能其他站点也会暴露,所以我们可以通过目录隔离的方式保护其他站点。

open_basedir = /usr/local/apache2.4/docs/dummy-host2.example.com/:/tmp

那这时候我打开host1的时候就会报错,

[root@localhost: ~]# curl -x192.168.244.128:80 dummy-host.example.com/
<br />
<b>Warning</b>:  Unknown: open_basedir restriction in effect. File(/usr/local/apache2.4/docs/dummy-host.example.com/index.php) is not within the allowed path(s): (/usr/local/apache2.4/docs/dummy-host2.example.com/:/tmp) in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Warning</b>:  Unknown: failed to open stream: Operation not permitted in <b>Unknown</b> on line <b>0</b><br />
<br />
<b>Fatal error</b>:  Unknown: Failed opening required '/usr/local/apache2.4/docs/dummy-host.example.com/index.php' (include_path='.:/usr/local/php5/lib/php') in <b>Unknown</b> on line <b>0</b><br />

虽然这样能保护host1,但是没办法访问host1不是我们的目的。

我们应该通过站点来禁止目录访问。php.ini是针对所有站点的,如果把目录设置成我的所有站点目录(/usr/local/apache2.4/docs/)又失去了意义。这个只能在虚拟主机的配置文件中做。

 php_admin_value open_basedir "/usr/local/apache2.4/docs/dummy-host2.example.com/:/tmp"

针对不同的虚拟主机创建不同的open_basedir。

扩展
apache开启压缩
apache2.2到2.4配置文件变更
apache options参数
apache禁止trace或track防止xss
apache 配置https 支持ssl

11.32 PHP扩展模块安装

动态扩展模块安装。

虽然我们PHP安装的时候指定安装大部分模块,后面有需求还是需要手动再次添加模块。

需求,PHP安装完之后我们要安装一个redis的模块。redis是一个nosql模块,在LAMP模式下当缓存来用。

下载安装包

[root@localhost: ~]# cd /usr/local/src/
[root@localhost: src]# wget https://codeload.github.com/phpredis/phpredis/zip/develop
--2018-08-09 00:19:25--  https://codeload.github.com/phpredis/phpredis/zip/develop
Resolving codeload.github.com (codeload.github.com)... 13.229.189.0, 13.250.162.133, 54.251.140.56
Connecting to codeload.github.com (codeload.github.com)|13.229.189.0|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 240091 (234K) [application/zip]
Saving to: ‘develop’

100%[==============================================>] 240,091      224KB/s   in 1.0s   

2018-08-09 00:19:28 (224 KB/s) - ‘develop’ saved [240091/240091]

[root@localhost: src]# ls
apr-1.6.3              httpd-2.4.32         mariadb-10.3.8.tar.gz  php-7.1.6
apr-1.6.3.tar.gz       httpd-2.4.32.tar.gz  mysql-5.5.61           php-7.1.6.tar.bz2
apr-util-1.6.1         isl-0.19             mysql-5.5.61.tar.gz
apr-util-1.6.1.tar.gz  isl-0.19.tar.bz2     php-5.6.30
develop                mariadb-10.3.8       php-5.6.30.tar.gz

develop其实是一个zip文件

[root@localhost: src]# file develop 
develop: Zip archive data, at least v1.0 to extract
[root@localhost: src]# mv develop phpredis-develop.zip
[root@localhost: src]# zi
zic       zip       zipcloak  zipgrep   zipinfo   zipnote   zipsplit  
[root@localhost: src]# zip -d phpredis-develop.zip 

zip error: Nothing to do! (phpredis-develop.zip)
[root@localhost: src]# unzip  phpredis-develop.zip 
Archive:  phpredis-develop.zip
399edf44f90f5c0b7be4f3bdefb6b402eda5f0af
   creating: phpredis-develop/
  inflating: phpredis-develop/.gitignore  
  inflating: phpredis-develop/.gitmodules  
  inflating: phpredis-develop/.travis.yml  
  inflating: phpredis-develop/COPYING  
  inflating: phpredis-develop/CREDITS  
  inflating: phpredis-develop/INSTALL.markdown  
  inflating: phpredis-develop/ISSUE_TEMPLATE.md  
  inflating: phpredis-develop/README.markdown  
  inflating: phpredis-develop/arrays.markdown  
  inflating: phpredis-develop/cluster.markdown  
  inflating: phpredis-develop/cluster_library.c  
  inflating: phpredis-develop/cluster_library.h  
  inflating: phpredis-develop/common.h  
  inflating: phpredis-develop/config.m4  
  inflating: phpredis-develop/config.w32  
  inflating: phpredis-develop/crc16.h  
  inflating: phpredis-develop/debian.control  
   creating: phpredis-develop/debian/
  inflating: phpredis-develop/debian/changelog  
 extracting: phpredis-develop/debian/compat  
  inflating: phpredis-develop/debian/control  
  inflating: phpredis-develop/debian/copyright  
  inflating: phpredis-develop/debian/postinst  
  inflating: phpredis-develop/debian/postrm  
  inflating: phpredis-develop/debian/rules  
   creating: phpredis-develop/liblzf/
  inflating: phpredis-develop/library.c  
  inflating: phpredis-develop/library.h  
  inflating: phpredis-develop/mkdeb-apache2.sh  
  inflating: phpredis-develop/mkdeb.sh  
  inflating: phpredis-develop/package.xml  
  inflating: phpredis-develop/php_redis.h  
  inflating: phpredis-develop/redis.c  
  inflating: phpredis-develop/redis_array.c  
  inflating: phpredis-develop/redis_array.h  
  inflating: phpredis-develop/redis_array_impl.c  
  inflating: phpredis-develop/redis_array_impl.h  
  inflating: phpredis-develop/redis_cluster.c  
  inflating: phpredis-develop/redis_cluster.h  
  inflating: phpredis-develop/redis_commands.c  
  inflating: phpredis-develop/redis_commands.h  
  inflating: phpredis-develop/redis_session.c  
  inflating: phpredis-develop/redis_session.h  
   creating: phpredis-develop/rpm/
  inflating: phpredis-develop/rpm/php-redis.spec  
 extracting: phpredis-develop/rpm/redis.ini  
  inflating: phpredis-develop/serialize.list  
   creating: phpredis-develop/tests/
  inflating: phpredis-develop/tests/RedisArrayTest.php  
  inflating: phpredis-develop/tests/RedisClusterTest.php  
  inflating: phpredis-develop/tests/RedisTest.php  
  inflating: phpredis-develop/tests/TestRedis.php  
  inflating: phpredis-develop/tests/TestSuite.php  
  inflating: phpredis-develop/tests/getSessionData.php  
  inflating: phpredis-develop/tests/make-cluster.sh  
  inflating: phpredis-develop/tests/mkring.sh  
  inflating: phpredis-develop/tests/regenerateSessionId.php  
  inflating: phpredis-develop/tests/startSession.php

使用phpize工具生成configure

[root@localhost: src]# cd phpredis-develop/
[root@localhost: phpredis-develop]# ls
arrays.markdown    CREDITS            mkdeb.sh            redis_cluster.c
cluster_library.c  debian             package.xml         redis_cluster.h
cluster_library.h  debian.control     php_redis.h         redis_commands.c
cluster.markdown   INSTALL.markdown   README.markdown     redis_commands.h
common.h           ISSUE_TEMPLATE.md  redis_array.c       redis_session.c
config.m4          liblzf             redis_array.h       redis_session.h
config.w32         library.c          redis_array_impl.c  rpm
COPYING            library.h          redis_array_impl.h  serialize.list
crc16.h            mkdeb-apache2.sh   redis.c             tests
[root@localhost: phpredis-develop]# /usr/local/php5/bin/phpize 
Configuring for:
PHP Api Version:         20131106
Zend Module Api No:      20131226
Zend Extension Api No:   220131226
[root@localhost: phpredis-develop]# ls configure
configure

配置

[root@localhost: phpredis-develop]# ./configure --with-php-config=/usr/local/php5/bin/php-config 

一般来说就这个选项就好

make && make install之后

[root@localhost: phpredis-develop]# echo $?
0
[root@localhost: phpredis-develop]# make install
Installing shared extensions:     /usr/local/php5/lib/php/extensions/no-debug-zts-20131226/
[root@localhost: phpredis-develop]# ls /usr/local/php5/lib/php/extensions/no-debug-zts-20131226/
opcache.so  redis.so

在一个目录里就生成了两个.so文件。就是我们需要的模块。

但是这个时候php还是不支持redis的

[root@localhost: phpredis-develop]# /usr/local/php5/bin/php -m | grep redis
[root@localhost: phpredis-develop]#

配置文件中可以定义扩展目录的位置


; Directory in which the loadable extensions (modules) reside.
; http://php.net/extension-dir
; extension_dir = "./"
; On windows:
; extension_dir = "ext"

也可以查询当前的扩展模块目录

[root@localhost: phpredis-develop]# /usr/local/php5/bin/php -i | grep -i extension_dir
extension_dir => /usr/local/php5/lib/php/extensions/no-debug-zts-20131226 => /usr/local/php5/lib/php/extensions/no-debug-zts-20131226
sqlite3.extension_dir => no value => no value

添加模块

extension=redis.so
[root@localhost: phpredis-develop]# /usr/local/php5/bin/php -m | grep redis
redis

扩展包可以在源码包中查找

[root@localhost: phpredis-develop]# ls /usr/local/src/php-5.6.30/ext/
bcmath              fileinfo   mbstring   pdo_firebird  shmop      tokenizer
bz2                 filter     mcrypt     pdo_mysql     simplexml  wddx
calendar            ftp        mssql      pdo_oci       skeleton   xml
com_dotnet          gd         mysql      pdo_odbc      snmp       xmlreader
ctype               gettext    mysqli     pdo_pgsql     soap       xmlrpc
curl                gmp        mysqlnd    pdo_sqlite    sockets    xmlwriter
date                hash       oci8       pgsql         spl        xsl
dba                 iconv      odbc       phar          sqlite3    zip
dom                 imap       opcache    posix         standard   zlib
enchant             interbase  openssl    pspell        sybase_ct
ereg                intl       pcntl      readline      sysvmsg
exif                json       pcre       recode        sysvsem
ext_skel            ldap       pdo        reflection    sysvshm
ext_skel_win32.php  libxml     pdo_dblib  session       tidy

如果没有就去官网下载,常用的在r.aminglinux.com里也有。

扩展

apache rewrite教程1

apache rewrite教程2

apache rewrite 出现死循环
php错误日志级别参考
php开启短标签
php.ini详解

转载于:https://my.oschina.net/u/3866688/blog/1923503

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值