日志檔案是伺服器提供的非常有價值的資訊,幾乎所有的伺服器、服務和應用程式都提供某種類型的日志記錄,用來記錄服務或應用程式運作時發生的事件和操作。
日志檔案為我們提供了伺服器行為的精确視圖以及關鍵資訊,例如何時、如何以及由誰通路了伺服器。這類資訊可以幫助我們監視性能、排除故障和調試應用程式,并幫助調查驗證人員展開可能導緻惡意活動的攻擊鍊。
以web服務為例,通路日志
access.log
記錄了所有對Web伺服器的通路活動。假設通路者通路
www.example.com/main.php
,将在日志檔案中添加以下記錄:
88.54.124.17 - - [16/Apr/2019:07:44:08 +0100] "GET /main.php HTTP/1.1" 200 203 "-" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
複制
上述日志顯示,IP位址為
88.54.124.178
的通路者于
2019年4月16日07:44
通路了
main.php
頁面,并且通路成功。
這個資訊可能不太重要,但如果日志檔案顯示IP為
88.54.124.178
的通路者在
2019年4月16日07:44
通路
dump_database.php
頁面,并且請求成功,該怎麼辦?如果沒有該日志檔案,我們可能永遠不會知道有人發現并運作了網站上的受限腳本,進而轉儲資料庫。
在确定了日志檔案是一項關鍵資産之後,讓我們通過一個攻擊案例來進行web日志安全分析,還原攻擊路徑。
攻擊案例
假設我們管理的WordPress網站遭到篡改:
發現網站被攻擊之後,運維團隊将伺服器斷網下線處理,保持系統及其日志的目前狀态,以便能夠進一步分析調查。
通常我們需要建立一個伺服器硬碟鏡像備份,然後在鏡像虛拟機做一些操作去溯源。但是,由于僅用于進行示範,在這種情況下,調查驗證小組可以處理原始資料。
調查驗證
為了開始調查,我們需要确定要尋找的證據。通常,攻擊證據包括攻擊者直接通路隐藏或異常檔案,對管理者權限區域内的非授權通路,遠端執行代碼,SQL注入,檔案包含,跨站點腳本(XSS)以及其他可能表明異常的行為漏洞掃描或偵察活動。
比如,我們的Web伺服器
access.log
可以有效記錄通路來源。
root@secureserver:/var/log/apache2# less access.log
複制
access.log
可以按天生成儲存,一般來說,如果網站在某一天遭受漏洞掃描,那麼這一天它的日志檔案會比平常大很多。
84.55.41.57 - - [16/Apr/2019:20:21:56 +0100] "GET /john/index.php HTTP/1.1" 200 3804 "-" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
84.55.41.57 - - [16/Apr/2019:20:21:56 +0100] "GET /john/assets/js/skel.min.js HTTP/1.1" 200 3532 "http://www.example.com/john/index.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
84.55.41.57 - - [16/Apr/2019:20:21:56 +0100] "GET /john/images/pic01.jpg HTTP/1.1" 200 9501 "http://www.example.com/john/index.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
84.55.41.57 - - [16/Apr/2019:20:21:56 +0100] "GET /john/images/pic03.jpg HTTP/1.1" 200 5593 "http://www.example.com/john/index.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
複制
每個日志檔案包含幾千條請求紀錄,檢查每一行明顯是不切實際的,是以我們需要過濾掉一些可能無關的資料,包括圖像和CSS、JS等資源檔案。
由于網站正在運作
WordPress
,在這種情況下,我們可以通過關鍵字過濾
access.log
來擷取滿足WordPress特定特征的通路請求。
root@secureserver:~#cat /var/log/apache2/access.log | grep -E "wp-admin|wp-login|POST /"
複制
通過上面這行指令會篩選
access.log
,僅顯示包含
wp-admin
、
wp-login
以及POST等關鍵字的記錄。其中,
wp-admin
是WordPress的管理背景,
wp-login
是WordPress的登入頁面,
POST
表示使用POST方法将HTTP請求發送到伺服器,一般來說主要是登入表單和資料送出。
在篩選之後的結果中,我們會注意到這樣一個通路請求:
84.55.41.57 - - [17/Apr/2019:06:52:07 +0100] "GET /wordpress/wp-admin/ HTTP/1.1" 200 12349 "http://www.example.com/wordpress/wp-login.php" "Mozilla/5.0 (Windows NT 6.0; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0"
複制
我們看到IP:
84.55.41.57
成功通路了WordPress管理界面。
讓我們看看這個IP位址的使用者還做了什麼,我們再次使用
grep
指令來篩選。
root@secureserver:~#cat /var/log/apache2/access.log | grep 84.55.41.57
複制
發現以下有趣的記錄:
84.55.41.57 - - [17/Apr/2019:06:57:24 +0100] "GET /wordpress/wp-login.php HTTP/1.1" 200 1568 "-"
84.55.41.57 - - [17/Apr/2019:06:57:31 +0100] "POST /wordpress/wp-login.php HTTP/1.1" 302 1150 "http://www.example.com/wordpress/wp-login.php"
84.55.41.57 - - [17/Apr/2019:06:57:31 +0100] "GET /wordpress/wp-admin/ HTTP/1.1" 200 12905 "http://www.example.com/wordpress/wp-login.php"
84.55.41.57 - - [17/Apr/2019:07:00:32 +0100] "POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1" 200 454 "http://www.example.com/wordpress/wp-admin/"
84.55.41.57 - - [17/Apr/2019:07:00:58 +0100] "GET /wordpress/wp-admin/theme-editor.php HTTP/1.1" 200 20795 "http://www.example.com/wordpress/wp-admin/"
84.55.41.57 - - [17/Apr/2019:07:03:17 +0100] "GET /wordpress/wp-admin/theme-editor.php?file=404.php&theme=twentysixteen HTTP/1.1" 200 8092 "http://www.example.com/wordpress/wp-admin/theme-editor.php"
84.55.41.57 - - [17/Apr/2019:07:11:48 +0100] "GET /wordpress/wp-admin/plugin-install.php HTTP/1.1" 200 12459 "http://www.example.com/wordpress/wp-admin/plugin-install.php?tab=upload"
84.55.41.57 - - [17/Apr/2019:07:16:06 +0100] "GET /wordpress/wp-admin/update.php?action=install-plugin&plugin=file-manager&_wpnonce=3c6c8a7fca HTTP/1.1" 200 5698 "http://www.example.com/wordpress/wp-admin/plugin-install.php?tab=search&s=file+permission"
84.55.41.57 - - [17/Apr/2019:07:18:19 +0100] "GET /wordpress/wp-admin/plugins.php?action=activate&plugin=file-manager%2Ffile-manager.php&_wpnonce=bf932ee530 HTTP/1.1" 302 451 "http://www.example.com/wordpress/wp-admin/update.php?action=install-plugin&plugin=file-manager&_wpnonce=3c6c8a7fca"
84.55.41.57 - - [17/Apr/2019:07:21:46 +0100] "GET /wordpress/wp-admin/admin-ajax.php?action=connector&cmd=upload&target=l1_d3AtY29udGVudA&name%5B%5D=r57.php&FILES=&_=1460873968131 HTTP/1.1" 200 731 "http://www.example.com/wordpress/wp-admin/admin.php?page=file-manager_settings"
84.55.41.57 - - [17/Apr/2019:07:22:53 +0100] "GET /wordpress/wp-content/r57.php HTTP/1.1" 200 9036 "-"
84.55.41.57 - - [17/Apr/2019:07:32:24 +0100] "POST /wordpress/wp-content/r57.php?14 HTTP/1.1" 200 8030 "http://www.example.com/wordpress/wp-content/r57.php?14"
84.55.41.57 - - [17/Apr/2019:07:29:21 +0100] "GET /wordpress/wp-content/r57.php?29 HTTP/1.1" 200 8391 "http://www.example.com/wordpress/wp-content/r57.php?28"
84.55.41.57 - - [17/Apr/2019:07:57:31 +0100] "POST /wordpress/wp-admin/admin-ajax.php HTTP/1.1" 200 949 "http://www.myw ebsite.com/wordpre ss/wp-admin/admin.php?page=file-manager_settings"
複制
我們來進一步分析這些記錄。
攻擊者通路了WordPress網站的登入頁面:
84.55.41.57 - GET /wordpress/wp-login.php 200
複制
攻擊者送出了登入表單(使用POST方法),并被重定向(302 HTTP狀态代碼)。
84.55.41.57 - POST /wordpress/wp-login.php 302
複制
攻擊者被重定向到
wp-admin
(WordPress管理背景),這意味着攻擊者已成功通過了身份驗證。
84.55.41.57 - GET /wordpress/wp-admin/ 200
複制
攻擊者通路了網站的主題編輯器:
84.55.41.57 - GET /wordpress/wp-admin/theme-editor.php 200
複制
攻擊者試圖編輯
404.php
檔案,攻擊者經常使用這種方式将惡意代碼寫入檔案,但由于缺少檔案寫入權限,所有并沒有成功。
84.55.41.57 - GET /wordpress/wp-admin/theme-editor.php?file=404.php&theme= twentysixteen 200
複制
攻擊者通路了插件安裝程式。
84.55.41.57 - GET /wordpress/wp-admin/plugin-install.php 200
複制
攻擊者安裝并激活了
file-manager
插件。
84.55.41.57 - GET /wordpress/wp-admin/update.php?action=install-plugin&plugin= file-manager &_wpnonce=3c6c8a7fca 200
84.55.41.57 - GET /wordpress/wp-admin/plugins.php?action=activate&plugin=file-manager%2Ffile-manager.php&_wpnonce=bf932ee530 200
複制
攻擊者使用
file-manager
插件上傳了r57.php,這很可能是一個PHP Web Shell腳本。
84.55.41.57 - GET /wordpress/wp-admin/admin-ajax.php?action=connector& cmd= upload&target=l1_d3AtY29udGVudA&name%5B%5D=r57.php&FILES=&_=1460873968131 200
複制
日志表明,攻擊者通路了
r57.php
,查詢字元串
?1
和
?28
表明攻擊者通過腳本代碼進行操作,但并未發現任何有趣的東西。
84.55.41.57 - GET /wordpress/wp-content/r57.php 200
84.55.41.57 - POST /wordpress/wp-content/r57.php?1 200
84.55.41.57 - GET /wordpress/wp-content/r57.php?28 200
複制
攻擊者的最後一個動作是通過
file-manager
插件編輯主題的索引檔案,并将其内容替換為
HACKED!
。
84.55.41.57 - POST /wordpress/wp-admin/admin-ajax.php 200 - http://www.example.com/wordpress/wp-admin/admin.php?page=file-manager_settings
複制
根據上述資訊,我們可以看到攻擊者的行為時間表,但是,目前還有一個問題沒有弄清楚,攻擊者是如何獲得登入憑據的?
假設管理者密碼沒有洩漏也沒有被暴力破解,讓我們回頭看看我們是不是忽略了什麼資訊。
在目前的
access.log
中并未發現任何有關管理者密碼洩露的線索,但我們可以檢視所有存檔的
access.log
檔案,來拼湊出攻擊者的行為軌迹。
首先,我們可以過濾日志出包含IP位址:
84.55.41.57
的日志記錄。我們發現,其中有一條日志疑似SQL注入攻擊的記錄:
84.55.41.57- - [14/Apr/2019:08:22:13 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=1 AND (SELECT 6810 FROM(SELECT COUNT(*),CONCAT(0x7171787671,(SELECT (ELT(6810=6810,1))),0x71707a7871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) HTTP/1.1" 200 166 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
84.55.41.57- - [14/Apr/2019:08:22:13 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=(SELECT 7505 FROM(SELECT COUNT(*),CONCAT(0x7171787671,(SELECT (ELT(7505=7505,1))),0x71707a7871,FLOOR(RAND(0)*2))x FROM INFORMATION_SCHEMA.CHARACTER_SETS GROUP BY x)a) HTTP/1.1" 200 166 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
84.55.41.57- - [14/Apr/2019:08:22:13 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=(SELECT CONCAT(0x7171787671,(SELECT (ELT(1399=1399,1))),0x71707a7871)) HTTP/1.1" 200 166 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
84.55.41.57- - [14/Apr/2019:08:22:27 0100] "GET /wordpress/wp-content/plugins/custom_plugin/check_user.php?userid=1 UNION ALL SELECT CONCAT(0x7171787671,0x537653544175467a724f,0x71707a7871),NULL,NULL-- HTTP/1.1" 200 182 "-" "Mozilla/5.0 (Windows; U; Windows NT 6.1; ru; rv:1.9.2.3) Gecko/20100401 Firefox/4.0 (.NET CLR 3.5.30729)"
複制
假設這個插件是系統管理者從網上直接下載下傳并拷貝到網站之中的,腳本安裝路徑:
/wordpress/wp-content/plugins/custom_plugin/check_user.php
複制
通過分析
check_user.php
檔案,發現存在SQL語句拼接,導緻網站存在SQL注入漏洞。
<?php
//Include the WordPress header
include('/wordpress/wp-header.php');
global $wpdb;
// Use the GET parameter ‘userid’ as user input
$id=$_GET['userid'];
// Make a query to the database with the value the user supplied in the SQL statement
$users = $wpdb->get_results( "SELECT * FROM users WHERE user_id=$id");
?>
複制
access.log
記錄表明,攻擊者使用了SQL注入自動化工具來查找資料庫名稱,表名稱和列,日志中的記錄将類似于以下内容:
/wordpress/wp-content/plugins/my_custom_plugin/check_user.php?userid=-6859 UNION ALL SELECT (SELECT CONCAT(0x7171787671,IFNULL(CAST(ID AS CHAR),0x20),0x616474686c76,IFNULL(CAST(display_name AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_activation_key AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_email AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_login AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_nicename AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_pass AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_registered AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_status AS CHAR),0x20),0x616474686c76,IFNULL(CAST(user_url AS CHAR),0x20),0x71707a7871) FROM wp.wp_users LIMIT 0,1),NULL,NULL--
複制
上面的SQL代碼非常有力地表明WordPress資料庫已被盜用,并且該SQL資料庫中的所有敏感資訊都有可能被洩露。
分析
通過這次調查,我們還原了攻擊事件鍊:
不過仍然存在一些疑問,比如說攻擊者到底是誰?從目前來說,我們隻知道攻擊者的IP位址,而且攻擊者一般都會使用代理伺服器或匿名網絡(例如Tor)來掩蓋其真實的IP位址。除非攻擊者留下了與他真實身份有關的證據,否則我們很難得知攻擊者的真實身份。
通過日志分析,我們發現了攻擊者的攻擊路徑和安全事件的根本原因:管理者所使用的那款自定義WordPress插件中存在SQL注入漏洞,導緻攻擊者通過SQL注入漏洞擷取管理者賬号密碼,進而登入管理背景進行網頁篡改。修複SQL注入漏洞并清除webshell,從備份檔案中恢複被篡改的檔案,使網站恢複正常。
在上述虛構的示例中,攻擊者入侵後的處理其實是非常草率的,留下了大量攻擊痕迹和驗證證據,而這些資訊将給調查人員提供很大的幫助。但在真實的攻擊場景中,攻擊者往往會清除很多關鍵資訊,這勢必會加大調查人員的驗證難度。
注:本文由Bypass翻譯并整理,文章來源:
https://www.acunetix.com/blog/articles/using-logs-to-investigate-a-web-application-attack/