A More Sophisticated Banner Scheme
Defeated by Combined SSI & CGI
Recently, I wrote a brief essay describing the defeat of a free web-space provider's advertising banner scheme by means of server-side includes. Sad to relate, the admins at Prohosting have not been idle, and the use of ssi is no longer enough to eliminate the banners. Readers unfamiliar with server-side includes should see my previous essay for some basic introductory material. This essay describes the 'new improved' advertising method, and the first part of its defeat.
As was described in my previous essay, the use of ssi in the accessed file prevented the insertion
of the following banner code:
<//--><//"--><center><a href=/redirect?http://www.prohosting.com>
<img src="/loadimage?/banner3.gif" alt=Prohosting.com border=0></a></center>
Not only was this quite easily defeated, but the code was reasonably small. This is no longer the case; advertising banner code is now successfully inserted into an shtml document, and it has increased considerably in size and unpleasantness. Plain html files still have the old code inserted into them; the new scheme, which inserts more banners, appears to be targeted at shtml files. The new code attempts three distinct 'assaults', of which only the last can be defeated by turning off Java-Script:
1. valueclick banner (embedded in the page):
2. prohosting imagemap (embedded in the page):
3. prohosting banner (in a popup window):
This code is injected immediately after the <body> tag (ie. the banners appear at
the top of the page) even if the file containing the <body> tag is #include-d in the
accessed file - as before, the files are not modified on disk, the banner-code insertion is done
'on the fly' when the shtml page is accessed.
A quick glance at the code reveals the following:
1. If Java-Script is enabled in the victim's
browser, it tries (the statement if (ValueLoaded) suggests that possible failure has been
anticipated, although there is no fallback) to get an ad-display script from a host belonging to valueclick.com (a
notorious source of banners & well known denizen of JunkBuster blockfiles), and then execute the downloaded function
ValueShowAd() - not only do you have to download the inserted code, but your browser
must open a connection to another server altogether, and download more banner display code from it,
which in turn downloads a hideous graphic.
Here is the code contained in http://oz.valueclick.com/jsmaster:
As the <NOSCRIPT> block indicates, they have made sure that you don't miss out entirely even
with Java-Script turned off - you will still have the pleasure of downloading a 468x60 pixel image
(probably a pulsating gif) from the delightful valueclick.com.
2. Java-Script or no, Prohosting then embeds a rather nasty
imagemap in the page, immediately below valueclick's monstrosity.
3. For those foolish enough to have Java-Script enabled, there is yet more...
The last code-block creates a pop-up window (that ensures that it creeps to the top of the window
z-order with the window.focus() method) displaying Prohosting's own banner.html.
Incredibly, not satisfied with the valueclick banner & their own embedded at
the top of every page, Prohosting want to have a popup advertisement as well; a remarkable
change from their previous 'no banner' policy - verily, none hath the zeal of the recent convert.
To see these horrors, follow this
link for the old html version, and
this for the new shtml version (the two files are identical apart from the extension); to get
the full benefit Java-Script should be enabled. It is not clear whether the fact that shtml pages get
more banners is a 'punishment' for using ssi and thus putting more load on their server, or just a
sign that they are still working on their advertisement scheme.
The last code block, that creates the popup banner window, appeared again twice after the
closing </html> tag in the test file, indicating that their scheme perhaps still does not
deal very well with ssi; or, alternatively, that they have little confidence in their code, and
hope by inserting it multiple times to ensure that it will be executed. The professionalism of
Prohosting's 'programmers' is reassuringly indicated by the following directive:
(in part 3 above):
<SCRIPT LANGAUGE="Java-Script">
although, sadly, this typo is not enough to prevent Netscape from dutifully executing the code if
given the chance.
And still this is not all - a
link to a binary file (that in the normal way would make the browser
pop up a File Save dialog) now leads to a hideous page stuffed with banners and pleas to
visit 'our sponsors' (I know not who or whose they are; certainly not mine, although that is what
seems to be implied). On this page Prohosting have generously supplied a link, accompanied by a
futile little icon reminiscent of a once 'popular' 24-bit OS, enabling you to download the file.
However, if you block cookies (with something like JunkBuster, for example), you will not be able
to download the file, you will return to that same page again and again - you must allow
cookies to be set in order to download the file. Here is a cookie set after accessing the
'download' page:
It is evident that Prohosting have 'sold their soul' (and mine) to valueclick, and made it
impossible for me to offer anything for download on my site (unless this download page can be
circumvented) - I do not feel to act as valueclick's agent by causing their data to be
written to the harddisks of my visitors.
Happily, after this rather dismal exposition, it seems that it is still possible to defeat this
new, bloated and multi-partite advertisement scheme, or at least some of it.
There are several goals:
The first case can be met with the addition of some complexity to the web pages (comments in green).
The shtml page that does the job is as follows:
Every link that points to a 'normal' page (ie. not a cgi script or binary for download) points to this
file, page.shtml. So how does page.html produce different pages, depending on which
link is clicked? All link urls are of the form page.shtml?../shtml/some_page.html; the
text following the '?' is a variable known as a query string which is passed to
page.shtml as an environment variable, in this case the name of another html file. The file
page.html is itself in the /shtml directory, so it may be wondered why the path
../shtml/ is prepended to some_page.html - it appears to be redundant, but in fact it is not.
Turning to the cgi script executed by page.shtml, disp_page.cgi:
Now the purpose of the seemingly redundant path info in the query string is clear, given that
the cgi script is in /cgi-bin and the file to be 'printed' is in /shtml. A query
string passed to an shtml file is automatically passed to a cgi script #exec-ed by that shtml file
(the cgi script 'inherits' the environment of the calling shtml file); for example, if the url is
page.shtml?../shtml/some_page.html, the variable $ENV{'QUERY_STRING'}
in disp_page.cgi will contain ../shtml/some_page.html. After the two files (the
header and the main body of the page) are printed, the cgi script exits, and control returns,
as it were, to the caller, page.shtml, and the file foot.shtml is #include-d,
completing the page.
It seems that these multiple levels of indirection (the <body> tag being in an html file
printed by a cgi script #exec-ed by an ssi directive) is enough to confuse the banner insertion
scheme, as none of the three blocks of code are inserted into the resulting file.
A problem still remains, however - the Prohosting popup banner Java-Script code is still inserted
(sometimes twice) after the closing </html> tag. Turning off
Java-Script would effectively disable the banner, but for the sake of completeness it is nice to
kill it even when the browser has Java-Script enabled. This is simply achieved by the addition of a
<noembed> tag after the closing </html>. The code is still inserted but the browser
ignores everything after the <noembed> tag, and the popup creation code is not executed.
The first goal has been met - banner free shtml pages; the remaining two, the
'peaceful liberation' of cgi scripts producing html output, and binary downloads, are a work
in progress.
I suspect that Prohosting may be using an 'off-the-shelf' banner scheme (server module, or whatever
it is), as I have a seen a download page that behaves in an identical fashion on a site
hosted by tripod.com; if so, it is possible that this scheme is in use by several 'free' hosts,
and can be defeated in the same way if those hosts permit the use of ssi & user cgi scripts.
<//--><//"--><table border=0 align=center>
<tr><td>
<!-- VC active -->
<SCRIPT LANGUAGE="Java-Script">
<!--
// ValueParameters
ValueHost = "hs0150918";
ValueID = "0";
ValueLoaded = false;
ValueVersion = "1.0";
//-->
</SCRIPT>
<SCRIPT LANGUAGE="Java-Script" SRC="/loadimage?http://oz.valueclick.com/jsmaster"></SCRIPT>
<SCRIPT LANGUAGE="Java-Script">
<!--
if (ValueLoaded) ValueShowAd();
//-->
</SCRIPT>
<NOSCRIPT>
<A HREF="/redirect?http://kansas.valueclick.com/redirect?host=hs0150918&b=0&v=0" TARGET="_top"><IMG
BORDER="0" WIDTH="468" HEIGHT="60" ALT="$
/loadimage?http://kansas.valueclick.com/cycle?host=hs0150918&b=0&noscript=1"></A>
</NOSCRIPT>
<!-- vc active -->
</td></tr>
<tr><td>
<A HREF="/redirect?/banner.map" TARGET="_new"><IMG ISMAP SRC="/loadimage?/banner.gif" BORDER=0></A>
</td></tr></table>
<//--><//"--><SCRIPT LANGAUGE="Java-Script">
<!--Ad Banner
function popupPage() {
var windowopts = "location=no,scrollbars=no,menubars=no,toolbars=no,resizable=yes,left= 50,\
top=50,width=490,height=130";
popup0 = open('/banner.html',"MenuPopup",windowopts);
popup0.focus();
}
popupPage();
// Ad Banner-->
</script>
// Copyright 1999-2000 ValueClick Inc. All rights reserved.
ValueLoaded = true;
ValueFullVersion = ValueVersion + ".9";
function ValueShowAd() {
ValueOptions = '&v=' + ValueFullVersion;
if (self.ValueCategory) ValueOptions += '&c=' + self.ValueCategory;
if (self.ValueBorder) ValueOptions += '&border=1';
if (! self.ValueNoText) ValueOptions += '&text=1';
if (self.ValueTargetCurrent) ValueOptions += '&target=self';
ValueRandom = Math.round(Math.random()*1000) + 1;
ValueHostInfo = "host=" + ValueHost + "&b=" + ValueID + "." + ValueRandom;
if (self.ValueServer == null) ValueServer = "oz";
ValueFullServer = "http://" + ValueServer + ".valueclick.com/";
if ((self.ValueWidth == null) || (self.ValueHeight == null)) {
ValueWidth = 468;
ValueHeight = 60;
}
ValueSize = '&size=' + ValueWidth + 'x' + ValueHeight;
ValueBanner = ValueFullServer + 'cycle?' + ValueHostInfo + ValueOptions + ValueSize;
ValueRedirect = ValueFullServer + 'redirect?' + ValueHostInfo + ValueSize;
ValueDimensions();
if (navigator.userAgent.indexOf("MSIE") >= 0) {
// don't try to set the bgcolor etc in the IFRAME for MSIE 3
if (navigator.appVersion.indexOf('MSIE 3') < 0) {
if (self.ValueBgColor) ValueBanner += '&bgcolor=' + escape(self.ValueBgColor);
if (self.ValueLinkColor) ValueBanner += '&linkcolor=' + escape(self.ValueLinkColor);
if (self.ValueAlinkColor) ValueBanner += '&alinkcolor=' + escape(self.ValueAlinkColor);
if (self.ValueVlinkColor) ValueBanner += '&vlinkcolor=' + escape(self.ValueVlinkColor);
}
document.write('<IFRAME ID="VC" NAME="VC" WIDTH="' + IWidth + '" HEIGHT="' + IHeight + '" ');
document.write('SCROLLING="no" FRAMEBORDER="0" FRAMESPACING="0" MARGINHEIGHT="0" ');
document.write('MARGINWIDTH="0" BORDER="0" HSPACE="0" VSPACE="0" ');
document.write('ALIGN="center" SRC="/loadimage?' + ValueBanner + '&t=html">');
document.write('</IFRAME>');
} else {
// should be all Netscapes that are reading this file
if (self.ValueVersion >= 1) {
document.write('<TABLE BORDER=0><TR><TD>');
document.write('<ILAYER ID="VC" VISIBILITY="hide" BGCOLOR="" WIDTH="' + IWidth);
document.write('" HEIGHT="' + IHeight + '"></ILAYER>');
document.write('</TD></TR></TABLE>');
} else {
document.write('<SCRIPT SRC="/loadimage?' + ValueBanner + '&t=js"');
document.write(' LANGUAGE="Java-Script"></SCR' + 'IPT>');
}
}
}
function ValueDimensions() {
if (self.ValueNoText) {
if (self.ValueBorder) {
IWidth = ValueWidth + 4;
IHeight = ValueHeight + 4;
} else {
IWidth = ValueWidth;
IHeight = ValueHeight;
}
} else {
if (self.ValueBorder) {
IWidth = ValueWidth + 4;
IHeight = ValueHeight + 24;
} else {
IWidth = ValueWidth;
IHeight = ValueHeight + 24;
}
}
}
.valueclick.com TRUE / FALSE 1749719186 ksa 0OUyRitFVA3cAANJ5BO431b6b7a1
Solution
<!--#exec cgi='../cgi-bin/disp_page.cgi'--> Execute page.cgi
<!--#include file='foot.shtml'--> Include foot.shtml - it's an shtml file
because it contains an ssi directive to
display the file modification date stamp
#!/usr/bin/perl
print "Content-type:text/html", "\n\n"; # header data specifying the output MIME type
$main_file = $ENV{'QUERY_STRING'}; # the query string passed to page.shtml in the url
$html_document = '../shtml/head.html'; # the header html file, containing the all important
# <body> tag and global background and link colour info
if (open (HTML, "<" . $html_document)) {
while (<HTML>) {
print; # opens the file head.html and prints it to
} # the output stream
close (HTML);
}
if (open (HTML, "<" . $main_file)) { # open the file passed in to page.shtml
while (<HTML>) { # in the url and print it to the output stream
print;
}
close (HTML);
}
exit (0); # exit without error ;-)
Conclusion
(c) 2000: [fravia+], all rights reserved