Sniffing Twitter
Curiosity overcame me recently and had me puzzling over who exactly was clicking any links that appeared on my twitter account. A web searched produced pages of a handful of webserver administrators who’d posted the access logs of their servers. Not keen on having to run the server from my own machines, writing some code to utilize a free webhosting service struck me as much wiser.
After grabbing a hosting account with free php and mysql access ( php to capture the details of anything clicking and redirect them to the page you wish to present and mysql to store them ), the following simple scripts allowed logging to commence. I present them for you consideration. Kindly note that these scripts are currently not very robust and are more flung together than beautifully designed.
The first task is to create the database schema. As, sadly, most hosting providers seem a little hesitant to allow just any old riff-raff to connect directly to their database server, opening this script should do that for you.
<?php
# snooperinitdb.php
# customise the 4 vars below to match your hosting setup
$server='localhost';
$user='root';
$password='secret';
$database='snooper';
$link=mysql_connect($server,$user,$password);
$dbexists=mysql_select_db($database,$link);
if($dbexists==FALSE) {
mysql_query("create database ".$database);
$dbexists=mysql_select_db($database,$link);
if($dbexists==FALSE) {
print('Database Error: Create manually');
}
mysql_query("create table snooper ( time timestamp, remotehost varchar(20), remoteport int, remotebrowser varchar(250), referer varchar(250))");
}
# If you can't create databases, comment out the above code from
# if($dbexists==FALSE) and use this instead ( HINT: THIS IS A COMMENT )
# after using phpmyadmin or whatever rubbish the webhost is using
# to control databasing access.
#
# mysql_query("create table snooper ( time timestamp, remotehost varchar(20), remoteport int, remotebrowser varchar(250), referer varchar(250))");
?>
To get the above script to setup the database for you, upload it and simply open with your browser. Once that is done, upload the following log display script and check it works without throwing a fit.
<?php
# snooperviewlog.php
# Prints out snoopers records to screen
# customise the 4 vars below to match your hosting setup
$server='localhost';
$user='root';
$password='secret';
$database='snooper';
$link=mysql_connect($server,$user,$password);
$dbexists=mysql_select_db($database,$link);
$result = mysql_query("select * from ".$database);
print "<HTML><BODY><TABLE>";
print "<TR><TD>Time</TD><TD>IP Address </TD><TD>Browser ID</TD><TD>Referer</TD></TR>";
while($record=mysql_fetch_assoc($result)) {
print "<TR><TD>".$record["time"]."</TD><TD>".$record["remotehost"]."</TD>>TD<".$record["remotebrowser"]."</TD><TD>".$record["referer"]."</TD></TR>";
}
mysql_free_result($result);
print "</TABLE></BODY></HTML>";
?>
The above script should produce just the field headings for the table of machines that have clicked the link to access the script. Assuming all is well so far, we’re ready to roll. Next, we need to upload the script that does the actual sniffing. Here it is.
<?php
# Snooper.php
# Logs the machines with follow a given link, then redirects them to a given page
$counter=0;
$address='';
# customise the 4 vars below to match your hosting setup
$server='localhost';
$username='root';
$password='secret';
$database='snooper';
$link=mysql_connect($server,$username,$password);
mysql_select_db($database,$link);
if(isset($_SERVER['HTTP_REFERRER'])) {
mysql_query("insert into snooper (time,remotehost,remotebrowser,remoteport,referer) values (now(),'".$_SERVER['REMOTE_ADDR']."','".$_SERVER['HTTP_USER_AGENT']."','".$_SERVER['REMOTE_PORT']."','".$_SERVER['HTTP_REFERRER']."')");
} else {
mysql_query("insert into snooper (time,remotehost,remotebrowser,remoteport,referer) values (now(),'".$_SERVER['REMOTE_ADDR']."','".$_SERVER['HTTP_USER_AGENT']."','".$_SERVER['REMOTE_PORT']."',NULL)");
}
foreach($_GET as $key => $val) {
if($key=='targurl') {
$address=$val;
} else {
if(!$counter) {
$address=$address."?".$key."=".$val;
$counter=1;
} else {
$address=$address."&".$key."=".$val;
}
}
}
#print($address);
header("Location: ".$address);
?>
So, let’s say we want to post a link to a book an amazon and monitor which IP addresses on twitter click our link to check out what we’ve linked to. Let say that book is Stephen Hawkings ‘The Universe in a Nutshell’ at http://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&field-keywords=Stephen+hawking&x=0&y=0 and our script is located on snooper.com and is called snooper.php.
The first thing we have to do is reformat the URL for the page so that we can successfully feed it into our script. All we have to do is change the ? in the url to a & and our script will be able to preserve any data that needs to be passed to our target server, thus : http://www.amazon.com/s/ref=nb_sb_noss&url=search-alias%3Daps&field-keywords=Stephen+hawking&x=0&y=0
Next, we need to feed this into our script. So we take the above and alter it so it reads thus : http://snooper.com/snooper.php?targurl=http://www.amazon.com/s/ref=nb_sb_noss&url=search-alias%3Daps&field-keywords=Stephen+hawking&x=0&y=0
Now this makes it rather obvious that we’re sniffing who clicks our links on twitter. So the next step is to take the above url and feed it into a URL shortening service, such as bit.ly, so we get a nice short link that’s indistinguishable from the other links pasted on twitter.
The main issue with this technique is that it, due the use of the URL shortening service, is unable to link an IP address to a given twitter user by name. To do that requires developing the scripts into a full blown man-in-the middle attack and embedding some javascript into the page to get at the browsers history and rewrite the address bar. Something for another post, I feel.