Web Shell 偵測與清除技術

Web Shell Detection and Removal Techniques

Web Shell 概述

Web Shell 是一種惡意腳本程式,攻擊者透過網站漏洞將其植入伺服器,以取得遠端控制權限。一旦 Web Shell 被成功植入,攻擊者可以執行系統指令、存取敏感資料、橫向移動至內網其他主機,甚至建立持久性後門。

Web Shell 的危害

  • 遠端程式碼執行:攻擊者可在伺服器上執行任意指令
  • 資料竊取:存取資料庫、設定檔、使用者資料
  • 權限提升:利用本地漏洞提升至 root/administrator 權限
  • 跳板攻擊:以受害伺服器為跳板,攻擊內網其他主機
  • 持久化存取:建立後門維持長期存取權限

常見 Web Shell 類型

PHP Web Shell

PHP 是最常見的 Web Shell 語言,以下是常見的 PHP Web Shell 特徵:

1
2
3
4
5
6
7
8
# 一句話木馬 (One-liner)
<?php eval($_POST['cmd']); ?>
<?php system($_GET['cmd']); ?>
<?php passthru($_REQUEST['cmd']); ?>

# 變形混淆版本
<?php $a='sys'.'tem'; $a($_GET['c']); ?>
<?php preg_replace('/.*/e', $_POST['c'], ''); ?>

ASP/ASPX Web Shell

1
2
<%eval request("cmd")%>
<%execute(request("cmd"))%>

JSP Web Shell

1
<%Runtime.getRuntime().exec(request.getParameter("cmd"));%>

Python Web Shell

1
import os; os.system(input())

偵測方法

檔案特徵分析

使用 grep 搜尋可疑函數

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 搜尋 PHP 危險函數
grep -rn --include="*.php" -E "(eval|assert|base64_decode|gzinflate|str_rot13|gzuncompress)\s*\(" /var/www/html/

# 搜尋 system 執行函數
grep -rn --include="*.php" -E "(system|exec|shell_exec|passthru|popen|proc_open)\s*\(" /var/www/html/

# 搜尋 $_GET/$_POST/$_REQUEST 結合 eval
grep -rn --include="*.php" -E "\$_(GET|POST|REQUEST|COOKIE)\s*\[.*\].*eval" /var/www/html/

# 搜尋可疑的字串操作函數組合
grep -rn --include="*.php" -E "(chr|ord|pack|unpack)\s*\(" /var/www/html/ | head -50

使用 find 搜尋可疑檔案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 搜尋最近被修改的 PHP 檔案 (7天內)
find /var/www/html -name "*.php" -mtime -7 -type f

# 搜尋異常的檔案權限
find /var/www/html -name "*.php" -perm 0777 -type f

# 搜尋隱藏的 PHP 檔案
find /var/www/html -name ".*\.php" -type f

# 搜尋檔案名稱可疑的檔案
find /var/www/html -type f \( -name "*shell*" -o -name "*backdoor*" -o -name "*c99*" -o -name "*r57*" \)

檢查檔案完整性

1
2
3
4
5
# 使用 md5sum 建立基準線
find /var/www/html -name "*.php" -exec md5sum {} \; > /tmp/baseline.txt

# 比對基準線找出被修改的檔案
md5sum -c /tmp/baseline.txt 2>/dev/null | grep -v "OK$"

網路流量分析

使用 tcpdump 擷取可疑流量

1
2
3
4
5
# 擷取 HTTP 流量
tcpdump -i eth0 -A -s 0 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)' -w /tmp/http_traffic.pcap

# 擷取包含 cmd 參數的請求
tcpdump -i eth0 -A 'tcp port 80' | grep -E "(cmd=|exec=|command=)"

分析 Apache/Nginx 存取日誌

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 搜尋 POST 請求到 PHP 檔案
grep -E "POST.*\.php" /var/log/apache2/access.log

# 搜尋可疑的 User-Agent
grep -E "(curl|wget|python|nikto|sqlmap)" /var/log/apache2/access.log

# 搜尋異常的 URL 參數
grep -E "(cmd=|exec=|system=|eval=|base64)" /var/log/apache2/access.log

# 統計異常的存取來源
awk '{print $1}' /var/log/apache2/access.log | sort | uniq -c | sort -rn | head -20

日誌分析

檢查系統日誌

1
2
3
4
5
6
7
8
# 搜尋可疑的程序執行
grep -E "(sh|bash|cmd|powershell)" /var/log/auth.log

# 檢查 www-data 使用者的活動
grep "www-data" /var/log/auth.log

# 搜尋失敗的登入嘗試
grep "Failed password" /var/log/auth.log | tail -50

檢查 PHP 錯誤日誌

1
2
3
4
5
# 搜尋 eval 相關錯誤
grep -E "(eval|assert|create_function)" /var/log/php_errors.log

# 搜尋檔案包含錯誤
grep -E "(include|require)" /var/log/php_errors.log

自動化掃描工具

ClamAV 病毒掃描

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 安裝 ClamAV
apt-get update && apt-get install -y clamav clamav-daemon

# 更新病毒定義檔
freshclam

# 掃描網站目錄
clamscan -r -i /var/www/html/ --log=/tmp/clamav_scan.log

# 掃描並移除感染檔案 (謹慎使用)
clamscan -r -i --remove /var/www/html/

Linux Malware Detect (LMD)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 下載並安裝 LMD
wget http://www.rfxn.com/downloads/maldetect-current.tar.gz
tar -xzf maldetect-current.tar.gz
cd maldetect-*
./install.sh

# 掃描網站目錄
maldet -a /var/www/html/

# 檢視掃描報告
maldet --report

YARA 規則掃描

 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
# 安裝 YARA
apt-get install -y yara

# 建立 Web Shell YARA 規則
cat > /tmp/webshell.yar << 'EOF'
rule PHP_WebShell_Generic {
    meta:
        description = "Detects generic PHP web shells"
    strings:
        $php = "<?php"
        $eval = "eval(" nocase
        $base64 = "base64_decode(" nocase
        $system = "system(" nocase
        $exec = "exec(" nocase
        $shell = "shell_exec(" nocase
        $passthru = "passthru(" nocase
        $request = "$_REQUEST" nocase
        $post = "$_POST" nocase
        $get = "$_GET" nocase
    condition:
        $php and (($eval or $base64) and ($request or $post or $get)) or
        $php and ($system or $exec or $shell or $passthru) and ($request or $post or $get)
}
EOF

# 使用 YARA 規則掃描
yara -r /tmp/webshell.yar /var/www/html/

自訂掃描腳本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/bash
# webshell_scanner.sh - 簡易 Web Shell 掃描腳本

SCAN_DIR=${1:-/var/www/html}
LOG_FILE="/tmp/webshell_scan_$(date +%Y%m%d_%H%M%S).log"

echo "[*] 開始掃描目錄: $SCAN_DIR" | tee $LOG_FILE
echo "[*] 掃描時間: $(date)" | tee -a $LOG_FILE
echo "======================================" | tee -a $LOG_FILE

# 掃描可疑 PHP 函數
echo "[+] 掃描可疑 PHP 函數..." | tee -a $LOG_FILE
grep -rln --include="*.php" -E "(eval|assert|base64_decode|system|exec|shell_exec|passthru|popen)\s*\(" "$SCAN_DIR" | tee -a $LOG_FILE

# 掃描混淆編碼
echo "[+] 掃描 Base64 編碼內容..." | tee -a $LOG_FILE
grep -rln --include="*.php" -E "[A-Za-z0-9+/]{50,}={0,2}" "$SCAN_DIR" | tee -a $LOG_FILE

# 掃描可疑的檔案權限
echo "[+] 掃描異常檔案權限..." | tee -a $LOG_FILE
find "$SCAN_DIR" -name "*.php" -perm 0777 -type f | tee -a $LOG_FILE

echo "======================================" | tee -a $LOG_FILE
echo "[*] 掃描完成,結果儲存至: $LOG_FILE"

清除與復原

隔離可疑檔案

1
2
3
4
5
6
7
8
# 建立隔離目錄
mkdir -p /var/quarantine/$(date +%Y%m%d)

# 移動可疑檔案至隔離區
mv /var/www/html/suspicious_file.php /var/quarantine/$(date +%Y%m%d)/

# 保留檔案屬性資訊
stat /var/quarantine/$(date +%Y%m%d)/suspicious_file.php > /var/quarantine/$(date +%Y%m%d)/suspicious_file.php.info

復原網站檔案

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 從備份復原 (使用 rsync)
rsync -avz --delete /backup/www/html/ /var/www/html/

# 從 Git 復原
cd /var/www/html
git fetch origin
git reset --hard origin/main

# 驗證檔案完整性
diff -rq /backup/www/html/ /var/www/html/

清除後門程式碼

1
2
3
4
5
# 移除被注入的程式碼 (範例)
sed -i 's/<?php eval.*?>//g' /var/www/html/infected_file.php

# 批量移除特定字串
find /var/www/html -name "*.php" -exec sed -i 's/base64_decode(".*")//g' {} \;

防護措施

檔案權限設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 設定網站目錄擁有者
chown -R www-data:www-data /var/www/html/

# 設定目錄權限 (755)
find /var/www/html -type d -exec chmod 755 {} \;

# 設定檔案權限 (644)
find /var/www/html -type f -exec chmod 644 {} \;

# 移除執行權限
find /var/www/html -name "*.php" -exec chmod 644 {} \;

PHP 安全設定

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
; /etc/php/8.1/apache2/php.ini

; 停用危險函數
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

; 限制檔案上傳
file_uploads = On
upload_max_filesize = 2M
max_file_uploads = 5

; 限制資源使用
max_execution_time = 30
memory_limit = 128M

; 停用遠端檔案包含
allow_url_fopen = Off
allow_url_include = Off

; 開啟安全模式日誌
log_errors = On
error_log = /var/log/php_errors.log

使用 ModSecurity WAF

1
2
3
4
5
6
7
8
9
# 安裝 ModSecurity
apt-get install -y libapache2-mod-security2

# 啟用 OWASP CRS 規則集
cp /usr/share/modsecurity-crs/crs-setup.conf.example /etc/modsecurity/crs-setup.conf

# 啟用 ModSecurity
a2enmod security2
systemctl restart apache2

設定檔案完整性監控 (AIDE)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 安裝 AIDE
apt-get install -y aide

# 初始化資料庫
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db

# 執行完整性檢查
aide --check

# 設定每日自動檢查 (crontab)
echo "0 3 * * * /usr/bin/aide --check | mail -s 'AIDE Report' admin@example.com" >> /etc/crontab

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy