先搞清楚:你遇到的多半不是「DNS 污染」

訪客連到你的站,結果被導去陌生的廣告頁;Google 搜尋結果裡你的網頁掛著一堆藥品或博弈關鍵字;你打開首頁原始碼,發現 <head> 多了一段看不懂的 <script>。第一個冒出來的念頭通常是「我被 DNS 污染了」。

但這兩件事發生的地方完全不同,搞錯方向會白忙一場。

DNS 快取污染(DNS cache poisoning / spoofing)發生在 DNS 解析器,不在你的伺服器上。 攻擊者往遞迴解析器塞假的解析結果,讓所有用到那台解析器的人把你的網域解析到攻擊者的 IP。受害的是解析層,動到的是別人家的快取,你改自己網站的 web.config、清 wwwroot、封鎖 .php,一點用都沒有,因為惡意內容根本不是從你的主機送出去的。這類攻擊通常範圍很大(一台 ISP 解析器可能服務上百萬人),而且你在自己機器上 nslookup 出來的 A 記錄往往是正常的。

如果出現的症狀是「首頁原始碼被塞了東西」「wwwroot 多出沒見過的 .php / .aspx 檔」「IIS 記錄檔有可疑的 POST」,那是站台被入侵、被植入了 web shell 或惡意轉址腳本,屬於 post-exploitation 階段的後門,跟 DNS 污染是兩回事。判斷方法很直接:從別台乾淨的機器、不同網路抓你的網域,比對解析到的 IP 和回傳的內容。內容髒、IP 是你自己的主機,就是站台被黑;內容髒、IP 根本不是你的主機,才往 DNS 那邊查。

這篇後面講的清查與修復步驟,對應的都是後者——站台被入侵植入後門。標題沿用大家慣稱的「DNS 污染」,但實際處置請照「站台被黑」來做。

至於 Google Search Console(GSC),它在這兩種情況下都值得先設好:被入侵時它會推安全性警示、能讓你看到 Google 眼中的索引狀態、清乾淨後可以要求重新檢索。

Google Search Console 能幫上什麼

GSC(前身是 Google 網站管理員工具)是 Google 的免費網站監控工具。對處理資安事故來說,它最有用的幾件事:

  • 在 Google 偵測到你的站被掛馬或被植入內容時,發安全性警示給你
  • 用「安全性問題」報告看 Google 標記了哪些頁面有問題
  • 清理完成後,要求重新檢索,加速把汙染的快照從搜尋結果換掉
  • 透過「網址檢查」看 Google 實際抓到的 HTML,比對你本機看到的有沒有落差(被入侵的站常對 Googlebot 回傳和一般訪客不同的內容)

要用這些功能,前提是先在 GSC 完成「擁有權驗證」。

開始使用:

  1. 前往 Google Search Console
  2. 用 Google 帳號登入
  3. 點「新增資源」
  4. 選資源類型(網域 或 網址前置字元),填入你的網站
  5. 依資源類型選驗證方式(下一節說明)

IIS 站台怎麼做擁有權驗證(重點:別走 customHeaders 那條路)

GSC 的「HTML 標記」驗證,是讀你首頁 HTML <head> 裡的 <meta name="google-site-verification"> 標籤。它讀的是 HTML 文件內容,不是 HTTP 回應標頭。

這點很重要,因為 IIS 的 httpProtocol/customHeaders 加的是 HTTP 回應標頭,不會在 HTML 裡注入任何 <meta> 標籤——這兩層是分開的。網路上流傳一種寫法,叫你在 customHeaders 加一個 X-Meta-Google-Site-Verification 的 header 來「自動幫所有頁面加上 meta 標籤」。這是錯的:GSC 根本沒有這個 header 的驗證機制,customHeaders 也不可能把回應標頭變成頁面裡的 meta 標籤。照抄一定驗證失敗。

對 IIS 站台,真正可行的有三種。

方式一:上傳 HTML 驗證檔(最適合 IIS,建議優先)

這是對伺服器型網站最省事、也最不會出錯的方式,因為它不碰你的版型檔,只丟一個檔到網站根目錄。

  1. 在 GSC 選「HTML 檔案」驗證方式,下載 Google 給的驗證檔(檔名類似 google1234567890abcdef.html
  2. 把這個檔原封不動放到網站根目錄(IIS 預設是 C:\inetpub\wwwroot\),不要改檔名、不要改內容
  3. 確認瀏覽器能直接開到 https://你的網域/google1234567890abcdef.html
  4. 回 GSC 按「驗證」

實務上最常見的兩個坑:檔案被放錯目錄、或上傳過程被改了檔名。再來是 IIS 的 MIME 設定——如果根目錄沒有對應的靜態檔處理設定,.html 仍可正常回傳,但若你之前動過 staticContent/請求過濾把某些路徑擋掉,記得確認這個驗證檔的路徑沒被擋。

方式二:DNS TXT 記錄(驗整個網域,最穩)

如果你能改網域的 DNS 設定,用「網域」資源 + DNS TXT 驗證會最穩,因為它一次涵蓋該網域底下所有子網域與協定(http/https/www/non-www 都算),日後也不會因為改版型而失效。

  1. 在 GSC 選「網域」資源類型,它會給你一段 google-site-verification=... 的 TXT 值
  2. 到你的 DNS 服務商,幫該網域加一筆 TXT 記錄,值就是那串
  3. 等 DNS 生效(通常數分鐘到數小時,看 TTL),回 GSC 按「驗證」

方式三:HTML 標記 meta(適合單一版型、你能改 layout 時)

如果你的站是單一共用版型(例如所有頁面共用一個 _Layout.cshtml 或母版頁),把 meta 標籤加進那個版型的 <head> 也可以。注意:要加的是 HTML 標籤,不是 IIS header。

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>您的網站標題</title>

<!-- Google Search Console 驗證標籤:直接寫在 HTML 的 head 裡 -->
<meta name="google-site-verification" content="您的驗證碼" />
</head>
<body>
<!-- 網站內容 -->
</body>
</html>

放置規則:必須在第一個 <head> 區段內、<body> 之前,而且不能塞進 head 裡的其他標籤內部。

三種選一種做完就好。IIS 站我會優先選方式一或方式二,避免去動版型,也避開那個不存在的 header 驗證法。

清查並移除後門(站台被入侵的處置)

驗證只是讓你能監控。真正要修的是被植入的東西。順序大致是:先確認解析正常、再揪出可疑檔、最後收緊 IIS 設定。

1. 確認解析與站台內容對不對

1
2
3
4
5
6
7
8
# 從本機查網域的解析結果
nslookup your-domain.com

# 檢查重點:
# - A 記錄指到的 IP 是不是你自己的主機
# - 有沒有冒出來的 CNAME
# 若 A 記錄指向不明 IP(且你沒設過),才往 DNS 那邊追
# 若 A 記錄正常但內容是髒的,就是站台被入侵,往下做

最好同時從別台、別網路(手機開熱點)再抓一次首頁原始碼比對。被入侵的站有時會只對特定來源(例如帶 Google referer 或 Googlebot UA)回傳惡意內容,本機看反而正常。

2. 揪出最近被新增或竄改的可疑檔

被植入的 web shell 多半藏在網站根目錄底下,而且修改時間集中在事故發生前後。下面這段列出近 7 天內被改、體積偏大的腳本檔:

1
2
3
4
5
6
7
8
# 以系統管理員身分執行 PowerShell
$websiteRoot = "C:\inetpub\wwwroot"
Get-ChildItem -Path $websiteRoot -Recurse -Include *.php,*.asp,*.aspx,*.ashx,*.js |
Where-Object {
$_.LastWriteTime -gt (Get-Date).AddDays(-7) -and
$_.Length -gt 1MB
} |
Format-Table FullName, LastWriteTime, Length -AutoSize

這只是粗篩——體積大未必是壞檔、壞檔也可能很小。實務上 web shell 常是幾 KB 的單檔,所以別只看大小。把可疑名單抓出來後,逐一打開看內容(有 evalbase64_decodeRequest.Form 直接執行、Process.Start 之類就高度可疑),對照原始程式碼或備份確認哪些是外來的,再移除。重要的是先保留一份副本當證據,別急著直接刪光。

3. 收緊 IIS 設定,降低再被打的機會

如果你的站是純 ASP.NET、根本用不到 PHP,那讓 IIS 直接拒絕執行 .php、限制上傳大小,可以擋掉一票自動化的 web shell 上傳。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- web.config:用請求過濾收緊 -->
<configuration>
<system.webServer>
<security>
<requestFiltering>
<!-- 限制請求內容大小(位元組),這裡約 30 MB,依需求調 -->
<requestLimits maxAllowedContentLength="30000000" />
<!-- 若站台不需要 PHP,拒絕這類副檔名 -->
<fileExtensions>
<add fileExtension=".php" allowed="false" />
</fileExtensions>
</requestFiltering>
</security>
</system.webServer>
</configuration>

提醒:fileExtensions 是阻擋「請求」對應副檔名的存取,不是掃描磁碟上的檔。它擋的是 http://你的站/shell.php 這種請求,無法把已經落地的惡意檔清掉——清檔還是要靠上一步。另外,這類設定收緊的同時,務必確認沒擋到你的 GSC 驗證檔路徑。

收完設定別忘了回頭補根因:被入侵通常是某個應用程式漏洞或弱密碼,光清檔不補洞,過幾天又會被種回來。

疑難排解

GSC 驗證一直失敗

最常見的幾個原因:

  1. 驗證檔放錯位置或被改名——用瀏覽器直接開那個檔的網址確認,能開、內容是 Google 給的那串才算數。
  2. 走錯方法——別再試 customHeaders 那套,那個 header 不存在於 GSC。
  3. Google 抓不到你的站——確認首頁對外可達、沒有整站擋掉外部存取;如果你有用防火牆白名單,別把 Googlebot 擋在外面。
  4. 快取——清瀏覽器快取、等 DNS(用 TXT 驗證時)生效後再按驗證。

關於「放行 Googlebot IP」

舊文常叫你把幾個 66.249.x.x 子網段寫死進防火牆白名單。Google 官方已不建議硬編 IP,因為這些範圍會變動,寫死的清單很快過時。

官方做法有兩種:

  • 要驗證某個請求是不是真的 Googlebot,用 反向+正向 DNS 雙重確認(FCrDNS):對來源 IP 做反向 DNS,確認主機名落在 googlebot.com / google.com / googleusercontent.com,再對該主機名做正向 DNS,看是否解析回原 IP。兩邊都對才算數,這樣假冒者沒辦法靠亂設反向 DNS 蒙混。
  • 真的要做防火牆規則或白名單,請抓 Google 持續更新的 JSON 清單,例如常見爬蟲的 common-crawlers.json,依當下內容套用,別把片段抄死在文章或設定裡。

預防措施

  1. 定期更新作業系統、IIS 與你的應用程式框架,補掉已知漏洞
  2. 收緊請求過濾與上傳限制,關掉用不到的處理常式對應(例如不用 PHP 就別讓它能執行)
  3. 啟用檔案完整性監控,wwwroot 一被改就有紀錄可查
  4. 定期備份,而且要保留乾淨版本當比對與還原來源
  5. 保存並定期檢視 IIS 記錄檔,異常的 POST、奇怪的路徑請求往往是早期徵兆
  6. 先在 GSC 設好擁有權驗證,讓 Google 的安全性警示能第一時間找到你

參考資源

  1. Google Search Console:驗證網站擁有權
  2. Google Search Console 新手指南
  3. IIS:customHeaders 設定(Microsoft Learn)
  4. IIS security 設定(Microsoft Learn)
  5. 驗證來自 Google 爬蟲的請求
  6. Cloudflare:什麼是 DNS 快取污染
  7. TWCERT/CC 資安警訊