Does this site look plain?

This site uses advanced css techniques

We've spent quite a bit of time researching a bug in ZoneAlarm 5.0.x where it incorrectly believes our computer is using a proxy server, and we have created some tools that help us do that research. We're making them public to all others to play too.

A short description is that when ZoneAlarm observes this send/response sequence, it believe that a proxy server is being used:

Client sends:
POST /zatest HTTP/1.0
Host: www.unixwiz.net

POST x

Server responds:
HTTP/1.1 200

HTTP/1.1

Subsequent checks for updates (manual or automatic) will be done via www.unixwiz.net instead of a ZoneLabs site.

Background

Zone Alarm 5.0.590.015 attempts to figure out if you're using a proxy server or not, and if it detects this, it will use that proxy server when it checks for updates. We have found that it sometimes guesses wrongly, so will start asking an unrelated webserver whether updates are available (this shows up the the server logs).

The response expected is of the form (and expected from update.zonelabs.com):

UpdateAvailable=no
UpdateURL=http://update.zonelabs.com/
UpdateNotice=Your Internet security is up to date.

We have not done any real research to see what happens if ZoneAlarm gets a response other than this, but we're really curious if there are ways to make ZoneAlarm behave badly if given "surprising" inputs. If a website is able to fool ZoneAlarm into believing it's a proxy server, there might be opportunities for malicious behavior. We may look into this yet.

Note that ZoneAlarm doesn't actually fetch the updates from the proxy site, it only checks to see if any are available. The user is invited to an update site via a regular browser session that would not use the false proxy.

Zone Labs is very much aware of this issue and has been working closely with us and DSLReports where this problem first surfaced. To date there have been two forum threads on this topic:

First reports

The in-depth research thread

Researching this on your own

When ZoneAlarm detects a proxy (correctly or otherwise), it updates a few registry values to reflect this, and it's helpful to know exactly when this happens. We've written a tool that watches these registry values and reports when they change.

Unixwiz.net tool - ZAWatch

This is always run on the same machine as ZoneAlarm, and it can be left minimized in the task bar while it watches. Full instructions are given on the page, and we'll assume this is installed.

The zaclient and zalistener programs both require a perl interpreter, and we did all our testing with the outstanding ActivePerl from ActiveState. We've found this to be a fantastic implementation of perl, and we use it every day for system administrative purposes.

All of our research is done in an MS-DOS window - sorry, no GUI tools here - which is reached with Start » Run » "cmd" + RETURN. You'll probably need two of these windows, one for the client and one for the listener.

zaclient

This "client" is a simulated web browser that makes an HTTP request to a server, and this can be a real server (default is DSLReports) or a simulated one (the zalistener program), and the data stream exchanged is designed to provoke a false proxy detection while Zone Alarm sniffs the data. If this happens, ZAWatch will provide this notification in real time.

zaclient normally requires no command-line parameters, though a few are supported to alter its behavior. By default, it makes a connection to www.dslreports.com and submits some data and collects the response (both are reported to the user). We're watching for the notification by ZAWatch as shown here:

[Notification]

Here, we're running zaclient, and it's making a connection to the DSLReports website with some very minimal data, and the combination of the sent and received data provokes a false-proxy detection as shown by the ZAWatch popup.

The file zaclient is text (a perl program), and the data we're sending can be edited to repeatedly try different data patterns. Simply look for the section:

from zaclient:
my $rawdata = <<EOF;
POST /zatest HTTP/1.0
Host: $proxyhost

POST x
EOF

The EOF tokens are delimiters for the text that lies between (shown here in red), and individual lines can be commented out with a #.

This program takes a few command-line parameters:

--help
Show a brief help listing
--port=P
Make the outgoing connection to port P/tcp (default 80/tcp) to the remote server. ZoneAlarm seems not to care which target port is used as long as the data transacted is in the special form.
--host=H
Make the outgoing connection to host H (default dslreports.com}; this can be used to redirect testing to a local server such as zalistener shown below.
--proxy=P
When sending our HTTP stream to the remote webserver, part of the contents is a Host: header that contains the name of a webserver; this is what ZoneAlarm seems to be using as the false proxy, so we can alter this string at will. It's not used for IP connectivity, and the default is www.unixwiz.net.
Later, when ZoneAlarm attempts to check for updates (either manually or automatically), it will connect to that machine.

zalistener

Though zaclient offers full control over what's sent to the webserver, it doesn't directly control the response. Since that response helps contribute to false-proxy detection, we'd like to manage both ends of the conversation.

zalistener is a perl program that acts as a webserver simulator: it accepts a connection from a client, receives and logs (but does not interpret) its data, then sends a canned response. In this manner we are responsible for every byte of the conversation and can fine tune it very highly: what breaks? what doesn't?

This program can run on the same machine with ZoneAlarm, ZAWatch, and zaclient, making any single machine a research workstation.

--help
Show a brief help listing and exit with success status.
--port=P
Listen on port P/tcp for connections from clients. The default is port 80/tcp - just like a webserver - but this can be changed to avoid conflicts with a "real" webserver on the same machine, or to use a non-privileged port on a UNIX system in a non-root account.
--timeout=N
When collecting data from a connected client, we're not able to know definitively that the client has sent everything because we do not necessarily expect to see a properly-formed HTTP request. Instead, we use a timeout of at most N seconds (default 2.0), after which we consider the request complete.

This screenshot (click for larger image) shows the whole group working together. ZAWatch is running in the background looking for registry value changes, zalistener is running in the leftmost console window waiting for connections, and zaclient is running to localhost in the foreground console window.

[Change detected]

Regardless of what it receives, zalistener responds only with fixed data that can be tuned while experimenting with patterns that cause false-proxy detection. As with zaclient, the fixed data is found in the perl source code:

from zalistener:
my $rawdata = <<EOF;
HTTP/1.1 200

HTTP/1.1
EOF

Remember that once a false-proxy detection has been made, that selection remains in effect until ZoneAlarm is restarted. We don't believe that it will attempt to re-detect a proxy once one has been discovered, so one must make a point of restarting ZoneAlarm after each detection.

Areas for Further Research

With ZoneAlarm misdetecting these proxies, it's just a matter of time before it actually tries to use one while checking for an update. It's expecting a few lines of text from the server, and by writing a custom CGI for a webserver pointed to by --proxy=host, it's possible to say anything we like to ZoneAlarm. We can anticipate at least two avenues of exploitation by a malicious false proxy.


NOTE BENE - These are only speculations, and there is positively no evidence (or even hints) that any of these approaches would actually work. We want to be careful that "thinking out loud" and "brainstorming" is not misread as "ZoneAlarm is vulnerable". As far as we know, it's not.

We'd like to be particularly clear about one matter that seems to be causing some confusion. ZoneAlarm does not attempt to fetch updates from the false proxy - it only checks if they are available or not, relying on a standard browser session for the download.

It's not possible for a false proxy to directly feed malware to ZoneAlarm


First, directly causing ZoneAlarm to fault by sending bad data. If ZA is expecting a few, short lines, what happens if we send a lot of really long ones? Though we'd expect Zone Labs to do proper buffer management, considering that they're expecting to talk to a "trusted" machine, it's conceivable that it hasn't been tested as strenuously as other modules.

Second, if the response from our fake proxy says that an update is available, it also provides a URL. If this URL "looks like" a Zone Labs download site but actually isn't, it may be possible to convince at least some portion of the user base to download malware thinking it was coming from a trusted site.

We've done a bit of toying with a fake checkupdate.asp CGI, and we can get ZoneAlarm to prompt this way:

[ZoneAlarm update config]

... and clicking "Update now" points to this Tech Tip.

Thanks

Zone Labs has been exceptionally responsive about this matter, and it's obvious that they are taking it seriously. We've seen what appears to be substantial engineering resources devoted to tracking this down, and we hope that our tools will make it easier to reproduce and fix it.

Download