对于经常玩SQL Injection的朋友来说,对于字符的猜解,通常是一件枯燥、乏味、痛苦的事情,特别是中文字符的探测。一遍遍的输入,然后又一次次的被否决。不过,据说这对于耐心的培养是一个非常好的办法。这时,你有没有想过自动注入呢?请看我写的文章SQL Server数据信息自动探测。(做个广告,别扔鸡蛋,不然我今天晚上就不用吃饭了。)
SQL Server中的汉字猜解
在SQL Server中,中文的ASCII为正数,但由于是UNICODE的双位编码,不能用函数ascii()取得ASCII码,必须用函数unicode ()返回unicode值,再用nchar函数取得对应的中文字符。
在探测出SQL Server中的汉字的Unicode编码后,如何知道相应的汉字呢?用工具,我现在没有找到。经过研究,我找到了3种解决办法。
1.在注入地址后添加“and nchar(猜解汉字的unicode编码)>0”,例如:http://www.xxx.com/id=1 and nchar(20013),由于nchar()函数返回值类型为nvarchar,拿一个 nvarchar的值跟int的数与0比较,系统会先试图将nvarchar的值转成int型。当然,转换的过程中肯定会出错,SQLServer的出错提示是这样的:
Microsoft OLE DB Provider for ODBC Drivers 错误 ’80040e07’
[Microsoft][ODBC SQL Server Driver][SQL Server]将 nvarchar 值 ’中’ 转换为数据类型为 int 的列时发生语法错误。
2.使用SQL Server。所谓的“解铃还需系铃人”,可能就是这个道理吧。通过SQL Server的查询分析器、或者企业管理器,我们构造查询条件select nchar(20013),执行查询操作,看到查询结果了吗?
3.使用字符对照表。这是本文的重点,也是SQL Server自动注入中必须解决的一个重要课题。
我们知道,任意一个汉字的Unicode编码是唯一的,其GB18030码也是唯一的,不然的话同一个编码表示N多汉字,你知道是什么吗?那么同一个汉字的Unicode编码和GB18030码有什么关系呢?相等?那还用这么麻烦吗,直接转化成汉字不就得了。我们暂且不管它们之间有什么关系,也不用知道有什么关系,只要清楚同一个汉字有唯一的Unicode编码,其对应的GB18030码也是唯一的就可以了。也就是说,知道了一个汉字的Unicode编码,可以唯一对应一个GB18030码,通过GB18030码,现在我们就可以查找出原来的汉字了。
关于Unicode与GB18030对应码表,你可以在http://www.uighurlinux.org/download.htm
下面我们的任务就是把这个Unicode与GB18030对应码表为我所用,转换成为Unicode- GB18030-汉字对应表。这儿我要说明一点,对于四位的GB18030码,十六进制的转换成十进制后用chr(数字)可以直接得到相应的中文字符(包括ASCII字符),但对于八位的GB18030码,举个例子如82328D35,我至今不知道是什么东东。还好,它不影响我们对中文字符的猜解,因为四位的十六进制GB18030码已经包含了足够多的汉字,至少到现在为止,我还没有遇到猜不出来的汉字。对于具体的转化过程,不就不在这儿罗嗦了,我把它放在附加文档中了,还包括了我已经转化好的正在使用中的对照表,Access格式的。
有了 Access格式的Unicode-GB18030-中文字符的对照表,我们现在就可以在自动注入程序中查询汉字Unicode编码所对应的汉字了。方法很简单,下面是我在自动注入的时候查询对照表的程序代码,注意我写注释的那几行。
Function Get_Field_Name(iUrl,Flen)
dim conn , i,rs,ch,SQL,result,char
result=""
set conn=GetConnection(server.MapPath("UnicodeMap.mdb"),"") ‘打开对照表数据连接
For i= 1 To Flen
ch=GetChar(Replace(iUrl,"[POS]",i),0,65535,0)
SQL="select chr from GB18030 where DU="&ch ‘查询注入时获取的unicode码的中文
set rs=get_rs(conn,SQL,1)
if rs.recordcount=1 then ‘找到对应的中文,包括ASCII
char=rs(0)
else
response.write “没有相应的字符”
resoponse.end
end if
result=result&char
rs.close
set rs=nothing
Next
conn.close ‘关闭数据连接
set conn=nothing
Get_Field_Name=result
end Function
补充一点,对于SQL Server中汉字的Unicode编码的获取,在我的SQL Server数据信息自动探测一文中已经介绍得非常清楚了。16次,也只有16次判断,我们就可以确定任何一个汉字的Unicode编码。