Skip to Content

Honey, I shrank the spam. Part II: How does it work?

In my  earlier Honey, I shrank the spam in 5 easy steps I showed you how easy it is to prevent malicious users from  accessing pages. Maybe this triggered your curiosity for what happens behind  the scenes. In fact, the mechanism is as simple as the code and is based on a  regular DNS query. The format of DNS query and the interpretation of the result  are the only things you need to pay attention to.

Let us first have a look at the DNS query. It has 3 major components:

The access key: see Step 1 in the Honey, I shrank the spam in 5 easy steps web log. A       key looks like this ‘abcdefghijk’

    1. The IP address you want to look up: the IP address must be specified in the reverse octet order. ( becomes Pay attention to the fact that it’s the octects that you need to reverse and not the IP address as a whole (thus NOT
    2. The list specific domain: This is Support for multiple sub-types of lists or other List-Specific Domains will follow at a later stage.

So if we want to look and see if is a malicious IP, we build this query:


After we’ve sent the request, we get a result that we need to analyse.

A possible answer can be Each octet has a specific meaning.

    1. Octet 1 (in this case 127). It must always be 127. If not, an error occurred, e.g.; wrong query
    2. Octet 2 (in this case 5). The number of days (between 0 and 255) since last activity of the queried IP address within the network of the Honeypot project. The lower the number of days, the more recent the IP has been active within the network and the more suspicious it could be.
    3. Octet 3 (in this case 10). An indicator (between 0 and 255) of the threat of this IP. The threat score is calculated within the project, based on factors such as the number of honeypots visited. The higher the score, the greater the risk.
    4. Octet 4 (in this case 1). Indication of the type of visitor.

      The possible types are

      0: search engine

      1: suspicious behaviour with no further actions

      2: harvester

      4: comment spammer

      It can also be a combination of different types

      0: search engine

      1: suspicious behaviour with no further actions

      2: harvester

      3: suspicious (1) + harvester (2)

      4: comment spammer

      5: suspicious (1) + comment spammer (4)

      6: harvester (2) + comment spammer (4)

      7: suspicious (1) + harvester (2) + comment spammer

      Other values can be added in the future.


If you don’t get any IP back as a result, you can’t be 100% sure that the IP is safe though.  It simply hasn’t cropped up in the honyepot project network db. In the case of, you won’t get any result back.


The code<br>
            How does  this translate in to code? I’ve already mentioned the code above, but here are  some details on how things are done. Let’s have a look at generating the query,  sending it and receiving the answer.</p>
          We need to  initialise variables.
   <pre>  data: param TYPE char255, result_table TYPE zeu_t_btcxpm, ip type string,
     itab TYPE TABLE OF string, idx type i,  result type string.</pre>
          <p> </p>
          <p>We know already a part of  the query: the access key</p>
          <pre>  param = key.</pre>
          <p> </p>
          Since we need to octet  reverse the IP, we split the IP into a table
   <pre>  split remote at ‘.’ into TABLE itab.</pre>
             <p> </p>
             <p>We need to start at the  end, so we set the table index to 4
             <pre>idx = 4. </pre>
          <p> </p>
             We need to pick an octet  4 times
   <pre>  do 4 times.</pre>
          <p> </p>
             Pick the octet
   <pre>  read table itab index idx into ip.</pre>
          <p> </p>
             And concatenate it to the  query
   <pre>  concatenate param ‘.’ ip into param.</pre>
          <p> </p>
             Move over to the next  octet
   <pre>  idx = idx – 1.
          <p> </p>
             <p>Append the list specific  domain. It’s hard coded for now<br>
<pre>  concatenate param ‘’ into param.</pre><br>
            Call the nslookup as  external command with the query as param<br>
<pre>  CALL FUNCTION ‘SXPG_COMMAND_EXECUTE'<br>  EXPORTING<br>  commandname                   = ‘ZNSLOOKUP'<br>  additional_parameters         = param<br>  operatingsystem               = sy-opsys<br>  terminationwait               = ‘X'<br>  TABLES<br>  exec_protocol                 = result_table<br>  EXCEPTIONS<br>  no_permission                 = 1<br>  command_not_found             = 2<br>  parameters_too_long           = 3<br>  security_risk                 = 4<br>  wrong_check_call_interface    = 5<br>  program_start_error           = 6<br>  program_termination_error     = 7<br>  x_error                       = 8<br>  parameter_expected            = 9<br>  too_many_parameters           = 10<br>  illegal_command               = 11<br>  wrong_asynchronous_parameters = 12<br>  cant_enq_tbtco_entry          = 13<br>  jobcount_generation_error     = 14<br>  OTHERS                        = 15.</pre></p>
             <p>if the calling of the  external went wrong we set a non hhtpBL error code<br>
  <pre>  if sy-subrc gt 0.<br>    rc = 99.<br>  else.</pre>
          <p>We got a result back in  the result_table. In our case (an AIX machine) we know that when we have less  than 4 records, we got a negative. </p>
          <pre>*** XXX can’t find  host/domain<br>Server:  XXX <br>Address:</pre>
          <p>If we have more than 4  records, we have a positive.</p>
          <pre><p>Server:  XXX<br>Address:</p><p>Non-authoritative answer:<br>Name:    Address:</pre></p>
          <p>You need to test out what  the result is on your system/OS.</p>
          <p>Thus we need to test if  there are more than 4 records
          <pre>    if lines( result_table ) gt 4.</pre></p>
          <p>If so, we need to pick  out record 6          </p>
          <pre>        read table result_table index 6 into result.</pre>
          <p>Skip all the blanks
          <pre>        condense result NO-GAPS.</pre></p>
          <p>We’re not interested in  the label eiter
  <pre>        split result at ‘:’ into TABLE itab.<br>        read table itab index 2 into result.</pre>
          <p>In our case, we want only  to give back the last octet
          <pre>        split result at ‘.’ into TABLE itab.
           read table itab index 4 into rc.
           rc = 0.
          In the BSP  page itself I call the method
          <pre><%@page language=”abap” %>
   <% data: remote type string.
             I determine the IP of the  end user
             remote = request->get_header_field( ‘~remote_addr’ ).%>
             And I pass it together with the acces key to the  method.
   <%= application->http_bl( key = ‘enter here  your key’ remote = remote )%></pre>
          <p> </p>
It’s up to you to decide what needs to happen next.  I’ve simply an output to the screen in this case. You can test for a certain  value. If it’s a safe value (see above) you continue. If not you can show some  message with eg. a link to a honeypot. Check my earlier web log on how to achieve this.

P.S. Which type of SDN Ubergeek/BPX suit are Which type of SDN Ubergeek/BPX suit are you??</p>

You must be Logged on to comment or reply to a post.