页面钓鱼:攻击花样、检测代码与防御实操

Published on with 0 views and 0 comments

页面钓鱼:攻击花样、检测代码与防御实操

钓鱼这事吧,说到底就一句话:让你把该给网站 A 的东西,交给网站 B。页面钓鱼攻击花样多,防不胜防,但只要抓住几个核心点,检测和防御并没有那么玄学。下面从攻击面、检测代码、防御方案三个层面梳理。


一、页面钓鱼常见类型

1. 克隆站

把目标站点的登录页、支付页原样扒下来,换个域名,骗你输入账号密码。技术含量最低,成功率却不低。

2. 域名混淆

  • 拼写近似:gooogle.compaypa1.com
  • IDN 同形异义:用西里尔字母 а 冒充英文 a,域名看着一模一样。
  • 子域名误导:login.taobao.com.attacker.com

3. 短链接与重定向

短信、邮件、社交平台里常见的短链接,点进去几次 302 跳转,最后落到一个钓鱼页。

4. 二维码钓鱼

海报、桌贴、共享单车上的二维码,一扫就跳转到假登录页或恶意 App 下载。

5. 搜索引擎广告/SEO 投毒

买“XX 银行官网”关键词,排第一的就是钓鱼页。

6. 中间人/流氓热点

公共 Wi-Fi 里做 DNS 劫持或 HTTP 注入,正常网站访问被插到钓鱼页。


二、检测代码示例

下面给几个日常能用上的小脚本,放在安全分析、SOC、邮件网关里都合适。

1. 域名相似度检测

用 Python 快速判断两个域名是不是长得像。

import difflib

def domain_similarity(a: str, b: str) -> float:
    return difflib.SequenceMatcher(None, a.lower(), b.lower()).ratio()

legit = "alipay.com"
suspicious = "al1pay.com"
score = domain_similarity(legit, suspicious)
print(f"相似度: {score:.2f}")
if score > 0.75 and score < 1.0:
    print("疑似仿冒域名")

这个适合批量跑,把新注册域名和自身品牌域名做比对。

2. IDN 同形异义字符检测

把 Unicode 域名展开成 Punycode,一眼就能看出有没有猫腻。

import idna

def inspect_idn(domain: str):
    try:
        ascii_form = idna.encode(domain).decode("ascii")
        print(f"原始: {domain}")
        print(f"Punycode: {ascii_form}")
        if ascii_form.startswith("xn--"):
            print("含非 ASCII 字符,需人工复核")
    except idna.IDNAError as e:
        print(f"IDNA 解析失败: {e}")

inspect_idn("раураl.com")  # 西里尔字母伪装 paypal

3. URL 跳转链追踪

邮件网关、浏览器插件常用逻辑:跟踪短链接最终落在哪里。

import requests

def trace_redirects(url: str, max_hops: int = 5) -> list[str]:
    hops = []
    try:
        resp = requests.get(url, allow_redirects=False, timeout=10)
        hops.append(resp.url)
        while resp.is_redirect and len(hops) < max_hops:
            loc = resp.headers.get("Location")
            if not loc:
                break
            hops.append(loc)
            resp = requests.get(loc, allow_redirects=False, timeout=10)
    except Exception as e:
        hops.append(f"error: {e}")
    return hops

print(trace_redirects("https://t.cn/xxx"))

4. 页面表单风险检测

一个简单规则:如果登录页表单把密码提交到第三方域名,基本就有问题。

from urllib.parse import urlparse
from bs4 import BeautifulSoup
import requests

def check_form_action(page_url: str) -> dict:
    resp = requests.get(page_url, timeout=10)
    soup = BeautifulSoup(resp.text, "html.parser")
    base = urlparse(page_url).netloc
    risks = []

    for form in soup.find_all("form"):
        action = form.get("action") or page_url
        target = urlparse(action).netloc
        if target and target != base:
            risks.append(f"表单提交到外部域名: {target}")
        if form.find("input", {"type": "password"}):
            risks.append("发现密码输入框")

    return {
        "domain": base,
        "risk_count": len(risks),
        "details": risks
    }

print(check_form_action("https://example.com/login"))

浏览器端也可以做类似校验:

document.querySelectorAll('form').forEach(form => {
    const action = new URL(form.action, location.href);
    if (action.hostname !== location.hostname) {
        console.warn('可疑表单提交到外部域名', action.hostname);
    }
});

三、防御与运维方案

1. 邮件/网关层

  • 配置 SPF、DKIM、DMARC,防止伪造发件人。
  • 邮件网关提取链接做 URL 重定向解析,命中威胁情报直接拦截。

2. DNS 与证书层

  • 企业内部 DNS sinkhole 恶意域名。
  • 部署企业证书,流氓热点或中间人代理较难伪造。

3. 端点层

  • 浏览器开启安全浏览(Safe Browsing / SmartScreen)。
  • EDR/XDR 检测凭据窃取行为。

4. 身份层

  • 关键账号强制 MFA,优先 TOTP 或硬件密钥。
  • 不同站点用不同密码,密码管理器必上。

5. 人员层

  • 定期钓鱼演练,让真邮件和假邮件混在一起训练。
  • 不点短链接、不扫不明二维码,手敲域名访问网银。

6. 品牌保护

  • 监控新注册域名里跟自己品牌相似的那些。
  • 买下常见 typo 域名,重定向回官网。
  • 对品牌关键词做 SEM 占位,减少 SEO/广告投毒空间。

四、总结

钓鱼页面千变万化,但核心攻击链路不变:诱导访问 → 伪装信任 → 骗取凭据/信息。对抗它不能只靠某一层,邮件网关、DNS、终端、身份、人员培训都要一起上。技术上,域名相似度、IDN 检测、跳转链追踪、表单提交域校验都是轻量但有效的手段。最后补一句:再强的技术也挡不住用户主动把密码填进去,安全意识永远是最贵的防线。