SQL注入—二次注入

原理:用户向数据库里存入恶意的数据,在数据被插入到数据库之前,肯定会对数据库进行转义处理,但用户输入的数据的内容肯定是一点摸样也不会变的存进数据库里,而一般都默认为数据库里的信息都是安全的,查询的时候不会进行处理,所以当用户的恶意数据被web程序调用的时候就有可能出发SQL注入。

图解:
在这里插入图片描述
二次注入比普通的注入更难发现,很难被工具扫描出来。

原理大概知道了,接下来就是实战了

以sql-libs第24关为例

在这里插入图片描述
有登录,注册页面

好奇的我就试了一下弱口令登录

在这里插入图片描述
啧啧啧,登陆成功了!不过这和本文没有联系,回到正题!

我们利用注册功能,将我们的数据插入数据库里。
在这里插入图片描述
登陆试试
在这里插入图片描述
登录进去,现在我们修改密码
在这里插入图片描述
我们查看一下
在这里插入图片描述
我们登录的是admin’#,但是修改的却是admin账号的密码,那为什么admin账号的密码会被改变呢???

我们去靶场源文件pass_chang.php看一下
找到这句话

$ sql = "UPDATE users SET PASSWORD=’$ pass’ where username=’$ username’ and password=’$ curr_pass’ ";

我们的用户名被admin'#传入进去,在数据库里#号为注释符
然后这句话就变成了

$ sql = "UPDATE users SET PASSWORD=’$ pass’ where username=’admin‘#’ and password=’$ curr_pass’ ";

然后就是

$ sql = "UPDATE users SET PASSWORD=’$ pass’ where username=’admin‘

从而将用户名为admin的账号的密码修改了

数据库还是对自己太过相信,认为数据库里的数据都是正常的,当从数据库里调用的时候没有经过过滤,这就造成了二次注入。

在源码里找到了mysql_real_escape_string($_POST["login_user"]);这个函数将我们的输入的数据进行转义

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符。

下列字符受影响:

\x00
\n
\r
\
'
"
\x1a
如果成功,则该函数返回被转义的字符串。如果失败,则返回 false。

emmmm

再次演示一下攻击

先创建一个list.php

<?php
include("../sql-connections/sql-connect.php");
error_reporting(0);
$sql="SELECT * FROM users ORDER BY id";
$result=mysql_query($sql);
$num=mysql_num_rows($result);
for ($i=0; $i < $num; ++$i) { 
    $row = mysql_fetch_array($result);
    $username = $row[1];
    $sql_detail = "SELECT * FROM users where username='$username'";
    $result_detail=mysql_query($sql_detail);
    $num_detail = mysql_num_rows($result_detail);
    for ($j=0; $j < $num_detail; ++$j) { 
        $row_detail = mysql_fetch_array($result_detail);
        echo<<<END
        <table border="1" style="table-layout:fixed;" width="1000">
            <tr>
                <th>$row_detail[1]</th>
                <th>$row_detail[2]</th>
            </tr>
        </table>
END;
    }
}
?>

我选择把list.php和sql-connect.php放在一起

现在我们在注册一个用户名1’ union select 1,user(),database()#

然后访问list.php
在这里插入图片描述
用户名和密码就被打印出来了

我们分析一下流程。

list.php包含了sql-connect.php,我们创建好账号后,再次登录使用1‘ union select 1,user(),database() #

$ username = $row[1];
$ sql_detail = “SELECT * FROM users where username=’$ username’”;

我们的username传入进去

$ sql_detail = “SELECT * FROM users where username=’1’ union select
1,user(),database() #’”;

也就是语句变成了

$ sql_detail = “SELECT * FROM users where username=union select 1,user(),database() ”;

我们从表里就打印出了账号和密码这张表。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值