天认u-sec
Web 渗透实战手册
开局一个登录口,你能想到多少种攻击路径?
说明:本文为渗透测试技术讨论与教学资料。仅在取得授权的情况下用于测试,禁止用于任何未授权或非法用途。作者对使用者的非法行为不承担责任。
目录
一、概述与攻击面分层
二、检测与初始侦查(初等信息收集)
三、基础认证攻击(高风险)
四、输入验证与注入类漏洞(高风险)
五、认证/逻辑绕过与越权(高风险)
六、验证码与反自动化机制绕过(中风险)
七、信息泄露与前端分析(中风险)
八、外围侦查与旁站(再次信息收集)
九、风险汇总表与防御建议(扩展代码示例)
附录
一、概述与攻击面分层
一个登录入口并非孤立组件,它与会话管理、用户注册、密码找回、第三方登录、前端 JS、后端 API、子域名及同 IP 的其它服务紧密相连。本文将攻击面按功能/风险进行分层,便于在渗透测试报告中给出结构化发现。
分层(示例)
(初等信息收集)检测与初始侦查:指纹、源码、目录接口、JS文件、参数、交互回显
基础认证攻击(高):弱口令、喷洒、爆破、默认密码
输入验证与注入(高):SQLi、XSS、SSRF、命令注入
认证/逻辑绕过(高):返回包篡改、IDOR、注册逻辑缺陷
验证码与反自动化(中高):验证码复用、短信接口滥用
信息泄露(中):接口目录、JS 硬编码、Source Map、Swagger/GraphQL泄露
(再次信息收集)周边与旁站:下属或控股资产、子域名、端口、管理面板
二、检测与初始侦查(初等信息收集)
“渗透的本质是信息收集”,信息收集非常重要。
先把登录口当成一个黑盒拆干净——只聚焦登录页本身及其直接暴露的攻击面,根据该站信息进行一遍渗透后,如果发现不行再进入“再次信息收集”阶段:扫端口、子域爆破、旁站、控股资产等——用新的攻击面反哺登录口,再进行一遍渗透,如此循环,或直接换目标。
推荐工具&插件
信息搜集工具:
无影(TscanPlus):集成指纹、目录、接口、Swagger、Nacos 等一站式登录面侦察
bp插件:
HAE:自动高亮请求/响应中的手机号、邮箱、API 路径等 20+ 类敏感关键字,登录页注释一眼可见。
TsojanScan:被动扫描国产中间件默认路由、备份文件、Spring 网关,适合“不主动爆破就捡洞”。
浏览器插件:
雪瞳:❄️国产生态指纹库,瞬间标出若依、Jeecg、CAS、O2OA 等登录框架,并附带默认路径入口。
Wappalyzer:老牌栈识别,前端框架、后端语言、CDN、Analytics 全部列队展示。
Cookie-Editor:可视化增删改 Cookie,快速测试“只改某字段能否进后台”而无需脚本。
指纹与已知漏洞关联(初等阶段只做“轻量级”比对)
快速识别框架/中间件
用 Wappalyzer /雪瞳/无影指纹识别:Spring Boot、Shiro、ThinkPHP、Jeecg、CAS 等关键字出现即高亮记录
响应头里 X-Powered-By: Express、Server: nginx/1.18.0 也记下,后续可查对应 CVE
“一眼洞”规则速查
Shiro:响应头带 rememberMe=deleteMe → 直接贴「Shiro 反序列化待验」标签
Spring Boot:看到 /actuator、/env 200 返回 → 贴「Spring 监控接口泄露」标签
ThinkPHP:HTML 注释出现 TP版本、/public/index.php → 贴「TP5 RCE 待验」标签
只做标记,不发送任何 Payload;具体验证留到正式攻击阶段
前端静态拆包
查看源码
注释里常掉出测试账号、内网地址、TODO
收集 JS
全局搜关键字:api, url, path, admin, guest, test, pass, token, secret, reset, ws:
发现 .map → 自动解析 SourceMap(burp 插件 “SourceMapper” 或 npm 包 reverse-sourcemap),还原目录结构 + 路由表
把前端路由与后端接口区分
React/Vue 路由以 #/ 开头,可暂时忽略;关注 /api/*、/auth/*、/login/* 这类真实后端前缀
尝试目录递增递减枚举,发现可利用目录和接口
找出“隐藏参数”
登录 POST 体除了 username/password 是否还有 captchaKey、execution、_token、lt(CAS)、sessionID?先记下名字与出现位置,为后续注入/逻辑绕过做准备
交互差异探测
输入一个“一定不存在”的用户名 + 任意密码
观察返回:
200 vs 401 vs 302
响应体长度、延迟、错误文案(”用户不存在” / “密码错误”)
若提示不同 → 用户名枚举已成立,先写入临时风险点
输入一个“超长/特殊字符”密码(80 位 + '"><)
返回 500 或 SQL 异常关键字 → 可能拼接 SQL,先贴标签
重复提交同一验证码/空验证码字段
若仍返回“密码错误”而非“验证码错误” → 后端极可能没校验验证码,可直接进入爆破逻辑
登录流链路梳理
画出“登录按钮按下后”完整序列
302 跳转顺序
是否伴随 OAuth、CAS、SSO、二次短信、图形验证码、滑块
哪些请求带 Set-Cookie,哪些带 Authorization: Bearer
把“关键判断节点”标红
例如 /api/auth 返回 {"needCaptcha":true} → 后续可尝试篡改该节点直接 false
出现 redirect_uri → 记录其域名、路径、是否校验严格
三、基础认证攻击(高风险)
1. 弱口令与默认口令(高)
检测要点
尝试常见凭据(admin:admin、root:root、test:test)
检查是否存在空密码、未完成的初始管理员设置
防御建议
强制复杂度与最小长度、禁止默认口令、首次登录强制重置
多因素认证(MFA)
补充:密码喷洒(Password Spraying)
描述:对大量账号使用少数常见密码(例如 Password123),以规避锁定机制。
防御:基于风险的登录限制、动态阈值、MFA,建议实施基于用户行为的动态锁定策略(如:5分钟内同一账号错误3次锁定,但允许不同账号尝试),避免影响正常用户。
2. 密码爆破(中高)
注意点
若存在账号锁定/速率限制或验证码需避免爆破(应使用账号喷洒与监测差异化响应)
识别登录响应差异(响应时间/内容长度/HTTP状态)
防御
全局并发限制、IP 限流、滑动窗口锁定、登录行为监控
3. SQL 注入导致的“万能密码”示例(高)
检测
在用户名或密码处尝试 ' OR '1'='1、' OR 1=1 -- 等
注意服务端是否拼接 SQL 字符串并返回成功
防御
使用参数化查询/ORM、输入白名单、最小权限数据库账号
四、输入验证与注入类漏洞(高风险)
4. SQLi(SQL 注入)
检测:特殊字符、延时注入、布尔盲注
工具:sqlmap(注意合法授权)
防御:参数化、ORM、最小权限数据库账号、WAF 规则
5. XSS(跨站脚本)
登录页常见点:错误提示、referer、redirect 参数
防御:输出编码(上下文敏感)、CSP、输入校验
6. SSRF(服务端请求伪造)
常见触发点:头像 URL、第三方回调、导入/预览 URL
检测:尝试访问内网地址(127.0.0.1、169.254.169.254、10.0.0.0/8)
防御:白名单外联、URL 主机名校验、响应重写与超时控制
7. 命令注入 / 文件包含
上传、日志解析、shell 命令拼接等均可能触发
防御:避免直接拼接命令、使用安全库
五、认证/逻辑绕过与越权(高风险)
8. 返回包篡改
说明:仅修改客户端返回值一般无法获得真实权限,关键是检查后端是否信任前端返回字段(如 is_admin) 。返回包篡改不止运用在登录,也可以用在重置密码绕过步骤,实现任意用户密码重置
检测:拦截成功登录的响应,分析前端是否基于某字段判定权限,再尝试直接调用高权限接口或权限字段参数 bypass 后端校验。
登录:
登录验证示例:
如果是前段验证,甚至可以找到并修改前端代码使之变成永真语句
密码重置:
响应包如下,可以看到响应包返回4003,修改响应包绕过,尝试把4003修改为0,errormsg修改为空,放包。
成功绕过限制跳转到输入新密码页面,在数据包加上第一步的token后,输入新密码后修改成功。
防御:所有权限决策必须在后端强制校验;不要在前端保存或信任权限位(token payload 除外,应由服务器签名)。
9. 用户名枚举
通过错误信息或时间差判断用户是否存在
防御:统一错误返回、节流机制、模糊错误提示
10. 任意注册、权限赋予与账户覆盖
风险点:
注册功能是否可注册管理员权限账号:
是否任意注册账户覆盖,实现账号接管:
数据包如下,可以看到数据包有个code参数,正常发包注册成功:
尝试修改请求包,把code参数去掉,发包,注册成功。
两者注册同一账号返回包都如下,都注册成功。
{“code”:10000,”message”:”success”,”data”:true)}
防御:注册默认普通用户,管理员权限由受控流程分配,使用唯一约束进行校验,并在注册时验证用户名的唯一性。
11. IDOR(Insecure Direct Object Reference,遍历ID越权)(高)
检查资源访问是否仅通过可预测的 ID 控制(例如 /user/123/profile)
测试:遍历不同 ID,观察是否返回他人数据
防御:基于主体的访问控制(RBAC/ABAC)、不可预测 ID(UUID)并在服务器侧校验归属关系
12. 第三方登录 / 回调绕过
OAuth 回调参数(redirect_uri)不严谨可能导致钓鱼
具体可以查看此文章,作者:Z20安全攻防
https://mp.weixin.qq.com/s/H9GR6nzMeVuFbk_PpcB0vA
防御:严格校验 redirect_uri,使用允许列表和 state 参数
13. 特殊示例:微信小程序登录三要素
小程序接口通常含 encryptedData、session_key、iv 等,若后端解密或验证不严可导致手机号/账号接管
防御:使用服务端对 session_key 做严格验证,避免在客户端做敏感决策
六、验证码与反自动化机制绕过(中风险)
14. 图片验证码
常见绕过手段:
验证码复用、置空或删除参数
前端只做校验,后端未校验(直接绕过)
异常字符或超长输入导致服务异常
防御
后端始终校验验证码、短期唯一性、限制复用
增加速率限制、IP/设备指纹、行为分析
15. 手机短信验证码
风险点:
短信轰炸:利用bp的repeater、intruder模块或并发插件,滥用发送接口对目标手机号造成骚扰
验证码返回:检查验证码是否在响应包中返回
验证码双发:同一请求导致发送多个验证码。
常见3种号码双写:
分号:phone=138…;198… / phone=138…;phone=137…
逗号:phone=138…,198… / phone=138…,phone=137…
&:phone=138…&198… / phone=138…&phone=137…
短信内容修改:能否篡改短信模板或内容(请求包)
验证码复用:服务端验证一次成功后没有立即作废验证码,给其他账户提交也能通过验证
验证码爆破:验证码位数较少或能无限重试
默认验证码:系统使用000000、123456等默认值
防御
限流、验证码有效期短、一次性标识、发送频率限制、MFA
16. 滑块/行为验证码与高阶防护
滑块可被重放或通过脚本模拟;行为验证码依赖设备指纹与行为模型
防御:需配合设备指纹(如FingerprintJS)与请求上下文(IP信誉库)进行综合风险评估
七、信息泄露与前端分析(中风险)
17. JS 中的敏感信息
搜索关键词:password、secret、api_key、token、.map
Source Map 泄露会还原源代码,暴露敏感逻辑
泄露大量API路径和敏感信息,深入利用危害会加大
防御:构建发布流程中移除源映射、前端不存储密钥
18. API/接口发现
Swagger、GraphQL、Unprotected API 文档是高价值目标
Swagger接口未授权
防御:认证保护 API 文档、对外隐藏或基于 IP 访问控制
19. 日志/错误消息泄露
详细堆栈或 SQL 错误会泄露内部实现
防御:生产环境关闭详细堆栈,统一返回模糊错误
八、外围侦查与旁站(再次信息收集)
如果该站打不出洞,可以试试通过信息搜集来外围侦查、搜索旁站、查找企业>=51%控股公司,以绕过防护较强的站点,攻击较偏僻、维护少、防护薄弱的旁站,工具推荐TscanPlus(无影),资产测绘推荐上某鱼捞个几块/月的FOFA的API,可接入无影
寻找控股公司资产(控股>=51%)
注意事项:项目和攻防时会认控股>=51%的公司资产,但日常上交漏洞给SRC平台可能驳回,最终解释权归SRC平台,如果100%控股,基本实锤
股权穿透:用天眼查/企查查“最终受益人”功能,一层层往上找,当看见目标企业 A 对 B 持股 ≥51%(或 100%)时,把 B 的全量域名、备案 APP、公网 IP 段一次性导出来——这些在 SRC 里大概率算同一资产。
并表关键字:按住 Ctrl+F 在 A 的年报里搜“并入财务报表”“纳入合并范围”,只要出现 B 的公司名,就能坐实“亲儿子”身份,后续交漏洞不会被拒收。
批量拉取:把 B 的名称丢进 FOFA org="B公司关键字",icp="B公司备案号",一键捞出旁站、测试域、旧版接口;再丢 TscanPlus 自动跑端口、目录、Spring 网关、Nacos、Swagger、Actuator——控股公司往往防护薄弱,容易出高危。
预报告:挖到洞后先贴股权图+年报截图到 SRC“资产归属疑问”工单,运营 10 分钟就会回“可接收”,再正式交漏洞,赏金稳稳到账。
端口、目录与旁站扫描
对登录服务 IP 扫描其他端口、目录(ssh、redis、memcached、管理端口)
例1:端口扫描和通过指纹识别出spring,用spring目录字典扫描出gateway/
该URL没信息,再递增一级目录扫描
泄露token和接口
最后根据拼接接口和提供的body示例能查询敏感信息
例2:端口和目录扫描扫出nacos接口,后续直接工具利用
成功登录后翻配置文件,找找可利用信息再继续利用,如下,找到Redis密码和端口,可以直接连接成功
旁站常见泄露:开发调试页面、备份、旧版服务
子域名与资产发现
子域名通常更少维护,易有默认凭证或老旧接口
尝试用资产测绘发现更多的资产,资产测绘推荐上某鱼捞个几块/月的FOFA的API,可接入无影工具
指纹与已知漏洞关联
识别框架/版本(若依、Spring、jeecg、Shiro、Struts、ThinkPHP、WordPress 插件等)
使用 CVE/nuclei 模板做高概率验证(谨慎,需授权)
例:shiro反序列化漏洞(响应头存在rememberMe字段)
用工具扫描扫描并利用
九、风险汇总表与防御建议(扩展代码示例)
攻击向量
风险等级
常见发现点
防御要点
弱口令 / 默认口令
高
初始管理员、默认组件
强制密码策略、MFA、首次登录强制修改
密码喷洒 / 爆破
高
登录接口无速率限制
IP 限流、账户限流、行为监控
SQLi(登录参数)
高
字符串拼接的登录查询
参数化查询、WAF、最小权限
XSS(错误提示)
中
login error / redirect
输出编码、CSP
SSRF(URL 参数)
高
头像、导入 URL
白名单、内部地址拒绝
IDOR(资源遍历)
高
可预测 ID
主体校验、不可预测 ID
验证码复用/爆破
中
无唯一标识/无频率限制
一次性 token、频率限制
JS/sourceMap 泄露
中
.map、公开源码
发布流程移除、最小化
扩展防御代码示例(Express / Node.js 片段)
1) 参数化查询(SQL 注入防护) — 使用 mysql2
// 使用参数化查询示例(mysql2)
const mysql = require('mysql2/promise');
const pool = mysql.createPool({ /* config */ });
async function findUser(username) {
const [rows] = await pool.execute('SELECT id, password_hash FROM users WHERE username = ?', [username]);
return rows[0];
}
2) 安全 Cookie / 会话设置(HttpOnly、Secure、SameSite)
// express-session 示例(基本配置)
const session = require('express-session');
app.use(session({
name: 'sid',
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
httpOnly: true, // 防止 JS 访问
secure: process.env.NODE_ENV === 'production', // 仅 HTTPS 时发送
sameSite: 'lax', // 防范 CSRF(可按需调整为 'strict')
maxAge: 1000 * 60 * 60 // 1 hour
}
}));
3) 登录速率限制(防爆破 / 喷洒)
// 使用 express-rate-limit
const rateLimit = require('express-rate-limit');
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 5, // 每个 IP 15 分钟内最多 5 次登录尝试
standardHeaders: true,
legacyHeaders: false,
message: { error: 'Too many login attempts. Try later.' }
});
app.post('/login', loginLimiter, (req, res) => {
// 登录处理
});
4) 验证码/短信的一次性 Token 验证(后端示例)
// 简化示例:短信验证码存在 redis 中,使用一次后删除
const redis = require('redis');
const client = redis.createClient();
async function verifySmsCode(mobile, code) {
const key = `sms:${mobile}`;
const stored = await client.get(key);
if (!stored) return false;
if (stored !== code) return false;
// 验证通过后删除,防止重放
await client.del(key);
return true;
}
5) OAuth redirect_uri 严格校验(防护回调被滥用)
function isValidRedirect(clientId, redirectUri) {
// 从数据库读取允许的 redirect_uri 列表
const allowed = getAllowedRedirectsForClient(clientId); // e.g. ['https://example.com/cb']
return allowed.includes(redirectUri);
}
app.get('/oauth/callback', (req, res) => {
const { client_id, redirect_uri } = req.query;
if (!isValidRedirect(client_id, redirect_uri)) {
return res.status(400).send('Invalid redirect_uri');
}
// 继续处理
});
6) 资源归属校验(防止 IDOR)
// 以 Express 为例,resourceOwnerId 为资源在 DB 中的 owner 字段
app.get('/profiles/:id', async (req, res) => {
const resourceId = req.params.id;
const resource = await db.findProfile(resourceId);
if (!resource) return res.status(404).end();
// 服务器端校验当前用户是否为资源所有者或有授权角色
if (resource.ownerId !== req.session.userId && !req.session.isAdmin) {
return res.status(403).end();
}
res.json(resource);
});
7) Content Security Policy(CSP)基础示例(减轻 XSS 风险)
// helmet 用法示例
const helmet = require('helmet');
app.use(helmet({
contentSecurityPolicy: {
useDefaults: true,
directives: {
"script-src": ["'self'"],
"object-src": ["'none'"],
"upgrade-insecure-requests": []
}
}
}));
8) 发布流程:移除 Source Map(示例脚本)
package.json 的构建脚本示例(简化)
{
"scripts": {
"build": "webpack --mode=production && rm -f dist/*.map"
}
}
附录:
Author: 天认u
GitHub: tianrenu
GitHub Pages: https://tianrenu.github.io
License: CC BY-NC-SA 4.0
版权与免责声明:本文档系技术分享资料,仅供学习和安全研究使用。任何未授权的攻击行为均属违法,请在授权范围内进行测试并遵守当地法律法规。