Web Exploits - Don’t be a victim
| Code: |
| This excellent tutorial is the work of NTSA, who has very kindly consented to the TAZ hosting it.Enjoy! |
Web Exploits - Don’t be a victim
Overview
There are three things to remeber about web programming security that you have to bear in mind when designing your applications. These are, respectively, validation, validation and validation. The first thing a cracker will do to your site is to see where it breaks.
(note: Cracker is the correct use of the term here. Hackers build things, crackers break things)
| Quote: |
| Most real hackers think that crackers are lazy, irresponsible and not very bright and object that being able to break security no more makes you a hacker that being able to hotwire cars makes you an automotive engineer Eric Raymond |
Common exploitative techniques
First Johnny Cracker will browse your site until he finds a script that accepts GET input in the format:
| Code: |
| scriptname.ext?parameter=value |
More experienced crackers will also be able to use the same sort of explotative techniques to attack scripts that accept POSTed variables, so don’t assume that POSTing form data will deter a serious cracker (but it might exclude some of the more lame kiddies). For the examples in this tutorial I’m going to stick to basic GETs however.
Next our cracker will play with the URL to see what he can get to break. For example:
| Code: |
| scriptname.ext?parameter= |
If our script does not validate that the parameter has been passed then this will likley generate an error. If our code contains an SQL statement that looks like this:
| Code: |
| set myRS = cn.execute(”select * from pubs where parameter=” & request(”parameter”)) |
then the cracker will get an error message containing the SQL statement and probably some infomation about the physical location of the script on the server. These are not good things to be giving out to Johnny Cracker.
TIP: In IIS and Apache it is possible to stop the server sending detailed error messages to the client (in IIS this is under application/debugging). Whenever you are not actively debugging your application you should ensure that this option is checked. Otherwise every error message is a bit more information for Johnny Cracker to work with.
Let’s say our cracker is malicious - They now know that we have a table called pubs in our database. They can now rework the URL to include SQL stuffing like this:
| Code: |
| scriptname.ext?parameter=1;delete * from pubs |
Bye-bye pubs table. Our code above will assume that everything after the semi-colon is another SQL query and run it with the same permissions that were set up to run the first query. If those permissions were to the master database of an MSSQL database then the cracker now has access to all the stored procedures, including xp_cmdshell to run programs from the command line, xp_sendmail to mail himself the contents of your tables etc.
TIP:Never connect a web script to the master database of a MSSQL server. Never run your web page scripts from an administrative account.
Overcoming these techniques through validation
In both of these instances we could have stopped these attempts with proper validation. For example if we had nested our SQL statement in the following clause:
| Code: |
| IF NOT (Len(request(”parameter”)>0 AND INSTR(LCASE(request(”parameter”)),”delete”) =0) THEN …Whatever… END IF |
then our cracker would not have been able to perform either of the above ‘exploits’.
Now re-writting these validation sequences for each of your scripts is a real waste of time and can really get quite tedious. Me personally I prefer to throw each of my validation sequences into a class that I can re-use time and again.
NTSA’s Validation script
Don’t try to copy and paste this script (not least because it’s taken from one of my ActiveX controls and probably won’t run as is in ASP). I am including it in this tutorial only as an example of what YOUR validation class might include - mine is tied into a number of sub classes that I’m not including here (debugging classes, INI file class,etc), but you can get the gist of what I’m doing. This class encapsulates all my validation routines and on completion allows an array of reported errors to be passed back to the calling script for display to the user.
You would call the routines in this class like this:
| Code: |
| Dim ers As Boolean Dim Er As Varianters = False Validate.ClearErrors Validate.BadWordsINI = “c:\badwords.ini” If ers = True Then |
The Class file
| Code: |
| Enum etType tInteger = 0 tDate = 1 tEMAIL = 2 tNoSpaces = 3 tRequired = 4 tPassword = 5 tNotObscene = 6 tNotHTML = 7 tNotSQL = 8 tLUHN = 9 End EnumDim Errors() ‘Default Property Values: Const m_def_BadWordsINI = “” ‘Property Variables: Dim m_BadWordsINI As String Private Sub UserControl_Initialize() Private Sub UserControl_Resize() Public Function IsValid(tName As String, Tron.Trace “Validate”, “Evaluating [” & tValue & “] as type ” & _ Select Case LCase(Trim(tType)) Case tDate Case tEMAIL Case tNoSpaces Case tRequired Case tPassword Case tNotObscene Case tNotHTML Case tNotSQL Case tLUHN End Select Select Case IsValid End Function Private Sub ReDimErrors(tName As String, tErrDesc As String) Dim Rec() ‘ Select Case MyArrayCls.UboundC(Errors) ReDim Rec(1) End Sub Public Function ClearErrors() Public Function GetErrors() As Variant Private Function AllowedChars(CheckString As String, Dim l As Integer For l = 1 To Len(CheckString) End Function Private Function TypeDescription(TypeVal As Integer) As String Select Case TypeVal End Function Public Property Let BadWordsINI(ByVal New_BadWordsINI As String) ‘Initialize Properties for User Control ‘Load property values from storage m_BadWordsINI = PropBag.ReadProperty(”BadWordsINI”, m_def_BadWordsINI) ‘Write property values to storage Private Function IsObscene(tValue As String) As Boolean Dim BWCount As Integer IsObscene = False Tron.Trace “Validate”, “Checking message: ‘” & tValue & “‘” If InStr(NoSpaces, “fuck”) > 0 Then tValue = ” ” & tValue If Not Len(m_BadWordsINI) = 0 Then INIFile.CloseINI bwc1 = UBound(badword) badwords = “” Tron.Trace “Validate”, “Pass 1 - Checking for all words…” If bwc2 > -1 Then testbw = ” ” & badword(BWCount) ‘Trace( “NoSpaces:” & nospaces) If LCase(Mid(NoSpaces, 1, Len(testbw))) = LCase(testbw) Then Next Private Function ContainsHTML(tValue As String) As Boolean If InStr(tValue, “<”) > 0 Then End Function Private Function ContainsSQL(tValue As String) As Boolean tValue = LCase(tValue) If InStr(tValue, “delete”) > 0 Or InStr(tValue, “select”) > 0 & _ End Function Private Function LUHNCheck(CardNumber As String) As Boolean Dim N, tot, x, chk, checkdigit If Len(CardNumber) = 0 Then tot = 0 For N = Len(CardNumber) To 1 Step -2 For N = Len(CardNumber) - 1 To 1 Step -2 ‘debug tot checkdigit = CInt(CStr(CInt(Left(CStr(tot), 1)) + 1) & “0″) - tot Tron.Trace “Validate”, If CInt(chk) = CInt(checkdigit) Then End If posted by nokia |
admin @ April 19, 2008