HOME | DNS | 使用iptables 的--string阻擋特定網域名稱查詢
linux的iptables可以針對封包的pattern直接進行比對進行阻擋

這個網路上可以查詢到相當多的資料

所以如果我們要針對DNS的惡意域名查詢在前端iptables做攔阻的話

首先我們必須要知道DNS查詢中的域名是在封包的哪一段

tcpdump -i eth0 -vv -nnn -X port 53  我們先針對自己的53 port做監聽

然後對自己查詢一個a.atest.tw A紀錄

0x0000:  4500 0070 c347 0000 4011 0a6f 3cfb 1968  E..p.G..@..o<..h
0x0010:  3cfb 1969 0035 9ebe 005c ad34 4493 8183  <..i.5...\.4D...
0x0020:  0001 0000 0001 0000 0161 0561 7465 7374  .........a.atest
0x0030:  0274 7700 0001 0001 c014 0006 0001 0000  .tw.............


每行是16byte,所以網域名稱是在第40個byte開始

編碼方式是將字串做hex,所以a.atest.tw就是6105617465737402747700

-A INPUT -p udp --dport 53 -m string --from 41 --to 48--alg bm --hex-string |6105617465737402747700| -j DROP

但是如果仔細觀察第一個點編碼後是01,第二個點編碼後是05,第三個點編碼後是02

一開始真的是讓我百思不得其解

測試了七八個域名之後才發現,他是一個shift的量

最後一個 . 一定是00,第二個點如果前面是tw(長度2),那就是02...依此類推

所以最後用php做轉換的程式碼大概是像下面

<?php
    $str = $argv[1];
    echo hexstring($str)."\n";
    function hexstring($str)
    {
        $var = explode(".",$str);
        $str = '';
        for($i = 0;$i < count($var);$i++)
            $str .= "0".strlen($var[$i]).tohex($var[$i]);
        $str .= "00";
        $rule = "-A INPUT -p udp --dport 53 -m string --from 42 --to 100 --alg bm --hex-string |$str| -j DROP";
        return $rule;
    }

    function tohex($string)
    {
        $hex = '';
        for ($i=0; $i < strlen($string); $i++)
            $hex .= dechex(ord($string[$i]));
        return $hex;
    }


    function toStr($hex)
    {
        $string = '';
        for ($i=0; $i < strlen($hex)-1; $i+=2)
            $string .= chr(hexdec($hex[$i].$hex[$i+1]));
        return $string;
    }
?>


當然你也可以使用cronjob定時去檢查log把一些惡意的攻擊做阻擋。







發表評論

暱稱

網址

電郵

開啟HTML 開啟UBB 開啟表情 隱藏 記住我 [登入] [註冊]