WordPress 站點的安全性非常重要,稍有不慎就有可能受到惡意攻擊。一種常見的手段是通過篡改站點的位址,于是使用者通路網站時将會被重新定向到惡意網站。

一般情況下,有 2 種手段可以達到這個目的,下面就讓長老帶領大家一步步去看整個攻擊手段是如何實施的,并找到每個環節的安全防護措施,大家可以根據自己的情況使用其中的某個或多個防護措施。也歡迎大家留言分享各自的防護心得。
第一種攻擊手段是在檔案中寫入惡意代碼。
該惡意代碼的表現形式為在網頁加載時執行一段 JS 代碼, 跳轉到惡意網址。
盡管我們可以保證自己購買的插件和主題都是正版軟體,我們也無法保證插件和主題沒有任何安全漏洞。一部分國産主題為了激活的校驗以及防止盜版,往往會故意留下一個口子,用來往資料庫中寫入授權資訊,再加上 WordPress 的插件和主題檔案本身就被設計成了可以被修改的,是以這樣的口子就會成為一個危險的入口。
最根本的方法當然是及時修補這個漏洞,将插件和主題更新到最新版。但是在此之前,我們隻能通過一些并不是“治本”的方法來阻止這件事情發生。
WordFence 之類的安全防護軟體也可以找到惡意代碼的源頭,但是很多惡意代碼并不是很顯而易見的,它會多次中轉,使得前面的代碼看上去都是非常正常的内容,這樣就算删掉了最後的危險代碼,由于前面的代碼還在,是以過段時間就會死灰複燃。
如圖是在一個主題檔案中插入惡意代碼的示例,惡意代碼十分隐晦,并不能直接通過搜尋
<script>
關鍵字查找,而且要調用好幾層。 注意這段代碼并不是通過 Unix Shell 執行的,而是被 PHP 執行的,是以,就算我們沒有給這個檔案執行的權限,也依然無法阻止這段惡意代碼被執行。是以,「權限不要給太高」這個教訓在這兒并不好使,這不是權限上能解決的。
這段代碼通過 POST 請求去通路了一個被 BASE64 加密的網址,然後将請求得到的内容寫到了一個名為
_a
的檔案中,并将 _a
包含進了主題檔案中,是以,隻要主題被加載了, _a
也被加載了。 <?php
後面,是以仍然會被作為 PHP 代碼執行。 _a
是一段 Unix Shell 指令,通過 PHP 的 shell_exec()
執行了這段指令。指令通過 wget 請求了一個腳本,并執行了這個腳本。
這個危險的腳本做的事情是在 WordPress 的核心的幾個
index.php
的檔案開始處,加上一段 <script src="bad_zzw.js"></script>
的檔案,這樣當 WordPress 被加載時,就會執行這段 JS 代碼,去請求了 src="bad_zzw.js"
中的 JS,而 bad_zzw.js
的内容隻有 2 行,包括了一句 windows.location
,即将目前頁面重定向到一個惡意的連結頁面。
到這裡,我們得到了第一個防護措施,那就是 PHP 官方推薦的:禁用
shell_exec()
。
可是,萬一本機别的服務需要用到
shell_exec()
呢,這個雖然不安全,但是我卻不得不使用它。在沒有可能改變其他業務的情況下,這個函數不能被禁用。
那我們就要嘗試将主題檔案和 WordPress 核心的檔案設定為隻讀了。
一般而言,檔案的最小權限會被設定為
644
或 640
,即自己可讀寫、組内其他使用者隻讀、組外使用者隻讀(或者組外使用者無權限),不會給執行權限 x
;而目錄的最小權限會被設定為 755
或者 750
,對于目錄而言, x
不再表示執行,而是表示是否可以進入該目錄通路其中的内容。
于是我們有了第二個防護措施,那就是将主題、插件檔案夾遞歸地設定為隻讀:首先
chown -R www:www .
確定整個目錄都在 www
使用者組内,然後 chmod 0640 -R .
遞歸地将目錄下的檔案全部修改為 640
權限,最後 find -type d -exec chmod 0750 {} \; .
遞歸地找到目錄下所有的類型為目錄的,并調用 exec
将權限修改為 750
對于 WordPress,隻讀的權限不會帶來任何問題, www
使用者組也足以完成全部的操作。隻是需要注意的是,這樣将不再支援有檔案讀寫操作的行為,例如插件的更新、例如某些插件需要在目錄中生成緩存或配置檔案等。
第二種攻擊手段是修改資料庫的字段。
我們這裡不讨論資料庫密碼洩露、資料庫管理面闆漏洞這樣的問題,隻考慮資料庫使用者和密碼足夠複雜,而攻擊者利用 WordPress 的「合法的」資料庫通路操作來修改了資料庫的字段。由于所有的操作都是 WordPress 的「合法的」資料庫通路,是以我們沒有辦法判斷這是惡意攻擊,還是正常的資料庫通路(例如更新設定、讀寫文章)。
惡意攻擊通常會篡改
wp_options
中的 siteurl
值和 home
值,使得使用者通路站點時,站點 URL 部分被替換成惡意網站,實作跳轉,并且由于 /wp-admin
的通路也會校驗站點位址,是以我們甚至無法登入背景去修改回來。
網上有很多這樣的案例,并且也給出了解決方案。
網上參見的解決方案為:首先想辦法進入資料庫,不管是 phpMyAdmin 或者 Unix Shell 登入。修改 WordPress 資料庫中
wp_options
表中的 siteurl
和 home
,儲存。這時候就可以登入背景了,隻需要把确實的設定重新修改。
還可以修改
wp-config.php
,通過 define('WP_HOME','https://www.jxtxzzw.com'); define('WP_SITEURL','https://www.jxtxzzw.com');
來指定自己的站點位址。
這裡長老再說一種方法:修改資料表,增加觸發器。
CREATE DEFINER=`wp_user`@`localhost` TRIGGER `trg_update_wp_options_forbidden`
BEFORE UPDATE ON `wp_options`
FOR EACH ROW
IF (NEW.option_id IN (1,2,3,4)) THEN
SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = 'Cannot update locked record';
END IF;
這個觸發器是在修改
wp_options
之前被觸發,如果新修改的值的 ID 是 1、2、3、4,那麼就令 SQL 執行逾時,并輸出資訊「Cannot update locked record」。
注意:① 添加觸發器需要較進階别的權限,你可以根據需要修改為
root
。② 上面的
(1,2,3,4)
在我的資料表中對應
siteurl
、
home
blogname
blogdescription
,你可以根據自己的情況修改這些 ID,也可以直接指定
NEW.option_name
。③ 你可以增加更多鎖定的字段,例如
userscanregister
WPLANG
date_format
等等。④ 添加觸發器前請先将内容修改為期望的值。⑤ 如果再次修改,需要先解除觸發器。
儲存後,讓我們修改這個字段,發現已經不能修改了。
但這不會影響背景的設定,當我們同時修改了背景的「站點标題」和「新使用者預設角色」後點選儲存,我們發現沒有被鎖定的記錄仍然可以正常修改,而被鎖定的記錄仍保持了鎖定的内容。
如果你的興緻到這裡就結束了,那麼,已經做好了防護,可以去玩啦。站點位址已經不能被篡改。
如果你還有興趣,那麼可以打開 SQL 的 general_log(這會儲存下所有的 SQL 操作,檔案大小增速很恐怖,記得及時關掉),去挖掘到底是什麼時候、被誰、執行了怎麼樣的一條指令,再配合其他的手段,一步一步定位真兇,并進一步地去将它繩之以法。
關鍵詞:WordPress,篡改,挂馬,惡意,攻擊,注入,跳轉,重定向,網址,siteurl,home,url,hacked,jump,redirect
摘要:WordPress 站點稍有不慎就有可能受到惡意攻擊。一種常見的手段是通過篡改站點的位址,使用者通路網站時将會被重新定向到惡意網站。長老将分析兩種常見的攻擊手段:修改檔案和修改資料庫,并分享一些安全防護的小技巧。
原文連結:
https://www.jxtxzzw.com/archives/5572