sql注入进阶

一、时间注入。

测试地址:自建靶场 http://192.168.57.128:1237/time/time.php?id=1

1.测试过程。

  当访问该地址时,页面返回yes,在网址的后面加上单引号,再次访问,页面返回no。这与Boolean注入非常相似,但是我们将采用另外一种注入方法解决——时间盲注。
  时间盲注是利用sleep()或benchmark()等函数让Mysql的执行时间边长,它多与IF(expr1,expr2,expr3)结合使用,此if语句含义是:如果expr1是TRUE,则if()的返回值为expr2;否则返回值则为expr3。所以判断数据库库名长度的语句则为:

if (length(database())>1,sleep(5),1)

  上面这行语句的意思是,如果数据库库名的长度大于1,则MySQL查询休眠5秒,否则查询1。查询1的结果,大约只有几十毫秒,根据burp中页面的响应时间,可以判断条件是否正确,我们构造如下SQL语句,查询结果如下图所示:

'and if (length(database())>1,sleep(5),1)--+

在这里插入图片描述  由以上的返回结果可知,页面的响应时间超过了5s,表明页面成功执行了sleep(5),所以长度是大于1的,接下来将长度改为10,结果如下所示:
在这里插入图片描述
  可以看出,执行的时间是0.404秒,表明页面没有执行sleep(5),而是执行了select 1,所以数据库库名长度大于10是错误的。通过多次测试,就可以得到数据库库名的长度。得出数据库库名长度后,我们开始查询数据库库名的第一位字母。,使用substr函数,这时的语句修改为:

if (substr (database(),1,1)='s',sleep(5),1)

在这里插入图片描述  页面5秒之后才返回了,说明数据库库名第一位字母是s,以此方式可以推断出数据库的库名、表名、字段名和具体数据。

2.代码分析。
<?php
$con=mysqli_connect("192.168.57.128","root","123","security");
if (mysqli_connect_errno())
{
	echo "连接失败: " . mysqli_connect_error();
}

$id = $_GET['id'];
if (preg_match("/union/i", $id)) {
	exit("<htm><body>no</body></html>");
}
$result = mysqli_query($con,"select * from users where `id`='".$id."'");
$row = mysqli_fetch_array($result);
if ($row) {
	exit("<htm><body>yes</body></html>");
}else{
	exit("<htm><body>no</body></html>");
}
?>

  在时间注意注入页面中,程序获取GET参数ID,通过preg_match判断参数ID中是否存在Union危险字符,然后将参数ID拼接到SQL语句中。从数据库中查询SQL语句,如果有结果,则返回yes,否则返回no。当访问该页面时,代码根据数据库查询结果返回yes或no,而不返回数据库中的任何数据,所以页面上只会显示yes或no,和Boolean注入不同的是,此处没有过滤sleep等字符。

二、堆叠查询注入。

测试地址:自建靶场 http://192.168.57.128:1237/sql/dd.php?id=1

1.测试过程。

  堆叠查询可以执行多条语句,多语句之间以分号隔开。堆叠查询就是注入就是利用这个特点,在第二个SQL语句中构造自己要执行的语句。
  首先访问id = 1’,页面返回Mysql错误,如下图所示。
在这里插入图片描述
  再访问id = 1’%23,页面返回正常结果。
在这里插入图片描述  在此我们尝试堆叠注入的方式来验证数据库名。我们构造如下的SQL语句,其实这里使用依然是时间盲注的语法结构,如下所示:

';select if(substr(database(),1,1)='s',sleep(5),1)%23

  因为该数据库名的第一个字母是s,所以页面返回的时间等于5s,如下图所示:
在这里插入图片描述  后面获取数据的操作与时间注入的一样,通过构造不同的时间注入语句,可以得到完整的数据库的库名、表名、字段名和具体数据。执行以下语句,就可以获取数据库的表名。

';select if(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1)='e',sleep(5),1)%23
2.代码分析。
<?php
try {
    $conn = new PDO("mysql:host=192.168.57.128;dbname=security", "root", "123");
    $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $stmt = $conn->query("SELECT * FROM users where `id` = '" . $_GET['id'] . "'");

    $result = $stmt->setFetchMode(PDO::FETCH_ASSOC);
    foreach($stmt->fetchAll() as $k=>$v) {
        foreach ($v as $key => $value) {
            echo $value;
        }
    }
    $dsn = null;
}
catch(PDOException $e)
{
    echo "error";
}
$conn = null;
?>

  在堆叠注入页面中,程序获取GET参数ID,使用PDO的方式进行数据查询,但仍然将参数ID拼接到查询语句,导致PDO没起到预编译的效果,程序仍然存在SQL注入漏洞。使用PDO执行SQL语句时,可以执行多语句,不过这样通常不能直接得到注入结果,因为PDO只会返回第一条SQL语句执行的结果,所以在第二条语句中可以用update更新数据或者使用时间盲注获取数据。访问dd.php?id=1";select if (ord(substring (user () , 1,1) ) =114, sleep (3), 1) ;%23时,执行的SQL语句为:

select * from users where 'id' = '1';select if(ord(substring(user(),1,1))=114,sleep(5),1);#

  此时SQL语句分为了两条,第一条Select * from users where ‘id’ = '1’是代码自己的select查询,而select if(ord(substring(user(),1,1))=114,sleep(3),1);#则是我们构造的时间盲注的语句。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晶晶娃在战斗

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值