
簡介
本報告提供對 PoisonSeed 釣魚套件的全面技術分析,這是一個採用 Adversary-in-the-Middle (AiTM) 技術來繞過多因素認證的複雜 MFA 抗性釣魚框架。分析聚焦於該套件的 React 基礎前端架構、後端功能以及運作方法,深入探討其模組化設計與攻擊鏈的實現。

簡介
多因素認證 (MFA) 已成為現代網路安全的核心,通過要求不只密碼的驗證方式,大幅提升了線上帳戶的安全性。然而,隨著網路威脅的不斷演進,出現了專為繞過 MFA 保護的複雜釣魚技術。其中一個顯著的威脅是 PoisonSeed 釣魚套件,它採用先進的 Adversary-in-the-Middle (AiTM) 策略來危害用戶認證並繞過 MFA 機制。本報告深入探討 PoisonSeed 釣魚套件的技術細節,分析其運作方法、前端與後端組件,以及支撐其欺騙行為的底層程式碼結構。通過了解這種 MFA 抗性釣魚套件的技術架構與攻擊鏈,組織和個人可以更好地強化防禦,抵禦這些持續且不斷演進的網路威脅。
本研究建立在 NVISO Labs [2] 和 Silent Push [1] 初步報告的基礎上,提供對 PoisonSeed 活動的綜合技術視角。焦點放在釣魚套件的技術層面,包括其基於 React 的前端以及對其 AiTM 能力至關重要的隱含後端功能,同時盡量減少對地理或國家環境的提及,以保持純技術分析。
釣魚套件概覽與技術分析
PoisonSeed 釣魚套件採用模組化架構設計,主要使用 React 開發其前端組件。這種設計提供了動態且具說服力的用戶體驗,幾乎完美模擬合法的登入服務。該套件的核心功能圍繞三個主要組件:偽造的 Cloudflare Turnstile 挑戰、登入表單和雙因素認證 (2FA) 表單 [2] 。
前端架構 (React)
PoisonSeed 釣魚套件的前端採用 React,這是一個用於構建用戶介面的 JavaScript 程式庫。使用 React 能夠創建單頁應用程式,無需完整頁面重新載入即可動態更新內容,從而提供無縫且具欺騙性的用戶體驗。該套件中識別出的主要 React 組件包括
App.jsx
、
TurnstileChallenge.jsx
、
LoginForm.jsx
、
TwoFactorAuthForm.jsx
和
SuccessPage.jsx
[2]
。
App.jsx
App.jsx
組件作為釣魚套件前端的核心協調器(Orchestrator)。其主要角色是管理受害者通過釣魚攻擊各階段的流程,確保完成初步安全步驟(如偽造的 Cloudflare Turnstile 挑戰)後,才能存取敏感路由,如登入和 2FA 表單。該組件使用 React hooks,例如
useState
管理組件狀態,以及
useEffect
處理副作用,例如 URL 參數解析和重新導向邏輯
[2]
。
App.jsx
中的一個關鍵功能是檢查 URL 中的加密電子郵件。如果未檢測到加密電子郵件且 session 未標記為已驗證,受害者將立即被重新導向至
https://www.google.com
。此機制可能是一種簡單的過濾方式,確保只有預選的受害者能繼續進行釣魚流程,排除非目標用戶或 bot
[2]
。
- function App() {
- const [error, setError] = useState('');
- const location = useLocation();
- const isVerified = sessionStorage.getItem('fakeTurnstileVerified') === 'true';
- useEffect(() => {
- const queryParams = new URLSearchParams(location.search);
- const encryptedEmail = queryParams.get('email');
- console.log('Location.search:', location.search);
- console.log('Encrypted email from query:', encryptedEmail);
- if (!encryptedEmail && location.pathname === '/' && !isVerified) {
- console.log('No encrypted email found on initial load, redirecting to Google');
- window.location.href = 'https://www.google.com';
- } else if (encryptedEmail) {
- console.log('Encrypted email found, proceeding:', encryptedEmail);
- } else {
- console.log('No email on subsequent route, continuing anyway');
- }
- }, [location]);
此外,
App.jsx
定義了一個
ProtectedRoute
包裝器。此包裝器作為門衛,確保只有經過驗證的用戶才能存取受保護的路由。如果用戶未驗證,則會被重新導向至
/verify
路由,顯示偽造的 Cloudflare Turnstile 挑戰。此重新導向保留了原始查詢字串和狀態,允許在成功(模擬)驗證後無縫返回到預定的受保護路由
[2]
。
- const ProtectedRoute = ({ children }) => {
- if (!isVerified) {
- const queryString = location.search;
- return (
- <Navigate
- to={`/verify${queryString}`}
- state={{
- from: location.pathname,
- }}
- replace
- />
- );
- }
- return children;
- };
App.jsx
中的路由將特定 URL 路徑映射到相應的 React 組件,協調用戶在釣魚流程中的旅程。
/verify
路徑呈現
TurnstileChallenge
組件,根路徑 (
/
) 呈現包裝在
ProtectedRoute
中的
LoginForm
組件,
/2fa
路徑呈現同樣包裝在
ProtectedRoute
中的
TwoFactorAuthForm
組件,而
/success
路徑則呈現
SuccessPage
組件
[2]
。
- return (
- <Router>
- <Routes>
- <Route path="/verify" element={<TurnstileChallenge />} />
- <Route path="/" element={
- <ProtectedRoute>
- <LoginForm />
- </ProtectedRoute>
- } />
- <Route path="/2fa" element={
- <ProtectedRoute>
- <TwoFactorAuthForm />
- </ProtectedRoute>
- } />
- <Route path="/success" element={<SuccessPage />} />
- </Routes>
- </Router>
- );
TurnstileChallenge.jsx
此組件旨在顯示一個令人信服但偽造的 Cloudflare Turnstile 挑戰。其主要目的是模擬驗證程序,從而為釣魚企圖增添一層合法性,同時可能繞過自動安全措施,這些措施可能會標記直接重新導向到登入表單的行為。該組件使用
useEffect
hook 模擬延遲,隨後將
sessionStorage
中的
fakeTurnstileVerified
標誌設置為
true
,並將用戶重新導向至根路徑。這種模擬驗證通常持續約 3 秒,是釣魚套件運作流程的關鍵
[2]
。
- function TurnstileChallenge() {
- const navigate = useNavigate();
- const location = useLocation();
- useEffect(() => {
- const queryParams = new URLSearchParams(location.search);
- const encryptedEmail = queryParams.get("email");
- if (!encryptedEmail) {
- window.location.href = "https://www.google.com";
- return;
- }
- // Simulate verification process
- setTimeout(() => {
- sessionStorage.setItem("fakeTurnstileVerified", "true");
- navigate("/");
- }, 3000); // Simulate a 3-second verification
- }, [navigate, location]);
- return (
- <div className="turnstile-challenge">
- <p>Verifying you are not a robot...</p>
- {/* Simulate Cloudflare Turnstile widget */}
- <div className="spinner"></div>
- </div>
- );
- }
LoginForm.jsx
LoginForm.jsx
組件負責呈現一個精心模仿合法服務的登入表單。此組件捕獲受害者輸入的用戶名稱和密碼。表單提交時觸發的
handleSubmit
函數設計用於將這些捕獲的認證資料發送到釣魚套件的後端。在現實場景中,此後端互動將涉及將認證資料外洩至攻擊者控制的基礎設施
[2]
。
- function LoginForm() {
- const [email, setEmail] = useState("");
- const [password, setPassword] = useState("");
- const navigate = useNavigate();
- const handleSubmit = async (e) => {
- e.preventDefault();
- // In a real scenario, this would send data to a backend
- console.log("Login attempt with:", { email, password });
- // Simulate successful login and navigate to 2FA or success page
- navigate("/2fa");
- };
- return (
- <div className="login-form">
- <h2>Sign In</h2>
- <form onSubmit={handleSubmit}>
- <input
- type="email"
- placeholder="Email"
- value={email}
- onChange={(e) => setEmail(e.target.value)}
- required
- />
- <input
- type="password"
- placeholder="Password"
- value={password}
- onChange={(e) => setPassword(e.target.value)}
- required
- />
- <button type="submit">Continue</button>
- </form>
- </div>
- );
- }
TwoFactorAuthForm.jsx
此組件對於繞過 MFA 至關重要。它處理受害者輸入的 2FA 程式碼,支持多種方法,例如驗證器程式碼、SMS 程式碼、電子郵件程式碼和 API Keys。與登入表單類似,
handleSubmit
函數負責將這些 2FA 詳情傳遞給合法服務,從而使攻擊者能夠捕獲第二認證因素
[2]
。
- function TwoFactorAuthForm() {
- const [code, setCode] = useState("");
- const [method, setMethod] = useState("authenticator"); // Default to authenticator
- const navigate = useNavigate();
- const handleSubmit = async (e) => {
- e.preventDefault();
- // In a real scenario, this would send 2FA data to a backend
- console.log("2FA attempt with:", { method, code });
- // Simulate successful 2FA and navigate to success page
- navigate("/success");
- };
- return (
- <div className="two-factor-auth-form">
- <h2>Two-Factor Authentication</h2>
- <form onSubmit={handleSubmit}>
- <select value={method} onChange={(e) => setMethod(e.target.value)}>
- <option value="authenticator">Authenticator Code</option>
- <option value="sms">SMS Code</option>
- <option value="email">Email Code</option>
- <option value="api_key">API Key</option>
- </select>
- <input
- type="text"
- placeholder="Enter code or API Key"
- value={code}
- onChange={(e) => setCode(e.target.value)}
- required
- />
- <button type="submit">Verify</button>
- </form>
- </div>
- );
- }
SuccessPage.jsx
SuccessPage.jsx
組件在看似成功的認證程序後顯示給受害者。此組件通常包括模擬重新導向到合法服務,完成正常登入的假象。此最後一步對於維持欺騙性並防止受害者立即意識到自己已被釣魚至關重要
[2]
。
- function SuccessPage() {
- useEffect(() => {
- // Simulate redirection to legitimate service after a short delay
- setTimeout(() => {
- window.location.href = "https://www.sendgrid.com"; // Example legitimate service
- }, 2000);
- }, []);
- return (
- <div className="success-page">
- <h2>Authentication Successful!</h2>
- <p>Redirecting you to the service...</p>
- </div>
- );
- }
後端互動與資料外洩
雖然提供的程式碼片段主要詳述了 PoisonSeed 釣魚套件的客戶端(前端)操作,但該套件的有效性取決於強大的後端基礎設施,該基礎設施促進其 Adversary-in-the-Middle (AiTM) 能力。後端負責攔截、處理和中繼認證資訊在受害者與合法服務之間,並將敏感資料外洩給攻擊者。AiTM 技術是一種複雜的中間人攻擊形式,攻擊者在用戶與合法網站之間定位,代理所有流量並即時捕獲認證和 session tokens [3] 。
後端的關鍵功能包括:
- 電子郵件驗證: 驗證 URL 中的加密電子郵件,並檢查任何黑名單或白名單,以確保目標有效且非安全研究人員或 bot。此伺服器端驗證增加了複雜性,使釣魚企圖更具針對性且難以檢測 [2] 。
- 認證中繼: 接收從 React 前端提交的認證資料(用戶名稱、密碼和 2FA 程式碼)。後端隨後將這些認證轉發至實際合法服務,代表受害者進行登入 [2] 。
- Session Hijacking: 在與合法服務成功認證後,後端捕獲返回的認證 cookies 或 tokens。這些 tokens 使攻擊者無需重新認證即可獲得對受害者帳戶的未授權存取 [2] 。
- 資料外洩: 捕獲的認證和 session 資訊隨後被儲存,並可能發送到由 PoisonSeed 控制的 Command and Control (C2) 伺服器。此外洩是釣魚操作的最終目標,使後續惡意攻擊(如批量電子郵件列表下載或進一步帳戶危害)成為可能 [2] 。
這種 AiTM 功能對於繞過 MFA 保護至關重要,因為它在用戶提供認證和第二因素後攔截認證流程。後端可能使用自定義腳本或專用代理工具來處理 HTTP requests、解析 responses 並管理與合法服務的 sessions,通常利用網路通信和資料處理的程式庫。
危害指標 (IoCs)
識別危害指標 (IoCs) 對於檢測和防止未來由 PoisonSeed 釣魚套件發起的攻擊至關重要。根據分析,識別出幾個關鍵 IoCs:
- 域名註冊: 與 PoisonSeed 相關的域名通過 NICENIC 註冊商註冊 [2] 。監控通過此註冊商新註冊的域名,特別是那些模仿合法服務的域名,有助於早期檢測。
- 主機提供商: 釣魚套件的基礎設施使用多個主機提供商,包括 Cloudflare、DE-First Colo 和 SWISSNETWORK02 [2] 。網路防禦者可利用此資訊識別並阻止來自或前往這些網路中可疑主機的流量。
- 網域名稱伺服器: Cloudflare 和 Bunny.net 用作 PoisonSeed 域名的名稱伺服器 [2] 。涉及這些名稱伺服器的異常 DNS 查詢或解析,可能表明釣魚活動。
進一步調查特定域名、IP 位址和與這些服務相關的唯一檔案 hashes,將提供更細緻的 IoCs,以增強檢測能力。威脅情報平台和安全資訊與事件管理 (Security Information and Event Management, SIEM) 系統可設定為對這些 IoCs 發出警報。
預防與緩解策略
防禦像 PoisonSeed 這樣複雜的釣魚攻擊需要多層次的方法,包括技術控制、用戶教育和持續監控。對 PoisonSeed 套件的技術分析強調了處理客戶端漏洞和底層 AiTM 技術的重要性。
- 強認證: 實施和執行抗釣魚的多因素認證 (MFA) 方法至關重要。雖然 PoisonSeed 旨在繞過 MFA,但某些 MFA 實現(如 FIDO2 安全密鑰)因其將認證加密綁定到合法來源而天生更抗釣魚 [4] , [5] 。組織應優先採用此類方法,而不是易受攔截的較不安全的選項,如基於 SMS 的 MFA 或一次性密碼 (One-Time Passwords, OTPs) [6] 。
- 用戶意識與教育: 人為因素仍然是一個重大漏洞。全面且持續的用戶教育計劃對於提高對釣魚策略的認識至關重要,包括 URL 操縱、偽造登入頁面的欺騙性質以及驗證網站真實性的重要性。應培訓用戶辨識釣魚企圖的細微跡象並報告可疑電子郵件或網頁 [2] 。
- 異常檢測與行為分析: 監控異常登入模式、可疑電子郵件活動和異常網路流量有助於檢測正在進行的釣魚活動。行為分析可以識別偏離正常用戶行為的情況,例如從異常地理位置登入、多次失敗的登入嘗試或帳戶設定的快速變化,這些可能表明帳戶已被滲透 [2] 。
- 電子郵件安全網關與網頁過濾器: 先進的電子郵件安全網關可以通過分析發件人信譽、電子郵件內容和嵌入的連結,在釣魚電子郵件到達最終用戶之前檢測並阻止它們。網頁過濾器可以防止存取已知的惡意域名和 IP 位址,這些位址與釣魚套件相關聯。
- 定期安全審計與滲透測試: 進行定期安全審計和滲透測試,包括模擬釣魚攻擊,有助於識別組織防禦中的弱點並提高事件響應能力。這些練習還可以驗證已實施的安全控制的有效性。
結論
PoisonSeed 的 MFA 抗性釣魚套件代表了認證採集技術的重大進化,利用基於 React 的前端與 Adversary-in-the-Middle (AiTM) 後端的複雜結合來繞過多因素認證。該套件的模組化設計及其模仿合法服務的能力使其成為一個強大的威脅。對其組件的詳細技術分析,從
App.jsx
協調器到用於 2FA 繞過的
TwoFactorAuthForm.jsx
,突顯了 threat actors 運用的巧妙技術。
了解此套件的技術細節,特別是其依賴 AiTM 進行 session hijacking 和資料外洩,對於制定有效的防禦策略至關重要。組織必須超越傳統安全措施,採取主動立場,優先採用抗釣魚的 MFA、持續的用戶教育、強大的異常檢測以及先進的電子郵件和網頁安全解決方案。進一步研究 threat actors 如 PoisonSeed 的演進策略以及分享詳細的危害指標,將對於增強對這些持續且適應性強的威脅的集體網路安全韌性至關重要。
參考文獻
- PoisonSeed Campaign Targets CRM and Bulk Email Providers in Supply Chain Spam Operation
- Inside PoisonSeed's MFA Phishing Tactics
- Adversary-in-the-Middle, Technique T1557 - MITRE ATT&CK®
- Defense-in-Depth Strategy to Combat MFA Bypass Attacks - Proofpoint
- What Is Phishing-Resistant MFA and How Does it Work? - HYPR Blog
- MFA Bypass Explained & How to Prevent It - Descope