通行证│用户名: 密码: 验证码: 验证码,看不清楚?请点击刷新验证码 电信网通铁通移动   在线
文章搜索:
热门搜索:红客 黑鹰 红客技术 安全动画 红客培训
首页 文章 软件 动画 资源 励志 论坛 邮箱 会员 军事 科技 博客 爱心红客 最近更新 800g资源
 业内新闻 漏洞公告 病毒公告 电脑知识 网络知识 菜鸟入门 攻防教程 黑客攻防 安全编程 工具使用 综合安全 个人安全 安全相关 Q Q安全 原创精华 红客人物 站内事件
您现在的位置: 爱国者安全网 >> 文章类 >> 红客教程 >> 网络攻防 >> 文章正文
SQL元数据注射和解决方案
责任编辑:酷酷の鱼   更新日期:2008-3-25
 

来源:安全中国

SQL元数据注射和解决方案
Author : kj021320
Team : I.S.T.O
台上 kj021320穿着一套便服,一点都不像安全技术人员...
台下一群 黑客 骇客 红客 白客 砍客 蓝客 灰客 漂客...
还有一堆开发工程师和架构师 貌似很期待的在听课,接收kj021320的培训
kj021320 : hi,大家好...今天我要跟大家一起讨论的是SQL注射...
台下一片郁闷声响起
有位骇客郁闷道 : 哎~咋又是注射!现在都快绝种的了啊!大企业都用JAVA DOTNET参数绑定,其他的公司都过滤了单引号,数字的就进行类型转换,哪来注射啊?大哥!...
kj021320 : .... ....
kj021320 : 只要使用了变量绑定就不存在注射了吗?就不用关注这方面的了?
开发工程师 : 废话!你到底懂不懂预编译的啊?
kj021320 : .... ....
kj021320 : 大家如果有兴趣了解预编译的细节,可以去google yahoo 找找 <<窥探SQL预编译内幕>>,这是偶写的烂文大家多多提点。
听到这里,台下开始认真重视起来了!kj 稳定一下在座的情绪继续说
kj021320 : 现在的企业WEB应用随着需求越来越复杂,新的安全问题也在诞生,那么我们的安全解决方案跟上这些脚步没有呢?我接下来分析SQL注射的问题
kj021320一边在 黑板上画一边说
现在来回眸一下 过去比较土的SQL注射攻击
下面一段代码
<%
id=request("id")
title=request("title")
sql="select * from news where id=" & id &" and title=’" & title & "’"
...
%>
这样的代码一看不及格了就不多说
后来又有人把这样的SQL注射攻击分类为 字符串 和 数值 , 然后总结出过滤转换规则
<%
id=cint(request("id"))
title=replace(request("title"),"’","’’")
sql="select * from news where id=" & id &" and title=’" & title & "’"
...
%>
再过了段时间,又有新的提倡使用参数绑定,乃至今天
以下为 JAVA 代码
PreparedStatement ps=con.prepareStatement("select * from news where id=? and title=?");
ps.setInt(1, id);
ps.setString(2, title);
ResultSet rlst=ps.executeQuery();
后来大家都很放心的认为,采用了预编译SQL 就不会再有注射出现...
其实隐患才刚刚开始...
现在WEB应用越来越复杂,讲求的是网站重构,代码重用,可能3句话的东西,现在整合为1句话!
例如以下的方式
<%
id=cint(request("id"))
title=replace(request("title"),"’","’’")
sql="select * from news where id=" & id &" and title=’" & title & "’ order by posttime"
...
sql="select * from news where id=" & id &" and title=’" & title & "’ order by updatetime"
...
sql="select * from news where id=" & id &" and title=’" & title & "’ order by viewcount"
%>
整合为
<%
id=cint(request("id"))
title=replace(request("title"),"’","’’")
orderCol=replace(request("order"),"’","’’")
sql="select * from news where id=" & id &" and title=’" & title & "’ order by "&orderCol
%>
很容易就能看到以上是存在攻击的,不多说!而在预编译SQL中可以使用类似过滤吗?
"select * from news where id=? and title=? order by ?"
kj021320 : 哈呵嘻噶!
台下有开发工程师摇摇头...
kj021320 : 那么你们是怎么写代码的啊?
开发工程师 : ps=con.prepareStatement("select * from news where id=? and title=? order by "+order);
kj021320 : 所以问题就出现了...(SQL注射,我们又见面了),那么该如何修补呢?
开发工程师 : ..... .....
架构师 : 是不是可以将order by 的字段放到一个 list里面 ,然后每次传进来的时候,判断变量是否包含在list里面,这样就OK了啊!
kj021320 : 很好非常好,这是一个很简单的解决方案!但是如果表结构将来会变化,或者现在需要按3个字段来排序,但是以后因为业务需求,要求加入更多的排序字段呢?.....
kj021320 : 那你就负责维护那个白名单的LIST吗?或者说,不局限于这个order by 有可能在 group by 或者 count max length 这些里面需要动态更换
架构师 : ..... .....
台下有位漂客老听着这些解决方案有点郁闷,大声问道
漂客 : 这样的SQL注射可以带来什么样的攻击啊?或者可以怎么利用
kj021320 : 把字段直接换为 攻击的函数,或者一段SQL语句
kj021320 : 例如 getNews.asp?order=2;drop table admin--
骇客 : 那我知道怎么利用这样的攻击了!(阴阴的笑~) 不过现在好象没有注射工具支持这样的猜解以及攻击,包括NBSI HDSI CASI PANGOLIN .. 
kj021320 : 呵,自己动手丰衣足食,手动无敌...
开发工程师&架构师 在一边郁闷,不明白kj021320跟骇客们在说什么东西
kj021320 : 言归正传...那到底用什么样的方式更好的解决呢!在这里考考 架构师和开发工程师一个问题!
kj021320 : 如果我需要建立一个表,表名字为 KJ 021320 中间有空格,那么在MSSQL里面怎么做呢?
开发工程师 : ~~~~恩~!好象是用 [] ,用个中括号罩着,create table [KJ 021320] 这样!
kj021320 : 对! 但是我不建议使用这样的方式,更提倡使用 " 双引号,例如 create table "KJ 021320" ,都能理解吧?
大伙都齐口回答 明白
kj021320 : 那么,现在攻击者会尝试绕过,例如 select * from news order by "id" ,攻击者有可能输入双引号怎么办呢?
开发工程师 : ................ 没想过!
架构师 : 两个转换为一个 select * from news order by """id"
kj021320 : 很好很强大... 那么现在我们来总结一下 关于这类型注射的过滤规则和防止方案
kj021320又在 黑板上画
1. 针对接收回来的参数进行替换
例如:
<%
order = """" & replace(request("order"),"""","""""") & """"
sql="select * from news order by " & order
%>
2. 针对预编译的修改
( 这里介绍JDBC 其他的ADO.NET可以参考着做 )
我们可以对 PreparedStatement Connection CallableStatement 重新封装,我提供思路
Connection con = DriverManager.getConnection(url);
SecurityConnection seccon=new SecurityConnection(con);//封装的安全连接类
SecurityStatement sstmt=seccon.prepareStatement("select * from news where id=? and title=? order by ?");//封装过的安全statement类
sstmt.setColumn(3,order);//新加入的方法 动态设置字段 其内部实现也是 采用替换
刚刚看了MSSQL是可以用双引号",MYSQL 是采用反引号`来转义的 而ORACLE是用 双引号" , 其他的数据库可以参看对应的官方文档,所以需要对证下药,因为现在的数据库驱动包没提供解决方法需要自己实现...
kj021320 : 这个问题 完满的结束...
开发工程师 : 现在的SQL注射就只需要解决这个问题吗?
kj021320 : NO,现在的应用开始BT起来,很多东西不可取的都应用起来了...
kj021320 : 下面需要介绍另外的语法上面的SQL注射以及解决方案
架构师 : 哦? 还有?
kj021320又在 黑板上画
因为有业务需求,需要动态使用排序的方式例如:
<%
orderByType = request("orderType")
sql="select * from news order by time "& orderByType
%>
以上即使 替换了 " 也会有问题,而且不能够加入 类似 " " 这样的标识符过滤方式
类似这样的应用例如 在 模糊查询跟 直接查询之间的切换
<%
selectType = request("seltype")
sql="select * from news where title " & selectType & " ? "
%>
这个查询类型可以为 like 可以为 = <> 等等
类似这样的传递有点BT, 为了满足开发人员的需求以及欲望
这里只能把SQL92标准 SQL3标准 以及当前数据库应有的 保留关键字 放入一个清单里面
然后逐一判断
ASP
<%
sqlkeywords = "select,union,asc,desc,in,like,into,等等"
selectType = request("seltype")
if not inkeywords(selectType) then response.end ’ inkeywords自己实现循环判断的函数
sql="select * from news where title " & selectType & " ? "
%>
JDBC
Connection con = DriverManager.getConnection(url);
SecurityConnection seccon=new SecurityConnection(con);//封装的安全连接类
SecurityStatement sstmt=seccon.prepareStatement("select * from news where id=? and title=? order by ? ?");//封装过的安全statement类
sstmt.setColumn(3,order);
sstmt.setKeyWord(4,orderType);
OK问题解决...
kj021320 : OK,很好很完美!
开发工程师在钻牛角尖
开发工程师 : 我记得ORACLE里面可以使用注释来说明SQL语句运行的方式的,那么...
kj021320 :对,具体可以参看这里 http://blog.csdn.net/I_S_T_O/archive/2008/02/15/2096228.aspx 获取更多的技术资料
kj021320自以为是的举例子说明
kj021320 : 例如在ORACLE中 SELECT /*+ PARALLEL(kj,4) */ COUNT(*) FROM kj 这样子可以让ORACLE调用4个CPU来处理这个SQL语句,那又有什么问题呢?
开发工程师 : 我想让里面的注释里面可以动态更换
开发工程师 : 例如 insert /*+ append*/ into kj select * from kj021320 不用日志形式,或者 insert /*+ PARALLEL(kj,2)/ into kj select * from kj021320 并发方式
kj021320 : ..... ..... (kj很纳闷,有点冲动把这个开发工程师拖出去打...)
kj021320 : 对于这样的方式不允许使用,因为DBA不一定同意你随便操作SQL里的性能更换,特别是数据库操作写不写日志,采用多少个CPU来运算
kj021320 : 这个应该对于开发人员是透明的,如果需要接触到这个层面,应该由DBA介入
OK现在来回顾一下今天所讲到的问题:
1. 数据库内对象的动态更变,例如一些字段名,表名,视图等,需要采用对应数据库的标识符来转义以及限制
2. 对于结构体内的动态更换,采用SQL标准的保留关键字进行约束

  • 上一篇文章:
  • 下一篇文章: 没有了
  • 最近更新
    固顶文章 Delphi编程培训班开课了
    普通文章 瑞星公司03月25日发布 每日计算机病毒及木马播报
    普通文章 巧用Windows命令 拒木马于"千里之外"
    推荐文章 推荐:网络时代个人电脑防黑安全准则
    普通文章 防范邮件病毒禁止非法程序暗中发送
    普通文章 SQL元数据注射和解决方案
    普通文章 风险评估应用技术和工具初探
    普通文章 网络嗅探Sniffer原理应用详解
    普通文章 Php注入原理
    普通文章 Belkin Wireless G Router绕过限制 拒绝服务漏洞
    热门文章
    普通文章“线上游戏窃取者变种MKU”病毒技术细节
    普通文章病毒专杀革新 用户定制杀毒软件
    普通文章IT头条:iPhone2.0未发布 黑客称已破解
    普通文章RealPlayer建议用户停止使用IE
    普通文章印度政府可能清除黑莓手机
    普通文章360木马周报:“磁碟机”带病毒特征
    普通文章哈佛大学服务器被黑 个人信息现身BT
    普通文章计算机在中毒后的五大紧急处理措施
    普通文章电脑菜鸟必懂 常见木马连接的原理
    普通文章拔营起寨 插入式木马的清除方法!
    精彩专题