HACK80

我们很年轻,但我们有信念、有梦想!

我们坚信只有今天付出了,才有机会看到明天的太阳!
现在!加入我们,给你一个气氛优秀的技术圈子

作者: djg222000
查看: 155|回复: 0

more +随机图赏Gallery

2017年中旬WEB渗透系列课程-27HASH提权2017年中旬WEB渗透系列课程-27HASH提权
2017年中旬WEB渗透系列课程-23提权认识2017年中旬WEB渗透系列课程-23提权认识
X站神器-灰长给力-X站神器-灰长给力-
2017年中旬WEB渗透系列课程-11注入的其他姿势2017年中旬WEB渗透系列课程-11注入的其他姿势
2017年中旬WEB渗透系列课程-10基于提交方式注入的分析2017年中旬WEB渗透系列课程-10基于提交方式注入的分析
2017年中旬WEB渗透系列课程-09Mysql注入跨库2017年中旬WEB渗透系列课程-09Mysql注入跨库
2017年中旬WEB渗透系列课程-08Mysql注入读写2017年中旬WEB渗透系列课程-08Mysql注入读写
2017年中旬WEB渗透系列课程-07Mysql常规注入2017年中旬WEB渗透系列课程-07Mysql常规注入
2017年中旬WEB渗透系列课程-06Mysql注入分析2017年中旬WEB渗透系列课程-06Mysql注入分析
2017年中旬WEB渗透系列课程-05Access注入分析2017年中旬WEB渗透系列课程-05Access注入分析

利用 XML Signature 攻击绕过 SAML 2.0 单点登录

[复制链接]
djg222000 发表于 2017-12-4 21:25:38 | 显示全部楼层 |阅读模式
查看: 155|回复: 0

马上注册,加入HACK80!与我们一起交流。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
0x00 前言
我们最近注意到有许多新西兰的网站计划使用单点登录(SSO)以应对密码泄露,包括许多政府服务。SSO最普遍的标准是SAML 2.0,支持多框架、多语言。这个机制通常使用在将验证用户身份的SAML响应数据返回给浏览器的传递过程中,并且使用签名来防止数据篡改。但是许多开发者并未正确的验证SAML返回的响应数据,导致攻击者可以绕过身份认证。
0x01 SAML 2.0 SSO
当登录到使用AML 2.0的网站时,有第三方服务商(SP)也有身份提供程序(IdP)。
服务商会将用户重定向到IdP并提交一个SAML请求。一旦IdP确认了用户的身份,就会向服务商返回一个SAML响应。SSO消息发送有以下三种方式,在标准中称之为绑定:
  • HTTP重定向绑定:将SAML消息包含在URL中;
  • HTTP POST绑定:将SAML消息包含在POST请求中;
  • HTTP Artifact绑定:发送一个随机令牌,并作为标识通过反向隧道获取文档。
头两种绑定方式存在一些比较严重的问题。
0x02 识别SAML响应
SAML响应消息通常通过像这样的URL进行传递:
或者包含POST请求中:
这两种方式都能被攻击者操纵,因为他们经过浏览器进行操作,另一方面,通过如下所示的SAML Artifact方式时,攻击者可能就无法操纵。这些随机令牌被解析成原始消息,然后通过一个反向通道获取,除非攻击者有机会访问目标的私有网络(比如SSL/TLS漏洞),不然这些令牌将毫无利用价值:
0x03 在传输过程中保护信息
这里的问题是,不论使用HTTP重定向绑定还是HTTP POST绑定,身份提供程序(IdP)返回的验证用户身份信息的数据都要通过用户的浏览器传递,因此在传输过程中可能被篡改。使用HTTP Artifact绑定不存在这种问题。
如果SAML响应消息缺乏相应的保护机制,攻击者就可以通过篡改响应数据来冒充他人身份。例如,我以Tim的身份登录IdP然后通过简单地修改SAML响应消息声称自己是Emmanuel。实事上,我可以篡改整个响应消息,然后冒充Emmanuel的身份。
当然,SAML标准的开发者并非不会让错误消息轻易通过认证。他们已经非常努力地修复这个问题。标准的解决方案方案是在每个响应消息中附加一个XML签名,防止数据被篡改。
0x04 XML签名标准
XML签名标准复杂难懂,这里就不过多解释了。参考:XML签名语法和处理(XML Signature Syntax and Processing)
在标准的数字签名应用中,需要我们对签名的文档执行密码散列函数计算出HASH,然后通过HASH值应用数字签名算法得到数字签名。如果被接收的文档和原始文档是完全一致的,那么通过同样的算法对接收文档计算得到的数字签名和接收到的数字签名是完全一致的;如果两个数字签名有一位数据不同,那么就会认为接收到的数字签名是无效的,文档将被拒收。
但是XML有一个致命的弱点:XML签名标准允许我们只对文档的一部分进行签名,并可以将这个签名嵌入同一个需要验证的文档:这就是所谓的Inline signatures(内联签名)。实现内联签名需要在被签名文档中包含对文档局部的引用,通常是通过引用XML元素的“ID”属性,但是理论上允许使用任何符合XPath标准的对象作为表达式。例如我可以在一个文档内的任意位置写入指向“third to last <foo> element”的签名,或者类似的模糊表达式签名。
当验证XML签名时仅仅确认“这是一个来自签名者的有效的签名”是远远不够的。我们也必须确认“签名是否存在?如果存在,指向文档的位置是否正确?是否遵守正确的标准?签名者所签发的是有效签名吗?”往往至少有一项未被验证。
0x05 SAML Raider入门
BurpSuite的SAML Raider插件是一个很有用的测试工具:
检测
前面提到过,签名可以出现在SAML消息中的不同位置并且覆盖消息的各个部分。通过保留消息内容,向其中增加新内容,并且修改剩余部分的结构,我们就可以构造出一个新的消息,这个新消息仍然是合法签名的,但是可能被SAML库解析为包含了已签名的关键内容,但是实际上该关键内容并不存在。
SP在进行验证时,有一定的机率验证失败或者进行了不正确的验证,这都会给攻击者绕过签名验证的机会。打开Burp的拦截功能,拦截SAML请求报文,然后尝试这些转换。每次尝试都要根据一个新的、有效的登录动作来完成。因为通常会有一个Nonce阻止我们重复发送相同的请求。
如下设置Burp的Proxy,仅仅拦截SSO登录请求:
签名是否必需?
SAML标准要求所有经过非安全信道(如用户的浏览器)进行传输的消息都要有数字签名。不过,如果消息通过安全信道(如SSL/TLS反向通道)进行传输的话,签名就不是必需的了。但是正因为这一点,我们发现SAML使用者经常这样做:如果有任何签名存在,就进行验证;如果签名被移除,则跳过验证。软件基本上假定我们已经检查了来自非安全信道的消息已签名,而真实情况并非如此。
这造成的影响就是,我们能够简单地删除签名,并篡改响应,就好像签名不存在一样。使用SAML Raider插件可以很容易完成该操作。
签名是否经过验证?
验证XML签名是一个非常复杂的过程,因为XML签名标准期望在签名验证之前先进行一系列的转换和规范化的操作(如忽略掉大量的空白符)。这就导致如果没有一个功能齐全的XML签名库在背后做支撑,那么验证签名就极其困难。这造成的影响有:
  • 开发者普遍对签名验证的内在过程理解不到位;
  • 一些中间组件,如WAF等,并不知道签名是否有效;
  • 签名库可能存在一些配置选项,如允许的规范化方法列表,这些选项对开发者来说却毫无意义。
实现签名标准并不容易,再加上签名标准自身也存在几分晦涩难懂的特性,这就导致了我们现在所遇到的问题。首先,测试一个签名是否有效是很简单的——改变被签名内容中的某些数据,然后看看是否会导致中断。
签名是否来自正确签名者?
另外一个障碍就是接收方是否验证了签名者的身份。我们无法看到这一步是否正确,但使用SAML Raider插件可以很容易地进行测试。
将签名证书复制到SAML Raider的证书存储区:
保存并对此证书进行自签名,便可以得到了同一证书的一个自签名版本。
这时我们就可以使用这个自签名证书对原始请求进行重新签名,对整个消息进行签名或者只签assertion部分。
你可以确认一下应用正常采用哪种签名方式或者两种方式都尝试一下。
签名部分是否正确?
XSW攻击原理
SAML标准允许的签名的位置有两处:
  • 签名位于<Response>标签中,对<Response>标签及其子节点进行签名;
  • 签名位于<Assertion>标签中,对<Assertion>标签及其子节点进行签名。
SAML标准对于签名允许的位置以及允许内容都有明确的描述。
然而,没有人为了仅仅使用SAML就完整地实现复杂的XML签名机制。签名标准是通用的,标准的实现以及为此所开发的软件库也是如此。结果“职责分离”就成了这样:
  • XML签名库根据XML验证标准验证签名,允许从任何地方签名任何内容;
  • SAML库期望XML签名库告诉它响应消息是否有效。
在两个组件之间往往缺少相关规则来规定哪些内容必须签名的。结果就是可以针对文档的不同部分进行签名,而且在接收方看来签名依然有效。我们可以将XML签名库验证的内容和SAML库需要的内容分开。
自动化XSW攻击
SAML Raider插件可以帮你实现最常见的XSW攻击:
下拉框中的每一个选项,然后点击“Apply XSW”发送请求数据。如果不报错就会改变SAML XML中所有的用户名或者其他用户标识符,然后重复这个动作。
SAML Raider的局限性
尽管SAML Raider插件可以对常见的情况进行测试,但仍然有一些攻击需要更深一层的理解:
  • 生成针对XML Schema进行验证的响应(需要在可能包含xs:any的元素中隐藏影子副本(shadow copy);
  • 当Response和Assertion都被签名和验证时,如何绕过验证;
  • 在非SAML上下文中绕过XML签名,如在使用WS-Security扩展的SOAP Endpoints中。
手动测试XSW
如果SAML Raider插件自带的选项都不起作用,你可以尝试手动测试方法:
  • 解码经过Base64编码的内容以获取SAML响应XML;
  • 检查签名的<Reference>标签是否包含被签名元素的“ID”;
  • 拷贝文档中其他部分被签名的内容,一般情况下放在<Response>标签的末尾。如果是验证XML Schema,那就放在不会破坏XML Schema的位置;
  • 从XML签名中删除副本,将其保留在原始文档中。XML封装签名标准去掉了将被验证的签名。在原始文档中,这就是所包含的签名,所以我们必须将其从副本中删除;
  • 改变原始签名内容的ID为其他值;
  • 改变原始assertion的内容;
  • 对上述内容重进行Base64编码,将其放回请求报文中,然后提交请求;
如果签名验证指向副本,它会忽略你的改动。你应该在服务器限制请求时间内完成这些步骤。
0x06 SAML安全检查
  • SAML响应是否通过浏览器?
  • 响应内容是否被签名?
  • 删除签名数据之后响应内容是否被接受?
  • 使用其他证书重新签名响应内容是否被接受?
  • 使用SAML Raider自带的8种转换方式生成的结果是否被接受?
  • 更改后的响应是否被接受?
  • 是否遇到了上文所述的SAML Raider的局限性?

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|HACK80 ( 沪ICP备15007512号 )

GMT+8, 2017-12-15 12:21 , Processed in 0.063531 second(s), 24 queries .

Powered by Discuz! X3.4 © 2001-2013 Comsenz Inc.