Web Buggery: Analyzing Tracking Images
Introduction
Web Bugs are images (Gifs, Jpegs, PNGs, etc.) that companies and organizations put into web pages, e-mails and other HTML supporting documents to track information about the viewer. These images are sometime know by other names such as tracking bugs, pixel tags, web beacons or clear gifs. What ever the name, their function is largely the same.
Under normal circumstances an organization would just look at their web logs to find the kind of information that a Web Bug might provide them. However, if the content the web bugger wishes to track is not hosted on their site, but instead its hosted from a third party's server, then the web bugger can not obtain this information since they would not have access to the web server logs. By putting an image from one of their servers into an HTML E-mail or a third party's webpage the Web Buggers can find the data they want about the contents viewer. Some of the interesting information items that can be obtained about the viewer are:
Since the clients IP is logged further information that can be obtained if the web bugger wishes to take further steps. Even going so far as to port map and do an OS detection on the clients IP using
Nmap.
Scripts
In this article I'll give you the source code to two simple web bugs I've written for test purposes, one written in Bash script and the other in PHP. The PHP script is a little more secure to run and a lot more flexible to add functionality to. A more professional web bugger might use a database back end to store information about the viewer's client but for these scripts I'll just use CSV (coma separated values) files that are easy to import into other databases and spread sheets for analyzing. My scripts don't use cookies, which a web bugger might use to find out more about your surfing habits by storing state information. Both scripts should be pretty easy to setup and run on your Linux or BSD box using the Apache web server.
Bash Script:
code:
#!/bin/bash echo "Content-Type: image/gif" echo cat x.gif OUTPUT=" $QUERY_STRING,$REMOTE_ADDR,$HTTP_USER_AGENT,$HTTP_ REFERER,`date`" echo $OUTPUT >> log.txt sleep 2.5
code:
touch log.txt chown www-data log.txt chmod 600 log.txt
PHP:
color="#0000CC"<?php
header("Content-type: image/png");
$im = imagecreatefrompng("1by1.PNG");
imagecolortransparent ( $im,imagecolorallocate($im, 255, 255, 255));
imagepng($im);
imagedestroy($im);
$hostname=gethostbyaddr($_SERVER['REMOTE_ADDR']);
$QUERY_STRING = preg_replace("%[^/a-zA-Z0-9@,_]%", '', $_SERVER['QUERY_STRING']);
//Write Log
$filename = 'webbug.csv';
$fp = fopen($filename, "a");
$string ='"'.$QUERY_STRING.'","'
.$_SERVER['REMOTE_ADDR'].'","'
.$hostname.'","'
.$_SERVER['HTTP_USER_AGENT'].'","'
.$_SERVER['HTTP_REFERER'].'","'
.date("D dS M,Y h:i a").'"'."\n";
$write = fputs($fp, $string);
fclose($fp);
//end Write Log
?>
code:
touch webbug.csv chown www-data webbug.csv chmod 600 webbug.csv
The string past the question mark (some-extra-stuff) is the data that will be passed into the QUERY_STRING server variable. It could contain and email address, or as the next example shows, information about the viewer's client pulled from java script:code:
<img src="http://tux.irongeek.com/cgi-bin/webbug.cgi?some-extra-stuff">
code:
<script language="javascript" type="text/javascript"> <!-- document.write("<img width=0 height=0 src=\"http://tux.irongeek.com/webbug.php?adc," +unescape(navigator.appName) +","+screen.width+"x"+screen.height +","+navigator.javaEnabled() +","+screen.pixelDepth +","+screen.colorDepth+"," +escape(document.referrer)+"\">"); // --> </script>
code:
Redirect /webbug.png /webbug.php
This site code works for many popular forum systems, including the one Antionline uses (at least for signatures).code:
[img]http://tux.irongeek.com/webbug.png[/img]
The above command should work in Linux also, but since the nslookup command is depreciated in Linux you may need to use the following dig command instead:code:
nslookup -querytype=mx gmail.com
By using the nslookup command we get the following information:code:
dig gmail.com mx
From the above output we see that gsmtp171.google.com is one of the mail servers, so lets telnet to port 25 on gsmtp171.google.com to establish a connection and send som email:code:
C:\>nslookup -querytype=mx gmail.com Server: dns2.irongeek.com Address: 192.168.162.1 Non-authoritative answer: gmail.com MX preference = 10, mail exchanger = gsmtp171.google.com gmail.com MX preference = 20, mail exchanger = gsmtp57.google.com gmail.com nameserver = ns4.google.com gmail.com nameserver = ns1.google.com gmail.com nameserver = ns2.google.com gmail.com nameserver = ns3.google.com gsmtp171.google.com internet address = 64.233.171.27 ns1.google.com internet address = 216.239.32.10 ns2.google.com internet address = 216.239.34.10 ns3.google.com internet address = 216.239.36.10 ns4.google.com internet address = 216.239.38.10 C:\>
Once the connection is established we use SMTP commands to create an HTML email with image tags pointing to our web bugs. In the following dialog the blue text is what the mail server sends us and the red text is what we send to the mail server:code:
C:\>telnet gsmtp171.google.com 25
220 mx.gmail.com ESMTP 70si2094099rnb
helo me.somepalace.com
250 mx.gmail.com at your service
MAIL FROM:<irongeek@iirongeek.com>
250 OK
RCPT TO:<irongeek@ggmail.com>
250 OK
DATA
354 Please start mail input.
To:Irongeek
From:Adrian
Subject: Webbug test
Mime-Version: 1.0;
Content-Type: text/html; charset="ISO-8859-1";
Content-Transfer-Encoding: 7bit;
<html>
<body>
<h2>Web Bug Test</h2>
Here's a Web Bug Test!
<BR>
<img src="http://tux.irongeek.com/webbug.php?irongeek@gmail.com">
<img src="http://tux.irongeek.com/cgi-bin/webbug.cgi?irongeek@gmail.com">
</body>
</html>
.
250 Mail queued for delivery.
quit
221 Closing connection. Good bye.
Connection to host lost.
In the above example I set the senders name as my account on the Irongeek.com domain, but I could have just as easily faked the information and sent it as any email address I wished (satan@hell.org for example). If the above works, when the target opens the email we should see an entry in our logs like the following:
"irongeek@ggmail.com","192.168.26.138","adrian.irongeek.com","Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.3) Gecko/20040910","http://gmail.google.com/gmail?view=cv&search=inbox&th=ff8f2f8f4869ea0&zx=a0b38249bec42991407828296","Tue 12th Oct,2004 06:05 pm"
If a spammer used a web bug and HTML e-mail like this one they would now know that Irongeek@ggmail.com is a valid e-mail address and a little more about the victim's web browser and ISP.
Detection and Prevention
You can find web bugs by viewing the HTML source code of a web page and looking for strange image tags like the ones in the examples above, or by finding images that don't show on the page because they are one pixel is size and/or transparent. Unfortunately even looking for these signs is no guarantee that you will spot a web bug since it could be any image on the page.
Preventing web bugs in e-mail is pretty simple, just look in your e-mail readers documentation for how to disable HTML e-mail or block external images. Some web e-mail services like Gmail disable external images by default, which is a good thing. Some newer mail clients, like Outlook 20003, also default to not loading image from outside sites.
Completely blocking web bugs in regular web pages is close to impossible, barring disabling images altogether. If you're really paranoid you can keep the web bugger from finding your IP address by using a proxy server, but make sure Javascript it turned off in your browser or they may still be able to obtain the information. Tools like Bugnosis ( http://www.bugnosis.org ) for IE and the Ad Block ( http://adblock.mozdev.org/ ) for Mozilla/Firefox can be of some help by choosing to block know web buggers. Another option is to round file know domains that host web bugs by editing you HOSTS file. For those that don't know, the HOSTS file is used by your computer to match a domain name to an IP address before using a DNS server to do the name resolution. See the links section at the bottom of this article for more information on how to edit your HOSTS file in Linux, Windows and Mac OS to help block web bugs and ads. Anti-spyware tools like Ad Aware and Spybot Search and Destroy can help find and destroy the cookies left by some web bugs.
For the most part I feel that web bugs outside of e-mail are only a problem for the most paranoid among us. I use web bugs regularly myself to track pages I host on web servers I can't get the logs for and web bugs have some great beneficial uses for a web master trying his best to tailor his site to the reader's web browser by finding out the most common browser types and screen resolutions. I do however recommend turning off images in HTML email since they can be used by spammers to confirm e-mail addresses.
I think that's about all I have to say on the subject of web bugs, so I guess I bugger off now.
WebBug Source Code
If you would like a more complicated example of a web bug, please take a look at this source code:
Irongeek's Webbug PHP & MySQL Souce Code
It's more or less the same code I use for my sites logo script. It logs to a MySQL server so it's easy to query results using something like PHPMyAdmin, you just have to make some minor changes to config.php.
Enjoy.
Further Reading:
The Electronic Frontier Foundation had a great FAQ on Web Bugs:
http://www.eff.org/Privacy/Marketing/web_bug.html
Wikipedia enty on Web Bugs.
http://en.wikipedia.org/wiki/Web_bug
7 reason why HTML e-mail is EVIL:
http://www.georgedillon.com/web/html_email_is_evil.shtml
Using the HOSTS file in Linux, Windows and Mac OS to block web bugs and ads:
http://www.ecst.csuchico.edu/~atman/spam/adblock.shtml
http://www.mvps.org/winhelp2002/hosts.htm
Special thanks to Jake Howlett who wrote the following article that help me figure out how to send HTML in e-mail:
http://www.codestore.net/store.nsf/unid/EPSD-587VVX?OpenDocument
Change Log:
07/04/2008: Added source code for my PHP & MySQL web bug. I also cleaned up the page's layout and changed email addresses to make them non-valid.
10/15/2004: Article first posted.