36 Chambers – The Legendary Journeys: Execution to the max!

October 31, 2011

Corporatism Pays Again—Well, Maybe Not

Filed under: Curmudgeonliness, Economics, Hey Whore How's The Whoring? — Kevin Feasel @ 6:08 pm

Well, I take that back:  corporatism paid off well for Fisker automotive, as they nailed down a $529 million loan from the US Department of Energy (the same geniuses who were responsible for Solyndra).  To be fair, Fisker hasn’t gone bankrupt yet:  instead, they’ve gone to Finland.

The biggest friend of big business and sweetheart deals is big government—where else do the deals come from?

October 30, 2011

Congress: Tackling The Important Issues

Filed under: Curmudgeonliness — Kevin Feasel @ 2:06 pm

Only the Senate can protect us against the horrors of fake maple syrup.  Heaven forfend that people actually need to read the bottle or, gasp!, consume anything short of maple.

10 bonus points for the first person to make a Syrup-Industrial Complex comment…

October 29, 2011

Security Notes

Filed under: (In)Security — Kevin Feasel @ 7:51 pm

All kinds of security notes this week…

October 28, 2011

Malware Means Losing Internet Access

Filed under: (In)Security — Kevin Feasel @ 1:50 pm

About a month ago, there was an article about an Australian woman whose internet access was cut off after her telephone company repeatedly warned her about malware on her computer.

Malware on a computer is a classic externality problem.  As long as your computer still works well enough, you might not really care about the negative things it is doing.  Alternatively, you may not have the skill necessary to remove it, or a safe backup  to which you could revert.  Thus, I don’t mind ISPs walling off computers which are known to be infected.  This might be the only way to get people to clean up their computers.

October 27, 2011

SQL Injection, Part 4C Of 8: Bonus Material

Filed under: (In)Security, Database Administration, Programming & Work — Kevin Feasel @ 5:12 pm

I don’t think I’ll have room for this anywhere else, so I wanted to include a little bit of bonus material.

In my simple workbench website, I included two extra columns in my gridview:  one in which I simply Eval(“Name”) and another in which I have a label whose Text property is set to Eval(“Name”).  I wanted to show you that both of these are bad ideas, and you probably should not use them.

Setting Up An Attack

Let’s go back to our basic website, that you can see in Part 3.  I’m going to perform SQL injection to insert an evil value.  In this case, I’ll inject script code.  Here is the code I would like to inject:

insert into Production.ProductSubcategory(ProductCategoryID, Name, rowguid, ModifiedDate) values(1, '// ', newid(), current_timestamp);--

So, trying it on the page gets me…an error:

Trying to run a script tag in a textbox returned this exception.

Trying to run a script tag in a textbox returned this exception.

So ASP.NET protected the server from my malicious script insertion attempt. That’s pretty cool, and I like that. Unfortunately, there are ways around this… My favorite way is to convert the message to binary and have SQL Server do the decoding and running for me. Doing this is rather trivial. In a copy of SQL Server Management Studio, all I have to do is run the following statement:

select cast('insert into Production.ProductSubcategory(ProductCategoryID, Name, rowguid, ModifiedDate) values(1, ''<script type="text/javascript">alert("A")</script>'', newid(), current_timestamp);--' as varbinary(8000));

This converts the query I want to run into varbinary. If I were to convert the varbinary back to text and execute that text, it would perform as if I had simply entered the text to begin with. The advantage (for an attacker) is that ASP.NET doesn’t understand what’s in that binary blob, so it doesn’t realize that there’s a script tag hanging around. Here’s the code we’ll use to attack:

declare @shmooi varchar(8000); set @shmooi = CAST(0x696E7365727420696E746F2050726F64756374696F6E2E50726F6475637453756263617465676F72792850726F6475637443617465676F727949442C204E616D652C20726F77677569642C204D6F64696669656444617465292076616C75657328312C20273C73637269707420747970653D22746578742F6A617661736372697074223E616C65727428224122293C2F7363726970743E272C206E6577696428292C2063757272656E745F74696D657374616D70293B2D2D as varchar(8000)); exec(@shmooi);--

That blob of binary is equivalent to the insert statement from above. But running it on the server presents us, as expected, with more favorable results.

Using a binary blob instead of text, we can circumvent ASP.NET's Request.Form protections.

Using a binary blob instead of text, we can circumvent ASP.NET's Request.Form protections.

We can go into SQL Server Management Studio and confirm that the evil subcategory has been inserted. Use the following query to find the record:

select * from Production.ProductSubcategory where Name like '%script%';
Javascript has been inserted into our database via a SQL injection attack.

Javascript has been inserted into our database via a SQL injection attack.

The next person who searches for anything on the page that matches this—like, say, the letter “A”—will be in for a rude surprise.

The Javascript is executed, causing a popup box to appear.

The Javascript is executed, causing a popup box to appear.

This is scary.  If you aren’t afraid at this point, something’s wrong with you.  Right here, we’ve demonstrated just how easy it is to perform a cross-site scripting attack using SQL injection.  My example is more limited, in that I’m not actually performing a cross-site scripting attack, but rather simply running Javascript, but turning it into an XSS attack is not that much more difficult.

So why did this attack succeed?  We can get a good idea of the problem by looking at the bottom of the page, where our new attack subcategory is:

The two columns in which an Eval statement is used actually evaluated the Javascript code; the non-Eval label does not.

The two columns in which an Eval statement is used actually evaluated the Javascript code; the non-Eval label does not.

The first two columns are empty.  That is because they were evaluated and not simply displayed.  By performing an evaluation, you also evaluate any script inside—regardless of whether you, as the developer, intended somebody to run your script.  The third column, which is the default GridView column, simply displays the text in a label.  It does not evaluate the code, and so even though somebody injected code into the database, it was not run.

Parameterize, Man!

Just like before, a SqlParameter can protect us against this attack. Here is what our parameterized, space-limited query looks like:

exec sp_executesql N'select Name, ProductSubcategoryID, ProductCategoryID from Production.ProductSubcategory where Name like ''%@Filter%'' order by ProductSubcategoryID;',N'@Filter nvarchar(50)',@Filter=N'boof''; declare @shmooi varchar(8000); set @shmooi '

Because there are only 50 characters allowed, the attack would fail. But more importantly, we made the query completely safe, so instead of looking for “boof” and then running the attack code, it tries to look for “boof'; declare @shmooi varchar(8000); set @schmooi ‘ as one of our product subcategories. No records are returned and the attack code, obviously, is not run.

Conclusions

Again, parameterize your queries.  It will save you so much headache and hassle.  In addition, I recommend not using the Eval functionality, and instead loading your labels and other form fields in the codebehind.  That way, even if somebody does sneak something evil into your database, it won’t run the way the bad guy expected.

October 26, 2011

Hopefully the end of the Hillis saga

Filed under: RTFBS, Sports — Tony Demchak @ 11:48 pm

Oh Peyton. Why couldn’t you have just said this weeks ago?

Each day, I begin to think it’s entirely the media and his agent that stirred up this shitstorm in the first place. If he said this during training camp, this would not have been a nagging issue all season.

Maybe with this behind the Browns, I can look forward to our offense trying some of these touchdowns I’ve heard so much about. I hear they’re worth two field goals, and you can even get a bonus point! What a crazy, mixed up world we live in.

Central Planning: Jobs Americans Will Do

Filed under: Curmudgeonliness, Economics — Kevin Feasel @ 1:41 pm

Vero de Rugy has a hilarious article by a former Gosplan planner who saw the light, writing to the Department of Energy and offering advice earned from years of sucking (which isn’t his fault, but rather the necessary result of central planning).

The sad part is that we know which side won the Cold War, but some people just can’t give up that socialist feeling.  Sadly, the urge to control other peoples’ lives and declare yourself better at that than the people whose lives you have decided to run runs deep in the West.

October 25, 2011

SQL Injection, Part 4B Of 8: Defending Websites

Filed under: (In)Security, Database Administration, Programming & Work — Kevin Feasel @ 5:22 pm

Last time around, I spent some time on things not to do when attempting to secure a website against SQL injection.  Now I’m going to suggest a few things you can do to lock down a site effectively.

Parameterize Your Queries

The single most important thing you can do is parameterize your queries.  If you do absolutely nothing else, this will at least prevent malicious users from manipulating your website forms  and querystrings to perform unexpected and undesirable actions.

Let’s go back to our query code and figure out what we can do differently.

                //I'm too sexy for my data objects.
                using (SqlConnection conn = new SqlConnection("server=localhost;database=AdventureWorks;trusted_connection=yes"))
                {
                    string sql = String.Empty;
                    sql = "select Name, ProductSubcategoryID, ProductCategoryID from Production.ProductSubcategory where Name like '%" + Filter + "%' order by ProductSubcategoryID;";
                    using (SqlCommand cmd = new SqlCommand(sql, conn))
                    {
                        cmd.CommandTimeout = 30;
                        conn.Open();

                        //We're using a reader, so there's no way that anybody could do anything bad, right?
                        SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                        gvGrid.DataSource = dr;
                        gvGrid.DataBind();
                        gvGrid.Visible = true;
                    }

                    lblSearchString.Visible = gvGrid.Visible;
                    lblSearchString.Text = Filter;
                }

This code is not parameterized. Instead, the Filter parameter is translated to its underlying string and put directly into the code. This is what allows us to perform SQL injection attacks. So let’s convert this into code which does use parameters correctly.

                //I'm too sexy for my data objects.
                using (SqlConnection conn = new SqlConnection("server=localhost;database=AdventureWorks;trusted_connection=yes"))
                {
                    string sql = String.Empty;
                    sql = "select Name, ProductSubcategoryID, ProductCategoryID from Production.ProductSubcategory where Name like '%@Filter%' order by ProductSubcategoryID;";
                    using (SqlCommand cmd = new SqlCommand(sql, conn))
                    {
                        //create a parameter for @Filter
                        SqlParameter filter = new SqlParameter();
                        filter.ParameterName = "@Filter";
                        filter.Value = Filter;

                        //attach our parameter to the SqlCommand
                        cmd.Parameters.Add(filter);

                        cmd.CommandTimeout = 30;
                        conn.Open();

                        //We're using a reader, so there's no way that anybody could do anything bad, right?
                        SqlDataReader dr = cmd.ExecuteReader(CommandBehavior.CloseConnection);
                        gvGrid.DataSource = dr;
                        gvGrid.DataBind();
                        gvGrid.Visible = true;
                    }

I made two basic changes here. The first change is that the SQL query no longer stops and inserts the value of Filter; instead, I replaced it with @Filter (like you would see in a stored procedure). The second change is that I added a SqlParameter to the SqlCommand. This SqlParameter’s name is @Filter (to match the @Filter parameter in the SQL call), and its value is the Filter we receive. Then, we add the parameter to the SqlCommand, and run it the same way.

For the cost of a few extra lines of code, we have completely eliminated SQL injection.  The following images should help prove this.

The call to drop a table simply gets parameterized.

The call to drop a table simply gets parameterized.

In this first image, we can see that the call to drop the table is still considered part of the filter, instead of breaking off into another statement.  Thus, the “drop table test” part does not execute as it did earlier.

Our UNION standby does not work, either.

Our UNION standby does not work, either.

The next thing you might try, a UNION, also does not work.  This is for the same reason:  you can’t get “outside” the parameter.  As long as the form field text must be “within” a parameter, there is no way to do any harm.

A querystring-based attack is also thwarted.

A querystring-based attack is also thwarted.

Because this defense is in the data layer—right before we make the SQL call—it does not matter which mechanism is used to perform the operation.  In this case, we can see that the querystring is also protected.  If we had web services or WPF applications or Silverlight apps which called the same method, they would also be protected, too.

So how does this actually work?  It is instructive at this point to fire up Profiler and watch the trace as we see what these operations do. The following SQL code is what is sent to SQL Server by ASP.NET when running the querystring attack attempt:

exec sp_executesql N'select Name, ProductSubcategoryID, ProductCategoryID from Production.ProductSubcategory where Name like ''%@Filter%'' order by ProductSubcategoryID;',N'@Filter nvarchar(14)',@Filter=N'bike'' or 1=1--'

In comparison, here is what gets sent to SQL Server by ASP.NET when we run the non-parameterized code:

select Name, ProductSubcategoryID, ProductCategoryID from Production.ProductSubcategory where Name like '%bike' or 1=1--%' order by ProductSubcategoryID;

We can see the difference quite clearly: without a SqlParameter, the code sent to SQL Server is static SQL, but has been malformed in such a way as to have an unexpected and undesirable (from the perspective of the developer) result. On the other hand, adding a SqlParameter makes the SqlCommand executor turn the statement into dynamic SQL, passing along the parameter. In addition, the apostrophe after “bike” gets doubled up to make it no longer able to close a string.

This little difference goes a long way in protecting your websites from attackers. There are a few other things you can do, however, to protect yourself even further.

Use Maximum Field Sizes (And Size Your SqlParameters)

In AdventureWorks, the maximum field length for product subcategories is 50 characters.  Why, then, should your field length allow more than 50 characters?  If you limit the size of a textbox, you limit what bad guys can do.  Say that you only allow 10 characters.  In that case, bad guys could not drop tables, because the phrase “drop table” takes up 10 characters right there.

This advice does not help for free-form text fields or fields which necessarily must allow for plenty of room, but it does limit the potential for harm, as well as providing users a helpful indicator that they have reached the size limit for a field.

As an addendum, I also recommend using fixed parameter sizes.  The above example did not include a maximum field size, and so the dynamic SQL created had a size of nvarchar(14).  If somebody else puts in 15 characters, that will create another plan with a size of nvarchar(15).  This can result in you unnecessarily storing cached plans which are essentially duplicates in all but parameter size.  Instead, use the following code:

SqlParameter filter = new SqlParameter();
filter.ParameterName = "@Filter";
filter.Size = 50;
filter.Value = Filter;

By filling out the size property, every time the SqlCommand sends over this dynamic SQL, it will use the same parameter size, thus keeping you down to one plan in cache:

exec sp_executesql N'select Name, ProductSubcategoryID, ProductCategoryID from Production.ProductSubcategory where Name like ''%@Filter%'' order by ProductSubcategoryID;',N'@Filter nvarchar(50)',@Filter=N'bike'' or 1=1--'

Protect Against HTTP Parameter Pollution

I mentioned the possibility of using HTTP Parameter Pollution earlier. HTTP Parameter Pollution will not allow an attacker to bypass our defenses, as you can see below. This is a Profile trace of what gets translated from the SqlCommand to the SQL Server instance when I try to go to QueryDriven.aspx?search=bike'; drop/*&search=*/ table test;:

exec sp_executesql N'select Name, ProductSubcategoryID, ProductCategoryID from Production.ProductSubcategory where Name like ''%@Filter%'' order by ProductSubcategoryID;',N'@Filter nvarchar(50)',@Filter=N'bike''; drop/*,*/ table test;'

Despite this protection, it may still be a good idea to prevent HTTP Parameter Pollution attacks.  Unfortunately, the only way I know how to do this is with a Web Application Firewall.  On the server side, Request.QueryString already translates the querystring value to a comma-delimited string, so you cannot get it as a base list of objects to see how many records there are which match that value.  This limits your ability to perform defensive operations.

Conclusion (No Longer Tentative)

Parameterization is the key to securing your ASP.NET website against SQL injection.  Even if you have shoddy, injectable SQL code, performing this simple step means that at least you wouldn’t be able to get attacked through your website.  There is some performance cost, given the overhead of dynamic SQL, but it’s small, especially compared to the risk that you can run by using the non-parameterized methods available to you.

October 24, 2011

Anti-Democratic Thought In Modern Democratic Thinkers

Filed under: Curmudgeonliness — Kevin Feasel @ 6:35 pm

Perhaps I should put scare quotes around the “thinkers” part.

Steven Hayward starts us off with a nice essay.  But what really gets me is a statement by Stephen Northcutt in a SANS security newsletter that I receive:  “What a week. NC Gov. Bev Purdue suggests suspending elections; NY State Senators argue that free speech is a privilege, not a right; and NSA wants to monitor public networks while not violating citizens’ civil liberties. At what point should we be concerned that democracy is under stress?”

So, as noted, we have a governor using “hyperbolic” speech when stating that maybe we should just suspend elections, New York Democrats who don’t care that much for free speech (at least when it’s speech they don’t like), and a government agency which wants to “monitor public networks for threats.”

Hayward’s essay really ties these types of themes together and I recommend reading it.

 

 

 

October 22, 2011

This Is Not How Jobs Are Created

Filed under: Curmudgeonliness, Economics — Kevin Feasel @ 6:28 pm

Keith Ellison is a moron.  You do not “create jobs” by dropping more and more onerous regulations.  What happens in real life is that costs of doing business go up.  When these costs go up, marginal businesses (the ones which were struggling to get by already) are forced under.  When that happens, there are fewer jobs available.  In an open market situation, this wouldn’t be _too_ bad in the long run, as people would find ways around the regulations or we become wealthy enough that we can afford the regulations, but these idiots keep piling them on.

The problem is that Ellison lives in a world where more regulations means he hires more staffers.  It’s not his money, so he doesn’t care how much of it gets spent.  And heck, we’re already $100+ trillion in the hole; what’s a few trillion more?  For businesses which can’t continuously degrade their product and still get large amounts of investor funding, however (hint:  almost every organization other than the US federal government), you hit a wall and run out of money.

Older Posts »

The Silver is the New Black Theme. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.

Join 100 other followers