目录:
1.讨论关于struts 安全问题。
2.黑客文化。
3.如何降低安全漏洞的出现。
4.忠告建议。
题记:
这篇文章本来很早应该和大家见面的,中间由于个人原因调整了系列文章发布时间,实属罪过。为了不误导大众文章中间讲述的经历想法实战,均属个人看法个人行为不代表任何团体及组织。观看者请保留自己的想法观点!欢迎各位热爱编程的技术人员交流。废话不多,开始正文。
1.讨论关于struts安全问题。
最近各位都看到了各种关于struts安全问题的文章,及实战演练,安全问题波及到了各种大小的互联网站点(京东,电信,IBM,其中后两个网站都是笔者请自尝试,只是做友情检测,并未做任何非法过激动作)。各个论坛相继出现各种诋毁,谩骂关于struts安全的回复。
对于以上的问题,个人奔着还原问题的本质,通过友情检测IBM报名网站做实战讲述+个人测试Test,讲述关于我们应该如何看待struts安全问题。
对于IBM报名网站这里做必要解释,并非刻意测试,而是今日公司安排报名培训,上去结果发现该网站亦是struts架构,遂友情检测。截止文章发布之时已经邮件通知IBM运维。如下截图为证。
在正式解读struts安全问题之前我们先来了解一下struts,其实在命名的时候都不知道改用struts还是struts2?有人会问题?为什么?看官且慢慢听我讲,现在apache官方称谓struts2,为何笔者又命名为struts呢?因为我们这里讨论 大家对struts安全的误解和盲区,struts作为apache众多项目的一个顶级项目,而struts2的前身就是struts,漏洞也是从struts开始暴露出来的,想必老一辈的coder应该用过struts,开始的时候就用struts2 了,截止前不久apache 官方对struts已经终结其生命了。各位可以到这里观摩()
早在没有使用struts之前,玩骇客的应该都知道有struts漏洞检测工具,不错!这个就是struts第一次出现安全漏洞问题,截止目前struts已经出现两次安全漏洞!最近一次的安全描述()
看完各种网络文章,评论,有人说这个漏洞5月份就提交apache处理了,但是漏洞大面积铺开的时候是7月中旬,也就是apache公开安全漏洞的不久后!而得知的是在7月14日有人在博客园闪存多次发布,而引起笔者注意,当天下午笔者边看到apache公开漏洞渗透的方法。这里apache的做法确实不对,因为按照国际惯例,漏洞发现后不能公开具体渗透方法,只能描述,等官方修复后才能!
过后几天,各种网站类似于struts2安全漏洞做各种的评论文章分析,导致各种的批判诋毁的争论不休的评论发生!确实如此笔者得知后第一时间google测试,结果发现确实如此,不幸的是google出来一个电信某积分分站,确实如此,之后突然想起来,交话费用的电信官网也是struts架构的,立刻友情检测,确实中招!之后想通过email通知,结果发现电信网站木有email提交,神马在线交流都是摆设,笔者隧到乌云(我朝号称为互联网安全而战的网站,上属国家互联网安全中心,自命白帽子)不行,忘记了账号密码,放弃!浏览网站,确实有人提交了,故放弃,看了看,发现乌云很多人为了提交漏洞而提交漏洞!觉得实属没有意思,放弃了,本来想写文章后来觉网上各种有,放弃!后来一想该漏洞确实不是出自struts,而是XWork,想必用过struts的人都知道,XWork才是struts的核心,早起这两个不是一家,后来apache收入麾下将XWork和struts结婚了(正所谓不是一家人不进一家门),而XWork提供的ONGL表达式语言正是两次struts漏洞的罪魁祸首!
ps:当我们发现安全问题的时候,而不是批判别人为我们做的不够,也不是推卸责任的时候,及时有效的解决问题才是!当然,作为商业性的要另行讨论,正如我下午在闪存和某兄讨论:项目管理之风险合理规避问题一样。说俗点就是推卸责任(但又在合理之中)。我们谩骂框架的不够完美也罢,维护人员维护不及时也罢,要看问题的实质是不是我们想的那样,正如Xwork的核心漏洞,struts维护人员怎能及时发现?尽管发现,轻而易举的修改核心?这个看起来似乎不是那么的简单!想必大家都是程序员,写程序比维护程序或者修改程序难的多!不管你有多么的牛逼,网上后来也有人试过一些非官方推荐方法,有些失败,因为表面对了,但是实质聪明的骇客还可以绕过他的过滤!
直到今日IBM亦出现该安全漏洞!故借此一起讲讲个人的安全看法!废话不讲了,下面看实战!
(图1.1)
(图1.2)
(图1.3)
到此,再也没有测试,因为测试也是意义不大,即使你可以远程启动也没有意义,做一些远程关闭服务器的事情也没意义!不过可以通过远程构造上传脚本小子提权!
下面讲讲三幅图的奥秘,图1.1中只是采用redirect中定向baidu,也算是初步判断是不是存在struts2的漏洞,到图1.2可以证明一点,确实存在struts2漏洞!那么接下来就是骇客常用的手法,小马提权再通过大马获取服务器(大小木马后面讲)。图1.3就是我尝试提交运行远程服务器的命令(开始calc,当然这个是windows下命令),response给我的jsp页面,从图中我们可以看出我的命令执行了,但是我们如何确定呢?因为我们通过这个无法判断是否成功!由于为IBM服务器,可能涉及法律相关问题,本人没有进一步渗透!
接下来通过自己的Demo来演示 上面的构造是否成功!搭建了一个struts2的入门项目,struts2 core是2.1.8。为了验证我们前面的猜想及准确性,我采用双系统切换测试,一个windows 一个linux,两个系统同时部署相同的项目,测试不同平台下看看结果是神马?客户端我采用的是服务器如果是linux,我就用windows客户端访问,反之同理。结果如下!
游戏开始:只需要redirectAction:%25{(new+java.lang.ProcessBuilder(new+java.lang.String[]{'calc','goes','here'})).start()} 一句话就可以构造起来远程服务器windows。
第一:我们先测试windows服务器下的结果(下面上图)
(图2.1.1)
从上面丰富的图中可以看出游戏的结果,图中我们可以看出上面的那一句话确实开启了windows 服务器的calc(计算器)绿色框中的就是windows 下服务器控制台爆出来的bug,为什么会出现bug呢?我们通过%{}构造了一个进程对象,而ONGL去执行了我们构造的进程对象,这个时候服务器端的计算器被远程开启,到这里漏洞就算是暴露的无疑了!那为什么控制台有那样的bug呢?redirectAction我们为什么要选用这个呢?见名知意,重定向去执行一个action,所以构造的进程对象被执行了,struts2的架构必须返回一个字符串来跳转到该action映射到的jsp页面,而我们只指定了其执行逻辑没有返回任何字符串,这个时候在Map搜寻不到就返回一个没有该映射(具体我们在后面详细解释)。
总结:windows 下如此构造出来的脚本可以远程启动windows下的commnd。
第二:既然windows可以那我们不妨换到linux平台再看看会发生神马情况!
首先我们要明白windows上面的命令和linux上面的是不同的,所以我们需要切换命令执行。
redirectAction:%25{(new+java.lang.ProcessBuilder(new+java.lang.String[]{'shutdown –h now'})).start()}(这次有点邪恶哦,用的关机命令,linux用不多,这个绝对记得!)
游戏开始:看下面图
(图2.2.1)
(图2.2.2)
图2.2.1中能看出来说明,执行成功了,图2.2.2中可以看出来执行了,抱的错误还是跟windows平台同理!有人会问了,为什么,木有关机?呵呵!确实,为什么呢?
其实道理很简单,linux执行权限规则审查比较严格.我们无权执行核心命令!所以执行无效!web正常返回!404page.那么有人就说了,能不能让其表现出我们所要看到的远控漏洞呢?这个是可以的,我们稍微修改一下检测的代码让正在运行的web服务器停机!通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。
struts2为我们提供了动态方法执行的模式!我们只需要开启,那么再加上struts2的ONGL漏洞执行,这样不就可以执行了嘛!(这里说是struts2还不如说是XWork提供的机制)
公开部分代码:
?('\u0023_memberAccess[\'allowStaticMethodAccess\']')(meh)=true&(aaa)(('\u0023context[\'xwork.MethodAccessor.denyMethodExecution\']\u003d\u0023foo')(\u0023foo\u003dnew%20java.lang.Boolean("false")))&(asdf)(('\u0023rt.exit(1)')(\u0023rt\u003d@java.lang.Runtime@getRuntime()))=1
简单解释一下这句话,这句话的意思就是通过客户的url地址栏修改了XWork的动态方法执行权限,然后借助ONGL漏洞,让其执行我们动态构造的终止当前正在运行的 Java 虚拟机指令。而这句话也是转义过的,否则Map里面不会去存放我们的执行指令(当然XWork设计者考虑到了这一点,就是禁止启用这一功能,但为什么我们能执行呢?你如果能看明白我们的代码是通过转义过的其实质代码就是:?('#_memberAccess['allowStaticMethodAccess']')(meh)=true&(aaa)(('#context['xwork.MethodAccessor.denyMethodExecution']=#foo')(#foo=new%20java.lang.Boolean("false")))&(asdf)(('#rt.exit(1)')(里面的“#”就是ONGL表达式中需通过“#+对象的名称”来访问context中的对象,里面的“@”就是调用静态方法,需要在类名和变量名前面加上@来调用,对于实例方法,用"."来调用。)、到时候ONGL也是无法执行的、
官方的解析参考是如图:这个是对动态方法执行的官方解释(这个是struts2最新版的XWork里面的描述,当然在我翻看API的时候发现struts2API和XWorkAPI依旧分开,虽然两人日子过一起了,可是“钱”还是各赚各的。)、
下图就是通过struts配置文件的形式启动动态方法执行(true就是开启,有些公司为了提高代码的高可用就是通过这个表达式来映射方法及jsp来执行的,当然这个相当危险项目的检查机制必须做好。)。看图很明显的解释。
结果:
(图3.1)
当我接到服务器响应给我图3.1的效果的时候,我肯定确实服务器停止了!这个过程稍微延迟了几秒,我心砰砰的,能感觉到服务器正在关闭!之后立刻查看服务器,结果如下图3.2!
(图3.2)
总结:到这里我的谜团打开了,就是为神马我检测IBM,中国电信,网站的时候给我一个404的原因了,原因就是这两家的都是linux服务器,电信的貌似是unix服务器(曾经听别人提起过!)IBM是linux服务器。最起码能断定该服务器不是windows,有过骇客经验的都应该清楚攻击服务器,对了解该服务器是那种平台又很重要意义,通过实践我们就能推理出来!而且确实执行了我的远程指令,只不过我木有高级权限,但是即使拿到高级权限我觉得也没多大意义,IBM服务器也不是吃素的应该上面有防火墙,而且有杀毒软件!执行这些高危系统进程肯定会被拦截、但是绝对有方法可以绕过去、这里就尝试这么多。
尝试了这么多,我们下面剖析ONGL漏洞,神马是ONGL。这里我给出官方的解释:OGNL is the Object Graph Navigation Language (see for the full documentation of OGNL).简言之就是:对象图导航语言。下面给出官方模型图(具体访问:)
演练了这么就是OGNL对象地图导航惹的祸,而且我知道的两次struts漏洞都是出自这个,对象导航顾名思义,构造对象然后去找Map里面存的地图。响应给客户jsp,所以struts的核心就是这个,其他的拦截过滤机制都是辅助ONGL来完成对象导航的、这里不多讲了,用过struts的都应该明白。我用图来给大家解读、
看图吧,写的都多了!最后总结一句话目前来看struts2将会伴随这种机制一直修补下去,除非重构这种方式,显然很难!我想struts2官方推荐升级版,也就是过滤防止不允许执高危构造方式,杜绝转码方式渗透。
如何预防:
1.网上有人通过
<interceptor-ref name="params">
<param name="excludeParams">.*\\u0023.*</param>
</interceptor-ref>
这个是struts提供的一种机制就是通过正则表达式过滤提交参数。
2.可以通过过滤器的方式初级过滤,然后再采用struts2提供validate来验证提交的参数(提高验证规则,比如:包括转码也需要考虑)。很多coder大多就是javascript蒙骗验证法,何谓蒙骗验证法?就是在页面通过javascript验证,后台从来不做规则验证。你要知道 骇客可是不吃这一套的。还有需要加入强制类型转换机制,这个struts2也提供了,只是很多coder也无视其存在。
3.这种是我个人推荐的五星级方法:天空一声巨响spring security 闪亮登场,关于安全的框架很少,但是这个东东绝对是一个好东西,可是国内对安全的不重视,导致该框架用的很少。网上资料也是很少。这个是spring 的一个顶级项目,本人用过spring security2,3没有用过,基本变化不大,里面有少数class做了修改。这里不做过多介绍各位好好研究去吧,这个东西是一套权限,安全,openID,cas单点登录,防止会话伪造等功能!对于未授权的action都是无法执行的、从集成ssh2的架构上来讲,他是保护在struts2外面的一到防线、
上篇【game over】