CSC 489 Day 16: Web server security and CGI attacks

Reading:
  1. The World Wide Web Security FAQ
  2. The CGI Security FAQ
Two of the main forms of attack these days seem to be attacks on web servers, and attacks on end users' via e-mail. E-mail attacks are typically viruses sent as Windows executables or macros in Windows files that exploit the numerous flaws in Microsoft's applications. You can attempt to detect and filter such attacks at the mail server, but ultimately it is the end user's responsibility to not run strange binaries sent by mail, and not run software applications that cause them to have their hard disk reformatted in response to the act of receiving an e-mail.

Today we will consider web server security and CGI attacks. Any internet server is subject to attacks and exploitable bugs, but most servers that reach wide use are carefully written by experts, and are mature (i.e. relatively carefully checked and debugged) by the time they are deployed on a wide scale. The basic problem is that every CGI script is essentially a miniature internet server, accessible by anyone, and new CGI scripts are written every day by novice programmers with no idea of what they are doing. The "CGI in Perl for Dummies in 24 Hours" crowd, and even many experienced Perl programmers who are not security oriented, may write CGI code with exploitable bugs. Some of the ideas here come from Phrack magazine, Vol. 9 Issue 55.

CGI scripts may be exploited to obtain information about the system that will help hackers break in. Hackers often want to get a regular user login account in order to rifle through directories or look at world-readable /etc files in order to see how they might try to get root access, and a CGI script with exploitable bugs may let them acquire the same information without a user login.

A second and more dangerous kind of CGI bug occurs in CGI programs that process forms input. Forms are useful and can be done safely, but some CGI programs use forms input unsafely and can be tricked into executing other programs (specified by the hacker) while processing forms input. Executing other programs might not seem dangerous if the CGI program is executing with "nobody" permissions, but on many or most systems, this is a critical security breach with which the wily hacker might:

Poison NUL

Poison NUL exploits are based on semantic differences between programming languages. For example Perl and C both have a concept of strings, but C strings are NUL terminated, and Perl strings can contain NUL. When Perl functions are implemented by calling underlying C language runtime functions, some string values will be interpreted differently by C than by Perl; for example, a Perl string with a NUL in the middle will be a shorter C string with the bytes after the NUL truncated.

If you are writing CGI scripts in C, this is not an issue, but if you are writing them in Perl, it can be. If the Perl code itself is then responsible for some of the security checks, it can be fooled. Consider code fragments such as

	if ("root\0I am invisible" ne "root")  # ... do stuff
or
	$file="/etc/passwd\0and stuff"
	die("no opening /etc/passwd!") if ($file eq "/etc/passwd");
	if (-e $file) {
		open(FILE, ">$file");
	}
In either case, Perl operators such as ne or eq consider the strings to be allowable, but the underlying C functions will take those strings to access precisely the names the Perl code is trying to disallow.

There are a couple of morals here. The one from Phrack magazine is: check your string data for bogus characters like NUL bytes. My addition to this is: don't run CGI's with any sort of root access privileges, and keep your regular system configuration files invulnerable to attacks from regular users. CGI's may be run by people without a valid user account on your system, so they should have even less access than regular users, if anything. The problem is that CGI scripts, in order to be cool and powerful, may need to run many programs and combine them in interesting ways in order to produce their normal intended output. Both the CGI programmer and the CGI administrator have to be very careful to provide functionality without compromising security.

Some other Perl-specific exploits

In Perl, if the filename given ends in a pipe character (|), the file is executed as a program instead of opened and read as data. A CGI script that thinks it is just giving web users the ability to open and read public files might actually be giving them the ability to run programs.

Of course, these different exploits can be used in combination. Suppose you are protecting your code from and users running programs by using

	if (!(-e $filename)) exit;
Well, a user can use a poison NUL byte, as in
	$filename="/bin/ls\0|"

Also in Perl, open() defaults to reading, but the initial characters of the string filename given can supply another mode, such as writing. This means if you default your call to open() in a CGI script, as in

	open(FILE, $filename)
You think they are reading but a wily hacker can be writing, by beginning his filename with a > character. If you explicitly specify your mode as in
	open(FILE, "<$filename")
you save yourself a lot of grief. Perl is NOT the only or best CGI scripting language and other very high level scripting languages may not have all these vulnerabilities. Do people actually write code with these kinds of vulnerabilities? Yes. Whether they are exploitable depends on the rest of the system security.

Some real-world CGI's with security holes

Many of these are historical, but older copies of software tend to lie around in use by lazy sites for years. This is from the w3.org security faq.

Some reasonable CGI rules of thumb

Do not use a pure interpreted scripting language for CGI, in which hackers can obtain your source code like they can your HTML documents. If they can study your source code they are more likely to find bugs and exploits.

Do not use a CGI script in the public domain, since hackers have its source code, without studying its code carefully to ascertain its safety. If other organizations more paranoid than you are using it, it might be more likely to be secure, but don't count on it.

Be especially leery of scripts that read or write files on the host system. It is possibly to exploit a script that is calling a SQL database to read and write records, but it is much easier to exploit a script that is calling open() to read and write files.

Check your input values VIGILANTLY. Abnormal user input is how the hacker tricks your program into doing something unintended. If your program checks every input carefully, it will in general do what you intended to do, and/or detect attempts to subvert it.

Homework

Some of this e-mail is catching up with stuff done earlier, which wasn't convenient for us to check until we were on the net.
  1. Send Dr. J an e-mail showing the output of the quota command for his account.
  2. Send Dr. J an e-mail showing the relevant crontab line, and a copy of whatever commands or script you use to perform his daily and hourly backups.