freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

SDLC之损坏的认证
2021-09-23 23:39:07

身份认证绕过

身份验证绕过以多种方式发生,但通常利用配置或逻辑中的某些缺陷。

隐藏输入

最简单的形式是依赖于网页/DOM 中的隐藏输入。

删除参数

有时,攻击者不知道参数的正确值,他们可能会从提交中完全删除参数以查看会发生什么。

强制浏览

如果站点的某个区域没有受到配置的适当保护,则可以通过枚举来访问该站点的认证区域。

paypal 2FA bypass案例

案例说的事情是,删除两个问题参数

image

相仿案例的测试手法,将问题参数都删除后,发现不行。然后分别试了其他可能,删其中一个参数,值为null都是一样的提示。

image

一直卡着对提升非常无助,要么扩大知识面增加攻击向量,要么模仿与练习增加测试姿势与见识。翻阅提示,它说不能删除参数,而是篡改问题参数。

image

仔细观察发现参数的附带ID,提醒了我们。

image

我们有理由猜测:服务器端在检查参数的数量,以及问题参数名是否为secQuestion,但不检查参数附带的后缀。造成的bypass。

image

JWT token

可以参考这篇文章

jwt debug资源

https://jwt.io/

ajax:异步JavaScript和XML。

其中XML带有一种误导性。现代的XML旨在表示数据交换中的XML格式和JSON格式。

总而言之,都是变量与值。形式,长相,表达可能不同。但本质相通。

识别jwt很简单:两点号,三部分,base编码

image

这么让我们解码:使用bp商城附带插件或者jwt debug网站,得到用户名

image

image

身份验证和获取JWT token

image

先认证,然后服务器返回JWT,认证头再发送JWT去拿授权后的资源,服务器检查JWT签名进行检查,最后响应资源。

从以上认知中,除了密钥以外,其他参数我们都可以看见。因此不要把敏感的信息放在参数中。尤其是一些改变授权的参数与值,比如password:12345678。

image

如果密钥被爆破,那么整个JWT形同虚设。

这里让我们观察JWT,篡改它提权为管理员,最后重置投票

image

随便切一个用户观察数据包。发现cookie中的JWT

image

image

admin字段改成true

image

找到重置投票功能点,观察数据包,修改admin字段,签名置空

image

image

JWT库诞生于规范中,包括支持的算法值以及加密算法背后的设计的缺陷,签名中密钥的配置,保护等

https://tools.ietf.org/html/rfc8725#section-2.1

image

这些规范增加了攻击向量:攻击者可以尝试加密算法篡改为none(None,nOne等多种变体),某些库会信任这个值并验证JWT,而不需要检查签名。你说没有加密算法,它就信。

RS256加密算法可以篡改为HS512时,一些库竟然会使用RS256的公钥进行签名。我们也能拿到公钥,自己给自己签名了。CVE-2015-9235

回顾以上关于JWT的重置投票功能点的测试手法:我们选择一个用户Tom可以投票但无法重置。解码请求头中的JWT,篡改了admin,但是签名过不去检测。这时候可以测试签名的空值,加密算法的none来绕过签名,因为是靶机或者用TOP100密码爆破密钥。

GET http://localhost:8080/WebGoat/JWT/votings/login?user=Tom HTTP/1.1

access_token=eyJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2MDgxMjg1NjYsImFkbWluIjoiZmFsc2UiLCJ1c2VyIjoiVG9tIn0.rTSX6PSXqUoGUvQQDBiqX0re2BSt7s2-X6FPf34Qly9SMpqIUSP8jykedJbjOBNlM3_CTjgk1SvUv48Pz8zIzA

基于多方观察,包括SANS社区的课程也是这么教学。意思是告诉您,评估进行到这里已经可以了,剩下的评估莫要钻入兔子洞,让专家解决掉更多的0day,或者让自己慢慢变成专家去发现更多的攻击向量。

https://www.youtube.com/watch?v=wt3UixCiPfo 安全周刊

https://www.youtube.com/watch?v=z1FL0lG_8ds SANS社区

代码审计

观察一下alg: none的,无签名JWT如何验证的。来翻译英文单词,解决掉大部分的代码理解问题。

eyJhbGciOiJub25lIiwidHlwIjoiSldUIn0.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.

image

整个代码的缺陷在于验证 if (isAdmin),它是基于字段的验证,而没有出现任何其他JWT签名的验证,因此bug显而易见。其他代码都是取参数,设参数,接收参数等。

try {
   Jwt jwt = Jwts.parser().setSigningKey(JWT_PASSWORD).parseClaimsJws(accessToken);
   Claims claims = (Claims) jwt.getBody();
   String user = (String) claims.get("user");     # 这里取用户
   boolean isAdmin = Boolean.valueOf((String) claims.get("admin"));
   if (isAdmin) {             # 这里的验证用户不是Admin,因此执行异常
     removeAllUsers();
   } else {
     log.error("You are not an admin user");
   }
} catch (JwtException e) {
  throw new InvalidTokenException(e);
}

密钥爆破

这里是要爆破签名密钥,提供了字典。得到签名密钥后,改用户名。

image

爆破,准备好签名文件与字典

image

hashcat -a 0 -m 16500 jwt.txt google-10000.txt

image

将爆破的密钥填入,再篡改一下用户名

image

如果出现jwt过期,则重置一下

image


访问令牌与刷新令牌

当您不停的重放登录认证包时,返回包中的cookie值不停的刷新,这个跟踪字符串就是刷新令牌。用于后面授权用户其他功能点的资源访问。

而请求包中的1的地方则是访问令牌,当刷新令牌刷新时则代替掉请求包的访问令牌的位置,使得访问令牌不再有效。这才具备刷新一词的安全性。当令牌又刷新,而原来的访问令牌居然还生效,这非常荒唐。

image

刷新令牌是服务器可以跟踪的随机字符串, 它可能存于服务器内存中或数据库里,为了将刷新令牌与授予刷新令牌的用户匹配。

每当攻击者获得访问令牌时,它只在一定时间内有效(比如10分钟)。然后攻击者需要刷新令牌来获取新的访问令牌。 这就是为什么刷新令牌需要更好的保护。

我们要检查什么?

自始至终,应该在服务器端存储足够的信息来验证用户是否还是值得信赖的。当您拿着无数张shenfenZ去过安检时,都可以通过,这非常荒唐。

您可以存储ip地址,跟踪刷新了多少次令牌(在访问令牌的有效时间窗口中多次使用刷新令牌可能表示奇怪行为,您可以撤销所有令牌并让用户再次进行身份验证)。 还要跟踪哪个访问令牌属于哪个刷新令牌,否则攻击者可能会为不同的用户获取新的访问令牌

赏金漏洞:https://emtunc.org/blog/11/2017/jwt-refresh-token-manipulation/

讲的是,不停的生成刷新令牌,然后给所有用户使用。。

JWT 是个好主意吗?

有很多可用资源质疑使用 JWT 令牌进行客户端到服务器身份验证的用例。使用 JWT 令牌的最佳位置是服务器到服务器之间的通信。在普通网络应用程序中,您最好使用普通的旧cookie。 有关更多信息,请参见:

停止使用JWT于会话管理

http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/

http://cryto.net/~joepie91/blog/2016/06/19/stop-using-jwt-for-sessions-part-2-why-your-solution-doesnt-work/

让他人付款

这是上面那篇,私人漏洞赏金计划的复盘 https://emtunc.org/blog/11/2017/jwt-refresh-token-manipulation/

叫我们通过下载日志,取得JWT,然后让Tom付款。

image

image

解码发现用户就是Tom

image

老毛病的话,重置一下靶机,刷新页面,就出来了。

这里有两个令牌:访问令牌与刷新令牌,两者都非常敏感,绝不能泄露……

image

而这个API就是Tom的JWT

image

我相信,靶机的目的就是篡改刷新令牌(自己)与访问令牌(Tom。不是使用旧的就是利用这两者去API获取新的)来使得让他人付款。但是靶机问题太多无法复盘。尽管如此,这种测试手法依旧可以用于他处。

image

尽管此问题牛头不对马嘴,但也侧面意识到并非一定要钻这个兔子洞。因为测试方法已经习得,何忧?

image

jwt.io篡改一下日志中的历史JWT,过期时间加到当下时间之后

image

使用空签名。

image

而靶机设计的目的是去另一个API端点获取刷新令牌。尽管通过了,但这本身也是一种bug

image

删除他人账户

抓包删除功能点发现JWT解码是jerry的

image

这一次空签名,加密算法之类的不行了吧。

image

它说头部分的kid字段有注入,让我们把内容改成tom的,最后签名的密钥hashcat爆破即可。

image

仓库类搜索关键词,注入点长这模样。

image

hacked' UNION select 'new_key' from INFORMATION_SCHEMA.SYSTEM_USERS -- 
hacked' UNION select 'bmV3X2tleQ==' from INFORMATION_SCHEMA.SYSTEM_USERS --    # base64编码

最后的payload如下

image

image

修复建议也是代码审计的点

刷新令牌却永远不过期?

没有任何的验证?

允许客户端切换算法?

签名时,请确保使用适当的密钥长度。

确保JWT中没有敏感信息。

使用以上测试方法评估JWT的安全性。

感谢师傅们很有耐心的阅读到了这里,我们还会再见面的,共勉。

参考资料:https://datatracker.ietf.org/doc/html/rfc8725#section-2

本文作者:, 属于FreeBuf原创奖励计划,未经许可禁止转载

# web安全
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
评论 按热度排序

登录/注册后在FreeBuf发布内容哦

相关推荐
\
  • 0 文章数
  • 0 评论数
  • 0 关注者
文章目录
登录 / 注册后在FreeBuf发布内容哦
收入专辑