Web 渗透实战手册:开局一个登录口,你能想到多少种攻击路径?

  • Home
  • Web 渗透实战手册:开局一个登录口,你能想到多少种攻击路径?
  • By: admin

天认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

版权与免责声明:本文档系技术分享资料,仅供学习和安全研究使用。任何未授权的攻击行为均属违法,请在授权范围内进行测试并遵守当地法律法规。