Web安全之SQL注入---基础
文章目录
- SQL注入简介
- SQL注入基础
- SQL注入分类
- SQL注入流程
SQL注入简介
什么是SQL注入
?
SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息,例如查询数据、下载数据、写入webshell、执行系统命令以及绕过登录限制等。
SQL原理图
在客户端,若存在可控参数能配合web页面返回的信息实现一定的操作,如实现无账号登录,窃取管理员账号、密码、关键信息,篡改数据库等操作
测试方法
在发现存在可控参数后,可直接使用sqlmap
检测此网站是否存在sql注入,何种类型的sql注入,然后利用其爆库、爆表、爆字段。也可以用Burpsuite
CO2模块 sqlmap插件探测,亦可以通过积累的非法sql参数,利用intruder
模块尝试。最后,在简单的sql下,可进行手工注入,使用积累的一些闭合符进行尝试
修复建议
代码层最佳防御sql漏洞方案:采用sql语句预编译和绑定变量,是防御sql注入的最佳方法。
1、SQL提供参数化查询接口,而不是将用户输入变量的值嵌入到SQL语句中,使可控参数局限于设计者设计的功能,而不能进行其他恶意操作
2、对特殊字符,例如空格 、逗号,
、单引号'
、双引号"
、反引号等进行转义处理,或编码转换。
3、判别数据类型要严格,规定为强等于,例如 0
和'0'
,前者为数字,后者为字符串,不相等。
4、规定数据长度,可在起一定程度的防范
5、网站各数据层编码统一,建议使用UTF8
,上下层编码不一致,可能会导致一些过滤被绕过
6、限制网站用户的权限,给与最小权限,可进行正常操作请求即可
7、最小化返回信息,关闭显示错误信息,例如报错注入就是利用网站的报错回显而窃取信息的
SQL注入基础
基础不牢,地动山摇。要进行SQL注入,首先要了解数据库基础知识,从而才可以猜想设计者的思路,及其构筑的SQL,更进一步的窃取信息
information_schema
在mysql5 版本以后,mysql默认在数据库中存放在一个叫 infomation_schema的数据库, 这个库里面有很多表 重点是这三个表columns 、tables、schemata
table_name | content |
---|---|
schemata | 所有数据库名 |
tables | 所有表名 |
columns | 所有列名 |
系统函数
以下是常用的几个系统函数
函数 | function |
---|---|
version() | MySQL版本 |
user() | 数据库用户名 |
database() | 数据库名 |
@@datadir | 数据库路径 |
@@version_compile_os | 操作系统版本 |
字符串连接函数
concat
concat(str1,str2,...)
直接连接,无间隔符。可添加间隔符,如以下添加:
concat(str1,':',str2)
concat_ws
concat_ws(separator,str1,str2,...)
第一个参数为间隔符,后跟要连接的字符串列名
group_concat
group_concat(str1,str2,...)
连接一个组的所有字符串,并以逗号分隔每一条数据
sql注释符
注释符 | 含义 |
---|---|
# | 单行注释 注意与url中的#区分常编码为%23 |
-- 空格 | 单行注释,注意为短线短线空格 |
/*()*/ | 多行注释 至少存在俩处的注入 |
/**/ | 常用来作为空格 |
逻辑运算&字符优先级
万能密码
' or 1=1#
为什么可以直接登录
and
前后条件都为真时为真
or
前后有条件为真时为真
注意: and优先级高于or
判别sql注入点
控制可控参数,根据页面回显的内容判别是否存在注入点,例如以下是一些假设id
参数可控进行的情况下判别网站是否存在注入点的测试语句
id =1 and 1=1
id = 1 and 1=2
id = 1 or 1=1
id = '1' or '1'='1'
id=" 1 "or "1"="1"
回显是指页面有数据 信息返回
无回显是指 根据输入的语句 页面没有任何变化,或者没有数据库中的内容显示
到网页中.
思考:以下如何判别注入点,在无回显的情况下
sql注入原理
SQL注入漏洞的产生需要满足以下两个条件
- 参数用户可控:从前端传给后端的参数内容是用户可以控制的
- 参数带入数据库查询:传入的参数拼接到SQL语句,且带入数据库查询。
一般的代码为:
$id=$_GET['id'];
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
此处考虑两个点,一个是闭合前面你的 '
另一个是处理后面的 '
。
一般采用两种思路,闭合后面的引号或者注释掉,注释掉采用--+
、 #
、%23
一般用于尝试的语句
–+可以用#替换,url提交过程中Url编码后的#为%23
or 1=1--+
'or 1=1--+
"or 1=1--+
)or 1=1--+
')or 1=1--+
") or 1=1--+
"))or 1=1--+
以上仅是部分基础知识,后续会穿插基础知识
SQL注入分类
基于获取信息方式不同的分类
- UNION query SQLinjection(可联合查询注入)
- Stacked queries SQL injection(可多语句查询注入)堆叠查询
- Boolean-based blind SQL injection(布尔型注入)
- Error-based SQL injection(报错型注入)
- Time-based blind SQL injection(基于时间延迟注入)
基于请求方式的分类
- GET注入
GET请求的参数是放在URL里的,GET请求的URL传参有长度限制 中文需要URL编码 - POST注入
POST请求参数是放在请求body里的,长度没有限制 - COOKIE注入
cookie 参数放在请求头信息,提交的时候 服务器会从请求头获取 - HTTP注入
http请求中,header有可利用参数
基于数据类型的分类
- int 整型
select * from users where id=1
- sting 字符型
select * from users where username='admin'
- like 搜索型
select * from news where title like '%标题%'
基于程度和顺序的注入
一阶注射
二阶注射
基于布尔SQL盲注
•基于时间的SQL盲注
•基于报错的SQL盲注
一阶注射是指输入的注射语句对WEB直接产生了影响,出现了结果;二阶注入类似存储型XSS,是指输入提交的语句,无法直接对WEB应用程序产生影响,通过其它的辅助间接的对WEB产生危害,这样的就被称为是二阶注入.
SQL注入流程
常规注入流程
1、寻找注入点,可以通过 web 扫描工具实现
2、通过注入点,尝试获得关于连接数据库用户名、数据库名称、连接数据库用
户权限、操作系统信息、数据库版本等相关信息。
3、猜解关键数据库表及其重要字段与内容(常见如存放管理员账户的表名、字
段名等信息),还可以获取数据库的root账号 密码—思路
4、可以通过获得的用户信息,寻找后台登录。
5、利用后台或了解的进一步信息。
参考文章
SQL原理
SQL天书MadeByLcamry-2016-7