一、环境介绍
当前Oracle数据库中有两张表:users表和info表:
采用PHP连接Oracle进行注入演示
<?php
header('content-type:text/html;charset=utf-8');
if(!isset($_GET['id'])){
die('请传入ID值');
}
$id=$_GET['id'];
$conn = @oci_connect('system', 'admin', "192.168.234.131:1521/orcl.168.234.131");
if (!$conn) {
$e = oci_error(); //返回上一个错误
print htmlentities('数据库连接错误:'.$e['message']);
exit;
}
$sql="SELECT TITLE,BODY FROM INFO WHERE ID='{$id}'";
$stid=@oci_parse($conn,$sql); // 配置 Oracle 语句预备执行
if(!$stid){
$e = oci_error($conn);
print htmlentities($e['message'].$e['sqltext']);
exit;
}
if(!@oci_execute($stid)){//执行一条语句
$e = oci_error($stid);
print htmlentities($e['message'].$e['sqltext']);
exit;
}else{
$nrows = oci_fetch_all($stid, $results);
if(@$results['TITLE'][0]==""){
echo '没有记录';
}else {
echo "标题:{$results['TITLE'][0]},内容:{$results['BODY'][0]}";
}
}
oci_close($conn); //关闭 Oracle 连接
?>
二、联合查询注入
1、判断注入点
http://127.0.0.1/?id=1 //正确页面
http://127.0.0.1/?id=1' //报错页面,根据报错,知道是采用单引号闭合
http://127.0.0.1/?id=3'-1-- //返回ID=2的结构,说明进行了算术运算
http://127.0.0.1/?id=1' and 1=1-- //返回正确页面
http://127.0.0.1/?id=1' and 1=0-- //返回空记录,说明进行了逻辑运算
//可以确定存在注入点
2、确认字段数
http://127.0.0.1/?id=1' order by 2-- //正确页面
http://127.0.0.1/?id=1' order by 3-- //报错页面
3、进行联合查询
当前用户名:
数据库信息:
表信息:通过不断调整limit=?参数,遍历全部表名。注意这里用了select * from,因为返回和查询字段都刚好2个字段。
字段信息:注意值要大写。
获取对应的字段值:
三、报错注入
修改PHP代码,使其不显示查询的结果,不管是否有数据都显示“hello oracle”字符。
此时,联合查询就不能使用,但开发者没有禁用数据库错误信息,那么可以使用报错注入得到信息。
当前用户名:
数据库版本信息:
表信息:
字段信息:
获取对应的字段值:
四、布尔盲注
修改PHP代码,屏蔽报错输出,如果有数据返回"hello oracle",没有数据或代码错误返回"没有记录"。
现在,网页返回两种状态,即可使用布尔盲注。
既然是盲注,那么肯定涉及到条件判断语句,Oracle除了使用IF the else end if这种复杂的,还可以使用decode()函数。
语法:decode(条件,值1,返回值1,值2,返回值2,...值n,返回值n,缺省值);
该函数的含义如下:
IF 条件=值1 THEN
RETURN(翻译值1)
ELSIF 条件=值2 THEN
RETURN(翻译值2)
......
ELSIF 条件=值n THEN
RETURN(翻译值n)
ELSE
RETURN(缺省值)
END IF
可看到这个比IF结构简单多了。
判断当前用户名是否为SYSTEM,返回正确页面,说明是。
当然,也可以一个一个字符进行比较:
当然,也可以使用二分搜索法进行:
五、时间盲注
修改PHP代码,使其不管什么都输出“hello word”字符。
可使用DBMS_PIPE.RECEIVE_MESSAGE('任意值',延迟时间)函数进行时间盲注,这个函数可以指定延迟的时间,很好用。