
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