Certificate Authority Request Monitoring with Powershell

November 24th, 2009 tcnolan No comments

Rolling out a certificate authority in Windows 2003 and Windows 2008 is a relatively trivial task if you are deploying a stand-alone CA, Enterprise CA’s are a bit more complex, but that’s a post for another day. The web interface (http://server.domain.local/certsrv/) is pretty limited and doesn’t provide the greatest interface for manually requesting certificates, it even relies on cookies for managing requests. It would be really nice to see Microsoft build this into a truly useful application like what you get with the Thawte Certificate Center.

One thing that is a bit frustrating is that even when you have the logging options fully enabled for the CA, events aren’t logged for new certificate requests so you have to manually check the server on a regular basis for outstanding requests. Usually this is a low priority kind of service in your enterprise and can get neglected, which has happened in my case a few times.

This neglect prompted me to write the following Powershell script which very simply uses certutil to check if there are any pending requests, and then fire off an email to a list of users if there are. This script could also be easily modified to check for revoked certificates or to generate a weekly report on existing certificates to monitor expiration dates, among a bunch of other things, however I really only needed this for requests so that’s all it does for right now. If anyone has any interest in something else, let me know and I’ll see about updating the script to include additional features.

To use this script, all you need to do is ensure you have a copy of certutil on the machine running this, update the configurable pieces of the script, then create a scheduled task to run it every hour or so, or whatever time-frame is appropriate for you and your organization.

More information and a download link is after the break…
Read more…

  • Share/Save/Bookmark

vSphere Client on Windows 7

September 4th, 2009 tcnolan 2 comments

Update 2009-09-08: I just updated the script because I received a report from wohali (Joan) over at VMware communities that they had a problem when the vSphere client was installed on a different drive and I have now fixed that problem.  I also added in support for making the host update utility work as well.  Lastly, I added a few output messages so you can see what’s going on and know what is getting done.

The past few months I have been enjoying Windows 7 quite a bit (both the RC and now the RTM), but at the office we use VMware for many of our clients and the vSphere Client unfortunately has an issue with Windows 7 due to an incompatibility with a .Net 2.0 library dll that comes installed on Windows 7.  When you install the vSphere client, you will be able to get through the install without an issue usually (If you have J# already installed you may encounter issues installing the vSphere client), but once you try to connect to your vSphere server you get an error stating “Error parsing <server> clients.xml file  Login will continue contact your system administrator” followed immediately by another error “The type initializer for “VirtualInfrastrcture.Utils.HttpWebRequestProxy” threw an exception” which then brings you back to the login screen and you are unable to connect in.

There’s big thread over at VMware Communities that discusses this problem and ways to fix it.  Unfortunately, it’s a manual process and deploying this out to all of our Windows 7 employee workstations is a bit of a hassle, so I have created a Powershell script that will do the necessary work for you, and create a shortcut on your desktop as well.

By default, powershell security options may prevent you from executing the script, so you may have to change a setting temporarily to get it to work.  If you type “Get-ExecutionPolicy” from a powershell window you will most likely see “Restricted” but there are a few others as well which will all prevent you from executing the script.  You can read more about this over at dotnetvj.com where he goes into a little more detail about these execution policies and what they mean.  All you need to do though is type “Set-ExecutionPolicy Unrestricted”  Just remember that you should probably set the execution policy back to its previous value after you run the script for security purposes.  Lastly, you will also need to run powershell as an administrator if you have UAC turned on because this script has to add files to the installation folder of your vSphere client.

Launch Powershell as Administrator

Launch Powershell as Administrator

Once you have powershell running as an administrator and change the execution policy, it is a simple process to run this script, simply CD to the folder that you have extracted the script, and run it by typing “.Windows7vSphere.ps1” and it will do the work of copying over the System.dll and creating the necessary files to launch vSphere client in development mode so it can use the System.dll.

Execute Windows7vSphere.ps1

Change execution policy and execute Windows7vSphere.ps1

You should now have an icon on your desktop called “VMware vSphere Client (Windows 7)” which you then simply run as administrator to launch the vSphere client.  The reason you have to launch it as administrator is because it creates an environment variable that lets the vSphere client know that you are giving it a different System.dll to work with.  This is something also discussed in detail in the thread over at VMware Communities.

For anyone interested in powershell, this script also shows a few cool things such as reading from the registry, writing to an xml document, as well as creating a windows shortcut using pretty simple commands.

Hopefully this will help a few people streamline the process of getting the vSphere client installed on your Windows 7 machines.  If you notice any problems with the script, feel free to comment and let me know and I’ll try to fix it as soon as possible.

Download the script and the dll needed here: Windows7vSphere.zip

  • Share/Save/Bookmark

401 Error on HttpWebRequest with NTLM Authentication

August 24th, 2009 tcnolan No comments

Due to a security update to SMB that fixes a remote code execution vulnerability, you may experience 401.1 or 401.2 errors in certain situations while performing a WebRequest to one of your servers. This is because part of the security update institutes a loopback check on the authentication requests to prevent replay attacks. The Microsoft KB article refers to a few different scenarios where you can see authentication problems after applying this patch, but the one I’m most interested in is when you start getting 401 errors after an HttpWebRequest on an ASP.Net page.

The issues I experienced were while creating a page to display general status of one of my companies Sharepoint servers. The main issue which is the meat of this article was when I switched the authentication over to use NTLM instead of Digest, which broke my script. Everything I had in place should have worked, but the previously mentioned security update slipped under the radar and it took a while to figure out what was going on. You can do a basic web request on a server with Basic authentication by doing the following:

Dim _response As String
Dim _auth As String = "Basic"
Dim _uri As Uri = New Uri("http://my.domain.local/my-page.aspx")
Dim _req As HttpWebRequest = WebRequest.Create(_uri)
Dim _cc As CredentialCache = New CredentialCache()
Dim _res As HttpWebResponse
Dim _sr As StreamReader

_cc.Add(_uri, _auth, New NetworkCredential("username", "password", "domain"))
_req.PreAuthenticate = True
_req.Credentials = _cc.GetCredential(_uri, _auth)
_res = _req.GetResponse
_sr = New StreamReader(_res.GetResponseStream)
_response = _sr.ReadToEnd
_sr.Close()

That code works perfectly well with Basic and even Digest(if you change the _auth value) authentication, however it will most likely not work for you if you are using NTLM authentication and your server has had the MS08-068 patch applied to it. Prior to discovering the conflict with this patch I went through a lot of effort to investigate the issue. One of the most useful debugging utilities in IIS7 is the failed request tracing logs. These logs give you really great insight as to what is going on inside your web request traffic. You can also use a tool like Fiddler to try and see what’s happening, but unfortunately because our Sharepoint server was live, it would have caused SSL certificate issues if I put it in the mix in my situation.

After looking at the failed request traces logs, I noticed an interesting difference between one of the failed requests from my health check script and a purposely failed request through a web browser that I pointed to a file I had no access to read.

401.3 Error message - Unauthorized due to ACL on resource

401_3

401.2 Error message - Logon failed due to server configuration

401_2

Note: Check out http://support.microsoft.com/kb/943891 for all the status codes in IIS7

The difference here is that on the WebRequest, it wasn’t even getting an NTLM token from the .Net app. This lead me astray however and made me think that there was a problem with the pre-authentication of the credentials as well as whether I was missing something in the web.config, or even if it was some unique problem with Sharepoint. After a lot of investigation I discovered the Microsoft KB article titled: “You receive error 401.1 when you browse a Web site that uses Integrated Authentication and is hosted on IIS 5.1 or IIS 6” After giving a thorough read of that document I realized the problem, Microsoft forgot to update the title of the KB article. The sub status code I was getting on the 401 errors is different than Microsoft mentions in the article, and while they don’t mention IIS 7 in the article’s title, it does show up in the applies to section.

Since Microsoft recommends you leave the loopback check in place because it is part of the security update, I followed their recommended method of adding in a specified host name to the BackConnectionHostNames key in the registry.

As always, make registry modifications at your own risk, Microsoft always recommends you make a backup before making any modifications, check out the following KB article for backup instructions: http://support.microsoft.com/kb/322756

Warning Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. TinyInt.Com cannot guarantee that these problems can be solved. Modify the registry at your own risk.

To specify the host names that are mapped to the loopback address and can connect to Web sites on your computer, follow these steps:

  1. Click Start, click Run, type regedit, and then click OK.
  2. In Registry Editor, locate and then click the following registry key:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0

  1. Right-click MSV1_0, point to New, and then click Multi-String Value.
  2. Type BackConnectionHostNames, and then press ENTER.
  3. Right-click BackConnectionHostNames, and then click Modify.
  4. In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK.
  5. Quit Registry Editor, and then restart the IISAdmin service.

Now that you have taken care of editing the registry to include the hostname you are using in your code, you should be able to make your WebRequest over NTLM without a problem, just make sure you have impersonate=”true” in your web.config file.

Attached below is the code for the health check script that I have been talking about throughout this article. As I mentioned earlier, it does some very basic checks on the server just to see if things are running smoothly. To use it you would simply need to change the variables being passed into the various functions to check your database connectivity. We use WhatsUp Gold to track the value of ALL_STATUS_OK to make sure things are working properly, and once one of the values fails it sends us an alert. Another thing to keep in mind is if you are using the WebRequest piece in this code, make sure you grant the user you are authenticating as access to the Sharepoint page you are checking. Lastly, if you use the code, make sure you read the comment in the web.config file about encrypting the settings so your password is not exposed, even if you are using a low privileged user account.

Download Source: sharepoint-contentscan.zip

  • Share/Save/Bookmark

Enumerate Distribution Groups Script Updated…

July 17th, 2009 tcnolan No comments

A reader sent in a question asking how to enumerate groups that have spaces in them and this lead me to realize I didn’t follow the specifications for valid distinguished names as well as I thought I had.  If you take a look at RFC 2253 and the Microsoft page that defines security group names, you will see what the allowed characters are for these names.  At this point the validation is a lot better, but it still isn’t perfect.

If you encounter a situation where you need to enumerate members of a group that my validation does not allow, you can scroll down to line 271 in the script and change the $rx variable to “.+” to make it simple which will allow you to pass any characters.  If you pass invalid characters you will get some funny errors happening, but it should work.  You may have to use quotes around the name if you are looking to use spaces or other allowed special characters.

Taking another look at the code, I also found a small bug that was causing the display of notes associated with a group to print out an error about null strings.  This should be fixed now.  If anyone notices any other problems, feel free to comment and let me know and I will try to fix it or add in the change as soon as possible.  I’ll be posting another update soon that goes the other direction of this script, one that enumerates group membership for a specific user.

Thanks again to Darren from Brisbane(?), Australia for pointing this out.

Here is the updated script download link: enumerate_groups.ps1

  • Share/Save/Bookmark

sp_help_revlogin cleaned up and revised with roles

July 8th, 2009 tcnolan No comments

When working with SQL Server there are often times where you will need to script your logins over to another server such as when you have database mirroring or log shipping configured for certain databases.   This is such a common thing that Microsoft provides in-depth instructions on how to do this as well as the T-SQL code required to do it, which you can read more about here: http://support.microsoft.com/kb/918992.  The script they provide is missing a few things so I took a little time to clean up the code, revise some of it, and add in a few of the missing pieces.

The three things that are overlooked in the Microsoft article that I have included are default language and default database (being mandatory) for logins as well as the scripting of roles.  The lack of the default language is pretty minor, but it’s something that could be important to people so I am including it in my script.  The lack of default databases being an option in the Microsoft script is not a big deal because it assumes you are scripting everything, but if you are only concerned with logins that are specific to a certain database you will get errors if you haven’t created that database on the target.  The lack of server roles is another important one that I have needed in previous configurations so it is also included here.  The resulting script is pretty long so you can check out the source of the revised procedure after the jump, which includes the sp_hexadecimal script from the Microsoft article.

Additionally, something just as important as the revlogin script itself is the question of “Well now that I have this script, how do I schedule this to happen automatically for me instead of just generating more code that I have to execute on the target server?” If you are asking that question then you might want to take a look at the next block of code. In order to automate sp_help_revlogin there are a few options, but the one that I prefer over all else is using osql and a SQL Agent job with a single T-SQL step because it is very simple to implement in most server configurations. The following script is relatively straight forward in that you only have one variable, the target server, to worry about. The only pre-requisites being that xp_cmdshell is enabled and that the Windows account that the job is being executed under has sysadmin rights to both servers. This script could easily be turned into a stored procedure but for the sake of brevity I have included it in its shortest form.

Disclaimer: Use these scripts at your own risk!!

-- Declare and set the target server...
DECLARE @TargetServer SYSNAME
SET @TargetServer = N'DB1.DOMAIN.LOCAL'

-- Define a temporary file to store the script output
DECLARE @guidfile VARCHAR(160)
SET @guidfile = '%TEMP%\' + CONVERT(SYSNAME, NEWID()) + '.txt'

-- execute sp_help_revlogin_roles and save the output to the temp file
DECLARE @cmd VARCHAR(8000)
SET @cmd = 'osql -E -n -h-1 -d master -w 8000 -Q "exec sp_help_revlogin_roles" -o "' + @guidfile + '"'
EXEC master.dbo.xp_cmdshell @cmd

-- execute the temp file on the target server
SET @cmd = 'osql -E -S ' + @TargetServer + ' -d master -w 8000 -i "' + @guidfile + '"' --' syntaxhighlighter fail :-(
EXEC master.dbo.xp_cmdshell @cmd

-- delete the temp file
SET @cmd = 'del "' + @guidfile + '"'
EXEC master.dbo.xp_cmdshell @cmd

Click here to view the code for sp_help_revlogin_roles

  • Share/Save/Bookmark
Categories: SQL Tags: , ,

Black Login Screen Showing Logo in Windows 2003

June 22nd, 2009 tcnolan No comments

Have you ever had a login screen show up in Windows where everything is black except for the logo like the image below? This happens sometimes when the system drive on a server fills up, and a bug in windows causing all of the color settings to default to black. It is a pretty common problem, however for some reason Microsoft has not released a KB article about this even though I have seen this happen numerous times.

Black Login Screen With Logo in Windows 2003

Black Login Screen With Logo in Windows 2003

If you ever see this happen on one of your machines, the solution is actually pretty simple. The first thing you will need to do is clear up the disk space on the server. The easiest way is to do this remotely from another server. If you do not have that option, try and type the username in the blank screen, you should see the text cursor move across as if it is recognizing the letters you are typing, which it is. If you don’t see the cursor moving, it may just be waiting for you to press Ctrl-Alt-Del, so press that and try again. Once the username is entered, press tab and enter the password. Then hit enter and you should be able to login without an issue. Once you are logged in you will see that all of the color is back on the screen and you can use the machine like normal and you can now clear up the disk space issue.

Now that the disk space has been cleared up, you will want to make a few changes to the registry. You will want to take a backup of the registry before you make any changes though. For more information on backing up the registry check out the following link http://support.microsoft.com/kb/322756 for Windows XP/Vista… the steps are pretty much the same for Windows 2003. Keep in mind that the next step of editing the registry can be dangerous if things are done improperly and you must do so at your own risk. To quote Microsoft, with one change to refer to this site:

Warning Serious problems might occur if you modify the registry incorrectly by using Registry Editor or by using another method. These problems might require that you reinstall the operating system. TinyInt.Com cannot guarantee that these problems can be solved. Modify the registry at your own risk.

Ok now that that is out of the way, and you have backed up your registry, you can try the following. You can manually edit the registry, specifically the string values located in the key [HKEY_USERS\.DEFAULT\Control Panel\Colors] to match the following block of text. You can also simply start up notepad, copy the text below into a blank document, then save the file to your desktop as something like colors.reg (make sure to change the “Files of Type” to “All Files” so it doesn’t save as a text file) then simply double click on that file on your desktop and click yes to allow it to be imported into your registry. Then you can log off and you should see that the colors have been updated!

Windows Registry Editor Version 5.00

[HKEY_USERS\.Default\Control Panel\Colors]
"ActiveBorder"="212 208 200"
"ActiveTitle"="10 36 106"
"AppWorkSpace"="128 128 128"
"Background"="102 111 116"
"ButtonAlternateFace"="181 181 181"
"ButtonDkShadow"="64 64 64"
"ButtonFace"="212 208 200"
"ButtonHilight"="255 255 255"
"ButtonLight"="212 208 200"
"ButtonShadow"="128 128 128"
"ButtonText"="0 0 0"
"GradientActiveTitle"="166 202 240"
"GradientInactiveTitle"="192 192 192"
"GrayText"="128 128 128"
"Hilight"="10 36 106"
"HilightText"="255 255 255"
"HotTrackingColor"="0 0 128"
"InactiveBorder"="212 208 200"
"InactiveTitle"="128 128 128"
"InactiveTitleText"="212 208 200"
"InfoText"="0 0 0"
"InfoWindow"="255 255 225"
"Menu"="212 208 200"
"MenuText"="0 0 0"
"Scrollbar"="212 208 200"
"TitleText"="255 255 255"
"Window"="255 255 255"
"WindowFrame"="0 0 0"
"WindowText"="0 0 0"
  • Share/Save/Bookmark

Windows 2008 DNS Query Issues with Root Hints

June 9th, 2009 tcnolan No comments

While browsing Newegg looking for some hardware, I came across an issue where the images on their site were not loading.  I couldn’t figure out exactly what was going on since it wasn’t a browser cache issue, and it didn’t seem to be a DNS issue, at least not on my workstation anyway.  After doing a little digging, I tried clearing the DNS cache on our DNS server and everything came up and the images started loading again fine.

Over the course of the last three months this happened a few times, not only for Newegg but for other sites as well, mostly in the .co.uk TLD though.  This happening once was easy enough to dismiss, even happening a second time, ok, but after a third time, there had to be some other underlying issue.  Fortunately, Microsoft released a KB article that explains what is going on and how to get around the problem.  You can read all about it here: http://support.microsoft.com/kb/968372

What is happening is basically that root hints are not updating on the DNS server and SERVFAIL is getting returned to the client requesting the DNS lookup.  This can cause pages to not load on certain domains, including but not limited to .co.uk, .cn, and .br, as well as certain .com’s that I have seen.  Fortunately the fix is easy enough; you can either configure forwarders or simply tweak the TTL of the root hints on your server.  I’m not going to get into the debate of which is better, root hints or forwarders; but for those of you using forwarders this problem will not affect you, and for those of you using root hints, below is a very easy set of commands you can run to fix the problem.

Launch an elevated command prompt and execute the following commands.  This will stop your DNS server, add the Microsoft recommended registry value, and start DNS back up again.

NET STOP DNS
REG ADD HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters /v MaxCacheTTL /t REG_DWORD /d 0x0002a300
NET START DNS
  • Share/Save/Bookmark
Categories: DNS, Windows Tags: , ,

Enumerate Distribution Group Members

May 24th, 2009 tcnolan No comments

Note: Script updated on 2009/07/17 to fix two bugs.  Read more here: http://www.tinyint.com/index.php/2009/07/17/enumerate-distribution-groups-script-updated/


In my organization, we make use of many different groups to separate departments and sub-groups of each department, and many groups build off of this. We also make use of Dynamic Distribution Groups to make things a bit easier on the admin side of things. When tasked with cleaning up these distribution groups and making them easier to manage, it was a bit difficult determining who was supposed to receive mail for what group.

This is because the Get-DistributionGroupMember cmdlet doesn’t have a parameter like –expand which will give you all of the child groups and their members as well. If you have a group called “Engineering” which then has 4 child groups for each department and then each of those groups has each individual mailbox, when you perform “Get-DistributionGroupMember -Identity Engineering”, you will only see the four child groups, not each member of those as well. This became a big issue because of how much we rely on sub-groups in our organization, and after a lot of investigation it turned out there was no way to do this built in directly to any cmdlet, so I wrote a script that would do this for me.  If you need to recursively enumerate distribution group members you are unfortunately out of luck with built in cmdlets.

There are a number of scripts out there that serve a similar purpose as the one I have created, but most do not handle mail contacts or dynamic distribution groups, so I figured if I am going to have to add functionality, I might as well write it myself from the ground up. So now, if you are ever in need of getting child members of a distribution group you can use this script to help you out.

One nice feature here is if you specify “-showTree” as a parameter, it will display a treeview of all the groups. Without -showtree it will just grab all child members and display them in a flat view. The script is pretty long because I included help text that displays if you run the script without any parameters, and for that reason I am just posting it as a download link. Hope this helps a few people out there who went through the same trouble I did finding out that there is no built in way to do this!


Download Link: enumerate_groups.ps1

  • Share/Save/Bookmark

Fix for a hanging server after shutdown in rdp session…

March 25th, 2009 tcnolan No comments

One of my least favorite, and recurring, issues with Windows is one that pops up all the time where you try to reboot a server while you are in a remote desktop session; the RDP session will end but the server never reboots.  In my experience this only happens when you reboot within a normal RDP session, but if you are logged in with the /console or /admin switch it will work fine.  This fix is relatively old, but it is one that is not talked about very frequently.  This can also happen if you are logged into a regular RDP session and are trying to run Windows Updates.

This problem is a result of deadlocks occurring between the NTFS shutdown process and disk resource access.  Usually, your server will remain online responding to ping when this happens, and you can even get into computer management, remote registry, and other things remotely.  Getting back into the server through RDP however does not work because terminal services is already shutting down.  You can read more about this at the link below for the KB article.

Without this fix your options are limited to bring the server down gracefully, in fact many people would just do a hard reset from the power button to finish the reboot.  You can however issue a remote shutdown command from the command line.  Simply run “shutdown /r /t 5 /m \\computer_name” without the quotes to reboot the machine in question.  Make sure you don’t forget the /m switch otherwise you will end up rebooting your own machine.  /t is for the time to wait before shutting down and you can use 0 if you like to shutdown immediately, but this doesn’t give you a chance to send an abort (/a) if you enter the wrong server accidentally. You can also issue “shutdown /i” without the quotes to get the interactive dialog which will let you enter a list of servers to reboot and a few other options.

The Microsoft patch for this can be acquired from the following page: http://support.microsoft.com/kb/930045

Note: This does not solve the problem every single time.  I have seen the issue occur even after applying this patch, but it seems to fix the problem for the vast majority.

  • Share/Save/Bookmark

The problem with SQL Injection…

March 23rd, 2009 tcnolan No comments

Oh yes, Little Bobby Tables we call him.

I know it’s an old comic, but XKCD really hit the nail on the head with this one.  It is something that I deal with on a regular basis and I think there are a lot of people out there who still don’t really understand the concept of SQL Injection, how it works, and how to get away from it.  While working with a client who fell victim to a SQL Injection attack on their website, I wrote some information for them to take and use as reference for what SQL Injection is, how to prevent it, and what to do about it when it happens.  I have generalized that info and hopefully it can help some others.

If you look at the snippet below you have an example of what might show up in your IIS logs if you were hit by one of the many sql injection attacks that have been going around the internet recently. I have changed the information to be similar to one of these common attacks, but modified to be something non-malicious. You can read more about the common attacks that have been happening lately here: http://forums.iis.net/p/1148917/1867511.aspx What the common attacks do, is they search through your entire database and find all varchar, nvarchar, text, and ntext values in every table in the database and update their values to include a reference to a malicious JavaScript on specific websites. Then, when your site displays the value of those fields, you end up displaying the malicious code to the visitors of your site through the new value inserted by the attack. Once that happens the JavaScript can take advantage of any unpatched vulnerabilities on the victims machine and possibly install a virus or spyware. Interestingly, some of these viruses will actually make it so as you are browsing websites it runs SQL injection tests on each of the pages you visit, and when it finds one it will exploit it the same way it was exploited upon you, making the victim the attacker.

2009-03-123 14:59:33 209.73.25.65 GET /page.asp id=248;DECLARE%20@S%20VARCHAR(4000);SET%20@S=CAST(0x435245415445205441424C45205B64626F5D2E5B546573745D280D0A095B69645D205B696E745D204944454E5449545928312C3129204E4F54204E554C4C2C0D0A095B76616C7565315D205B766172636861725D2835313229204E4F54204E554C4C2C0D0A095B76616C7565325D205B6269745D204E4F54204E554C4C2C0D0A090D0A09434F4E53545241494E54205B504B5F546573745D205052494D415259204B455920434C5553544552454420280D0A09095B69645D204153430D0A0929205749544820280D0A09095041445F494E44455820203D204F46462C200D0A0909535441544953544943535F4E4F5245434F4D5055544520203D204F46462C200D0A090949474E4F52455F4455505F4B4559203D204F46462C200D0A0909414C4C4F575F524F575F4C4F434B5320203D204F4E2C200D0A0909414C4C4F575F504147455F4C4F434B5320203D204F4E0D0A0929204F4E205B5052494D4152595D0D0A29204F4E205B5052494D4152595D3B0D0A0D0A414C544552205441424C45205B64626F5D2E5B546573745D204144442020434F4E53545241494E54205B44465F546573745F76616C7565325D202044454641554C5420282831292920464F52205B76616C7565325D3B%20AS%20VARCHAR(4000));EXEC(@S);--|23|800a000d|Type_mismatch:_'[string:__248;DECLARE_@S_VARCH_]' 80 - 83.25.197.62 Mozilla/4.0+(compatible;+MSIE+7.0;+Windows+NT+5.1;+.NET+CLR+2.0.50727) 500 0 0

If this happens to your site, first and foremost you will need to restore your old data into your database to get back what was lost and to remove the dangerous scripts from your webpage so it doesn’t hurt any visitors. If you do not have the option of shutting your site down while you protect the code from SQL injection, it is best to restore the data afterwards, since it could end up being wasted time if someone does SQL injection after the data is restored and before you protect all of the code. Once you have the data restored or before if you can’t take down the site temporarily, you still have to update the vulnerable code on your web application(s). Keep in mind that the location of this code depends on how your site was developed and set up, but it could be anywhere that SQL is called to pull information to display on the site through a querystring telling the page to load a certain database record or where user input is allowed and not validated. These pages would be vulnerable and would need to be fixed.

The part of that querystring from the “;DECLARE” to the “–” is the actual SQL injection code. SQL Server will interperet that because the attacker put a semi-colon after the id number. This tells SQL “this is the end of the command, remaining text is a new command.” Then the “–” tells SQL that the rest is a comment so that in case you are doing other things like sorting the results or grouping anything will not be recognized and SQL will execute the whole command. The CAST part actually just takes a binary value and converts it to a string. The value above converts to the following block of code and just creates a dummy table, whereas a malicious attacker would be doing something much worse.

CREATE TABLE [dbo].[Test](
[id] [int] IDENTITY(1,1) NOT NULL,
[value1] [varchar](512) NOT NULL,
[value2] [bit] NOT NULL,

CONSTRAINT [PK_Test] PRIMARY KEY CLUSTERED (
[id] ASC
) WITH (
PAD_INDEX = OFF,
STATISTICS_NORECOMPUTE = OFF,
IGNORE_DUP_KEY = OFF,
ALLOW_ROW_LOCKS = ON,
ALLOW_PAGE_LOCKS = ON
) ON [PRIMARY]
) ON [PRIMARY];

ALTER TABLE [dbo].[Test] ADD CONSTRAINT [DF_Test_value2] DEFAULT ((1)) FOR [value2];

The next snippet is a perfect example of vulnerable code that would allow SQL injection through. While I am using classic ASP for my example, it could really be any language that doesn’t have a built in mechanism for checking your SQL queries such as PHP, Perl, ASP.Net, etc. Any page which executes an ad hoc SQL query based on a query string passed in or user input, without being validated, will be vulnerable to SQL injection. Instead of using something like conn.execute(“select * from [table] where value=” & request(“parameter”)) you should instead be either using a stored procedure to pass the value (see: http://www.asp101.com/samples/viewasp.asp?file=storedprocs.asp) or at the very least you should be checking the query string parameter for validity before inserting it into your query.

strSQL = "select * from table_name where id_column=" & REQUEST("id") & " order by sort_column"
SET objDB = objConn.EXECUTE ( strSQL )

While stored procedures are the best way to protect yourself, there are still instances where you could have a problem such as if you used a stored procedure where the code was actually generating a dynamic SQL statement internally based on parameters that were passed in, so you would have to protect those SPROCs as well from characters that can cause problems. See also: http://msdn.microsoft.com/en-us/library/ms161953.aspx and http://www.sqlsecurity.com/FAQs/SQLInjectionFAQ/tabid/56/Default.aspx There are many “paged results” stored procedures around where you can say essentially “give me the records for page 4 when we have 50 records per page” and mose of these are vulnerable to the same issue because they make use of adhoc queries such as the one below. The following snippet shows an example of a stored procedure that would not save you here.

CREATE PROCEDURE usp_mySelectFromNameTable
@mName varchar(50),
@mTable varchar(50)
AS
BEGIN
SET NOCOUNT ON;
DECLARE @query varchar(150)
SET @query = 'select id from ' + @mTable + ' where user_name=''' + @mName + ''''
EXEC(@query)
END

In the future, when writing code that will interface with your database, you should always be using parameterized queries for accessing information from the database. It takes a little extra code and effort, but in the long run you are much safer this way. If there were ever a case where you were storing usernames, passwords, and other personal data, in theory someone could use SQL injection to actually retrieve that information from your database and would have access to any other information available as well.

SQL Injection is a very real problem(http://news.google.com/news?hl=en&q=sql+injection+attack) that is continually being exploited due to lazy programmers, sloppy coding, or sadly, sometimes when a developer is just rushed through a project and they forget. We all need to remember to do proper checks of our inputs and paramaterize our queries and hopefully this issue will be less of a problem… at least until the next technology comes out with a different way to exploit it.

  • Share/Save/Bookmark
Categories: SQL Tags: , , , , ,