服务热线

020-38921330

首页 > 新闻资讯 > 行业新闻

影响关键基础设施安全的几种身份验证漏洞绕过技术

2023-2-2 0:00:00浏览量:647编辑:管理员来源:天畅

对于一个安全的应用来说,身份验证是第一道门槛,是与用户建立数字信任关系的基础部分,现代的身份管理系统可以自动收集有关用户的信息,验证他们的身份是否与他们的实际身份相符,并允许他们的注册或访问请求,从而创建了一种不会影响用户体验的安全身份验证功能。


身份验证-2.png


根据 Javelin 2020 年身份欺诈调查,2019 年身份欺诈的总成本接近 170 亿美元,现在这个数字更高。由于这些非常真实的风险,可靠地验证用户身份的能力是安全基础设施的关键组成部分。


身份验证的本质
01


为了对那些有安全需求的特定资源进行访问控制,只让某些特定的主体(个人、公司、甚至是一段代码)对其执行某些特定的操作(查看、修改等)。需要按照顺序达成如下两个条件:

1、认证(Authentication):知道 ta 究竟是谁

2、授权(Authorization):知道 ta 有没有权限对资源执行试图执行的操作



认证


认证是决定一个主体究竟是谁的过程,换句话来说,是将当前意图访问资源的用户和提前存储好的身份信息对应起来的过程。显然,这个操作需要由身份信息的持有者来完成,我们称其为IdP(Identity Provider),它存储的身份信息列表称为用户目录或用户池。
所谓的身份信息可以是任意格式,包含但不限于以下两种内容:用户的唯一标识符(可以是唯一的用户名、随机字符串、UUID 等),以及只有该用户才能提供,用来确认该用户身份的私密信息(密码、指纹等)。前者可以是公开的,但后者必须是私密的,只有 IdP 和用户自身才能持有。

为了完成认证,用户必须首先宣称自己是谁,并且这个宣称需要以某种形式和用户目录中的唯一一条记录产生关联。显然,最简单的办法就是直接向 IdP 宣布自己的唯一标识符。之后,用户需要通过某种保密的途径悄悄告诉 IdP 自己的私密信息,IdP 确认无误后,就可以将当前正在进行请求的用户和用户目录中的身份信息对应起来,如此一来,用户在 IdP 上的认证过程就完成了。


授权


确认了用户的身份之后,下一步就是确认用户到底有没有权限访问想要访问的资源了。拥有身份信息后,这一步就变得很简单了——只需根据对应资源的权限设置,检查用户的对应操作是否被允许即可。



身份和资源的分离
02


在最简单的身份模型中,身份持有者(IdP)和资源持有者运行在同一个上下文中。这意味着一旦 IdP 完成了某个用户的认证,资源持有者立刻就能知道(例如通过数据库查询)用户的身份信息。之后用户访问资源时,资源持有者就能利用这一信息来决定是否允许用户的操作(相当于自己执行授权),或者把这一决定交给 IdP 来做(相当于 IdP 执行授权)。
这种模型的缺点显而易见——每个应用都要维护一套自己的用户目录,不同应用之间无法共享身份信息。为了解决这个问题,一个自然的想法就是将 IdP 独立出来,让所有资源持有者都从 IdP 处获取用户的身份。
这种做法存在一个前提条件:当一个用户在 IdP 上完成了认证之后,资源持有者必须得知这一点,并能从 IdP 处获取用户对应的身份信息,而且这一渠道必须是可信的,身份信息不能被恶意篡改。在实际应用中,资源持有者一般会在用户访问资源时,向 IdP 获取用户的认证状态和身份信息。如果成功,之后的授权步骤就和上面一致了。
独立的 IdP 有一个天然的好处——只要用户在 IdP 上进行过了认证,其下关联的所有资源持有者都能获取到用户的身份信息,正所谓一次认证,到处访问。所谓的单点登录(SSO)本质上就是如此。



由于 Web 应用天生的无状态性,资源持有者并不能确定访问资源的用户和在 IdP 上认证过的用户是同一个,因此用户每次访问资源时都需要提供身份标识符和密码,由资源持有者向 IdP 进行确认。为了解决这一问题,IdP 在完成认证时可以向用户颁发一个临时的令牌(Token),这个 Token 存储着用户目录中的用户身份,只有用户本人才能持有,并且经过 IdP 的数字签名。用户访问资源时,通过 Cookie 等手段自动向持有者提供 Token,持有者可以在本地利用签名验证 Token 的真实性和有效性,并且从 Token 中获取到用户的身份信息,无需再经过 IdP 了。为了防止 Token 从用户处泄露,它只在短时间内有效,失效后必须由 IdP 重新颁发。
最著名的 Token 技术是JWT(Json Web Token),它也是 OIDC 协议的一部分。除此之外,SAML 协议中的断言(Assertion)也可以起到和 Token 相同的作用。当然,用户的登录态也可以由资源提供者来维护,资源提供者在向 IdP 确认用户身份后自己向用户颁发一个类似的 Token,存放在用户 Cookie 中。此时的 Token 可以实际存储身份信息并进行签名,也可以作为一个索引的 Key,指向存放在资源提供者后端的,从 IdP 处获得的身份信息(也就是所谓的 Session)。
值得注意的是,在分离模型中,如果授权步骤由 IdP 执行,用户在 IdP 上进行授权时还需要提供自己想要访问的资源种类和执行的操作,IdP 签发 Token 时也需要将这些信息写在 Token 中,以便资源持有者核验。资源和操作的二元组被称为Scope,OIDC 登录时传人的其中一个参数就是它。



JWT常见安全问题
03


签名signature未校验
修改或者删除signature

敏感信息泄露
由于Header和Payload是通过base64编码的,因此如果敏感信息处理不到会导致泄露风险。
签名算法可被修改为none(CVE-2015-2951)
也就是header中的“alg”为none,在线工具jwt.io无法修改,使用Pyjwt库进行修改,生成的jwt token只有header和payload两部分,没有signature:

密钥被爆破
String encodedString = base64UrlEncode(header) + "." + base64UrlEncode(payload);
String token = HMACSHA256(encodedString, 'secret');
jwt利用算法对header和payload进行加密生成signature,如果能知道密钥secret就能随意修改jwt token了;
伪造密钥(CVE-2018-0114)
jwk ,json web key,就是header中的密钥,通过伪造header中的密钥来控制jwt token的生成:


身份验证绕过的几种漏洞
04


身份验证绕过漏洞是现代web应用程序中普遍存在的漏洞,也是隐藏最深很难被发现的漏洞。尽管单点登录(SSO)等工具是对旧的登录用户方式的改进,但仍然可能包含严重的漏洞。无论是业务逻辑错误还是其他软件漏洞,都需要专业人员来分析其中的复杂性。


刷新令牌终端配置错误


在这种情况下,一旦用户使用有效凭证登录到应用程序,它就会创建一个在应用程序其他地方使用的承载身份验证令牌。该认证令牌在一段时间后过期。就在过期之前,应用程序在终端/refresh/tokenlogin中向后端服务器发送了一个请求,该请求在标头和HTTP主体部分的用户名参数中包含有效的身份验证令牌。
进一步的测试表明,删除请求上的Authorization标头并更改HTTP主体上的用户名参数将为提供的用户名创建一个新的有效令牌。利用此漏洞,拥有匿名配置文件的攻击者可以通过提供用户名为任何用户生成身份验证令牌。


SSO配置不正确


大多数应用程序都使用SSO系统,因为与处理许多身份验证门户相比,SSO系统更容易安全管理。但是简单地使用SSO并不能自动保护系统,因为SSO的配置也应得到保护。
现在,一个应用程序使用Microsoft SSO系统进行身份验证。当访问internal.redacted.com URL时,web浏览器会重定向到单点登录系统:

乍一看,它似乎是安全的,但对后端请求的分析显示,应用程序在重定向响应上返回了异常大的内容长度(超过40000字节)

为什么应用程序要这样做呢?当然是配置错误。在将用户发送到SSO的重定向时,应用程序向每个请求泄露了其内部响应。因此,可以篡改响应,将302 Found头更改为200 OK,并删除整个Location标头,从而获得对整个应用程序的访问。


基于CMS的访问漏洞


内容管理系统(CMS),如WordPress、Drupal和Hubspot也需要进行安全配置,以免它们在使用中引入漏洞。
在发现的一个示例中,一个内部应用程序中使用了一个流行的CMS平台Liferay。该应用程序只有一个不需要身份验证就可以访问的登录页面,所有其他页面都在应用程序UI中受到限制。
对于那些不熟悉Liferay的人来说,CMS为应用程序工作流使用了portlet,它的参数是数字中的p_p_id。对于该应用程序,可以通过将参数值更改为58来访问登录portlet。在正常的登录页面中,只有登录表单是可访问的。然而,通过直接访问portlet,可以达到Create Account功能,然后在不需要适当的授权情况下就可以进行自注册并访问内部应用程序。

请注意,虽然Liferay以前使用过这个工作流,但它的最新版本使用了portlet名称而不是数字ID。不过,也可以通过更改名称来访问其他portlet。


JWT令牌的使用


JWT令牌或JSON web令牌,在新的web应用程序中很流行。但是,虽然它们默认具有安全机制,但后端服务器配置也应该是安全的。
然而,一些JS文件不需要身份验证就可以访问。测试显示,该应用程序使用了安全登录后通过Microsoft SSO系统发送的JWT令牌。在后端机制上,存在一个安全错误配置,即不检查是否为特定的应用程序生成了JWT令牌。相反,它接受任何具有有效签名的JWT令牌。因此,使用来自微软网站的JWT令牌示例如下:

在通用值内:

有可能访问内部终端,泄露公司数据。


将身份验证类型更改为Null


在此情况中,应用程序通过 base64 编码的 XML 请求向 HTTP 发布数据上发送所有请求。在登录机制上,它将用户名作为参数别名发送,将密码作为scode发送。scode 参数内的值已进行哈希处理。分析显示,它使用了所提供密码值的 md5 值。请求中还有另一个有趣的标志:scode 有一个属性,其类型值为 2。

尝试将该值赋值为1,它将接受明文密码。成功了!因此,在明文值中使用暴力攻击中是可能的。把它赋值给空值怎么样?或者其他值,如-1、0或9999999999?大多数都返回了除0之外的错误代码。用属性0做了几次尝试,但没有成功,直到将密码值作为空值发送出去。

这才意识到只需提供用户名和密码即可访问任何帐户。事实证明,这是一个很大的错误。



复杂的身份验证机制可能成为攻击者使用的最具隐蔽性的攻击手段,特别是在容易出现业务逻辑漏洞的应用程序上。因为自动扫描器大多无法进入这类漏洞,所以仍然需要手工来找到它们。保障用户的合法资产和权益,维护系统安全稳定地运行,身份认证路长且艰,任重而道远。