What is NV32ts and its SQL Injection Attack trying to do? - sql-server

I have been getting a number of attacks on my website lately, with a User-Agent of NV32ts.
They all are some variation of the following injection attacks against a querystring variable (where 99999 represents a valid querystring value, the attack is appended to the value):
(For convenience I have urldecoded the following attacks)
999999 And char(124)+(Select Cast(Count(1) as varchar(8000))+char(124) From [sysobjects] Where 1=1)>0
or
999999' And char(124)+(Select Cast(Count(1) as varchar(8000))+char(124) From [sysobjects] Where 1=1)>0 and ''='
or
999999' And char(124)+(Select Cast(Count(1) as varchar(8000))+char(124) From [sysobjects] Where 1=1)>0 and ''='
I believe that sysobjects has something to do with the Sql Server master database, but I can't figure out what they are trying to accomplish.
Edit:
I have now seen these same things with two different user agents:
NV32ts
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1; InfoPath.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.30; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022; WWTClient2)

I read this one two ways, but I'm not 100% sure which:
At this point they're just fishing. The script is looking for web sites that have both open injection vulnerabilities and access to the sysobjects table in sql server. That table will provide a list of all tables and columns (and their types) in the database. If the page actually returns a result rather than throwing an error, the script will log that for a future more detailed attack. You'll eventually end up with malicious javascript code appended to every text (varchar, nvarchar, char, nchar, text) column of every row of every table in the entire db. I think this is the more-likely option.
It creates an expression that will always return true, perhaps allowing them bypass your authentication system. This seems less likely, because the sysobjects reference makes it needlessly complex. Also: they used And rather than Or.

I believe what they are trying to figure out here is if your application is vulnerable to SQL Injection.
The Char(124) translates to the | character which forces the whole query result to be seen as the result of the query with two pipes attached. So you end up with the number of tables in your database with two pipes attached (ex. |1428|). Which when compared to 0 in the > 0 causes an error because |1428| is not an int.
So if your application is open to SQL Injection they now know it (because the valid parameter value caused the application to err). They might also know that you have bad error handling if they SQL database error bubbles up to the top. If you do have bad error handling they also know how many tables you have (not sure what good that does them but the more information the better).
A lot of SQL injection attempts are really meant to cause your application to fail in order to know that you are vulnerable. If you do handle errors well they may then attempt to blind SQL inject you.
Check out this to see that in detail.
I hope that you are not vulnerable, and if you are good luck!

HP has a free tool you can run to check if your site (or any site) has SQL Injection vulnerabilities called sdrawlr.
You can download it here:

Related

How can I observe the effect of SET CONCAT_NULL_YIELDS_NULL off?

We have an old database product; the master deployment has always done ALTER Database [databasename] SET CONCAT_NULL_YIELDS_NULL OFF. Since this setting is going away, we want to come up with a testing plan for getting rid of it and tracking down what code depends on it.
With this switch off, the documentation says that SELECT 'abc' + NULL FROM sometable results in abc rather than NULL.
I can easily observe this behavior at the connection level; however the application never sets it at the connection level. That's not the question here.
How can I observe by any SQL statement the effect of turning off CONCAT_NULL_YIELDS_NULL only at the database level using .NET System.Data.SqlClient as the database access client?
We audited the entire codebase and removed all instances of SET commands except for transaction isolation level as these hose things pretty hard. While I tried EXEC to see if it would bypass the driver settings and found it didn't, I'm reasonably certain there's some sufficiently exotic SQL construction that could succeed.
I think I have finally understood what you actually want: to change the connection option without changing it. No, there are no ways to achieve this, otherwise I would have heard about them, and Rutzky would have mentioned them in his answer I referenced in my original response.
There is a strict hierarchy in a way the options can be set:
Instance-wide settings for all databases, using sp_configure 'user options'. Lowest level defaults.
Database-specific options which can be set via ALTER DATABASE. Take precedence over instance defaults.
Explicit SET statements executed on the connection. Override everything.
The advice? Change the application' connection string, if you can, so that it would use another driver that doesn't set / touch this option. Assuming, of course, it wouldn't crash anything, but this is a thing which can be tested relatively quickly.
Also, you may try to change the instance defaults, and see if the driver somehow favours them over #2. It is possible that it can be too smart for its own good.
P.S. For the sake of completeness, the only cases of interdependent options that I know of are listed below:
Shortcut settings, for example ANSI_DEFAULTS. Setting it actually affects several options related to ANSI compatibility;
SET LANGUAGE. When you change the connection language, it also overrides the DATEFIRST and DATEFORMAT options.
P.P.S. I decided to leave my previous answer intact, as it still contains some info which might be useful for people who would understand your question the way I initially did.
Even if your application doesn't specify this option explicitly, different ODBC and OLEDB drivers have different defaults for connection options. Depending on the driver, this particular option can either be set implicitly, or inherited from database / server settings.
In order to see the actual state of this option for connections established by your app, you can setup a Profiler trace which will show you effective connection settings.
In regards to overriding the driver's behaviour setting this option, there is a rather thorough answer for a similar question on DBA StackExchange. There, you can find several possible approaches, and see which one suits you best.
On the SQL side, one possible solution is to replace old style + string concatenations with the newer concat() function which is available since SQL Server 2012. This function skips NULL arguments during concatenation, so the result always looks as if concat_null_yields_null is set to off. Depending on the amount of SQL code modules in your system, it might be quite an undertaking, especially as it's difficult to distinguish between numerical additions and string concatenations with a naked eye.
I would recommend to shop around for some code analysis / refactoring tools that might lend a hand in this. Not sure if SSDT has this capability, but I would start with it first, since it's free (and it might make sense to try out the Visual Studio 2019, which was released 2 days ago - there might be something there). Other than that, well... RedGate, Idera, ApexSQL, you name it. Someone might have done this already.
This can be achieved with this query
IF (SELECT ''+NULL) IS NULL
BEGIN
SET CONCAT_NULL_YIELDS_NULL OFF
END
ELSE
BEGIN
SET CONCAT_NULL_YIELDS_NULL ON
END

SQL injection attempt on my server

I know a little about SQL injections and URL decode, but can someone who's more of an expert than me on this matter take a look at the following string and tell me what exactly it's trying to do?
Some kid from Beijing a couple weeks ago tried a number of injections like the one below.
%27%20and%20char(124)%2Buser%2Bchar(124)=0%20and%20%27%27=%27
It's making a guess about the sort of SQL statement that the form data is being substituted into, and assuming that it will be poorly sanitised at some step along the road. Consider a program talking to an SQL server (Cish code purely for example):
fprintf(sql_connection, "SELECT foo,bar FROM users WHERE user='%s';");
However, with the above string, the SQL server sees:
SELECT foo,bar FROM users WHERE user='' and char(124)+user+char(124)=0 and ''='';
Whoops! That wasn't what you intended. What happens next depends on the database back-end and whether or not you've got verbose error reporting turned on.
It's quite common for lazy web developers to enable verbose error reporting unconditionally for all clients and to not turn it off. (Moral: only enable detailed error reporting for a very tight trusted network, if at all.) Such an error report typically contains some useful information about the structure of the database which the attacker can use to figure out where to go next.
Now consider the username '; DESCRIBE TABLE users; SELECT 1 FROM users WHERE 'a'='. And so it goes on... There are a few different strategies here depending on exactly how the data comes out. SQL injection toolkits exist which can automate this process and attempt to automatically dump out the entire contents of a database via an unsecured web interface. Rafal Los's blog post contains a little more technical insight.
You're not limited to the theft of data, either; if you can insert arbitrary SQL, well, the obligatory xkcd reference illustrates it better than I can.
You'll find detailed info here:
http://blogs.technet.com/b/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx
These lines are double-encoded -- the
first set of encoded characters, which
would be translated by IIS, are
denoted by %XX. For example, %20 is a
space. The second set aren't meant to
be translated until they get to the
SQL Server and they use the char(xxx)
function in SQL.
' and char(124)+user+char(124)=0 and ''='
that's strange..however, make sure you escape strings so there will be no sql injections
Other people have covered what's going on, so I'm going to take a moment to get on my high-horse and strongly suggest that if you're not already (I suspect not from a comment below) that you use parameterized queries. They literally make you immune to SQL injection because they cause parameters and the query to be transmitted completely separately. There's also potential performance benefits, yadda yadda, etc.
But seriously, do it.

Site update, testing was fine, after deployment, again fine, once user load increases, FAIL?

We are using ASP.NET MVC with LINQ to SQL. We added some features and tested them all to perfection on our QA box. We are using Windows Server 2003 and SQL Server 2005. So when we pushed out changes to the Live web server we also used Red Gate SQL Compare to push new database changes to the LIVE database. We tested again between the few of us, no problems. Time for bed.
The morning comes and users are starting to hit the app, and BOOM. We have no idea why this would happen as we have not been doing any new types of code things that we were not doing before. However we did notice that during the SQL Compare sync the names of all the foreign keys were different between the two databases, not the IDs in the tables, FK_AssetAsset_A0EB67 to FK_AssetAsset_B67EF8 (for example, don't remember the exact number of trailing mixed characters during the SQL Compare), we are not sure why but that is another variable in this problem.
Strangely once this was all pushed out we could then replicate the errors on QA, but not before everything was pushed to LIVE.
QA and LIVE databases are on the same SQL Server, but the apps are on different instances of Windows Server 2003.
Errors generated:
Index was outside the bounds of the array.
Invalid attempt to call FieldCount when reader is closed.
Server failed to resume the transaction.
There is already an open DataReader associated with this Command which must be closed first.
A transport-level error has occurred when sending the request to the server.
A transport-level error has occurred when receiving results from the server.
Invalid attempt to call Read when reader is closed.
Invalid attempt to call MetaData when reader is closed.
Count must be positive and count must refer to a location within the string/array/collection. Parameter name: count
ExecuteReader requires an open and available Connection. The connection's current state is connecting.
Any one have any idea what the heck could have happened?
EDIT: Since we were able to replicate the errors all of a sudden on QA, it might not be a user load issue... Needless to say we all feel really screwed here.
Concurrency always brings bugs out of the woodwork. I'd recommend you check for objects that could be shared among requests (such as static members and singletons) and refactor your code so that as little as possible is shared.
As far as specifics go, for the error "There is already an open DataReader associated with this Command which must be closed first," you may want to try adding MultipleActiveResultSets=True to your connection strings.
It sounds like you're crossing the streams a bit and trying to share DataContexts across requests. My suggestion would be to wire in a dependancy injection framework that creates a new instance of the dependancy for each request.
I use Castle's IoC and wire it into the controller factory so that when it sees a dependancy on a repository it creates a new instance of that repository for each request. If you go this route let me know and I can shoot you a few more resources.

parametrization in VBScript/ASP Classic and ADO

I'm a bit confused here. Microsoft as far as I can tell claims that parametrization is the best way to protect your database from SQL injection attacks. But I find two conflicting sources of information here:
This page says to use the ADO command object. But this page says that the command object isn't safe for scripting. I seem to recall reading somewhere that the command object shouldn't be used in VBScript or JScript because of security vulnerabilities, but I can't seem to find that article.
Am I missing something here, or do those two articles seem to contradict each other?
I could be wrong here, but I think this just means that someone could use the Command object to do bad things. I.e. it's not to be trusted if someone else is scripting it.
See safe for scripting in this article. Every instance that talks about this phrase online, references it as if you are marking an ActiveX control saying "This control does no I/O or only talks back to the server that it came from" but the Command object doesn't do that. It can be used to do a lot of things which could be unsafe.
The "safe" they are talking about and the "safe" to prevent from SQL injection are two different things. The article about using the ADO Command object to parametrize your data is spot on. You should do that.
And, Microsoft further confirms this here:
http://msdn.microsoft.com/en-us/library/ms676585(v=VS.85).aspx
I think "safe for scripting" means "safe to be run from a webpage we just retrieved from some Nigerian prince". The command object should be safe to run on the server.
At work though, back in the day my colleagues didn't trust it so we had an in-house framework that basically did the same thing.

VBScript/ASP Classic

I have a couple of questions regarding VBScript and ASP Classic:
What is the preferred way to access an MS SQL Server database in VBScript/ASP?
What are best practices in regards to separating model from view from controller?
Any other things I should know about either VBScript or ASP?
If you haven't noticed, I'm new at VBScript coding. I realize numbers 2 & 3 are kind of giant "black hole" questions that are overly general, so don't think that I'm expecting to learn everything there is to know about those two questions from here.
ADO is an excellent way to access a database in VBScript/Classic ASP.
Dim db: Set db = Server.CreateObject("ADODB.Connection")
db.Open "yourconnectionstring -> see connectionstrings.com"
Dim rs: Set rs = db.Execute("SELECT firstName from Employees")
While Not rs.EOF
Response.Write rs("firstName")
rs.MoveNext
Wend
rs.Close
More info here: http://www.technowledgebase.com/2007/06/12/vbscript-how-to-create-an-ado-connection-and-run-a-query/
One caveat is that if you are returning a MEMO field in a recordset, be sure you only select ONE MEMO field at a time, and make sure it is the LAST column in your query. Otherwise you will run into problems.
(Reference: http://lists.evolt.org/archive/Week-of-Mon-20040329/157305.html )
I had to walk away from my PC when I saw the first answer, and am still distressed that it has been approved by so many people. It's an appalling example of the very worst kind of ASP code, the kind that would ensure your site is SQL-injectable and, if you continue using this code across the site, hackable within an inch of its life.
This is NOT the kind of code you should be giving to someone new to ASP coding as they will think it is the professional way of coding in the language!
NEVER reveal a connection string in your code as it contains the username and password to your database. Use a UDL file instead, or at the very least a constant that can be declared elsewhere and used across the site.
There is no longer any good excuse for using inline SQL for any operation in a web environment. Use a stored procedure -- the security benefits cannot be stressed enough. If you really can't do that then look at inline parameters as a second-best option... Inline SQL will leave your site wide open to SQL injection, malware injection and the rest.
Late declaration of variables can lead to sloppy coding. Use "option explicit" and declare variables at the top of the function. This is best practice rather than a real WTF, but it's best to start as you mean to go on.
No hints to the database as to what type of connection this is -- is it for reading only, or will the user be updating records? The connection can be optimised and the database can handle locking very efficiently if effectively told what to expect.
The database connection is not closed after use, and the recordset object isn't fully destroyed.
ASP is still a strong language, despite many folks suggesting moving to .NET -- with good coding practices an ASP site can be written that is easy to maintain, scaleable and fast, but you HAVE to make sure you use every method available to make your code efficient, you HAVE to maintain good coding practices and a little forethought. A good editor will help too, my preference being for PrimalScript which I find more helpful to an ASP coder than any of the latest MS products which seem to be very .NET-centric.
Also, where is a "MEMO" field from? Is this Access nomenclature, or maybe MySQL? I ask as such fields have been called TEXT or NTEXT fields in MS-SQL for a decade.
Remember to program into the language rather than program in it. Just because you're using a limited tool set doesn't mean you have to program like it's 1999.
I agree with JasonS about classes. It's true you can't do things like inheritance but you can easily fake it
Class Dog
Private Parent
Private Sub Class_Initialize()
Set Parent = New Animal
End Sub
Public Function Walk()
Walk = Parent.Walk
End Function
Public Function Bark()
Response.Write("Woof! Woof!")
End Function
End Class
In my projects an ASP page will have the following:
INC-APP-CommonIncludes.asp - This includes stuff like my general libraries (Database Access, file functions, etc) and sets up security and includes any configuration files (like connection strings, directory locations, etc) and common classes (User, Permission, etc) and is included in every page.
Modules/ModuleName/page.vb.asp - Kind of like a code behind page. Includes page specific BO, BLL and DAL classes and sets up the data required for the page/receives submitted form data, etc
Modules/ModuleName/Display/INC-DIS-Page.asp - Displays the data set up in page.vb.asp.
Echoing some ideas and adding a few of my own:
1) Best way to access the database would to abstract that away into a COM component of some sort that you access from VBScript.
2) If you really wanted to you could write the controller in VBScript and then access that in the page. It would resemble a Page Controller pattern and not a Front Controller that you would see in ASP.NET MVC or MonoRail
3) Why are you doing this to yourself? Most of the tooling required to do this kind of work isn't even available anymore.
AXE - Asp Xtreme Evolution is a MVC framework for ASP classic
There are some attempts at making test frameworks for asp:
aspUnit is good, but no longer maintained.
I saw a sample on how to make your own one a few months back.
The example used nUnit to call functions against the website for automatic testing.
I think i got it off here (my line is borked so I can't check)
On number 2, I think you have a few options...
1) You can use COM components developed in VB6 or the like to separate some of your business logic from your UI.
2) You can create classes in VBScript. There is no concept of inheritance and other more advanced features are missing from the implementation, but you can encapsulate logic in classes that helps reduce the spagehtti-ness of your app. Check out this: https://web.archive.org/web/20210505200200/http://www.4guysfromrolla.com/webtech/092399-1.shtml
I agree with #Cirieno, that the selected answer would not be wise to use in production code, for all of the reasons he mentions. That said, if you have just a little experience, this answer is a good starting point as to the basics.
In my ASP experience, I preferred to write my database access layer using VB, compiling down to a DLL and referencing the DLL via VBScript. Tough to debug directly through ASP, but it was a nice way to encapsulate all data access code away from the ASP code.
way way back in the day when VBScript/ASP were still ok
I worked in a utility company with a very mixed DB envrionment, I used to swear by this website: http://www.connectionstrings.com/
#michealpryor got it right
I've been stuck building on ASP, and I feel your pain.
1) The best way to query against SQL Server is with parameterized queries; this will help prevent against SQL injection attacks.
Tutorial (not my blog):
http://www.nomadpete.com/2007/03/23/classic-asp-which-is-still-alive-and-parametised-queries/
2) I haven't seen anything regarding MVC specifically geared towards ASP, but I'm definitely interested because it's something I'm having a tough time wrapping my head around. I generally try to at least contain things which are view-like and things which are controller-like in separate functions. I suppose you could possibly write code in separate files and then use server side includes to join them all back together.
3) You're probably coming from a language which has more functionality built in. At first, some things may appear to be missing, but it's often just a matter of writing a lot more lines of code than you're used to.
Also for database access I have a set of functions - GetSingleRecord, GetRecordset and UpdateDatabase which has similar function to what Michael mentions above

Resources