什么是SQL注入?

1.1概述

SQL注入是影响企业运营且破坏性最强的漏洞之一,它曾经几次在TOP10登顶,它会泄漏保存在应用程序数据库中的敏感信息,例如:用户名,口令,姓名,地址,电话号码以及所有有价值的信息。
如何定义SQL注入:应用程序在向后台数据库传递SQL(Structured Query Language,结构化查询语言)查询时,如果为攻击者提供了影响该查询的能力,则会引发SQL注入。攻击者通过影响传递给数据库的内容来修改SQL自身的语法和功能,并且会影响SQL所支持数据库和操作系统的功能灵活性。SQL注入不只是一种会影响Web应用的漏洞;对于任何从不可信源获取输入的代码来说,如果使用了该输入来构造SQL语句,那么就很可能受到攻击。

1.2 理解Web应用的工作原理

不管用任何语言编写的Web应用,有一点是相同的:它们都具有交互性并且多半是数据库驱动的。在互联网中,数据库驱动的Web应用非常普遍,它们往往包含一个后台数据库和很多Web页面,在这些页面中包含了使用某种编程语言编写的服务器脚本,而这些脚本则能够根据Web页面与用户的交互从数据库提取特定的信息。
数据库驱动的Web应用通常包含三层:

1.表示层(Web浏览器或呈现引擎)
2.逻辑层(如:C#,ASP,.NET,PHP,JSP等语言)
3.存储层(如:Microsoft SQL Server,MySQL,Oracle等数据库)

Web浏览器表示层:如:Internet Explorer(IE浏览器),Safari,Firfox等向逻辑层(中间层)发送请求,中间层通过查询,更新数据库(存储层)来响应该请求。
举个例子,当我们在线购物时,我们搜索价格低于100的商品时,在URL上面通过一个GET请求显示如下:

http://www.shopping.com/products.php?val=100

当用户以这样的方式去向服务器发送请求时,可能会运行以下脚本(PHP):

//connect to the database
(连接数据库)
$conn = mysql_connect("localhost","username","password");
//dynamically build the sql statement with the input
(使用输入动态构造的SQL语句)
$query = "SELECT * FROM Products WHERE Price < '$_GET["val"]' "
         "ORDER BY ProductDesription";
//execute the query against the database
(对数据库进行查询)
$result = mysql_query($query);
// iterate thought the record set
(迭代浏览)
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
      // display the result to the browser
      (展示结果在浏览器上)
      echo "Discription : {$row['ProductDescription']} <br>"
         "Product ID : {$row['ProductID']} <br>"
         "Price : {$row['Price']} <br><br>";
}

接下来的代码更清晰地说明了PHP脚本构造并执行的SQL语句,该语句返回数据库中所有价格低于100的商品,之后在Web浏览器上显示并呈现这些商品以方便顾客在预算范围内继续购物

SELECT *
FROM Products
WHERE Price < '100.00'
ORDER BY ProductDescription;

简单的应用架构:
数据库驱动的Web应用通常包含三层:表示层,逻辑层,存储层
简单的三层架构

1.3 理解SQL注入

SQL注入是一种将SQL代码插入或者添加到应用的输入参数中的攻击,之后再将这些参数传递给后台的SQL服务器并加以解析执行。凡是构造SQL语句的步骤均存在被潜在攻击的风险。如果Web应用未对动态构造的SQL语句所使用的的参数进行正确性审查(参数化技术)那么攻击者就很可能会修改后台SQL语句的构造。如果攻击者能够修改SQL语句,那么该语句将与应用的用户拥有同样的运行权限。
当使用SQL服务器执行与操作系统交互的名利时,该进程将于执行命令的组建(数据库服务器,应用服务器/Web服务器)拥有相同的权限。

示例:

http://www.victim.com/products.php?val=100

注:这里为了方便演示URL参数的构造,使用GET传参。
这里我们尝试输入参数val插入自己的SQL命令:

http://www.victim.com/products.php?val=100'OR'1'='1

这次,PHP脚本构造并执行的SQL语句将忽略价格而返回数据库中的所有商品。这是因为修改了查询逻辑。添加的语句导致查询中的OR操作符永远返回值为真。从而出错。

构造的查询语句:

select *
from ProductsTb1
where Price < '100.00' OR '1'='1'
order by ProductDescription;

这里就可以看到单引号闭合的问题;如果该应用可以使用CMS会出现什么情形呢?CMS是一种Web应用,用于为Web站点创建,编辑,管理及发布内容。

 可以构造这样的payload查看:
http://victim.com/cms/login.php?username=foo&password=bar'OR'1'='1

这样通过修改查询逻辑,返回了所有的userid。添加的语句导致查询中的OR操作永远返回真。

总结:

1.什么是SQL注入?
答:SQL注入是一种通过操纵输入来修改后台SQL语句已达到利用代码进行攻击目的技术。
2.是否所有数据库都容易受到SQL注入攻击?
答:根据情况不同,大多数数据库都易受到攻击。
3.SQL注入漏洞有哪些影响?
答:这取决于很多因素。例如:攻击者可潜在操纵数据库中的数据,提取更多应用运行范围之外的数据,并可能在数据库服务器上执行操作系统命令。
4.如果有人故意在输入中添加一个单引号字符,代码会如何执行?
答:SQL数据库将单引号字符解析成代码与数据间的分界线;假定单引号外面的内容均为需要运行的代码,而用单引号括起来的内容均为数据。
5.如果Web站点禁止输入单引号字符,是否可以避免SQL注入?
答:不能,可使用很多种方法对单引号进行编码,这样就能将它作为输入来接受。有些SQL注入漏洞不需要使用该字符。此外,单引号字符并不是唯一可用于SQL注入的字符。攻击者还可以使用很多种其他字符,比如双竖线"||"和双号字符等" " "等。
6.如果Web站点不适用GET方法,是否可以避免SQL注入?
答:不能,只要在将输入传递给动态创建的SQL语句之前未经过验证,就容易潜在的受到攻击,除非使用参数化查询和绑定变量。

最后修改:2022 年 03 月 12 日 11 : 45 PM
如果觉得这篇文章不错,不妨赏我碎银几两。