分类 WEB安全 下的文章

CVE-2016-5007 Spring Security / MVC Path Matching Inconsistency

概要

  • 产品名称:Spring Web + Spring Security / Spring Boot
  • 标题:Spring Security / MVC Path Matching Inconsistency
  • CVE ID: CVE-2016-5007
  • Intrinsec ID:ISEC-V2016-01
  • 风险级别:中
  • 漏洞利用:远程
  • 影响:请求授权绕过

描述

此漏洞影响的Spring Web和Spring Security使用HttpSecurity.authorizeRequests用于URL访问控制的应用。

Spring提供了一个Spring Security使用文档:

http://docs.spring.io/spring-security/site/docs/current/reference/html/jc.html#authorize-requests

protected void configure(HttpSecurity http) throws Exception {
    http
        .authorizeRequests()                                                                
            .antMatchers("/resources/**", "/signup", "/about").permitAll()                  
            .antMatchers("/admin/**").hasRole("ADMIN")                                      
            .antMatchers("/db/**").access("hasRole('ADMIN') and hasRole('DBA')")            
            .anyRequest().authenticated()                                                   
            .and()
        // ...
        .formLogin();
}

在以下示例中,用户”User”不是管理员,并且无法访问”/admin/”管理目录:

cve-2016-5007-1.png

但是,如果在URL中将空格(或其他空格字符)附加到”admin”前后,可以轻易绕过安全过滤器。

  • 附加空格(由浏览器自动编码为”%20″):

cve-2016-5007-2.png

  • %0D前置:

cve-2016-5007-3.png

问题是使用不同的匹配器来实现访问控制,并且识别哪个控制器类应该处理请求。用于访问控制的第一个匹配器是严格的:”admin “被认为不同于”admin”:

cve-2016-5007-4.png

然而,用于找到适当的控制器的第二匹配器应用删除每个URL令牌之前和之后的空白的修剪操作,因此”admin”变为”admin”:

cve-2016-5007-5.png

总之:

访问控制匹配器不识别受保护的路径,因此应用默认的“允许”规则,而控制器查找器匹配器找到受保护的控制器。

两个匹配器之间的严格性不匹配导致了这种情况。

这个漏洞危害性高低与否取决越权查看页面后查询数据的时候是否有校验当前用户的session。

影响版本

  • Spring Security 3.2.x,4.0.x,4.1.0
  • Spring框架3.2.x,4.0.x,4.1.x,4.2.x
  • 其他不受支持的版本也会受到影响

解决方案

Spring Security提供了可以将模式匹配委派给Spring框架的URL授权,要利用这个选项,应用程序应该升级到Spring Security 4.1.1+和Spring Framework 4.3.1+并使用MvcRequestMatcher。

Spring Framework 3.2.x,4.0.x,4.1.x,4.2.x的用户可以使用MVC Java配置或MVC命名空间将AntPathMatchertrimTokens属性设置为“false”。

此外,应用程序应该总是使用Spring Security的一种机制(例如添加@Secured注释),在应用程序的业务层使用额外的授权来补充基于URL的授权。

分享一个两年前的测试案例:

目标是基于拦截器的访问控制,但是系统做拦截判断的时候是采用完全匹配模式校验,所以可以轻易绕过。

http://xxx.com:8000/security/security!admin.action --blocking
http://xxx.com:8000////security/security!admin.action --bypass

简单总结下这个两个漏洞产生的原因:

第一个案例的问题问题出现在第二个规则检测前的数据处理工作,do_work(a)的时候已经不知道do_check(a)是什么内容了!这里能做什么?只能保证保持输入a不变,能做事就做,做不了就反馈错误!此类问题绝非个案,平时代码审计可以多加关注。

Reference

Hadoop渗透及安全加固

最近看到微博有人在讨论在Hadoop安全问题,也顺便了看一下。

hadoop1.jpg

前言

很多产品设计之初就是使用在内网,所以默认不开启身份认证或者压根就没有身份认证模块,这种设计理念是有问题的 。例如es、redis、mongodb这些基础设施级的软件就因为没有身份认证很多安全问题都是由它导致的 。同时产品的安全设计也不要寄托在开发人员/运维人员的安全意识上,即使是安全人员也有疏忽大意的时候。

Hadoop简介

Hadoop是一个由Apache基金会所开发的一个开源 高可靠 可扩展的分布式计算框架。Hadoop的框架最核心的设计就是:HDFS和MapReduce。

HDFS为海量的数据提供了存储,MapReduce则为海量的数据提供了计算。

HDFS是Google File System(GFS)的开源实现。

MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。

安全问题

总的来说Hadoop安全问题涉及三个方面

WebUI敏感信息泄漏

Hadoop默认情况开放了很多端口提供WebUI,下面这些多多少少都会泄漏一些信息,但是总的来说在内网还好吧。

一、HDFS

1.NameNode 默认端口                    50070
2.SecondNameNode 默认端口        50090
3.DataNode 默认端口                       50075
4.Backup/Checkpoint node 默认端口  50105

二、MapReduce

1.JobTracker 默认端口    50030
2.TaskTracker 默认端口   50060

端口探测,扫描HDFS和MapReduce的WebUI对应的服务端口

hdoop2.jpg

hadoop.jpg

NameNode WebUI管理界面

通过NameNode节点管理HDFS

hadoop3.jpg

其中比较重要的是DataNode 默认端口50075开放的话,攻击者可以通过hdsf提供的restful api对hdfs存储数据进行操作。

restful api参考:http://hadoop.apache.org/docs/r1.0.4/webhdfs.html

hadoop4.jpg

MapReduce代码执行漏洞

MapReduce demo:https://github.com/huahuiyang/yarn-demo

稍微改动了一下:

FileInputStream file = null;
BufferedReader reader = null;
InputStreamReader inputFileReader = null;
String content = "";
String tempString = null;
try {
   file = new FileInputStream("/etc/passwd");
   inputFileReader = new InputStreamReader(file, "utf-8");
   reader = new BufferedReader(inputFileReader);
   // 一次读入一行,直到读入null为文件结束
   while ((tempString = reader.readLine()) != null) {
      content += tempString;
   }
   reader.close();
} catch (IOException e) {
   e.printStackTrace();
} finally {
   if (reader != null) {
      try {
         reader.close();
      } catch (IOException e1) {
      }
   }
}
utput.collect(new Text(content), new IntWritable(1));

执行mapreduce任务:

bin ./hadoop jar wordcount.jar com.yhh.mapreduce.wordcount.WordCount data.txt result

查看执行结果:

bin cat result/part-00000

hadoop6.jpg

既然可以执行jar程序,执行系统命令还是很容易的,但是这个需要一个Hadoop的shell, 问题也不大。

Hadoop的第三方插件安全漏洞

Cloudera Manager <=5.5

  • Cloudera Manager CVE-2016-4949 Information Disclosure Vulnerability
  • Template rename stored XSS (CVE-2016-4948)
  • Kerberos wizard stored XSS (CVE-2016-4948)
  • Host addition reflected XSS (CVE-2016-4948)

Cloudera HUE =< 3.9.0

  • Enumerating users with an unprivileged account (CVE-2016-4947)
  • Stored XSS (CVE-2016-4946)
  • Open redirect

Apache Ranger =< 0.5

  • Unauthenticated policy download
  • Authenticated SQL injection (CVE-2016-2174)

Apache Group Hadoop 2.6.x

  • Apache Hadoop MapReduce信息泄露漏洞(CVE-2015-1776)

Hive任意命令/代码执行漏洞

  • HQL可以通过transform自定义Hive使用的 Map/Reduce
    脚本,从而调用shell/Python等语言,导致攻击者可以通过hive接口等相关操作方式直接获取服务器权限

漏洞往往是相似的,Spark 6066 7077端口也存在着类似的安全问题,默认情况下可以推送jar包执行,如果权限足够大可以实现植入ssh公钥,有兴趣的可以研究下,估计在内网可以搞到一些研发的机子。。。

总结

漏洞往往是相似的,Spark 6066 7077端口也存在着类似的安全问题,默认情况下可以推送jar包执行,如果权限足够大可以实现植入ssh公钥,有兴趣的可以研究下,估计在内网可以搞到一些研发的机子。

安全解决方案

reference

如何使用开源组件解决web应用中的XSS漏洞

本文包含以下内容:

  • XSS概述
  • XSS的防御原则
  • 开源组件的使用

XSS(跨站脚本攻击)漏洞是Web应用程序中最常见的漏洞之一,它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行,从而达到恶意攻击用户的特殊目的,比如获取用户的cookie,导航到恶意网站,携带木马等。根据其触发方式的不同,可以分为反射型XSS、存储型XSS和DOM-base型XSS。漏洞“注入理论”认为,所有的可输入参数,都是不可信任的。通常我们说的不可信任的数据是指来源于HTTP客户端请求的URL参数、form表单、Headers以及Cookies等,但是,与HTTP客户端请求相对应的,来源于数据库、WebServices、其他的应用接口数据也同样是不可信的,这即是反射型XSS与存储型XSS的本质区别。+

一般来说,我们可以通过XSS漏洞的表现形式来区分漏洞是反射型、存储型、DOM-base三种中的哪一种类型。

其name参数的值为<script>alert(1);</script>,这样的参数值进入程序代码后未做任何处理,从而被执行。其代码如下图:

01.png

  • 存储型XSS是指恶意脚本代码被存储进数据库,当其他用户正常浏览网页时,站点从数据库中读取了非法用户存储的非法数据,导致恶意脚本代码被执行。通常代码结构如下图:

02.png

其发生XSS的根本原因是服务器端对写入数据库中的内容未做javascript脚本过滤。

  • DOM-base型XSS是指在前端页面进行DOM操作时,带有恶意代码的片段被HTML解析、执行,从而导致XSS漏洞。

无论是哪种类型的XSS漏洞,其解析完成后,漏洞利用的代码基本雷同的。在日常工作中,常见的XSS漏洞Exploit攻击点有:

  • 恶意js的引用

03.png

  • Img标签(以img为例,下同)

04.png

  • 大小写绕过安全检测

05.png

  • 破坏原始标签结构

06.png

  • 基于标签事件触发

07.png

  • fromCharCode编码绕过

08.png

  • javascript 转码

09.png

  • HTML转码

10.png

  • 混合型

11.png

  • CSS文本

12.png

  • CSS属性值

13.png

基于XSS上面所述的特性,在XSS的频发代码中,我们通常遵循以下处理规则:

14.png

从上表中我们可以看出,ESAPI、HeadLines、AntiSamy、HTML Sanitizer 是开源组件中防御功能比较全面的4个,其中ESAPI、HeadLines除了对XSS具有很好的防御能力外,还对OWASP TOP 10中其他的安全漏洞都具有规范处理的能力。在单纯性地讨论其对XSS的防御能力时,我们需要看具体的应用场景或者需求点。如果仅仅是对客户端提交的简单的请求参数(通常指form表单域,不包含复杂文本和可编辑文本)做安全过滤,则HTML Sanitizer、Java Encoder都可以作为首选解决方案;如果不但对客户端提交的简单的请求参数做安全处理,而且,应用中会涉及复杂文本,类似于BBCode文本之类的数据处理,通常会首选AntiSamy作为解决方案;如果除了以上两点外,还需要做同源策略安全、Http Header安全、Cookies安全,则通常会首选HeadLines作为解决方案;如果还有更多层次的用户安全、Session会话安全、口令或随机数安全等,则ESAPI和Apache Shiro将会被考虑。那么,具体到某个软件项目中,是如何使用开源组件对XSS漏洞进行防护的呢?下面就以Java语言为例,对处理过程做简要的阐述。

第一步:确定使用的开源组件

首选是确定使用的开源组件,只有开源组件确定下来,才能确定解决方案的细节部分。在选择开源组件之前,要理解业务涉及的需求点,以免遗漏。一般来说,简单文本参数使用HTML Sanitizer,复杂文本参数使用AntiSamy。

第二步:定义安全过滤器

针对于XSS的处理,常用的解决办法是使用过滤器(Filter),由Filter中的doFilter方法对参数的内容进行安全过滤操作。其代码核心结构如图所示:

15.png

第三步:处理XSS

编写处理XSS函数clearXSS时,我们会根据所选择的开源组件不同而编写方式有所不同。当我们把开源组件的jar和依赖库添加到项目中之后,主要的工作是对此函数功能的实现,实现的基本思路是:从Request对象中获取请求的参数和http消息头,遍历每一个参数,如果某个参数值存在XSS,则对该值进行处理(过滤、编码、转义、拦截等),处理完毕后再重新赋值。 如果使用HTML Sanitizer,你的核心代码可能是

16.png

或者使用了Java Encoder,代码类似:

17.png

如果使用了AntiSamy,代码或许类似于

18.png

在HTML Sanitizer和AntiSamy中,我们都看到一个词:Policy,Policy即XSS防护策略,是指在XSS的文本进行处理时,按照怎么的规则去处理数据块:哪些html标签或属性是允许存在的,哪些的需要转义的,哪些是需要进行格式校验的,哪些是需要移除的等,这些都是在策略文件里去定义的。 HTML Sanitizer组件中,包含5个预定义的策略,具体在使用中,我们可以根据自己的需求选择某个策略。这5个策略的内容分别是:

19.png

AntiSamy组件中对策略的定义相对复杂些,是由配置文件中多个选项指定的。其配置如图所示:

20.png

AntiSamy的策略配置是由规则(tag-rule、css-rule)来控制Antisamy对html标签(tag)、属性(attribute)中不可信数据做怎样的操作行为(action),其中操作行为可分为校验(validate)、过滤(filter)、清空(truncate)、移除(remove)。根据定义的操作行为,可以对不可信数据进行移除、清空、过滤和校验操作。当对不可信数据进行校验时,比如input标签,我们可以校验align属性值指定枚举值范围为left,right,top,middle,bottom,也可以校验value值是否匹配既定义的正则表达式,如图中common-regexps和common-attributes节点所示。Antisamy依据策略文件的具体配置,对传入的不可信数据,按照定义的规则对数据进行处理,最终返回可信的文本,即代码段中的cr.getClearHTML函数的返回值。当原来的不可信数据,经过处理变成可信数据,我们防护XSS的目的也就达到了。与HTML Sanitizer类似的是,AntiSamy除了默认的antisamy.xml外,也提供5个策略模板文件:antisamy-anythinggoes.xml、antisamy-ebay.xml、antisamy-myspace.xml、antisamy-slashdot.xml、antisamy-tinymce.xml。其中ebay的模板文件使用广泛,在实际项目中,可以直接使用此策略模板或者在其基础上修改即可。

第四步:添加http响应头XSS防护

完成clearXSS函数之后名,我们需要对http响应头添加XSS防护策略。通过clearXSS函数调用是在服务器层对XSS做防护,而添加http响应头XSS防护策略是从客户端浏览器层面防护XSS。常用的参数有:

21.png

其核心代码大体如下:

22.png

第五步:启用安全过滤器

完成安全过滤器对不可信数据处理的编码逻辑之后,我们需要启用它。启用的过程即配置的过程,目的是使安全过滤器生效,这需要在web.xml中配置,并对所有请求进行拦截,其基本配置如下:

23.png

通过以上步骤的处理, web应用中因前端输入导致的XSS数据基本得以解决,但在实际的项目中,发生XSS的点可能各不相同,不是仅仅用一个安全过滤器进行全局拦截处理即可托付全盘那么简单。例如通过文件导入引发的XSS漏洞,则需要单独编码,调用开源组件对XSS进行防护。总之,无论是XSS漏洞还是其他的漏洞,安全防护是一个动态的概念,在进行XSS防护过程中,我们需要根据实际情况,不断地调整处理策略(Policy),以达到既能满足安全需要,正确处理非法的、不安全的数据,又能满足业务需要,不会错误拦截或处理了正常业务数据的最终目标。

Struts2中webconsole.html漏洞利用完全剖析

近来,随着Struts2漏洞接二连三地被披露,企业对Struts2的心理安全指数也在降低,很多企业或者安全从业人员,在日常的安全检测或者扫描过程中有点草木皆兵,如果发现了webconsole.html页面,则判断系统存在Struts2漏洞,要求各个厂商做对应的安全整改。那么出现webconsole.html页面到底是不是Struts2的安全漏洞呢?

首先,我们来看看Struts2框架中为什么会存在webconsole.html。 在Struts的官网的Debuggin页面中,有如下一段话:

The Debugging Interceptor provides three debugging modes to provide insight into the data behind the page. The xml mode formats relevant framework objects as an XML document. The console mode provides a OGNL command line that accepts entry of runtime expressions, and the browser mode adds an interactive page that display objects from the Value Stack.

我们注意引文被我加粗标注出来的句子,从这里我们可以看出来,此交互页面(即struts/webconsole.html)是Struts官方为了方便开发人员进行Debug而提供的功能。基于此,我们应该有第一个基本的认识:这是调试功能,只有在调试模式下才能使用。

接着,我们看到此文档中还有如下语句的描述:

s2_01.png

从这段话中,我们可以看出,Struts2的Debug功能,只有在开启了此功能,即配置了: <constant name="struts.devMode" value="true" /> 基于此,我们应该有第二个认识:struts/webconsole.html的调试功能只有在启用了调试参数的情况下才会生效,否则即使看到此页面,也不具有调试的功能。+

那么,是不是说,只要开启了Debug模式,struts/webconsole.html就可以进行交互了呢?答案当然是否定的。当我们访问struts/webconsole.html,使用浏览器,按F12进行查看就会发现,webconsole.html页面中加载了几个js脚本。如下图所示:

s2_02.png

从图中我们可以看出,webconsole.html页面与后端交互时,使用了Dojo的js框架来完成请求和应答处理,也就是说,webconsole.html页面可以与后端进行正常交互的前提是,项目中使用了Dojo的lib库。而在Struts2中,有一个jar,专门供此功能使用的。如下图:

s2_03.png

基于此,我们应该有更深一层的认识:只有在开启了Debug模式且ClassPath中使用了struts2-dojo-plugin-*.jar的情况下,webconsole.html页面才有可能存在安全漏洞的风险。

这时我们该明白,如果应用程序中使用了Struts2,启用了Debug模式,且ClassPath中包含了struts2-dojo-plugin-*.jar,那么,当我们访问http://ip:port/app_name/struts/webconsole.html 即可以看到如图中所示的交互界面。但是,看到了界面,就真的可以交互了么?我们接下来看看一下webconsole.html中提交事件是如何触发的?

s2_04.png

如上图中的箭头所示,当我们在页面输入内容释放键盘操作时,调用的javascript函数为keyEvent(event),我们再来跟踪一下这个函数,发现它存在于webconsole.js中,其关键代码如下图:

s2_05.png

当触发此函数时,需要两个参数,一个是event,一个是url。event表示键盘的动作事件,这比较好理解,那么url是什么呢?为什么此处并没有传递调用呢?在图中的53行我们看到源码如下: var the_url = url ? url : window.opener.location.pathname; 这句代码的语义是:如果存在url参数则使用url参数,如果不存在,则使用当前对象的父对象的url(相当于使用referer作为url的值)。很显然,此处url值不存在,只能使用当前对象的父对象的url。因此,要想能交互地使用此页面,必须有一个页面作为父页面,打开webconsole.html才可以。故我们需要有一个前置的页面,然后我们在页面上可以通过浏览器调试功能,添加如下代码: <a href="struts/webconsole.html" target="_blank">Click Me</a> 页面如图所示:

s2_06.png

s2_07.png

基于此,我们应该有第四个认识:webconsole.html是否能交互是需要有指定接受消息的url路径。
那么,是不是所有的url都可以进行交互呢?当然答案也是否定的。我们都知道webconsole.html主要用来进行Debug,其使用OGNL表达式,而OGNL表达式需要以Struts2的Action为入口,也就是说,通常情况下,这个url的路径类似于http://ip:port/app_name/xxx.action,是以action结尾的,且其实现类必须集成于com.opensymphony.xwork2.ActionSupport (后面的原理与S2-032一致),只有基于以上叙述的所有条件都满足的情况下,webconsole.html才是真正可交互的。
说到这里,我想你应该明白什么样的情况下你所看到的webconsole.html才是存在安全风险的。至于你可能出于安全目的,在禁用了devMode之后,仍然不希望其他人员看到webconsole.html页面,则可以直接删除webconsole.html的源文件,它的位置存在于:

s2_08.png

我们手工删除struts2-core-*.jar\org\apache\struts2\interceptor\debugging\文件夹下的browser.ftlconsole.ftlwebconsole.htmlwebconsole.js即可。删除完毕后,当我们再次访问,将会出现404页面。