Tag: dns query attack

  • การใช้ fail2ban สำหรับการตั้งรับ DNS Brute Force Query Attack

    ต่อเนื่องจาก บทความนี้

    หลังจากวิธีการใช้งาน blackhole เพื่อให้ bind9 ไม่ตอบกลับ query ที่ client ส่งมา แล้วพบว่าวิธีการนี้
    จะมีปัญหากับการโจมตีแบบ DDoS ดังนั้น เราก็ต้องรับมือกับการโจมตีแบบนี้ด้วยเครื่องมืออื่นๆแทน

    เครื่องมืที่ผมใช้งานแล้วพบว่ามีประโยชน์มากตัวนึง สำหรับการป้องกันการโจมตีแบบอัตโนมัติก็คือ fail2ban ซึ่งบน Debian/Ubuntu สามารถติดตั้งได้ด้วยคำสั่ง

    $ sudo apt-get install fail2ban

    ซึ่งจะสร้าง configuration file ของ fail2ban ขึ้นมาอยู่ใน directory /etc/fail2ban
    configuration ของ fail2ban จะแบ่งเป็นส่วนของการตรวจจับ (โดยการใช้ regular expression) จาก log file ที่กำหนดไว้ (ซึ่งจะอยู่ใน directory /etc/fail2ban/filter.d)  และสามารถ กำหนด action (ซึ่งจะอยู่ใน directory /etc/fail2ban/action.d) ซึ่งใช้ในการ ban  การเข้าใช้งาน service ของ server ของเรา หรือตอบสนองแบบอื่นๆ เช่นส่ง email ไปเตือน admin ได้ มี action ที่ได้กำหนดเอาไว้แล้วหลายรูปแบบ ในที่นี้ ผมจะเลือกใช้ iptables filter สำหรับการ filter query packet ที่จะเข้ามา ซึ่ง config นี้ จะอยู่ในไฟล์ /etc/fail2ban/action.d/iptables.conf

    ส่วนของการ ตรวจจับ จะมีตัวอย่างของการ เขียน expression เอาไว้แล้วในไฟล์ตัวอย่าง ที่มีอยู่ใน /etc/fail2ban/filter.d ซึ่งสำหรับกรณีนี้ ผมจะสร้างไฟล์ขึ้นมาใหม่ชื่อ named-query-dos.conf โดยจะมีข้อมูลในไฟล์ดังต่อไปนี้

    [Definition]
    failregex = client <HOST>#.+: query: isc.org IN ANY \+ED .+
    ignoreregex =

    โดยบรรทัด failregex จะเป็น regular expression ที่ได้มาจาก logfile /var/log/named/query.log ซึ่งจะมีรูปแบบของการ query ที่แน่นอน นั่นคือ query “isc.org” แบบ ANY และมี flag ของการ query คือ ‘ED’

    28-Nov-2012 11:23:54.063 client 46.160.80.232#25345: query: isc.org IN ANY +ED

    ส่วน filed ของ วันที่/เวลา จะเปลี่ยนไปเรื่อยๆตามเวลาของการ query ที่เกิดขึ้น หมายเลข ip ของ client จะถูก match กับ <HOST> และส่งกลับไปให้ action ซึ่งจะนำเอาไปใช้ต่อไป

    ส่วนของ action เราจะใช้ iptables สำหรับการ filter ซึ่งจะมี config กำหนดเอาไว้แล้ว ซึ่งไม่ต้องวเปลี่ยนแปลงอะไร ส่วนของการ config ที่จะต้องเพิ่มขึ้นมาก็คือ ระบุให้ตัว fail2ban รู้ว่าจะต้องเอา config ส่วนนี้ไปใช้ โดยการเพิ่มข้อมูลต่อไปนี้ เข้าไปในไฟล์ /etc/fail2ban/jail.conf

    [named-query-dos]
    enaled = true
    banaction = iptables
    port = domain,53
    protocol = udp
    filter = named-query-dos
    logpath  = /var/log/named/query.log
    bantime  = 86400
    maxretry = 5

    ซึ่งจาก config ที่เพิ่มเข้าไป (หรืออาจจะสร้างเป็นไฟล์ใหม่ ในชื่อว่า jail.local ก็ได้)
    [named-query-dos] จะเป็นการระบุว่า config ส่วนนี้ เป็การเริ่มต้น section ใหม่
    enabled = true จะระบุว่าให้เอา config นี้ไปใช้ ซึ่งเราสามารถ disable config ส่วนนี้ได้ โดยไม่ต้องลบ config ออก เพียงแต่เปลี่ยนค่า enable = false
    banaction = iptables เป็นการเลือก action ที่จะใช้ ban client ที่เข้ามาโจมตี
    port = domain,53
    protocol = udp
    ทั้ง port และ protocol จะเป็นการระบุข้อมูลการ ban ให้กับ iptables
    filter = named-query-dos เป็นการเลือก filter (match regular express ที่จะใช้ ซึ่งในที่นี้ก็เป็นการอ้างถึงไฟล์ /etc/fail2ban/filter.d/named-query-dos.conf)
    logpath  = /var/log/named/query.log เป็นการระบุชื่อไฟล์ ที่เป็น input ของการ match expression ซึ่งในที่นี้ก็คือไฟล์ ที่เรากำหนดให้ bind9 สร้างขึ้น
    bantime  = 86400 เป็นระยะเวลาที่ unban สำหรับ ip นั้นๆหน่วยเป็นวินาที
    maxretry = 5 จำนวนครั้งของการ query ที่เกิดขึ้น ก่อนที่จะเริ่ม ban

    ในที่นี้ ระยะเวลาของการ ban — bantime ผมกำหนดให้เท่ากับ 24 ชม. ซึ่งนานพอที่จะป้องกันการกลับเข้ามาโจมตีใหม่ในเวลาอันสั้น เราอาจจะไม่ยกเลิกการ ban เลยก็ได้ แต่สำหรับ iptables แล้วมันจะทำให้ tables โตขึ้นเรื่อยๆ ซึ่งจะทำให้การ process packet ช้าลง เพราะฉะนั้นเวลา ban 24 ชม. น่าจะเหมาะสม และถ้ามีการโจมตีเข้ามาอีก ก็จะถูก ban อีกในรอบ 24 ชม.ถัดไป

    maxretry กำหนดค่า default เป็น 3 ผมเพิ่มให้เป็น 5 เพื่อ ยืนยันว่าเป็นการโจมตีจริง ไม่ใช่ query ผิดพลาด ซึ่งอาจจะเกิดขึ้นได้

    หลังจาก config เสร็จแล้ว เราก็สั่งให้ fail2ban เริ่มต้นทำงานได้โดยใช้คำสั่ง

    $ sudo service fail2ban start

    เราสามารถตรวจสอบผลของการทำงานของ fail2ban จาก logfile ได้ โดยการใช้คำสั่ง

    $ sudo tail -f /var/log/fail2ban.log

    เท่าที่ผมใช้อยู่สามารถ จัดการกับการโจมตีที่เกิดขึ้นได้อย่างดีครับ

  • สร้าง log สำหรับ DNS Query เมื่อใช้ bind9 เป็น DNS Server

    เนื่องจากปัญหาของ DNS Query Brute Force Attack ที่เกิดขึ้นกับ DNS Server บางตัวภายในเครือข่ายของมหาวิทยาลัย สงขลานครินทร์ วิธีการแรกที่ควรจะเอามาใช้ในการที่จะแก้ปัญหานี้ก็คือ “identify your enemy”.

    ใครคือคนที่ส่งคำสั่ง query เข้ามา? query อะไร? และ query บ่อยขนาดใหน?
    หลังจากแยกแยะข้อมูลในส่วนนี้ได้แล้ว เราค่อยตัดสินใจกันต่อว่าจะทำอย่างไรต่อไป

    สำหรับบทความนี้ จะพูดถึง Bind9 เท่านั้น Bind version ต่ำกว่า 9 ยังไม่ได้ทดสอบว่าใช้งานได้หรือเปล่า ส่วน version สูงกว่า 9, ถ้ามีก็น่าจะใช้งานได้ ส่วน DNS Server ตัวอื่นๆ ก็ยังไม่ได้ใช้อย่างจริงจังก็เลยไม่รู้เหมือนกันครับว่าจะจัดการอย่างไร แต่โดยหลักๆแล้วก็เหมือนกันครับ ก็คือ

    สร้าง log แล้วตรวจสอบจาก log

    สำหรับ bind9 ในส่วนของ option configuration จะมี keyword “logging” อยู่ ซึ่งสามารถใช้ระบุการ log ข้อมูลแบบต่างๆได้หลายอย่าง และ หลายรูปแบบมาก ในที่นี้ สมมติ เราสนใจเฉพาะส่วนของการ query นะครับ ก็อาจจะสร้าง config ได้แบบนี้

    logging {
          channel query_logging {
                 file “/var/log/named/query.log”;
                 print-time yes;
          };
          category queries { query_logging; };
    };

    เป็นการสร้าง channel สำหรับ log ขึ้นมาชื่อว่า “query_logging” โดยข้อมูลที่ถูกส่งมาที่ channel นี้จะเก็บลงไว้ในไฟล์ที่ชื่อว่า query.log ซึ่งไฟล์นี้จะเก็บอยู่ใน directory ที่ชื่อว่า /var/log/named

    config ข้างต้นจะเก็บเอาไว้ในไฟล์ /etc/bind/named.conf.options (สำหรับ Debian หรือ Ubuntu)
    โดยเพิ่มต่อท้ายเข้าไป

    ในส่วนของ directory ที่ใช้ในการเก็บ log (/var/log/named) ถ้ายังไม่มีอยู่ ก็ต้องสร้างขึ้นมาใหม่ก่อน และกำหนดให้เป็นของ user ซึ่ง run ตัว named daemon ซึ่งสำหรับบน Debian/Ubuntu จะใช้ user ที่ชื่อว่า bind ดังนั้น สามารถสร้าง diectory ขึ้นมาใช้งานได้โดยใช้คำสั่งดังนี้

    $ sudo mkdir -p /var/log/named
    $ sudo chown bind:bind /var/log/named

    หลังจากแก้ไขไฟล์ /etc/bind/named.conf.options แล้ว เราก็ควรที่จะตรวจสอบก่อนว่า config ไฟล์ที่แก้ไขไปยังอยู่ใน format ที่ถูกต้องก่อนที่จะใช้งาน ซึ่งทำได้โดยการใช้คำสั่ง

    $ sudo named-checkconf /etc/bind/named.conf

    ซึ่งถ้าไม่มีข้อความใดๆแสดงออกมา ก็แสดงว่า config ถูกต้อง เราก็สามารถสั่งให้ named อ่าน config ใหม่เข้าไปใช้ได้ โดยการใช้คำสั่ง

    $ sudo service bind9 reload

    หรือ

    $ sudo rndc reconfig

    หลังจากนั้น ก็สามารถตรวจสอบการทำงานของตัว named server ได้โดยใช้คำสั่ง

    $ host www.mydomain.net localhost

    เปลี่ยน ‘www.mydomain.net’ เป็น host ที่ตัว name server ของเราให้บริการอยู่
    หลังจากนั้นก็ไปตรวจสอบดูว่าในไฟล์ /var/log/named/query.log มีข้อมูลเพิ่มขึ้นมาหรือไม่

    ซึ่งถ้าการ config ทุกอย่างถูกต้อง ก็ควรที่จะมีข้อมูลของการ query เกิดขึ้น
    ตัวอย่างของข้อมูลที่ตัว named จะ log เอาไว้ครับ

    28-Nov-2012 11:54:14.911 client 174.127.97.86#25345: query: isc.org IN ANY +ED (172.30.0.85)
    28-Nov-2012 11:54:15.589 client 174.127.97.86#25345: query: isc.org IN ANY +ED (172.30.0.85)

    ซึ่งในที่นี้ client ที่ส่งคำสั่ง query มาก็คือ 174.127.97.86 โดย server ก็คือ 172.30.0.85 และข้อมูลที่ query ก็คือ isc.org ชนิดของข้อมูลเป็น any (ข้อมูลทั้งหมดเท่าที่มี)

    ในสภาวะที่ตัว Server ของเราถูกโจมตี ขนาดของ query.log ก็จะเพิ่มขึ้นอย่างรวดเร็วมาก
    จากตัวอย่างข้างต้น query ทั้งสองครั้งเกิดขึ้นในช่วงเวลาน้อยกว่า 1 วินาที (ครั้งแรกเวลา 11:54:14, ครั้งถัดมา 11:54:15 ตัวเลข 3 ตัวหลังจุด จะเป็นส่วนย่อยของวินาที)

    เราจะรู้ได้อย่างไรว่า client ตัวใหนบ้างที่กำลังโจมตี server ของเราอยู่ ตัวใหนที่ใช้งานแบบปกติ?
    เราสามารถใช้เครื่องมือบน linux/unix ในการช่วยตรวจสอบได้ครับ โดยการนับ

    $ cat /var/log/named/query.log | cut -f4 -d’ ‘ | cut -f1 -d’#’ | sort | uniq -c | sort -rn | head -20

    ตัวอย่าง output ที่ผมได้จาก server ที่ถูกโจมตีคือ

      18174 178.32.76.101
      10924 64.120.228.188
       5297 194.8.75.57
       4584 37.77.82.161
       1744 72.20.55.30
       1548 88.232.24.58
       1356 216.119.157.90
       1242 69.64.58.160
       1189 5.47.41.41
       1155 128.204.201.22
       1115 5.135.60.245
        872 31.214.144.181
        629 37.59.93.86
        513 88.228.212.44
        467 94.121.242.57
        438 178.32.239.65
        382 37.59.194.200
        343 174.127.92.85
        325 174.127.103.234
        296 88.245.53.247

    ตัวเลขข้างหน้าคือจำนวนครั้ง และตัวเลขข้างหลังคือ ip address ของ client ที่ส่งคำสั่ง query เข้ามาทั้งหมดนี้ query ช้อมูลตัวเดียวกันก็คือ “isc.org” type ANY

    เรารู้ตัวว่าผู้โจมตีเป็นใครแล้ว หลังจากนี้ก็จะเป็นคำถามว่า แล้วจะแก้ปัญหาอย่างไร
    ขอยกไปเป็นบทความหน้าครับ