by   April 23 2015   
When Scripting that old ASP page from that soon to be out of life support Server 2003 you might need to review your SQL Injection Practices. I bet if you're still on Server 2003 you still have some old SQL issues. Or maybe not. I am sharing a few methods of handling Forms and Query strings that might help you. If you have questions, google plus them to me.

I Want to Screw up Script Kiddie SQL Injection Scripts!

I'm so glad you're thinking the right way and not working too hard at controlling your SQL Script Kiddies. 

I'm going to share with you my basics which I use on live sites and all API feeds my sites generate for anything that touches my SQL Database. 

First of all, look at your QueryStrings. 

Is it the classic ?q=Test+One+Two+Three ?

If so you're in luck. 

No, let's have fun and change ?q= to ?c= but really it's still Q=. 

First, let's write the Encode part.

You can do this in your .Net as well.

Function EncodeQueryString(str)
'# Simple ASCII Shifting method
Dim strS,strSOut,i
strS = Trim(str)
strSOut = ""
For i = 1 To Len(strS)
strSOut = strSOut + Chr(Asc(Mid(strS, i, 1)) - 1)
Next
'Google doesn't like a ' in URL so lets play change for Sir Goolge.
If InStr(strSOut,"`") >= 1 Then
strSOut = Replace(strSOut,"`","(MnW)")
End If
EncodeQueryString = strSOut
End Function

So what we really do is encode your full query string. Not to worry about having more than one querystring variable. We are looking to make one single string that once encoded injection has to be encoded the same or the ASCII shift will break the Injection script. (Sort of)

 Here's how you encode: 

Let's say you have a product menu that creates Dynamic QueryString Product Categories. 
That link directs you to products with links to their product details. 

If you have products.asp?prod=XYZ 
You know encode that full string as products.asp?q=<%=EncodeQueryString(URLEncode(prod=XYZ))%>

Now that you've applied your offset and then made it Good to Go in your URL you'll see something like:

products.asp?q=gssor$2@$1E$1E(MnW)oh$1Db(MnW)qddqathkcdq$1Dbnl$1Eu0$1Eina$2ECHC$2CIGR36K5V433JBU67G7Y$15GnrsRhsd$2CTR$15CdudknodqJdx$2CVCGK1J854JBLYJA7WEOI

Now, inject anything you would like because the next time that querystring is seen by anything at all is on the side of a "URLDecode" and a DecodeQueryString ASCII Offset shift. 

If you would like, and I do this on some of my more script kiddie versions I MD5 encode them but that's a bit much, the idea is we are going after those automated scripts that look for classical SQL weaknesses.

Nothing Classical here other than ASP Classic which I kind of like.

Function DecodeQueryString(str)
'# Simple ASCII Shifting method
Dim strS,strSOut,i
strS = Trim(str)
strSOut = ""
If InStr(strS,"(MnW)") >= 1 Then
strS = Replace(strS,"(MnW)","`")
End If
For i = 1 To Len(strS)
strSOut = strSOut + Chr(Asc(Mid(strS, i, 1)) + 1)
Next
DecodeQueryString = strSOut
End Function 

Now, I have tested it with some very long SQL Strings. 
You might want to put a counter which I use as a checksum so the loop doesn't go as long as the actual SQL String only as long as your string. 
Prior to the DecodeQueryString = strSOut do this but you must have the length set prior.
I place a dummy query just after my length so I know what it should be. In the example it's abc= 

During your Encode Phase add a query &QLen=Len(str) any place in your string.

During decode before the output run this. 

Function MyStrLen(str)
Dim j,strSQlenOut
MyStrLen = 0

If InStr(str,"QLen=") Then
j = InStrRev(str, "QLen=")
if j > 0 Then
strQLenOut = Mid(str, j+5)
end if
j = InStr(strQLenOut, "abc=")
if j > 0 Then
strQLenOut = Left(strQLenOut, j-3)
End If
If IsNumeric(strQlenOut) Then
MyStrLen = strQLenOut
End If
End Function

As you can see, if the string len isn't set it's 0 which then in your code would trigger a "No, Data To Process" response. 

If they Scripted before your encoding the length would be a number maybe but it's not going to be correct. What you would do is place a check to the length. The function above gives you a numeric value, you then need another script to compare the numeric value to the actual full string length. (It's easier than I just explained it.)

What you end up with... 

With this I'm not do any major SQL Injection compare in string functions or processes.
I could if I felt you could actually offset to match my office and my specific character replacements with groups.
But I could after this encode it into HEX which would require.

If InStr(str,"0x") > = Then

Now, this one I like, you would do all the above but before you off-shift the ASCII you would HEX encode it. Now those smarter Scripting Kiddies Hex would be offset and would completely mess up the designed goal. 

Following me?

Function CHexToS(strHexS)
Dim intLS
Dim intC
Dim strB

If Len(strHexS) Mod 2 = 0 Then
'Do Notta
Else
strHexS = strHexS & "4"
End If

If Len(strHexS) = 0 Or Len(strHexS) Mod 2 <> 0 Then Exit Function

intLenS = Len(strHexS)
For intC = 1 To Len(strHexS)

If intC Mod 2 <> 0 Then
strB = strB & Chr("&H" & Mid(strHexS, intC, 2))
End If

Next
CHexToS = strB
End Function

With the above you have converted your QueryString back to HEX for internal server side work. 
Really messes with the Scripting Kiddies. 

You can go and and on. 

I like to mix a few things up, say let's go for a Form Submit. 

We all know Captcha and some learn to hate it. 
I setup Captcha Numbers with a Math Question and others use Pictures or simple questions. People Like it better, But, from time to time something goes wrong and the people complain. 

I haven't had spammy stuff but users often are set back by it all. 

So, if you have a form try the API approach to processing. 

Example: 
Email: Form.Email="Email"
Name: Form.Name="Name"
Message: Form.Msg="Msg"

Submit to a page processing.asp

Dim strEmail, strName,strMsg
strEmail = Request.Form("Email")
strName = Request.Name("Name")
strMsg = Request.Form("Msg")

You could just email it to yourself but this example is to store the message to your server. Why would I put an email form under SQL Injection anyway? (humor)

Now, do your encoding magic. Store the string in blocks if you think that will matter. 
I have some forms setup to store the encoded strings in blocks of 25. 

gssor$2@$1E$1E(MnW)oh$1Db (MnW)qddqathkcdq$1Dbnl$1E u0$1Eina$2ECHC$2CIGL2BU5C 3FLMQI7LVBA$15GnrsRhsd$2C TR$15CdudknodqJdx$2CVCGK1 J854JBLYJA7WEOI

I store them in simple nvarchar tables as many or as few as I would like. I decode by joining them and the decode is on a API output. 

Sounds like work doesn't it. 
Well, if you venture into my Security Section you'll see the codes I've picked up. (I don't bother with it anymore)

The only way I can store harmful scripts is to encode them so my SQL doesn't get harmed. 

If you're interested I'll post some of the more complex functions that capture more than just a few scripts. 

The goal is to respond with a good Page Status = 200 which will if the script kiddie knows their stuff make your IP address not their favorite. 

It also works as a great way to find your weakest pages. Kind of like paying for a scanning service. 

 

 

When Scripting that old ASP page from that soon to be out of life support Server 2003 you might need to review your SQL Injection Practices. I bet if you're still on Server 2003 you still have some old SQL issues. Or maybe not. I am sharing a few methods of handling Forms and Query strings that might help you. If you have questions, google plus them to me.