# OQL(对象查询语言)在产品实现中造成的RCE(Object Injection)

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2014-12-02T01:09:00Z
Canonical: https://wepostx.com/topics/650

> 乌云历史资料归档
>
> **原始作者：** Nebula
> **原始编号：** superkieran-wooyundrops:415
> **原始发布时间：** 2014-12-02 09:09
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

# 0x00 前言

前几天,有几个屌丝高帅富给我看一个这样的漏洞类型:
地址:http://blog.emaze.net/2014/11/gemfire-from-oqli-to-rce-through.html
GemFire内存数据库是来自云计算公司Pivotal(未来我最看好的云计算产品提供商,由EMC、VMware、通用电气这三家公司合资等方式组成,这里有我们熟悉Spring技术团队支撑的就是这家公司云计算前端开发框架)的产品.

# 0x01 内存数据库基础

那什么是内存数据库,为什么需要它?给大家举个简单的例子:
在百度中搜索: GemFire,排在第5位的结果就是我们的答案

![原文图片](/media/2016/06/5ff9321bcfd899ab9a865a765f7a19bc)

我们知道中国是个人口大国,由于地域经济差异大,外出打工挣钱的人特别多.逢年过节买火车票一直有个头痛的问题,就是关键时候这个网站就打不开了.无论它体验及性能有多烂,我们还是要去上它,因为要回家(这是刚需),随着国人网上预订越来越多,存在并发访问量爆表的问题,庆幸的是它一直在通过技术手段解决这个问题.
并发访问与数据库技术的演变简单描述可能是:开始使用关系数据库,如:Oracle,并发量大会挂;然后使用数据在内存做缓存，如：memcached (因为读写内存要比读写硬盘快很多,可极大提升访问性能),还是有性能问题;所有后来就干脆使用云计算数据库解决产品GemFire（充当一下国外新产品的小白鼠）,不知道今年过年买票能否不挂?拭目以待!
但GemFire内存数据库在数据存储中并非简单的字符串,如:"123456"；而是Java对象，所以它也是个对象数据库，比如：我们在J2ME开发中使用的DB4o也是。学过J2EE持久层框架的人都知道,如: Hibernate; ibatis等,就是把关系数据库中的每张表映射到内存中(ORM,表的字段对应内存中Java对象的属性),另外还有一个特点,Java对象中可以放更为复杂的对象结构(如:迭代对象,数据集合).再进行数据传输操作,就非常方便了,抛弃传统关系数据库操作概念.而GemFire内存数据库支持更为强大的对象操作API,OQL(Object Query Language)
那什么是OQL?百度就简单几句话,大家很难理解:
http://baike.baidu.com/view/2554236.htm?fr=aladdin
这里举个例子就清晰了:它类似SQL
如，sql查询表user的字段name为test的数据，sql语句是：
sql ="select * from where name ='test' ";

而oql可能就是这样：
oql=" select referrers(u) from xxx.xxx.User u where u.name = 'test' ";

这里简单解释一下语法及语义：xxx.xxx为对象包路径，在返回引用对象xxx.xxx.User中name对象为test的引用对象。是不是更为强大？OQL还有更多更为强大的API.
而形成的新漏洞类型对比SQL注入漏洞就更好理解了，sql注入是外部参数污染sql语句，OQL注入是外部参数污染oql语句。这里更要命的是oql语句是支持java代码语义及语法解析的（可以理解为我们之前熟悉的OGNL表达式注入），所以这个漏洞类型为：OQL注入漏洞（Object Injection），最大的利用就是远程代码执行，最大危害就是执行系统命令了。

# 0x02 实例分析

说了这么多，大家肯定会说给个例子吧,别光YY! 我们知道学习技术也是要成本的，GemFire内存数据库，对于我这样的穷人现在是用不起的！但不影响我们去学习OQL这门对象查询语言。
它其实就在我们的JDK中：
首先，我们启动任何一个Java程序，我这里是个Tomcat,再找到它的PID,如图：

![原文图片](/media/2016/06/89c00a98d0c0fdcf1b0dd71a574a314e)

然后使用jmap命令生成堆转储快照，如图：

![原文图片](/media/2016/06/6551dd1331a5bf9533446a6a038a778b)

然后使用堆分析命令jhat,它是个http服务，默认端口7000，如图：

![原文图片](/media/2016/06/f7684c4d8aaf56b83935a297b0c9b42d)

我们就可以使用浏览器查看堆信息了，它还提供我们前面需要的OQL查询功能，如图：

![原文图片](/media/2016/06/74d642d56d6380f5ccf5104ba65795a0)

查询长度大于100的字符串：

![原文图片](/media/2016/06/dccaaad40ad67cfa7b33010ba495f7d3)

Java代码执行系统命令也不需要老外说的那么复杂，还使用反射？（当然，看语句拼接情况）：

![原文图片](/media/2016/06/594a9f0b1e20155874b72366898e68af)

![原文图片](/media/2016/06/921a1bf7957e576b5f2556f655143939)

未来使用对象数据库会越来越多，而漏洞类型已经不是我们之前熟悉的SQL注入漏洞了，而是OQL注入，危害就更为严重了(不仅限于Java)。

## Replies
