社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

最新SQL注入漏洞原理及与MySQL相关的知识点

Ms08067安全实验室 • 1 年前 • 283 次点击  
点击星标,即时接收最新推文


本文选自《web安全攻防渗透测试实战指南(第2版)》

点击图片五折购书
















SQL注入漏洞简介















SQL注入是指Web应用程序对用户输入数据的合法性没有判断,前端传入后端的参数是攻击者可控的,并且参数被带入数据库查询,攻击者可以通过构造不同的SQL语句来实现对数据库的任意操作。

一般情况下,开发人员可以使用动态SQL语句创建通用、灵活的应用。动态SQL语句是在执行过程中构造的,它根据不同的条件产生不同的SQL语句。当开发人员在运行过程中根据不同的查询标准决定提取什么字段(如select语句),或者根据不同的条件选择不同的查询表时,动态地构造SQL语句会非常有用。

以PHP语句为例,命令如下:

$query = "SELECT * FROM users WHERE id = $_GET['id'


    
]";

由于这里的参数ID可控,且被带入数据库查询,所以非法用户可以任意拼接SQL语句进行攻击。

当然,SQL注入按照不同的分类方法可以分为很多种,如报错注入、盲注、Union注入等。

















SQL注入漏洞原理















SQL注入漏洞的产生需要满足以下两个条件。

— 参数用户可控:前端传给后端的参数内容是用户可以控制的。

— 参数被带入数据库查询:传入的参数被拼接到SQL语句中,且被带入数据库查询。

当传入的参数ID为1'时,数据库执行的代码如下:

select * from users where id = 1'

这不符合数据库语法规范,所以会报错。当传入的参数ID为and 1=1时,执行的SQL语句如下:

select * from users where id = 1 and 1=1

因为1=1为真,且where语句中id=1也为真,所以页面会返回与id=1相同的结果。当传入的参数ID为and 1=2时,由于1=2不成立,所以返回假,页面就会返回与id=1不同的结果。

由此可以初步判断参数ID存在SQL注入漏洞,攻击者可以进一步拼接SQL语句进行攻击,致使其获取数据库信息,甚至进一步获取服务器权限等。

在实际环境中,凡是满足上述两个条件的参数皆可能存在SQL注入漏洞,因此开发者需秉持“外部参数皆不可信”的原则进行开发。

















MySQL中与SQL注入漏洞相关的知识点















在详细介绍SQL注入漏洞前,先介绍MySQL中与SQL注入漏洞相关的知识点。

在MySQL 5.0版本之后,MySQL默认在数据库中存放一个名为“information _schema”的数据库。在该库中,读者需要记住三个表名,分别是SCHEMATA、TABLES和COLUMNS。

SCHEMATA表存储该用户创建的所有数据库的库名,如图4-7所示。需要记住该表中记录数据库库名的字段名为SCHEMA_NAME。


图4-7


TABLES表存储该用户创建的所有数据库的库名和表名,如图4-8所示。需要记住该表中记录数据库库名和表名的字段名分别为TABLE_SCHEMA和TABLE_NAME。


图4-8  


COLUMNS表存储该用户创建的所有数据库的库名、表名和字段名,如图4-9所示。需要记住该表中记录数据库库名、表名和字段名的字段名分别为TABLE_ SCHEMA、TABLE_NAME和COLUMN_NAME。


图4-9  


常用的MySQL查询语句和语法如下。

1.MySQL查询语句

在不知道任何条件时,语句如下:

SELECT 要查询的字段名 FROM 库名.表名

在有一条已知条件时,语句如下:

SELECT 要查询的字段名 FROM 库名.表名 WHERE 已知条件的字段名='已知条件的值'

在有两条已知条件时,语句如下:

SELECT 要查询的字段名 FROM 库名.表名 WHERE 已知条件1的字段名='已知条件1的值' AND 已知条件2的字段名='已知条件2的值'


2.limit的用法

limit的使用格式为limit m,n,其中m指记录开始的位置,m为0时表示从第一条记录开始读取;n指取n条记录。例如,limit 0,1表示从第一条记录开始,取一条记录。不使用limit和使用limit查询的结果分别如图4-10和图4-11所示,可以很明显地看出二者的区别。


图4-10  


图4-11  

3.需要记住的几个函数

— database():当前网站使用的数据库。

— version():当前MySQL的版本。

—  user():当前MySQL的用户。

4.注释符

在MySQL中,常见注释符的表达方式为“#”“--空格”或“/**/”。

5.内联注释

内联注释的形式为/*! code */。内联注释可以用于整个SQL语句中,用来执行SQL语句,下面举一个例子。

index.php?id=-15 /*!UNION*/ /*!SELECT*/ 1,2,3



MS08067安全实验室视频号已上线
欢迎各位同学关注转发~


—  实验室旗下直播培训课程  —



和20000+位同学加入MS08067一起学习


Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/161515
 
283 次点击