- Shopping Bag ( 0 items )
Featuring real-world examples using UNIX, Windows, and Cisco routers and switchers, this nuts-and-bolts guide helps computer professionals make a meaningful security assessment of their systems by understanding hackers' methods. Tables summarize key information and little-known intrusion detection tips are listed in an appendix.
Being on the Internet means the application is remotely accessible by other people. If coded poorly, the application can leave your system open to security vulnerabilities. Poor coding can be the result of lack of experience, a coding mistake, or an unaccounted-for anomaly. Large applications are often developed in smaller parts consecutively, and joined together for a final project; it's possible that there exist differences and assumptions in a module that, when combined with other modules, results in a vulnerability.
Notes from the Underground…
Politics as Usual
The battle between application developers and network administrators is ageless. It is very hard to get non-security-conscience developers to change their applications without having a documented policy to fall back on that states security as an immediate requirement. Many developers do not realize that their application is just as integral to the security posture of a corporation as the corporation's firewall.
The proliferation of vulnerabilities due to unexpected data is very high. A nice list can be found in any Web CGI (Common Gateway Interface) scanner (cgichk, whisker, etc). Most CGIs scanned for are known to be vulnerable to an attack involving unexpected user input.
Three classes of attack can result from unexpected data:
The actual format of the unexpected data varies; an "unexpected data" attack could be as simple as supplying a normal value that modifies the application's intended logical execution (such as supplying the name of an alternate input file). This format usually requires very little technical prowess. Then, of course, there are attacks that succeed due to the inclusion of special metacharacters that have alternate meaning to the application. The Microsoft Jet engine had a problem where pipes ( | ) included within the data portion of a SQL query caused the engine to execute Visual Basic for Applications (VBA) code, which could lead to the execution of system commands. This is the mechanism behind the popular RDS (Remote Data Services) exploit, which has proven to be a widespread problem with installations of Internet Information Server on Windows NT.
Normally this isn't a large problem-if a user does something bad, the application crashes and that's that. However, in the Unix world (which now includes the Macintosh OS X world as well), some of these applications have special permissions called 'set user id' and 'set group id'. This means the applications will run with elevated privileges compared to that of the normal user. So while tricking a normal application might not be of much benefit, tricking a suid or sgid application can result in the privilege to do things that are normally limited to administrator types. We'll look at some of the common ways to trick these types of applications later in this chapter.
The biggest mistake applications make is relying on the HTTP referer header as a method of security. The referer header contains the address of the referring page. It's important to note that the referer header is supplied by the client, at the client's option. Since it originates with the client, which means it is trivial to spoof. For example, we can telnet to port 80 (HTTP port) of a Web server and type:
GET / HTTP/1.0 User-Agent: Spoofed-Agent/1.0 Referer: http://www.wiretrip.net/spoofed/referer/
Here you can see that we submitted a fake referer header and a fake user agent header. As far as user-submitted information is concerned, the only piece of information we can justifiably rely on is the client's IP address (although, this too can be spoofed; see Chapter 12 for more information on spoofing).
Another bad assumption is the dependency on HTML form limitations. Many developers feel that, because they only gave you three options, clients will submit one of the three. Of course, there is no technical limitation that says they have to submit a choice given by the developers. Ironically enough, I have seen a Microsoft employee suggest this as an effective method to combat renegade user data. I cut him some slack, though-the person who recommended this approach was from the SQL server team, and not the security or Web team. I wouldn't expect him to know much more than the internal workings of a SQL server.
So, let's look at this. Suppose an application generates the following HTML:
<FORM ACTION="process.cgi" METHOD="GET"> <SELECT NAME="author"> <OPTION VALUE="Ryan Russell">Ryan Russell <OPTION VALUE="Mike Schiffman">Mike Schiffman <OPTION VALUE="Elias Levy">Elias Levy <OPTION VALUE="Greg Hoglund">Greg Hoglund </SELECT> <INPUT TYPE="Submit"> </FORM>
Here we've been provided with a (partial) list of authors. Once receiving the form HTML, the client disconnects, parses the HTML, and presents the visual form to the user. Once the user decides an option, the client sends a separate request to the Web server for the following URL:
Simple enough. However, at this point, there is no reason why I couldn't submit the following URL instead:
As you can see, I just subverted the assumed "restriction" of the HTML form. Another thing to note is that I can enter this URL independently of needing to request the HTML form prior. In fact, I can telnet to port 80 of the Web server and request it by hand. There is no requirement that I need to request or view the prior form; you should not assume incoming data will necessarily be the return result of a previous form.
Of interesting note, using the size parameter in conjunction with HTML form inputs is not an effective means of preventing buffer overflows. Again, the size parameter is merely a suggested limitation the client can impose if it feels like it (i.e., understands that parameter).
If there ever were to be a "mystical, magical" element to HTTP, it would definitely involve cookies. No one seems to totally comprehend what these little critters are, let alone how to properly use them. The media is portraying them as the biggest compromise of personal privacy on the Web. Some companies are using them to store sensitive authentication data. Too bad none of them are really right.
Cookies are effectively a method to give data to clients so they will return it to you. Is this a violation of privacy? The only data being given to you by the clients is the data you originally gave them in the first place. There are mechanisms that allow you to limit your cookies so the client will only send them back to your server. Their purpose was to provide a way to save state information across multiple requests (since HTTP is stateless; i.e., each individual request made by a client is independent and anonymous).
Considering that cookies come across within HTTP, anything in them is sent plaintext on the wire. Faking a cookie is not that hard. Observe the following telnet to port 80 of a Web server:
GET / HTTP/1.0 User-Agent: HaveACookie/1.0 Cookie: MyCookie=SecretCookieData
I have just sent the "MyCookie" cookie containing the data "SecretCookieData." Another interesting note about cookies is that they are usually stored in a plaintext file on the client's system. This means that if you store sensitive information in the cookie, it may stand the chance of retrieval.
The Structured Query Language (SQL) is a database-neutral language syntax to submit commands to a database and have the database return an intelligible response. I think it's safe to say that most commercial relational database servers are SQL compatible, due to SQL being an ANSI standard.
Now, there's a very scary truth that is implied with SQL. It is assumed that, for your application to work, it must have enough access to the database to perform its function. Therefore, your application will have the proper credentials needed to access the database server and associated resources. Now, if an attacker is to modify the commands your application is sending to your database server, your attacker is using the preestablished credentials of the application; no extra authentication information is needed on behalf of the attacker. The attacker does not even need direct contact with the database server itself. There could be as many firewalls as you can afford sitting between the database server and the application server; if the application can use the database (which is assumed), then an attacker has a direct path to use it as well, regardless.
Of course, it does not mean an attacker can do whatever he or she wishes to the database server. Your application may have restrictions imposed against which resources it can access, etc; this may limit the actual amount of access the attacker has to the database server and its resources.
One of the biggest threats of including user-submitted data within SQL queries is that it's possible for an attacker to include extra commands to be executed by the database. Imagine we had a simple application that wanted to look up a user-supplied value in a table. The query would look similar to:
SELECT * FROM table WHERE x=$data
This query would take a user's value, substitute it for $data, and then pass the resulting query to the database. Now, imagine an attacker submitting the following value:
1; SELECT * FROM table WHERE y=5
After the application substitutes it, the resulting string sent to the database would be:
SELECT * FROM table WHERE x=1; SELECT * FROM table WHERE y=5
Generically, this would cause the database to run two separate queries: the intended query, and another extra query (SELECT * FROM table WHERE y=5). I say generically, because each database platform handles extra commands differently; some don't allow more than one command at a time, some require special characters be present to separate the individual queries, and some don't even require separation characters. For instance, the following is a valid SQL query (actually it's two individual queries submitted at once) for Microsoft SQL Server and Sybase databases:
SELECT * FROM table WHERE x=1 SELECT * FROM table WHERE y=5
Notice there's no separation or other indication between the individual SELECT statements.
It's also important to realize that the return result is dependent on the database engine. Some return two individual record sets as shown in Figure 7.1, with each set containing the results of the individual SELECT. Others may combine the sets if both queries result in the same return columns. On the other hand, most applications are written to only accommodate the first returned record set; therefore, you may not be able to visually see the results of the second query-however, that does not mean executing a second query is fruitless. MySQL allows you to save the results to a file. MS SQL Server has stored procedures to e-mail the query results. An attacker can insert the results of the query into a table that he or she can read from directly. And, of course, the query may not need to be seen, such as a DROP command....
|Foreword v 1.5||xxix|
|Foreword v 1.0||xxxiii|
|Chapter 1||How To Hack||1|
|Chapter 2||The Laws of Security||11|
|Chapter 3||Classes of Attack||45|
|Chapter 7||Unexpected Input||205|
|Chapter 8||Buffer Overflow||243|
|Chapter 9||Format Strings||319|
|Chapter 11||Session Hijacking||407|
|Chapter 12||Spoofing: Attacks on Trusted Identity||443|
|Chapter 14||Hardware Hacking||609|
|Chapter 15||Viruses, Trojan Horses, and Worms||655|
|Chapter 16||IDS Evasion||689|
|Chapter 17||Automated Security Review and Attack Tools||719|
|Chapter 18||Reporting Security Problems||749|