{"id":596,"date":"2007-05-03T15:07:07","date_gmt":"2007-05-03T13:07:07","guid":{"rendered":"http:\/\/planetozh.com\/blog\/honey-pot-httpbl-simple-php-script\/"},"modified":"2007-05-03T15:11:17","modified_gmt":"2007-05-03T13:11:17","slug":"honey-pot-httpbl-simple-php-script","status":"publish","type":"page","link":"https:\/\/planetozh.com\/blog\/my-projects\/honey-pot-httpbl-simple-php-script\/","title":{"rendered":"Honey Pot &#038; http:BL Simple PHP Script"},"content":{"rendered":"<p><strong>http:BL<\/strong> is a blacklist of all the suspicious IPs that were trapped in one of the honey pots run for <a href=\"http:\/\/www.projecthoneypot.org?rf=33327\">Project Honey Pot<\/a>. This service has a simple API, allowing anyone to check an IP against their blacklist. Here is a detailed and simple example script showing how to use this API.<\/p>\n<h2>Honey pot ?<\/h2>\n<p>Simply put, a honey pot is a webpage that will trick malicious users (as in &quot;robots&quot;) into doing something that will allow collecting data about them, while real users (as in &quot;human&quot;) won&#39;t notice or do anything particular.<\/p>\n<p>For example, <a href=\"http:\/\/planetozh.com\/smelly.php\">this<\/a> is a honey pot. Open this page in your browser, and you&#39;ll see nothing but uninteresting legalish text. Now have a look at the source of the page, and you will spot a hidden &lt;div> containing a form and emails. So, typically, if anything inputs text in that form, or sends anything to those emails, it&#39;s not human. It&#39;s a program spidering the web in search for spam food.<\/p>\n<h2>Using http:BL<\/h2>\n<p>First, you&#39;ll need to create an account on <a href=\"http:\/\/www.projecthoneypot.org?rf=33327\">PHPot<\/a> in order to be given a access key. Don&#39;t worry, it&#39;s free, and I even suspect it&#39;s a spam-free service :P Your access key will be a random string, like <em>ab234fghijkl<\/em><\/p>\n<p>Testing an IP with http:BL is a simple DNS query. For example, to check IP <strong>12.13.14.15<\/strong> you will need to query the following domain :<br \/>\n<strong><span style=\"color: rgb(153, 0, 0);\">ab234fghijkl<\/span>.<span style=\"color: rgb(0, 153, 0);\">15.14.13.12<\/span>.dnsbl.httpbl.org<\/strong>.<br \/>\nThe red part is your accesskey, the green part is the IP in the reversed octet format.<\/p>\n<p>The DNS query response will be something like <strong><span style=\"color: rgb(255, 0, 255);\">127<\/span>.<span style=\"color: rgb(153, 0, 0);\">3<\/span>.<span style=\"color: rgb(0, 153, 0);\">5<\/span>.<span style=\"color: rgb(0, 0, 153);\">1<\/span><\/strong> with the following meaning :<\/p>\n<ul>\n<li><span style=\"color: rgb(255, 0, 255);\">127<\/span>: the first octet is always 127. if it&#39;s not 127, then the query has failed, for some reason.<\/li>\n<li><span style=\"color: rgb(153, 0, 0);\">3<\/span>: the second octet is the number of days since last activity of the checked IP<\/li>\n<li><span style=\"color: rgb(0, 153, 0);\">5<\/span>: the third octet represents a threat score for IP. The greater this number, the more dangerous it is.<\/li>\n<li><span style=\"color: rgb(0, 0, 153);\">1<\/span>: the last octet defines the type of visitor<\/li>\n<\/ul>\n<p>For more detailed information refer to the <a href=\"http:\/\/www.projecthoneypot.org\/httpbl_api.php\">API documentation<\/a>. For now, we&#39;ll just make a simple example script to check wether an IP is threatening or not.<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-1\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">\/\/ your http:BL key\r\n$apikey = &#039;abcdefghijkl&#039;;\r\n\r\n\/\/ IP to test : your visitor&#039;s\r\n$ip = $_SERVER[&#039;REMOTE_ADDR&#039;];\r\n\r\n\/\/ build the lookup DNS query\r\n\/\/ Example : for &#039;127.9.1.2&#039; you should query &#039;abcdefghijkl.2.1.9.127.dnsbl.httpbl.org&#039;\r\n$lookup = $apikey . &#039;.&#039; . implode(&#039;.&#039;, array_reverse(explode (&#039;.&#039;, $ip ))) . &#039;.dnsbl.httpbl.org&#039;;\r\n\r\n\/\/ check query response\r\n$result = explode( &#039;.&#039;, gethostbyname($lookup));\r\n\r\nif ($result[0] == 127) {\r\n\t\/\/ query successful !\r\n\t$activity = $result[1];\r\n\t$threat = $result[2];\r\n\t$type = $result[3];\r\n\t\r\n\tif ($type &amp; 0) $typemeaning .= &#039;Search Engine, &#039;;\r\n\tif ($type &amp; 1) $typemeaning .= &#039;Suspicious, &#039;;\r\n\tif ($type &amp; 2) $typemeaning .= &#039;Harvester, &#039;;\r\n\tif ($type &amp; 4) $typemeaning .= &#039;Comment Spammer, &#039;;\r\n\t$typemeaning = trim($typemeaning,&#039;, &#039;);\r\n\r\n\techo &quot;IP seems to belong to a $typemeaning ($type) with threat level $threat&quot;;\r\n}<\/code><\/pre><\/div>\n<p>This simple snippet checks an IP against PHPot&#39;s blacklist, an if anything suspicious is detected, it outputs its verdict. How simple was that ?<\/p>\n<p>Now, what to do with this ? You can for example prevent your email address from appearing on a contact form if a email harvester is detected, or disable comment posting for all comment spammers. We will log and block malicious users :<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-2\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">\/\/ Our blocking policy\r\nif (\r\n($type &gt;= 4 &amp;&amp; $threat &gt; 1) \/\/ Comment spammer with very low threat level\r\n\t||\r\n($type &lt; 4 &amp;&amp; $threat &gt; 40) \/\/ Other types, with threat level greater than 40\r\n) {\r\n\t$block = true;\r\n}\r\n\r\nif ($block) {\r\n\tlogme($block,$ip,$type,$threat,$activity);\r\n\tblockme();\r\n\tdie();\r\n}<\/code><\/pre><\/div>\n<p>The <strong>logme()<\/strong> function would be just a logfile writing, collection a few data for further analysis : ip, requested page, user agent, etc&#8230;<\/p>\n<p>The <strong>blockme()<\/strong> function would be a nice &quot;403 Fordidden&quot; screen, explaining that unfortunately the IP was flagged as malicious and therefore the access to the page is not granted.<\/p>\n<h2>What about false positives and legitimate users ?<\/h2>\n<p>That&#39;s a good one. I believe every blocking measures should give a second chance to real users. It could be some harmless and innocent reader using a popular open proxy to read your site behind their corporate firewall, after all.<\/p>\n<p>A simple yet effective way to give real humans a chance to see your page is giving them a javascript redirection link. 99.9% of the infrequent false positive should have a real browser with javascript enabled. We will also set a cookie that will tell the checking script not to annoy this user and let him access pages.<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-3\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">function blockme() {\r\n\theader(&#039;HTTP\/1.0 403 Forbidden&#039;);\r\n\techo &lt;&lt;&lt;HTML\r\n\t&lt;script type=&quot;text\/javascript&quot;&gt;\r\n\tfunction setcookie( name, value, expires, path, domain, secure ) {\r\n\t\t\/\/ set time, it&#039;s in milliseconds\r\n\t\tvar today = new Date();\r\n\t\ttoday.setTime( today.getTime() );\r\n\t\r\n\t\tif ( expires ) {\r\n\t\t\texpires = expires * 1000 * 60 * 60 * 24;\r\n\t\t}\r\n\t\tvar expires_date = new Date( today.getTime() + (expires) );\r\n\t\r\n\t\tdocument.cookie = name + &quot;=&quot; +escape( value ) +\r\n\t\t( ( expires ) ? &quot;;expires=&quot; + expires_date.toGMTString() : &quot;&quot; ) + \r\n\t\t( ( path ) ? &quot;;path=&quot; + path : &quot;&quot; ) + \r\n\t\t( ( domain ) ? &quot;;domain=&quot; + domain : &quot;&quot; ) +\r\n\t\t( ( secure ) ? &quot;;secure&quot; : &quot;&quot; );\r\n\t}\t\r\n\tfunction letmein() {\r\n\t\tsetcookie(&#039;notabot&#039;,&#039;true&#039;,1,&#039;\/&#039;, &#039;&#039;, &#039;&#039;);\r\n\t\tlocation.reload(true);\r\n\t}\r\n\t&lt;\/script&gt;\r\n\t&lt;h1&gt;Forbidden&lt;\/h1&gt;\r\n\t&lt;p&gt;Sorry. You are using a suspicious IP.&lt;\/p&gt;\r\n\t&lt;p&gt;If you &lt;strong&gt;ARE NOT&lt;\/strong&gt; a bot of any kind, please &lt;a href=&quot;javascript:letmein()&quot;&gt;click here&lt;\/a&gt; to access the page. Sorry for this !&lt;\/p&gt;\r\n\t&lt;p&gt;Otherwise, please have fun with &lt;a href=&quot;http:\/\/planetozh.com\/smelly.php&quot;&gt;this page&lt;\/a&gt;&lt;\/p&gt;\r\nHTML;\r\n}<\/code><\/pre><\/div>\n<p>Now, before checking an IP, we&#39;ll first check for any cookie named &#39;notabot&#39; with value &#39;true&#39;. If there is one, don&#39;t bother making any check against the blacklist, and let the user access the page.<\/p>\n<h2>Wrapping it up<\/h2>\n<p>Here is the final script that checks for a whitelisting cookie, otherwise checks the IP and decide whether to block or not the user, logging malicious attempts accordingly. It also logs people clicking on the &quot;I&#39;m a human, not a bot&quot; link so that you can measure how tight or lose your blocking policy is.<\/p>\n<ul>\n<li><a href=\"http:\/\/planetozh.com\/download\/httpbl.php\">httpbl.php<\/a> (highlighted code, cut and paste)<\/li>\n<li><a href=\"http:\/\/planetozh.com\/download\/httpbl.txt\">httpbl.txt<\/a> (raw text, save as .php)<\/li>\n<\/ul>\n<p>To use the script, you would include it on the very top of your pages, i.e. :<\/p>\n<div class=\"igsh-code-box\" id=\"ig-sh-4\"><pre class=\"language-php line-numbers\" data-no-optimize=\"1\" data-cfasync=\"false\"><code class=\"language-php\">&lt;?php require(&#039;\/home\/you\/blog\/httpbl.php&#039;); ?&gt;<\/code><\/pre><\/div>\n<h2>Disclaimer and stuff<\/h2>\n<p>This script is a rather simple example serving as a basic http:BL tutorial for PHP. There has to be room for some improvements, such as better logging, or giving alternate javascript-free access to legitimate users.<\/p>\n<p><a href=\"http:\/\/www.projecthoneypot.org?rf=33327\">Project Honey Pot<\/a> is an awesome initiative in which you can contribute by setting up your own honey pots. Not only it&#39;s as easy as 1-2-3, but it&#39;s kind of rewarding : the day I had my first honey pot installed, it identified a new before-unseen harvester :) Installing a honey pot is an easy way of making the web a cleaner place. Or at least contributing to do so.<\/p>\n<p>Links to <a href=\"http:\/\/www.projecthoneypot.org?rf=33327\">Project Honey Pot<\/a> include my referral number. I&#39;m not earning anything but, maybe, satisfaction. What are you waiting for ? Install your honey pots.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>http:BL is a blacklist of all the suspicious IPs that were trapped in one of the honey pots run for Project Honey Pot. This service has a simple API, allowing anyone to check an IP against their blacklist. Here is a detailed and simple example script showing how to use this API. Honey pot ? Simply put, a honey pot\u2026<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":241,"menu_order":0,"comment_status":"open","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-596","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages\/596","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/comments?post=596"}],"version-history":[{"count":0,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages\/596\/revisions"}],"up":[{"embeddable":true,"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/pages\/241"}],"wp:attachment":[{"href":"https:\/\/planetozh.com\/blog\/wp-json\/wp\/v2\/media?parent=596"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}