转载

HITB16议题解析:Java应用ORM注入开发新方法

HITB16议题解析:Java应用ORM注入开发新方法

“Hack In The Box”会议是在欧洲阿姆斯特丹举办的全球知名安全峰会。今年的会议十分有趣,其中一个由安全研究员Mikhail Egorov和Sergey Soldatov提出的议题“Java应用ORM注入开发新方法”引发了热议。

什么是对象关系映射(ORM)?

ORM是指对象映射关系,这是一种程序开发技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象数据库”。现今这项技术在商业应用广泛。

几个著名的Java ORM数据库:

–Hibernate ORM(经常应用在Wildfly和JBoss)

–eclipselink(例如GlassFish)

–TopLink(例如Oracle WebLogic)

–OpenJPA(例如TomEE和IBM WAS)

SQL vs ORM 注入

Mikhail 和Sergey专注于Java数据库ORM注入的研究。ORM注入也叫做JPQL或者HQL 注入,它们和SQL注入十分相似。不是直接定义SQL查询,ORM库使用自己专有语言JPQL/HQL(Java Persistence Query Language/Hibernate Query Language)。这些查询被ORM库译成SQL。

HITB16议题解析:Java应用ORM注入开发新方法 HITB16议题解析:Java应用ORM注入开发新方法

他们认为这些语言是奇怪的并且受限制的。如果你找到方法注入ORM查询,你会发现你的权限是受限的,只能访问被映射到实体的数据库表(Java对象),并且不能使用sqlmap。

开发技术

Mikhail和Sergey展示了如何利用这个ORM库绕过ORM语言,以及发送abritary  SQL查询,还有如何使用sqlmap进行深入渗透。

Eclipselink和TopLink ORM

Eclipselink ORM和TopLink ORM有神奇的功能,允许执行任意的SQL功能:Eclipselink有function()(原func())调用数据库的具体功能。你不仅可以执行数据库的功能,还可以使用这个“诀窍”进行正常的SQL查询:

JPQL语句:

... FUNCTION('(select count(1) from table where 1=1)>0 and length','qq')=2 ...

译成SQL语句:

... (select count(1) from table where 1=1)>0 and length('qq')=2 ...

如果是TopLink,你就不需要使用这个“诀窍”,因为它可以执行正常的SQL查询和sql()命令。

OpenJPA

在Apache OpenJPA ORM他们发现了执行abritary SQL函数的两种方法:第一个是错误的 进程:在检查语法后,通过一个’(单引号)替换一个序列”(双引号)。 这使得在字符串中隐藏选择语句成为可能:

ORM 参见: and ’1′=’1” and (select 1 where 1=1) = ”1′ and

DBMS 获取: and ’1′=’1′ and (select 1 where 1=1) = ’1′ and

第二个方法是引号不敏感:

ORM 参见: and “a’ = ‘a’ and (select 8 where 1=1)=8 and ‘b” = ‘b’

DBMS 获取: and ‘a’ = ‘a’ and (select 8 where 1=1)=8 and ‘b’ = ‘b’

Hibernate

在Hibernate库里,他们已经发现了几个方法:第一种是单引号转义的方法,这种方法在MySQL里起作用,因为可以在字符串里用一个反斜杠(/’)跳过单引号:

在HQL里是一个字符串:

'abc/''or 1=(select 1)--'

在MySQL里是一个字符串和一个附加的SQL表达式:

'abc/''or 1=(select 1)--'

在PostgreSQL和H2里有可能使用两个美元符号跳过字符串($$)。他们已经将这种方法应用到$引用字符串方法中:

在HQL里相比于一个字符串则解释为变量$$:

$$='$$=concat(chr(61),chr(39)) and 1=1--'

但是在SQL里一个$美元引用字符串和contact()函数相比:

$$='$$=concat(chr(61),chr(39)) and 1=1--'

对于PostgreSQL和Oracle,他们也展示了神奇的函数方法。PostgreSQL的有一个建立在功能query_to_xml(’arbitrary SQL”)和Oracle dbms_xmlgen getXML(’sql”)。使用此功能可以执行任意的SQL语句。

第四种方法使用的是UNICODE符号: Microsoft SQL 服务器和H2转换unicode分隔符,比如将无中断空格(U+00A0, %C2%A0)作为空白,因此SELECT LEN([U+00A0](select[U+00A0](1))的功能就和SELECT LEN((SELECT(1)))相同了。HQL允许符号标识符中运用unicode(函数或参数名称)。你可以利用这一点,因为Hibernate将 [U+00A0](…) 转化成一个有效的函数名,并且将其看作是一个函数调用。

最后一个方法是 JAVA CONSTANTS ,除了MySQL之外,大多数的DBMS都可以使用这种方法。 Hibernate 重新解决了Java在HQL查询中的公共静态字段。特殊字符或是字符串字段必须在类路径的类/接口中声明。他们已经给出了几个致命的Java库,你可以在其中找到所需字符。

这个HQL语句就利用了这种方法:

...dummy' and hqli.persistent.Constants.C_QUOTE_1*X('<>CHAR(41)(select count(1) from sysibm.sysdummy1)>0 --')=1 and '1'='1...

然后在下面的SQL查询中得到解决:

...dummy' and '''*X('<>CHAR(41) and (select count(1) from   sysibm.sysdummy1)>0 --')=1 and '1'=...

如何识别ORM?

在最后,他们给出一个很好的列表,这十分有助于确定应用程序中所使用的ORM库:

– Hibernate: .. and 1bi = 1bd and ...  – EclipseLink: ... and FUNCTION('1=1 and','2')='2' and ...  – TopLink: ... and SQL('1=1') and ...  – OpenJPA: ... and "1"='1' and ...

更多

如果你想知道更多有关漏洞的具体情况和sqlmap用法的详细说明,可以看一下这份幻灯片:

D2T2 – Mikhail Egorov and Sergey Soldatov – New Methods for Exploiting ORM Injections in Java Applications.pdf (conference.hitb.org) 

*参考来源:insinuator.net,FB小编极客小默编译,转载请注明来自FreeBuf黑客与极客(FreeBuf.COM) 

原文  http://www.freebuf.com/vuls/106605.html
正文到此结束
Loading...