In the past days I came across a stimulating blog post titled "Dissecting a Multistage Web Attack that uses the recent IE7 0day". The authors described how a vulnerable web application was then able to infect web browsers visiting the infected website. The attackers, who used an IP that originates from China, made a lot of attempts (presumably using automated tools) to inject SQL statements (SQL Injection) through the web application. The attacker's favorite method of penetration appears to be SQL injection probably since it is so prevalent. However this particular web application was not vulnerable to SQL injection and therefore they had to move on to a different attack vector.
The attackers looked around for vulnerable ASP pages and identified a library that allows users to upload images. Attackers are known to exploit upload forms by uploading CGI scripts such as EXE, PHP or ASP files to the web server. When these files are accessed through the web server, the web server tries to interpret or execute these files as legitimate CGI or ASP. This means that code is executed on the server side and this code can be anything from a normal web application to a backdoor allowing remote access to the server. In this case, this library had taken precautions to only allow certain file types to be uploaded. The image library made sure to only allow files with certain file extensions (.gif, .jpeg etc) and possibly checked the contents of the files to make sure that it is indeed an image.
So how were the attackers able to execute remote code on the victim web server?
The attackers made use of a filename with the extension .CDX. Such files can refer to various file types, one of which is a graphics file type used by Corel Draw. Additionally, by default IIS interprets CDX files as ASP scripts. This image library allowed users to upload files with this extension and store it on the web server. However the image library could also check if the contents of the file contain an image or not. To bypass that check, the attackers included the contents of a real GIF file and embedded some VBScript code. The image library would detect the GIF file and allow the upload to take place, while the IIS server would interpret the VBScript code just similar to any other ASP script on the server. This combination keeps everyone (both IIS and the image library) happy, and therefore the attacker gets execute his or her custom VBScript code on the IIS server just as if he had uploaded an ASP file!
Once the CDX file was uploaded, the attacker then started sending it commands. In this particular case, the attacker uploaded a variation of a well known ASP backdoor that is typically used by Chinese speakers. From this point on the web pages were modified to include code that exploited a security hole in Internet Explorer. This meant that visitors who went to the infected website could end up running arbitrary code on their desktop computers. Such code usually installs backdoors and spyware on the victim machines. To keep tabs on this story and how it develops visit the Attack research blog which should be posting a juicy update soon.
How does one prevent similar attacks?
Since filtering by file extension was bypassed, it might appear that an appropriate fix would be as simple as making sure that CDX files are not successfully uploaded to the server. However this fix is not hacker proof and it alone does not provide a complete solution. Such a solution will only be sufficient until attackers find another way of bypassing this security mechanism.
To solve this issue we should be looking at the source of the problem. Allowing files in the "images" or "uploads" directory to be executed by the server is probably the main culprit. Setting the correct permissions on the web server to only read such files would be a good solution to this issue. Additionally, if anonymous uploads are not needed, then it is a good idea to avoid providing that functionality in the first place.
Note that this solution does not do much to prevent the GIFAR attacks that target the client-side rather than the server-side. But that will be for another post.