Message Board

Installing Honey Pots

Older Posts ]   [ Newer Posts ]
 PHP total link randomizer proposal
Author: S.Lesimple   (2 Aug 06 6:16pm)
Hello,

I've spent a couple of hours writing and testing a script to generate totally random links to honeypots.
All these links are invisible to the user, and probably impossible to detect as being honeypots by a non-human.
I've commented the code and there's some sort of a readme at the beggining of the code,
so instead of repeating it here, I invite you to look at the php source.
There's a demonstration here : http://speed47.free.fr/hpot
Just go to this page, and view the html source.
You'll see that the invisible links are insanely randomized, still, they're valid.
(you can view the formatted php script and/or download it at the above address).
I'm pasting the script here for reference, but this will probably be easier to read at the above address
Don't hesitate to test it and use it. Tell me if anything goes wrong.

--- cut here ---

<?php
// don't insert any line before the opening tag above !
// this would generate an empty line on your webpage
/*
Honey Pot Randomizer Script, for ProjectHoneyPot, see www.projecthoneypot.org
This script generates INSANELY randomized links to your honeypot

*** Changelog
v1.0 : first public version

*** This has been tested under :
- firefox 1.5.0.4 (OK)
- internet explorer 6.0 (OK)
- konqueror 3.5.3 (OK)
- elinks 0.11 (activate compatibility mode if it's important to you, see below)
- lynx 2.8.5 (activate compatibility mode if it's important to you, see below)

- PHP5, should work on PHP4 and PHP3, tell me if it doesn't.

** This script has been written with the following in mind :
- always produce an output which is invisible to users
- make output realistic, in an html-code point of view
- make very difficult to use pattern matching techniques
to tell if this output is an honeypot or not
- be fast and transparent

*** But why this script ?
It's meant to be used with www.projecthoneypot.org honeypots.
The output it'll produce will make it more or less virtually impossible
for harvesters to detect the honeypot. That's what you want. :)

*** How to use ?
You're encouraged to change the filename of this script to something else,
for the same very reason the name of your honeypot is random : avoid
having easy-to-detect patterns between different honeypots.
Then, simply include this script on your page, using :
<?php include("path/to/this_script.php"); ?>
And were you want to insert your honeypot, use :
<?php hpot(); ?>
And that's it.
Don't forget to set the options below.

*** I'm not sure. How to know if it works ?
There's a test included : set "TESTONLY" below to "yes".
You then just need to directly access this page via your browser
It'll display a couple of tests (useful to test with others browsers, etc.)

Any feedback is welcome, use the Board :
http://www.projecthoneypot.org/board/list.php?f=6

by SpeedFire.
*/

// set this to your honeypot's url :
$URL = "http://www.example.com/honeypot.php";

// compatibility mode with text-only browsers, if you set it, much less
// techniques will be used, but it'll always look okay in text-only browsers.
// activate only if it's important to you, and if your website is already
// compatible with text-only (or console-based) browsers
// $COMPAT = true;
$COMPAT = false;

// you can put anything there, random garbage, as much as you want !
// I've put some random words, it should be enough
$WORDS = array("different","important","something","sometimes","beautiful","carefully","developed","difference","direction","discovered","government","instruments","paragraph","questions","represent","scientists","syllables","thousands","understand","adjective","angle","appear","conditions","consonant","continued","determine","dictionary","difficult","especially","everything","experience","factories","information","molecules","necessary","particular","presidents","statement","stretched","substances","suggested","temperature","themselves","underline","Washington","wasn't","wear","weight","we'll");

// if set to true, this means the script is test-only, which is useful
// if you want to see how (and if) it works, this is probably not what you want
// IN SHORT: leave this to false, or it won't work.
$TESTONLY = false;

// ### END OF OPTIONS - YOU DON'T NEED TO CHANGE ANYTHING BELOW THIS LINE ###

// ######################################
// top-level function : call this one in your page !
// it will print an invisible link to the honey pot page
function hpot()
{
echo hpotgen();
}

// ######################################
// level 4 function (honey pot generator)
function hpotgen()
{
global $COMPAT;
if ($COMPAT == true) { $r = mt_rand(0,2); } // reduced functionality
else { $r = mt_rand(0,6); } // full functionality
switch ($r)
{
case 0:
return aTag(true).'<!--'.rndSpace().rndStuff().rndSpace().'-->'.
'</'.rndCase('a').'>';
case 1:
return aTag(true).'</'.rndCase('a').'>';
case 2:
return '<!--'.rndSpace().rndStuff().aTag(true).rndStuff().
'</'.rndCase('a').'>'.rndStuff().rndSpace().'-->';
case 3:
$tag = split('#SPLIT#', spanDivTag(false));
return $tag[0].rndStuff().aTag(true).rndStuff().
'</'.rndCase('a').'>'.rndStuff().'</'.rndCase($tag[1]).'>';
case 4:
return aTag(false).rndStuff().'</'.rndCase('a').'>';
case 5:
return aTag(true).imgTag().'</'.rndCase('a').'>';
case 6:
$tag = split('#SPLIT#', spanDivTag(false));
return aTag(true).$tag[0].rndStuff().
'</'.rndCase($tag[1]).'></'.rndCase('a').'>';
}
}

// ######################################
// level 3 functions (tags generators)


// this function returns random (but valid) garbage
function rndStuff()
{
return rndWord().rndSpace().rndWord();
}

// this function returns an invisible image
function imgTag()
{
return '<'.rndCase('img').rndSpace().rndParams(2).rndSpace().
((mt_rand(0,1) == 0) ? styleZero() : styleNone()).
rndSpace().rndParams(2).'>';
}

// this function returns either :
// a visible link (to be used in an invisible container)
// an invisible link (to be used alone)
function aTag($visible)
{
global $URL;
$q = rndQuote();
$href = 'href='.$q.$URL.$q;
if ($visible == true) $s = $href;
else
if (mt_rand(0,1) == 0)
$s = styleNone().rndSpace().rndParams(1).rndSpace().$href;
else
$s = $href.rndSpace().rndParams(1).rndSpace().styleNone();

return '<'.rndCase('a').rndSpace().rndParams(1).rndSpace().
$s.rndSpace().rndParams(1).'>';
}

// this function returns an invisible span or div container
// output is meant to be split(), the array will be :
// [0] : container
// [1] : tag only (used to know how to close the tag)
function spanDivTag($canbezero)
{
if ($canbezero == true)
switch (mt_rand(0,1))
{
case 0: $style = styleNone(); break;
default: $style = styleZero(); break;
}
else
$style = styleNone();

$tag = (mt_rand(0,1) == 0) ? rndCase('span') : rndCase('div');
return '<'.$tag.rndSpace().rndParams(1).rndSpace().$style.rndSpace().
rndParams(1).'>#SPLIT#'.$tag;
}

// ######################################
// level 2 functions (more complex utilities)

// this function returns between 0 and max html attributes
// with random values that will have no impact on invisible elements
function rndParams($max)
{
$s = "";
if (!is_numeric($max) || ($max < 0) || ($max > 5)) { $max = 2; }
for ($n = mt_rand(0,$max); $n > 0; $n--)
{
$q = rndQuote();
switch(mt_rand(0,4))
{
case 0:
$s .= 'id='.$q.rndWord().$q.rndSpace();
break;
case 1:
$s .= 'title='.$q.rndWord().$q.rndSpace();
break;
case 2:
$s .= 'onclick='.$q.'void()'.$q.rndSpace();
break;
case 3:
$s .= 'onmouseover='.$q.'void()'.$q.rndSpace();
break;
case 4:
$s .= 'onkeydown='.$q.'void()'.$q.rndSpace();
break;
}
}
return $s;
}

// this function returns between 0 and max css attributes
// with random values that will have no impact on invisible elements
function rndCSS($max)
{
$s = "";
if (!is_numeric($max) || ($max < 0) || ($max > 5)) { $max = 2; }
for ($n = mt_rand(0,$max); $n > 0; $n--)
{
switch(mt_rand(0,7))
{
case 0:
$s .= 'background-color:'.rndSpace().rndColor().';'.rndSpace();
break;
case 1:
$t = array('none','hidden','dotted','dashed','solid','double',
'groove','ridge','inset','outset');
$s .= 'border-style:'.rndSpace().$t[array_rand($t)].';'.rndSpace();
break;
case 2:
$t = array('courier','serif','sans-serif','arial');
$s .= 'font-family:'.rndSpace().$t[array_rand($t)].';'.rndSpace();
break;
case 3:
$s .= 'font-size:'.rndSpace().mt_rand(0,9).'px;'.rndSpace();
break;
case 4:
$t = array('normal','italic','oblique');
$s .= 'font-style:'.rndSpace().$t[array_rand($t)].';'.rndSpace();
break;
case 5:
$s .= 'color:'.rndSpace().rndColor().';'.rndSpace();
break;
case 6:
$t = array('none','underline','overline','line-through','blink');
$s .= 'text-decoration:'.rndSpace().$t[array_rand($t)].';'.rndSpace();
break;
case 7:
$t = array('none','capitalize','uppercase','lowercase');
$s .= 'text-transform:'.rndSpace().$t[array_rand($t)].';'.rndSpace();
break;
}
}
return $s;
}

function styleNone()
{
$q = rndQuote();
return 'style='.$q.rndCSS(2).rndSpace().'display: none;'.
rndSpace().rndCSS(2).$q;
}

function styleZero()
{
$q = rndQuote();
return 'style='.$q.rndCSS(1).rndSpace().
'height: 0px; '.rndCSS(1).' width: 0px; '.rndCSS(1).
' border: 0px;'.rndSpace().rndCSS(1).$q;
}

// ######################################
// ######################################
// ######################################
// level 1 functions (very simple utilities) :

function rndQuote()
{
// Will return either " or '
return (mt_rand(0,1) == 0) ? "'" : '"';
}

function rndSpace()
{
// Will return often one space, sometimes two spaces.
// Returning too often two spaces would be unrealistic.
return (mt_rand(0,5) == 0) ? " " : " ";
}

function rndCase($str)
{
// Will return STRING or string, never mixed case, because this is
// unlikely for a "real" (non-honeypot-related) tag to be mixed case.
return (mt_rand(0,1) == 0) ? strtoupper($str) : strtolower($str);
}

function rndWord()
{
// Will return something from the WORDS array, a bit modified
global $WORDS;
$w = $WORDS[array_rand($WORDS)];
for ($i = mt_rand(0,2); $i > 0; $i--)
{
$n = mt_rand(0,strlen($w));
$w = substr($w,0,$n).chr(mt_rand(0,25)+97).substr($w,$n);
}
return $w;
}

function rndColor()
{
// Will return a random value for a color
$s = "";
for ($i = 0; $i < 7; $i++) { $s .= dechex(mt_rand(0,15)); }
return "#".$s;
}

// ######################################
// ######################################
// ######################################
// test function (will do nothing if not in test mode)

if ($TESTONLY == "yes") {

echo "<hr><center><b>This is the honey pot randomizer test.<br>
If you didn't expect to see this, ensure that <i>TESTONLY</i>
has been set to <i>NO</i> in the ".__FILE__." file !</b><br>";
echo "<hr>Between each quotes, there's an hidden link (you can ";
echo "check the source if you like, and you're in fact encouraged to ";
echo "do so!)<br>On each line below, if you just see '' with your browser, ";
echo "then everything is fine.<br>Each time this page is refreshed, ";
echo "100 new examples are generated.<br>\n";
for ($i = 1; $i <= 100; $i++)
{
echo "$i : '";
hpot();
echo "'<br>\n";
}
}

// don't insert any line after the closing tag below !
// this would generate an empty line on your webpage
?>
 
 Re: PHP total link randomizer proposal
Author: M.Prince   (2 Aug 06 8:33pm)
I love it! That's soooo cool! Maybe we can include a copy of it (with your permission) with the PHP HPOTs? Shouldn't be too hard to port to Perl and some other languages too!

One thing that may be cool is that we're going to start trying to track a lot more data. For example, we want to know what types of links harvesters follow and what types they ignore. (Google, for example, has gotten smart and doesn't follow very many hidden link types anymore.)

Maybe we could insert and track a GET variable through the honey pot scripts which indicates what method of linking was used. For example, if you're using CSS to hide it by positioning it absolute and sending it -200px to the left of the window, maybe that's type "1" hiding. Could then include in the links:

www.projecthoneypot.org/honeypot.php?type=1

I wouldn't want to standardize it so much that you could spot our honey pot URLs, but it would be a cool stat to track.

Anyway... you've got me thinking....

Again, very cool! Kudos!!

Matthew.
 
 Re: PHP total link randomizer proposal
Author: S.Lesimple   (3 Aug 06 1:26pm)
Thanks for your support !

Of course you can include a copy of it with the php honeypots. It's meant to be useful, and used ! I've changed two little things in the script, so you're invited to download the zip again.

Maybe it'll not be too hard to port to others languages, but I'm afraid I can't help you there. However I've tried to comment the source and make it readable (lots of simple functions).

Tracking the type of links that harversters follow, this would be an interesting thing to add to the stats indeed. The idea of a GET variable seems interesting. In PHP there's a way to access GET variables no matter their name, i.e. if you want the value of the first variable, you can have it. Which means that script.php?blah=1 will work, and script.php?foobar=1 will work too. Interesting to avoid patterns ! About the value itself (1 in this case), I think there's some ways to normalize it without being too obvious. For example using the length of the value as the meaning. Not the value itself. i.e. script.php?azerty=web would be the third (length of "web" is 3) type of url obfuscation. Well... that's just a couple of ideas :)

You'll notice I haven't used the "CSS absolute positioning offscreen" in the script. That's because the layout of the page fails with Konqueror with this method (It's ok in Firefox and Internet Explorer). I'm not sure if it works in others browsers or not. That's why I've chose to avoid it. All the output produced by the script in its actual state don't echo a single blank character nor a blank line nor anything else, at least in the browsers i've tested it with.

Regards,

Stéphane.
 
 Re: PHP total link randomizer proposal
Author: M.Nordhoff   (10 Aug 06 10:44pm)
I've heard that if you do position something 5000 pixels off the left side of the screen, the standards say the browser should make the page another 5000 pixels wide so that you can scroll over to it. Some browsers don't obey that because, well, nobody wants that behaviour. So, if that's true, doing that would be a Bad Thing anyway.

-- Another Matthew, who has nothing really useful or on-topic to say.
 
 Re: PHP total link randomizer proposal
Author: L.Veltkamp   (20 Aug 06 8:08pm)
That's awesome! When I noticed that the linking example text was random, I thought that seemed useful and wanted to recreate the effect. Thank you, S.Lesimple, for doing the work for me. ;) I've already started using it.

Post Edited (21 Aug 06 6:01pm)
 
 Re: PHP total link randomizer proposal
Author: R.Monks2   (18 Sep 06 3:14pm)
Another cool thing you can do, and I think this script could be expanded to allow this:

Make a subdomain (EG: heh.youdomain.tld) and on it, place a php honeypot named index.php, and have an .htaccess file to make all the randomness go to a honeypot.

That's a good idea actually, sec.


.......................

Here it is: http://usr2.linkzerver.org/gen.php
Source: http://usr2.linkzerver.org/gen.phps

View source of the gen.php page to see the magic. The author gets full access to my modifications as public domain, as well as everyone else who's interested. Here's what I've changed:
1) added REWRITE variable so the use can select to do rewrites instead.
2) modified the aTag function to add gibberish to the end of the honeypot URL (which is still valid, & used so standards compliant sites including this won't have broken validation.
3) Modified aTag to add gibberish folders at the end of the .htaccess controlled domain or directory.
4) Removed the ?> tag at the end, it's not necessary and only makes errors possible ;)

Enjoy! Beat the spammers!

Robin



do not follow this link

Privacy Policy | Terms of Use | About Project Honey Pot | FAQ | Cloudflare Site Protection | Contact Us

Copyright © 2004–25, Unspam Technologies, Inc. All rights reserved.

contact | wiki | email