NETWORK DEFENSE

by Rik Farrow

DATABASES UNDER FIRE

MS SQL AND ORACLE SERVERS ARE OFTEN EXPOSED TO ATTACKS--THROUGH YOUR WEB SERVER

In my February 2002 column I urged people to keep database servers behind firewalls.
Now, I have to urge you to take the next step and secure those database servers. Attacks known as SQL Injection or SQL poisoning have been popular for over a year, and rely on poor database server configurations, programming errors, and unpatched servers.

Some of the problems with database servers will be familiar. Microsoft posted two security bulletins in February 2002 about buffer overflows in SQL Server. But SQL injection may not be as familiar, even though it too has been the subject of Microsoft Security Bulletings.

Oracle has taken its licks too. The very same day that Oracle CEO Larry Ellison boasted that no one could break into the Oracle 9iAS server, Security Researcher
David Litchfiled demonstrated techniques for doing so at the Blackhat Security Briefing in Amsterdam. Let's take a look at some of the ways that real "black hats" may be compromising your SQL servers.

ORACLE

Litchfield had already been researching weaknesses in Oracle 9iAS when Ellison boasted of Oracle security. Litchfield, of NGS Software Ltd (www.ngssoftware.com), had been working on a commercial scanning tool that would audit Oracle servers for flaws in application logic. Litchfield had focused on five of the front end application environments used to access Oracle 9iAS from Web servers, and found buffer overflows, denial of service, ability to read scripts, remote administration of the server, and execution of arbitrary commands.

Of course, this news will be old when you read this, and if you use Oracle 9iAS, you will surely have installed the patches of workarounds for all of these issues. But I consider it worthwhile for network security people, who aren't database admins, to better understand the issues raised by Litchfield.

Figure 1 shows how the various components of Web server using a backend database server are arranged. Firewalls protect both the Web server and the internal network, only permitting limited access between the Web server and the internal network. In the case of MS SQL, the problem is easier, as SQL Server listens at a single, known port (1433/tcp by default, although this port number can be changed through configuration). Oracle servers use a more complex system, where a TNS (Transparent Network Substrate) Listener listens at port 1521/TCP, and arranges for connections to the actual server. For firewalls, this means that a simple packet filtering rule will not work, but an application gateway or stateful packet filter rule that understands the TNS Listener protocol must open connections for access to the Oracle server.

The front end software, that runs on the Web server itself, can be written in many different programming languages. Litchfield reported the most problems in PL/SQL (Procedural Language/ Structured Query Language). PL/SQL had buffer overflow issues, directory traversal issues, remote administration of DADs (Database Access Descriptors), and the ability to display source code and database schema information. Litchfiled also demonstrated a technique to bypass authentication, through the use of utility procedures included in a default install of Oracle 9iAS (the OWA_UTIL package).

The Oracle Java Servlet programming interface permitted reading the source code for the Java servlets themselves. The Java source code files are created on the fly in directories that should be protected, so that remote users cannot access them. Oracle uses the Apache Web server, even when used on Windows 2000 systems, so you need to follow instructions for configuring Apache to prevent access to the directories containing these files.

Usernames and passwords are exposed if remote users are permitted to read scripts or source code. A connection to the SQL server requires a valid username and password combination, and this combination can be found in a software used on Web servers-- if it can be read. The same information can also be found in configuration files on the Oracle server, and Litchfield also provided tricks for viewing this data as well.

To make matters worse, Litchfield reported that it is not uncommon for programmers and database administrators to leave default passwords unchanged. Litchfield listed 160 default username and password combinations.

The TNS Listener had vulnerabilities of its own. If an attacker can connect to the Listener, the attacker could potentially load any library on the system where the attacker is located, and execute functions found in that library. Both UNIX and Windows 2000 libraries include the system() function, that can execute programs with the privileges of the Listener process. The TNS Listener will normally be protected by firewall rules from connections by external attackers, except one coming from the Web server itself.

While this litany of exploits makes Oracle security sound pretty poor, Oracle has worked at building secure software, and has a history of hiring external auditors to examine its code, and has sought (and actually acchieved) some trusted system evaluations. And all of these attacks have corresponding patches or workarounds that can be found at the Oracle patch site (see Resources).

SQL INJECTION

SQL injection, or SQL poisoning, should actually be familiar to anyone who has read my articles about securing Web servers. SQL injection is an attack very similar to those that are used against CGI (Common Gateway Interface) programs or scripts. In SQL injection, the attacker includes something in a response from a Web browser that the script writer didn't anticipate. The main difference between SQL injection and other CGI attacks is that the attack relies on some basic understanding of SQL.

Structured Query Language was originally an invention of IBM, and is now an ANSI standard. With SQL,
someone who is not a programmer can make requests to a database server and perhaps even get back the information requested. Of course, SQL is really not that simple, and it is possible for a naive SQL user to make very resource intensive SQL queries, or, more likely, get nothing back but incomprehensible error messages.

For our purposes, all you really need to know about is a very basic database query request, SELECT. The basic syntax for a SELECT request is "SELECT _select-list_ From _table-name_ Where _condition_". This roughly translates to: "Select the data matching the select-list from table-name that matches this condition." In an ASP script, the SELECT string might be built first, so it can be passed later to a Microsoft SQL Server using a line like:

<pre>
sql_query = "SELECT * FROM PRODUCTS
WHERE ID = " & Request.QueryString("CAT") </pre>

The call Request.QueryString("CAT") extracts the value of the Web form variable "CAT" so it can be appended as the SELECT condition, for example "CAT = blenders". Now, SQL server can return all rows matching the category "blenders".

But, there is a problem with this script fragment. The value of the "CAT" variable is blindly accepted. What if the wiley attacker had sent "blenders+OR+1=1"? Now, the condition will always be true, and all rows will be returned. If the database table named PRODUCTS contains nothing that must remain confidential, that really isn't much of a problem. But, suppose the request was for customer account information, or something else that should be kept private?

SQL Server treats the non-printing character one, represented in URL encoding as %01, as a line delimiter. When the Web server script does not check the value provided by the remote "user", the value could be "blenders%01DROP+TABLE+PRODUCTS". Dropping a table means to delete it from the database, and is probably not something you want.

The most interesting attack comes through the use of stored procedures. Stored procedures are SQL subroutines, some of which come bundled with your SQL server. For Microsoft's SQL Server, the extended stored procedure xp_cmdshell executes programs in the context of the SQL Server, which you (hopefully) have configured as some special account with few privileges (like Guest group, and Login as a Service privilege). Software Development Kits (SDK), like the ones that come with .NET, use the default account, sa, a member of the Administrators group, and while this is convenient for a programmer, it is a disaster for security.

Again, using the same SELECT example, the attacker sets the value of "CAT" to be "blenders%01EXEC+master..xp_cmdshell+ net+user+crack+secret+/ADD". If SQL Server is running as the sa user, you now have a new user account named "crack" with a password of "secret". A second SELECT statement could be used to add the "crack" user to the Administrators group.

SQL Server has other, interesting extended stored procedures, for registry access and database administration (adding users, changing passwords, etc.). If you are running MS-SQL Server, it is also possible to access MS-SQL Server, and these procedures, using pipes connecting to port 139/TCP.

By now, I am hoping that you have gotten the point. Your front end software, whether it be PL/SQL or ASP, cannot blindly accept input from remote users. You must filter the input so that it will resemble what you expect. If it is a number, check to see that the value contains only digits and dots. If it is a name, check to see that the value contains letters (and dots and dashes) that can occur in a person's name. And so on.

If this seems painfully obvious, a company running the Microsoft Developers Store Web site, under contract to Microsoft, had this very problem in January 2002 (see Resources). And they are not the only site, by any means.

One organization, the Open Web Application Security Project, is working on developing a set of filters that will block evil characters (like %01), and make it easy to configure filters that will only permit the answers you expect in a value. Of course, you can do a lot of this today, just by carefully checking the value of any variable you will be reading from the remote Web browser.

LOCKDOWN

Adding a database backend to your Web server adds lots of functionality, and lots of potential security holes. The usual rules for securing servers apply to backend database servers as well. That is, secure the server, and run the database process with the lowest privileges possible.

Securing servers is something I have often written about. What has changed over time is that the position of Microsoft servers has shifted when compared to Linux systems. Windows 2000 Professional Server comes, with a default installation, with dozens of network services, while new Linux distributions come with most everything disabled.

The user account that runs the database server should be a nonprivileged user. You might encounter several problems here, as Oracle wants to run as LocalSystem, and many software packages that come with a bundled MS-SQL Server will use the default sa account.

The usual admonitions to install security patches as soon as possible apply to databases as well. Both Oracle 9iAS and MS-SQL (both 7 and 2000 versions) have numerous security patches that must be applied, and this will be true for other SQL servers as well.

Just because you don't understand SQL servers doesn't mean that attackers don't either. All it takes is for one person to write an exploit, and your site is toast. Secure your servers.

RESOURCES:

MS SQL FAQ and search tool sqlping: http://www.sqlsecurity.com

Input filters for Web server applications: http://www.owasp.org/

Microsoft Developer's store vulnerable to SQL poisoning: http://online.securityfocus.com/news/307

Presentations and recordings of past BlackHat conference presentations (look for David Litchfield, JD Glaser, Chip Andrews and others): http://www.blackhat.com/html/bh-multi-media-archives.html

David Litchfield's site, with software and presentations: http://www.ngssoftware.com/

Oracle site for downloading patches: http://metalink.oracle.com/