钓鱼这事吧,说到底就一句话:让你把该给网站 A 的东西,交给网站 B。页面钓鱼攻击花样多,防不胜防,但只要抓住几个核心点,检测和防御并没有那么玄学。下面从攻击面、检测代码、防御方案三个层面梳理。
把目标站点的登录页、支付页原样扒下来,换个域名,骗你输入账号密码。技术含量最低,成功率却不低。
gooogle.com、paypa1.com。а 冒充英文 a,域名看着一模一样。login.taobao.com.attacker.com。短信、邮件、社交平台里常见的短链接,点进去几次 302 跳转,最后落到一个钓鱼页。
海报、桌贴、共享单车上的二维码,一扫就跳转到假登录页或恶意 App 下载。
买“XX 银行官网”关键词,排第一的就是钓鱼页。
公共 Wi-Fi 里做 DNS 劫持或 HTTP 注入,正常网站访问被插到钓鱼页。
下面给几个日常能用上的小脚本,放在安全分析、SOC、邮件网关里都合适。
用 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("疑似仿冒域名")
这个适合批量跑,把新注册域名和自身品牌域名做比对。
把 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
邮件网关、浏览器插件常用逻辑:跟踪短链接最终落在哪里。
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"))
一个简单规则:如果登录页表单把密码提交到第三方域名,基本就有问题。
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);
}
});
钓鱼页面千变万化,但核心攻击链路不变:诱导访问 → 伪装信任 → 骗取凭据/信息。对抗它不能只靠某一层,邮件网关、DNS、终端、身份、人员培训都要一起上。技术上,域名相似度、IDN 检测、跳转链追踪、表单提交域校验都是轻量但有效的手段。最后补一句:再强的技术也挡不住用户主动把密码填进去,安全意识永远是最贵的防线。