Network Defense by Rik Farrow Anatomy of a hack While hacking has never gone out of favor, the notion of putting a system up on the Internet and inviting hackers to have a go at it goes in and out of fashion. In the summer of 1999, the hacker's challenge was very much in fashion, with a several challenges. Microsoft exposed an Windows 2000 Web server, which soon disappeared from the net, only to reappear later with claims of power failure (that affected only that system). The Linux PPC (Linux on the PowerPC architecture) group put up a system which you could have if you cracked the Web server. After seven weeks, and no crashes or cracks (and only one reboot), the PPC folks ended the on-line challenge (because people were attacking their ISP). In an unrelated challenge, PCWeek labs hosted an NT system and an Linux on Intel system. After several days, the Linux system was cracked, while the NT system was still uncracked. Rather than trying to glean information about the relative security of these two operating systems, what is more interesting is reviewing the steps that the hacker took in replacing the home page (the challenge) on the Linux-based Apache Web server. Jfs, the handle used by the Spanish cracker of the Linux system, provided a record with some of his probes, and a lot of his thought processes, which you can find at his Web site (see Resources). His successful attack illustrates nicely what I consider typical strategy in breaking into any computer system, whether it runs UNIX, NT, or some other operating system. And his success was also based upon mistakes in configuration and management of the targeted system, something that we can all learn from. Recon The beginning of any attack comes with selecting the potential target. In many cases, almost any system will do, especially when the goal is to set up a relay system that can be used to hide the source of an attack. But in this case, the target was known in advance, as PCWeek not only had advertised the address, but also offered an award of $1000 for the person who could successfully replace the home page on either target machine. With a choice like this, hackers tend to go after the most familiar system. But if the target system happened to be NT (and there was no choice), this would matter little. With the address of the target in hand, the hacker port scanned the target. Port scanning reveals TCP-based servers, such as telnet, FTP, DNS, and Apache, any of which are potential access points for an attacker. Further testing, either with telnet or netcat (see Resources), revealed that most of the potentially interesting services refused connections, with Jfs speculating that TCP wrappers was used to provide access control. The Web server port, 80/TCP, had to be open for Web access to succeed. Jfs next used a simple trick. If you send GET X HTTP/1.0 to a Web server, it will send back an error message (unless there is a file named X) along with the standard Web server header. The header contains interesting facts, such as the type and version or the Web server, and sometimes the host operating system and architecture (Listing 1). Information like this is gold for an attacker. As the header information is part of the Web server standard, you can get this from just about any Web server, including IIS. As the source code is available for Apache, some sites might consider dissembling a bit, perhaps by describing their server as NT 4 running IIS, in the server reply header. The notice that announced the hack also mentioned that mod-perl was installed. But mention of mod-perl did not appear in the header (it would have if installed). Still, Jfs tried a mod-perl attack, as well as a server side include attack. In both of these, by sending a carefully crafted browser request, a vulnerable Web server could be tricked into sending back files that should not have been accessible through the Web server. Both of these attempts failed. Jfs next navigated through the Web site, working out the directory structure based on links. He found both a cgi-bin directory (standard for Apache, but with nothing of interest in it) and a /photoads/cgi-bin directory, that did look promising. Jfs viewed a copy of the source to the photoads Perl scripts that a friend had, looking for mistakes in the code. Using a recent Phrack article, he found several potentially exploitable mistakes in the Perl code. CGI and UNIX CGI, the Common Gateway Interface, provides the most commonly exploited means of breaking into UNIX Web servers. CGI permits programs to process forms or the contents of URLs, and the result of this process gets formatted as a Web page for the requestor. NT typically does similar things in the Scripts directory and with ASP (Active Server Pages) scripts. The weakness that gets exploited on UNIX systems has to do with the scripts written to process the requests. CGI script writers generally assume that their users will play by the rules, and that is something you should expect will NOT happen anytime you program, but especially when writing Internet applications. In particular, any variable that can be affected by a remote user and is used in the script can potentially be abused. Jfs, through reading of the Perl scripts used in photoads, discovered that though the script writers had generally been very careful to strip out potentially dangerous metacharacters in user input, had missed the HTTP_REFERER variable, that was used to test the potential for mod-perl and server side includes. Jfs also discovered a variable named 'filename' that, although it goes through filtering and tests, might be exploitable. The filename variable gets set through form input, but then is checked to see if it includes any number of dot-dot (..) the characters used on UNIX and NT to indicate the parent directory. Tricks involving filenames with dot-dot permit an attacker to point a filename to some otherwise off-limits area. The other test involved checking for a suffix of .gif or .jpg, as well as for a reasonable heigtht vs width values. Jfs found ways around all of these tests. For example, the test for a suffix of .gif or .jpg can be foiled by inserting a null character into the filename, %00 for the Web, and \0 for C programmers. Perl permits the inclusion of nulls in variables, but the UNIX system, written in C, treats a null as the end of a string. So, index.html%00.gif passes the test in the photoads script, but refers to the index.html file, the target. In the actual attack, Jfs used a much longer filename to specify the full pathname to the target index.html file. The script also contained a test for parameters read from the header of either a GIF or JPEG file. But Jfs realized that values of zero could satisfy the GIF tests, so any file that contained zeroes in the sixth and ninth byte would be accepted. Then Jfs discovers another hurdle: only filenames consisting totally of digits are accepted, and are then renamed. This test blows away his attempt to point filename at the location of his choice. Twists Or does it? On Linux systems, there is a limit to the total filename length of 1024, and filenames surpassing this limit cause the rename system call to fail. And the script under attack simply assumes that the rename succeeds, leaving the way open for Jfs to specify the filename of his choice--if he uses a long filename, following a return (%0a) and 1024 digits. At this point Jfs attempts to use this trick to overwrite the target index.html file, but this fails. Most likely, index.html has permissions and ownership preventing a script to overwrite it (scripts under Apache will run as the nobody user unless changed in the configuration file). So, it is time for another approach. Permissions on the scripts in the photoads/cgi-bin directory permit the nobody user to overwrite them. Allowing these scripts to be written (or owned) by the nobody user is a configuration mistake that you should avoid. Jfs had discovered a script named advisory.cgi that is apparently not used elsewhere (or in his attack), and should be a candidate for overwriting. The easy thing to do would be to upload a shell script, but there is a problem. The test for correct height and width prevents putting the magic characters that must begin a shell script (#!/bin/sh) here, as the sixth through ninth bytes must be either zero or very small, and "n/sh" won't work. But the header format for an executable file on Linux running on i386 does contain zeroes in the critical bytes. So, Jfs could upload a compiled program to replace advisory.cgi. But there is a limit set by Apache on the maximum URL size. The program must fit after the long ad number filename (over 1024 bytes), but be less than 7000 bytes after being converted to HTML encoding (where each byte gets converted into three characters, for example, zero becomes %00). Even the simplest program turned out to be too large. Jfs surmounts this difficulty by hand stripping the executable files to bring them down to an acceptable size. Jfs wrote several programs that he could execute by overwriting advisory.cgi, and using http://securelinux.hackpcweek.com/photoads/cgi-bin/advisory.cgi to execute them. Note that you can write C programs instead of using scripts for your Web server, and be a lot safer (well, if you are a good C programmer, and avoid things like system(), popen(), and the execl*() system calls). Now, Jfs can execute arbitary code, within limits, but cannot overwrite the target file. The solution? Get root. A root exploit for the version of Linux used on the target system had appeared on Bugtraq just weeks previous. This exploit involved the use of cron (the clock daemon, similar to at under NT) and cron's use of sendmail to deliver notification to the user. The exploit can be used to run arbitrary scripts as root, and Jfs uses this to create a SUID root shell that can also execute arbitrary scripts or commands as root. Then, he uploads his own version of the index.html file, and uses the SUID shell to overwrite the target version. Game over. Collect $1000. Epilog There had been a patch for the cron vulnerability used in this successful attack. Also, there were several places where the use of correct file permissions and ownerships would also have foiled the attack. Small mistakes in the Perl scripts in the photoads/cgi-bin directory provided the initial toehold. In other words, with a little attention to detail, and better system administration, the attack would have failed. At least, this version of it. What I found so interesting in this attack, which Jfs said took twenty hours, were the many twists and turns. Also, the use of one bit of information, the directory layout, that lead to finding the vulnerable scripts, that lead to overwriting a script, that lead to uploading executable code, that finally lead to uploading an exploit and success. Not a straight path to success at all, but a crooked one illustrating how many factors can lead to a compromise. As usual, success is in the details--for both the attacker and the defender. Listing 1: Web servers will reveal information about their version number (and sometimes more) by making a simple request. You can use telnet or nc (netcat) for this, but not a Web browser or wget (a UNIX tool), as these hide the server's header: [NOTE to NETWORK: You can delete down to next NOTE if you need the space RIK] 246 ) nc securent.hackpcweek.com 80 GET X HTTP/1.0 HTTP/1.1 400 Bad Request Server: Microsoft-IIS/4.0 Date: Mon, 04 Oct 1999 23:09:45 GMT Content-Type: text/html Content-Length: 87 ErrorThe parameter is incorrect. [NOTE: END of possible deletion RIK] 247 ) nc securelinux.hackpcweek.com 80 GET X HTTP/1.0 HTTP/1.1 400 Bad Request Date: Mon, 04 Oct 1999 23:21:56 GMT Server: Apache/1.3.6 (Unix) (Red Hat/Linux) Connection: close Content-Type: text/html 400 Bad Request

Bad Request

Your browser sent a request that this server could not understand.

Invalid URI in request GET X HTTP/1.0

248 ) Resources: The PCWeek labs site, with pointers to notes from the successful attacker: http://www.hackpcweek.com/ The hacker's own site: http://hispahack.ccc.de/en/mi019en.htm In response to the Microsoft Windows 2000 challenge, The Linux on the PowerPC site had a Linux box up for seven weeks without being cracked: http://crack.linuxppc.org/ The Windows2000 test site: http://www.windows2000test.com/ Phrack magazine, where you can find issue 55, article 7, with some notes about common mistakes in Perl CGI scripts: http:/www.phrack.com Home Office Online, the sellers of the PhotoAds scripts that had some minor problems: http://www.hoffice.com Sources for netcat include http://www.avian.org/ and http://www.l0pht.com/. Bugtraq can be found at http://www.securityfocus.com/ under Forums