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架構
的安所有署及優化,也就差很少完成了,咱們關注的點,更多可能仍是集中在防護入侵上,捎帶了一點性能優化,這裏所給的參數選項基本所有均可直接用於實戰部署,但並非全部的參數配置都是必須的,還須要你好好根據本身實際的業務需求作出適當取捨,或者在此基礎進行定製改進,有些地方都是基於本身平時實戰經驗的考量來的,並不必定徹底是對的,若是有性能更好,更安全的方案,也很是歡迎你們一塊兒來私信交流 ^_^