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’
- The IP address you want to look up: the IP address must be specified in the reverse octet order. 155.56.92.16 (sdn.sap.com) becomes 16.92.56.155. 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 61.29.65.551).
- The list specific domain: This is dnsbl.httpbl.org. 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 155.56.92.16 is a malicious IP, we build this query:
abcdefghijk.16.92.56.155.dnsbl.httpbl.org
After we’ve sent the request, we get a result that we need to analyse.
A possible answer can be 127.5.10.1 Each octet has a specific meaning.
- Octet 1 (in this case 127). It must always be 127. If not, an error occurred, e.g.; wrong query
- 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.
- 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.
- 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 155.56.92.16, 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
</p>
<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.
enddo.</pre>
<p> </p>
<p>Append the list specific domain. It’s hard coded for now<br>
<br>
<pre> concatenate param '.dnsbl.httpbl.org' into param.</pre><br>
<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>
<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 abcdefghijk.1.0.0.127.dnsbl.httpbl.org:Non-existent host/domain<br>Server: XXX <br>Address: xxx.xx.xxx.x</pre>
</p>
<p>If we have more than 4 records, we have a positive.</p>
<pre><p>Server: XXX<br>Address: xxx.xx.xxx.x</p><p>Non-authoritative answer:<br>Name: abcdefghijk.0.1.1.127.dnsbl.httpbl.org Address: 127.1.1.0</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>
<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>
<p>In our case, we want only to give back the last octet
</p>
<pre> split result at '.' into TABLE itab.
read table itab index 4 into rc.
else.
rc = 0.
endif.
endif.
endmethod.
</pre>
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>
<p><b>Finalize</b></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 eddy.declercq/blog/2005/03/17/mr-spamman-don146t-bring-me-a-dream 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>