« July 2007 | Main | September 2007 »

August 2007

August 28, 2007

Both insurance and prevention!

One of the hardest things about security is getting people to understand and to implement it. This can be small simple things or something more advanced. For example, most of us realize that having a complex password is a good thing but what about changing that password on a regular basis. Work probably forces you to change it quarterly but when is the last time you changed your Amazon password? Or the password for your banking account?

Deciding what kind of security system is needed is part of this process. Some things such as a network firewall or SMTP gateway are easy decisions. They are de facto needs (firewalls) or an obvious problem (blocking spam via a SMTP gateway). Deciding to protect against something that hasn't happened to you yet (your Web site being hacked as an example) takes a more forward thinker. How much does having an automated Web application security solution really help? Are you wasting resources and time testing for something that might never affect you? Or will you be glad to have it?

If you think about it, security is an insurance policy. It's something that you spend effort deploying and implementing in order to protect yourself. When you don't need it, you feel like the time and money was wasted. At the same time though, when it is needed, you are eternally grateful.

Yet at the same time security is a preventative tool. If you regularly lock your car, then nothing is stolen (or at least not as often). If you've fixed all the holes in your Web applications, then there is no opening for the hackers to get in. So while security might seem tedious and at times an overkill, it is still better than cleaning up the mess of lost or stolen data afterwards.

- Mike Kazmierczak, Cenzic, Inc.

 

August 23, 2007

How Programs Can Behave Unexpectedly from Cenzic's SANs Contest Winner!

Dereferencing a Freed Pointer During Linked List Deletion

I've decided to discuss this block of code since deleting nodes from linked lists is a common topic in introductory programming courses and online tutorials. It is a textbook example of how programs can behave unexpectedly when there is a lack of attention to subtle details. Observe the following C code loop:

for(p = head; p != NULL; p = p->next) {

free(p);

}

The problem becomes more apparent when the for loop is converted to its equivalent while syntax. It is easier to see how the value of the pointer identified by the p variable is referenced by the assignment statement in successive loop iterations after being freed.

p = head;

while(p != NULL)

{

free(p);

p = p->next;

}

It is quite possible that no memory corruption will occur during runtime depending on the execution environment. I was able to compile and run the code on Linux and the program exited successfully instead of terminating from receipt of a memory fault signal. This is why these types of errors can go overlooked and undetected.

However, there is no guarantee that the memory will hold the same value after it has been freed. The memory address holding the pointer location could be reallocated or overwritten. At a minimum, this could cause a denial of service condition because the program will crash when it attempts to access an invalid memory address.

Reflexive Cross-Site Scripting in ASP

<html>

<body>

<p>

<b>You are browsing this site with:</b>

<%Response.Write(Request.ServerVariables("http_user_agent"))%>

</p>

<p>

<b>Your IP address is:</b>

<%Response.Write(Request.ServerVariables("remote_addr"))%>

</p>

<p>

<b>The DNS lookup of the IP address is:</b>

<%Response.Write(Request.ServerVariables("remote_host"))%>

</p>

<p>

<b>The method used to call the page:</b>

<%Response.Write(Request.ServerVariables("request_method"))%>

</p>

<p>

<b>The server's domain name:</b>

<%Response.Write(Request.ServerVariables("server_name"))%>

</p>

<p>

<b>The server's port:</b>

<%Response.Write(Request.ServerVariables("server_port"))%>

</p>

<p>

<b>The server's software:</b>

<%Response.Write(Request.ServerVariables("server_software"))%>

</p>

</body>

</html>

It’s pretty obvious that this Active Server Page is returning untrusted input data to the browser that has not been sanitized. The question immediately becomes how do we exploit it? The four server variables that a malicious party would be capable of modifying are request_method, remote_host, remote_addr, and http_user_agent. request_method is out of the question since it would invalidate the HTTP request. Perhaps remote_host or remote_addr could be modified through a spoofing attack such as DNS cache poisoning, but if the user’s network addressing scheme has already been compromised they have bigger problems.

Injecting the payload into the User-Agent HTTP header field looks like the most fruitful approach. This can be accomplished with the setRequestHeader method from the XMLHttpRequest JavaScript API or ActionScript’s addRequestHeader method. Microsoft, Mozilla, Adobe, and Apple have all been updating their client code in an attempt to prevent HTTP header injection. Regardless, attackers will continue to find ways to bypass any client-side restrictions as long as the server side programming is vulnerable--recent HTTP header injection techniques in the aforementioned API’s have involved the insertion of newline characters within header string arguments (see CVE2006-5330 and CVE2007-2401.)

- Derek Callaway, Security Consultant (Cenzic's SANS Contest Winner August 2007)

Secure Web Links