Moke|墨客

 找回密码
 立即注册
搜索
查看: 8792|回复: 0

Amazon?AWS?Java?SDK漏洞披露

[复制链接]

3636

主题

0

回帖

3681

积分

超级版主

Rank: 8Rank: 8

积分
3681
发表于 2016-5-12 18:13:28 | 显示全部楼层 |阅读模式






      今天我们来讨论下Amazon AWS java SDK的一个拒绝服务漏洞。这个官方的AWS SDK常被Java开发者用于整合一系列的AWS服务,包括像Amazon S3中整合Amazon APIs用于存储和索引文件等。其中1.8.0-1.10.34版本的官方AWS Java SDK已被确认受到影响,而最新版1.10.36 SDK已经修复了这个漏洞。
  这个漏洞可以利用AWS Java SDK操纵存储在Amazon S3上的文件来实现对web服务的攻击。攻击者可以上传文件到S3存储中让web服务使用SDK执行,执行时可能会出现死循环从而导致拒绝服务。
  鉴于AWS Java SDK是Amazon默认提供给Java开发者使用的,这个漏洞有着很广的影响面。例如:Nuxeo 一个非常受欢迎的开源框架–使用AWS S3 SDK存储文件的内容管理系统。大量使用Nuxeo框架的商业应用都会受到这个漏洞的影响。
  我们已经将这个漏洞私下提交给了Amazon AWS安全团队。Amazon迅速修复了这个漏洞并于上周在Maven Central发布了新版本的SDK。具体修改的代码可以查看这里。
  概述
  这个问题存在于SDK里SdkDigestInputStream类的skip方法。标准中规定其应该返回略过的字节数,但在一些特殊情况下其会返回-1。skip方法是2014年6月21日作为另一个问题的修复方案加入到类中的。在此之前SdkDigestInputStream并没有重载skip方法。
  分析
  如果我们查阅Java官方文档关于InputStream类中skip方法的描述,文档说skip方法应该返回实际略过的字节数。如果没有略过或者输入是负数,那么skip方法会返回0。不管任何情况下skip方法都不应该返回一个负数。
SdkDigestInputStream.java的第75行(来自之前的提交 https://github.com/aws/aws-sdk-java/commit/257dd4908cf99ec1982feed247fd2253589c222a#diff-97412a92b5fccaea1893be646257fa3b),skip方法可能返回-1:

  返回的这个负值可能会导致其他接收skip方法返回值的方法出错,因为这些方法从来没考虑过接收一个负值。例如:看下popular Apache Commons Compress library中的IOUtils类。它通过调用skip方法处理底层的InputStream来实现自己skip方法。

  这个方法使用了while循环,其中skip方法的返回值用于结束循环。
while (numToSkip > 0) {
  long skipped = input.skip(numToSkip);
  if (skipped == 0) {
  break;
  }
  numToSkip -= skipped;
}
  当Amazon S3存储使用SDk读取底层input数据流时,skip方法可能会返回-1。这个返回值存储在skipped变量中。因此,循环结尾处的numToSkip -= skipped变成了numToSkip -= -1。这样变量numToSkip会不停的增长最终变成死循环。
  实例
  攻击场景出现于Amazon S3存储文件使用AWS SDK处理时。Apache Commons Compress library是一个Java中非常常用的处理归档的库。
  对于使用Amazon S3的Web服务来说.tar是最容易遭受拒绝服务攻击的。攻击者只需创建一个带有额外填充数据(空字节)的归档上传到网站。然后,AWS S3 SDK会读取文件并将inputStream传递给TarArchiveInputStream类。为了略过额外的填充数据会调用skipRecordPadding方法:

  这个方法在第335行调用skip方法,之后程序就会进入一个死循环从而导致拒绝服务。
  修复
  一个新版本的AWS SDK已经发布在Maven Central,我们建议立刻升级到这个版本。假如你不能升级的话,那么可以进行如下修复。
  如果你直接调用了skip方法,那么你可以增加一个判断确保其返回值>=0。另外,如果需要你可以你可以复制inputStream到一个字节数组中,然后在把数组传递给需要调用的应用。例如,使用Apache Commons Compress library处理.tar时可以使用如下代码:
// Assuming that input is the inputStream obtained from the AWS S3 SDKByteArrayOutputStream baos = new ByteArrayOutputStream();
IOUtils.copy(input, baos);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
TarArchiveInputStream tarStream = new TarArchiveInputStream(bais);
  * 原文链接: blog.srcclr,译者/xiaix,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM)
xiaix14篇文章等级:4级  
NULL
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

 

 

快速回复 返回顶部 返回列表