Home All Groups Group Topic Archive Search About

IIS6 - URLScan and MaxQueryString

Author
7 Oct 2008 11:06 AM
Julie
I've been running URLScan 2.5 on a Windows Server 2003 system, due to
a problem with that <insert swear word here> SQL Injection attack that
went around.

One of the things that I did was set MaxUrl=260 and
MaxQueryString=512. Since the query string that does this runs over
1000 characters, it worked pretty well; occasionally some would get
through to the website (I could never figure out why) but I have code
in place that searches again for % and DECLARE and such, and just
redirects to a 404 page, while I've been slowly but surely modifying
the problematic pages.

Yesterday we got zapped again...almost the same attack, except that it
used a POST command instead of a GET command, and had odd % in between
ALL of the SQL keywords I was searching for, for the redirect. (e.g.
DEC%LARE%20) so my ASP didn't catch it. The thing is, URLscan didn't
catch it either, even though A) the querystring was 1118 characters
and B) the % is the the DenyURLSequences section.

I need to keep this from happening while I am finishing fixing the ASP
in the problem pages. I upgraded to URLScan 3.0 (which of course uses
the same .ini file).  Anyone have a clue what I may have done wrong in
configuring URLScan? As I said, works MOST of the time - lol. Will I
have the same problem with 3.0?

Any guidance would be received gratefully. Server management/security
is not my strong point.

Thanks,

Julie

Author
7 Oct 2008 1:36 PM
Daniel Crichton
Julie wrote  on Tue, 7 Oct 2008 04:06:25 -0700 (PDT):

Show quoteHide quote
> I've been running URLScan 2.5 on a Windows Server 2003 system, due to a
> problem with that <insert swear word here> SQL Injection attack that
> went around.

> One of the things that I did was set MaxUrl=260 and
> MaxQueryString=512. Since the query string that does this runs over
> 1000 characters, it worked pretty well; occasionally some would get
> through to the website (I could never figure out why) but I have code
> in place that searches again for % and DECLARE and such, and just
> redirects to a 404 page, while I've been slowly but surely modifying
> the problematic pages.

> Yesterday we got zapped again...almost the same attack, except that it
> used a POST command instead of a GET command, and had odd % in between
> ALL of the SQL keywords I was searching for, for the redirect. (e.g.
> DEC%LARE%20) so my ASP didn't catch it. The thing is, URLscan didn't
> catch it either, even though A) the querystring was 1118 characters and
> B) the % is the the DenyURLSequences section.

> I need to keep this from happening while I am finishing fixing the ASP
> in the problem pages. I upgraded to URLScan 3.0 (which of course uses
> the same .ini file).  Anyone have a clue what I may have done wrong in
> configuring URLScan? As I said, works MOST of the time - lol. Will I
> have the same problem with 3.0?

> Any guidance would be received gratefully. Server management/security
> is not my strong point.

> Thanks,

> Julie


POST data is not a querystring - the data is sent in the HTTP request body,
not in the GET request header.

Do you have an included file used throughout your ASP Application? If so, a
quick and dirty way to work around not taking your site down while you sort
out all the issues is to put a check in one of the include files to look for
the SQL in the Request.Form() and/or Request.QueryString() collections, and
in the event of either return a suitable response and stop processing the
page. It's not as efficient as URLScan, but in the case of POST data as you
have already seen URLScan is going to stop these requests. You can also do
some additional handling in the ASP code to normalise the strings before
checking them, making it easier to handle.

As a quick and easy solution, to most if not all of the current batch of SQL
injection requests, and assuming you are using SQL Server, just deny SELECT
to the sysobjects table for the login used by the ASP application - if the
injection code can't get a list of table names and varchar/char/text columns
then it won't run anyway. Ideally (and I guess you already realise this) you
need to parameterise your queries and lock down INSERT/UPDATE to only those
tables/columns that are required for your application to work.

--
Dan
Author
7 Oct 2008 2:01 PM
Julie
Show quote Hide quote
On Oct 7, 6:36 am, "Daniel Crichton" <msn***@worldofspack.com> wrote:
> Julie wrote  on Tue, 7 Oct 2008 04:06:25 -0700 (PDT):
>
>
>
> > I've been running URLScan 2.5 on a Windows Server 2003 system, due to a
> > problem with that <insert swear word here> SQL Injection attack that
> > went around.
> > One of the things that I did was set MaxUrl=260 and
> > MaxQueryString=512. Since the query string that does this runs over
> > 1000 characters, it worked pretty well; occasionally some would get
> > through to the website (I could never figure out why) but I have code
> > in place that searches again for % and DECLARE and such, and just
> > redirects to a 404 page, while I've been slowly but surely modifying
> > the problematic pages.
> > Yesterday we got zapped again...almost the same attack, except that it
> > used a POST command instead of a GET command, and had odd % in between
> > ALL of the SQL keywords I was searching for, for the redirect. (e.g.
> > DEC%LARE%20) so my ASP didn't catch it. The thing is, URLscan didn't
> > catch it either, even though A) the querystring was 1118 characters and
> > B) the % is the the DenyURLSequences section.
> > I need to keep this from happening while I am finishing fixing the ASP
> > in the problem pages. I upgraded to URLScan 3.0 (which of course uses
> > the same .ini file).  Anyone have a clue what I may have done wrong in
> > configuring URLScan? As I said, works MOST of the time - lol. Will I
> > have the same problem with 3.0?
> > Any guidance would be received gratefully. Server management/security
> > is not my strong point.
> > Thanks,
> > Julie
>
> POST data is not a querystring - the data is sent in the HTTP request body,
> not in the GET request header.
>
> Do you have an included file used throughout your ASP Application? If so, a
> quick and dirty way to work around not taking your site down while you sort
> out all the issues is to put a check in one of the include files to look for
> the SQL in the Request.Form() and/or Request.QueryString() collections, and
> in the event of either return a suitable response and stop processing the
> page. It's not as efficient as URLScan, but in the case of POST data as you
> have already seen URLScan is going to stop these requests. You can also do
> some additional handling in the ASP code to normalise the strings before
> checking them, making it easier to handle.
>
> As a quick and easy solution, to most if not all of the current batch of SQL
> injection requests, and assuming you are using SQL Server, just deny SELECT
> to the sysobjects table for the login used by the ASP application - if the
> injection code can't get a list of table names and varchar/char/text columns
> then it won't run anyway. Ideally (and I guess you already realise this) you
> need to parameterise your queries and lock down INSERT/UPDATE to only those
> tables/columns that are required for your application to work.
>
> --
> Dan

Hmmm, thanks. Yes, I do have an include file, the top of which is
already parsing query strings, but this one slipped through somehow. I
realize this isn't an ASP/VBScript forum, but this part is what's run
on every asp page.

dim testQS
Set testQS = New RegExp
testQS.pattern = "(%)|(DECLARE)|(VARCHAR)|(EXEC)|(UPDATE)|(DELETE)|
(TRUNCATE)|(DROP)"
testQS.IgnoreCase = True
if testQS.Test(Request.QueryString)=True then
response.redirect("404.html")

I understand why it didn't catch "DECLARE", 'cause like I said, it had
a % in the middle of the word. There's obviously something wrong with
my regexp, though...thanks for at least letting me know that I was on
the right track at least - lol. I'll figure it out.

And I'll see if I can figure out how to "deny SELECT to the sysobjects
table for the login used by the ASP application". Yes, it's SQL Server
2000 on a dedicated Win 2003 Server. I haven't spend a lot of time in
SQL Server, but no time like the present, I guess!

Thanks again.

Julie
Author
7 Oct 2008 2:05 PM
Julie
> And I'll see if I can figure out how to "deny SELECT to the sysobjects
> table for the login used by the ASP application". Yes, it's SQL Server
> 2000 on a dedicated Win 2003 Server. I haven't spend a lot of time in
> SQL Server, but no time like the present, I guess!

Oh, duh. (Way too many "Duhs" this week.)

I know how to do that. Thanks again.

J.
Author
7 Oct 2008 2:31 PM
Daniel Crichton
Julie wrote  on Tue, 7 Oct 2008 07:01:00 -0700 (PDT):

Show quoteHide quote
> On Oct 7, 6:36 am, "Daniel Crichton" <msn***@worldofspack.com> wrote:
>> Julie wrote  on Tue, 7 Oct 2008 04:06:25 -0700 (PDT):



>>> I've been running URLScan 2.5 on a Windows Server 2003 system, due
>>> to a problem with that <insert swear word here> SQL Injection attack
>>> that went around.
>>> One of the things that I did was set MaxUrl=260 and
>>> MaxQueryString=512. Since the query string that does this runs over
>>> 1000 characters, it worked pretty well; occasionally some would get
>>> through to the website (I could never figure out why) but I have
>>> code in place that searches again for % and DECLARE and such, and
>>> just redirects to a 404 page, while I've been slowly but surely
>>> modifying the problematic pages.
>>> Yesterday we got zapped again...almost the same attack, except that
>>> it used a POST command instead of a GET command, and had odd % in
>>> between
>>> ALL of the SQL keywords I was searching for, for the redirect. (e.g.
>>> DEC%LARE%20) so my ASP didn't catch it. The thing is, URLscan didn't
>>> catch it either, even though A) the querystring was 1118 characters
>>> and
>>> B) the % is the the DenyURLSequences section.
>>> I need to keep this from happening while I am finishing fixing the
>>> ASP in the problem pages. I upgraded to URLScan 3.0 (which of course
>>> uses the same .ini file).  Anyone have a clue what I may have done
>>> wrong in configuring URLScan? As I said, works MOST of the time -
>>> lol. Will I have the same problem with 3.0?
>>> Any guidance would be received gratefully. Server
>>> management/security is not my strong point.
>>> Thanks,
>>> Julie

>> POST data is not a querystring - the data is sent in the HTTP request
>> body, not in the GET request header.

>> Do you have an included file used throughout your ASP Application? If
>> so, a quick and dirty way to work around not taking your site down
>> while you sort out all the issues is to put a check in one of the
>> include files to look for the SQL in the Request.Form() and/or
>> Request.QueryString() collections, and in the event of either return
>> a suitable response and stop processing the page. It's not as
>> efficient as URLScan, but in the case of POST data as you have
>> already seen URLScan is going to stop these requests. You can also do
>> some additional handling in the ASP code to normalise the strings
>> before checking them, making it easier to handle.

>> As a quick and easy solution, to most if not all of the current batch
>> of SQL injection requests, and assuming you are using SQL Server,
>> just deny SELECT to the sysobjects table for the login used by the
>> ASP application - if the injection code can't get a list of table
>> names and varchar/char/text columns then it won't run anyway. Ideally
>> (and I guess you already realise this) you need to parameterise your
>> queries and lock down INSERT/UPDATE to only those tables/columns that
>> are required for your application to work.

>> --
>> Dan

> Hmmm, thanks. Yes, I do have an include file, the top of which is
> already parsing query strings, but this one slipped through somehow. I
> realize this isn't an ASP/VBScript forum, but this part is what's run
> on every asp page.

> dim testQS
> Set testQS = New RegExp testQS.pattern =
> "(%)|(DECLARE)|(VARCHAR)|(EXEC)|(UPDATE)|(DELETE)|
> (TRUNCATE)|(DROP)"
> testQS.IgnoreCase = True if testQS.Test(Request.QueryString)=True then
> response.redirect("404.html")

> I understand why it didn't catch "DECLARE", 'cause like I said, it had
> a % in the middle of the word. There's obviously something wrong with
> my regexp, though...thanks for at least letting me know that I was on
> the right track at least - lol. I'll figure it out.

> And I'll see if I can figure out how to "deny SELECT to the sysobjects
> table for the login used by the ASP application". Yes, it's SQL Server
> 2000 on a dedicated Win 2003 Server. I haven't spend a lot of time in
> SQL Server, but no time like the present, I guess!

> Thanks again.

> Julie


Your code is still not checking POST data, which is in the Request.Form()
collection. Maybe

if testQS.Test(Request.QueryString)=True or testQS.Test(Request.Form)=True
then

and you can drop the =True too ;)

--
Dan
Author
7 Oct 2008 3:59 PM
Julie
<snip>

> > dim testQS
> > Set testQS = New RegExp testQS.pattern =
> > "(%)|(DECLARE)|(VARCHAR)|(EXEC)|(UPDATE)|(DELETE)|
> > (TRUNCATE)|(DROP)"
> > testQS.IgnoreCase = True if testQS.Test(Request.QueryString)=True then
> > response.redirect("404.html")

<snip>

>
> Your code is still not checking POST data, which is in the Request.Form()
> collection. Maybe
>
> if testQS.Test(Request.QueryString)=True or testQS.Test(Request.Form)=True
> then
>
> and you can drop the =True too ;)
>
> --
> Dan

And yet another "duh" on the True - lol. Sheesh. I wrote that the last
time this happened after being up all night; here I am again, up all
night. Can't wait until I finish fixes these pages...I'm tired of
staying up all night! Anyway, after I wrote it, I never really
*looked* at it again, if ya know what I mean.

Sorry for being stupid about this; I never use the forms collection, I
always access it the same way I would a query variable (e.g.
request('myformfield"). I'm tired and making all the wrong
assumptions.

Thanks again, so much.

Julie