เหตุใดแฮกเกอร์จึงโจมตีเซิร์ฟเวอร์ DNS ด้วย DoS
เช้านี้ฉันตื่นขึ้นมาเพื่อรีบูตเซิร์ฟเวอร์ เซิร์ฟเวอร์ DNS ทำงานเกิน 100% หลังจากทำงานได้เล็กน้อยฉันได้รับ fail2ban เพื่อบล็อกคำขอทั้งหมดนั้น
คำขอนั้นถูกต้องโดยทำซ้ำหลายร้อยครั้งต่อวินาที เมื่อบล็อกมี IP จำนวนมาก (ร้อย) ฉันจะเห็นว่าฉันบล็อก 1 ล้าน UDP hit ทุกสองสามชั่วโมง
นั่นเป็นเพียงการโจมตี [D] DoS หรือไม่? (อาจถือว่าเป็นแบบไดนามิกเนื่องจากคอมพิวเตอร์หลายเครื่องมีส่วนเกี่ยวข้องและเมื่อมีการบล็อกนานพอดูเหมือนว่าจะหยุดการร้องขอ)
ความเป็นไปได้อื่น ๆ ที่ฉันคิดได้ก็คือผู้โจมตีกำลังพยายามทำให้เซิร์ฟเวอร์ DNS พังและเข้าถึงได้เมื่อรีสตาร์ทหรือทำให้คอมพิวเตอร์เสียหายทั้งหมดและพยายามเชื่อมต่อกับบริการอื่น ๆ (เช่นในกรณีที่คุณไม่ทราบวิธีการติดตั้งไฟร์วอลล์ก่อนที่คุณจะเริ่มบริการ)
นับตั้งแต่การรีเซ็ตไฟร์วอลล์ครั้งล่าสุดของฉันนี่คือสถิติของฉัน:
ฮิต: 2,346,742
จำนวน IP: 473
มันดำเนินไปอย่างรวดเร็ว หลายร้อยครั้งต่อวินาที อย่างไรก็ตามจำนวน IP ไม่ได้เพิ่มขึ้นมากนัก
คำตอบ
จากความคิดเห็นของ @ Schroeder ฉันได้ทำการค้นหาเพิ่มเติมและพบข้อมูลเพิ่มเติมเกี่ยวกับการโจมตีประเภทนี้
ฉันคือเป้าหมาย!
ก่อนอื่นดูเหมือนว่าฉันเป็นเป้าหมายของการโจมตี ทำไม? เนื่องจากการโจมตี DNS Amplification หมายความว่าพอร์ตต้นทางของคำขอ DNS ถูกตั้งค่าเป็น 53 ซึ่งทำให้สามารถบังคับให้ DNS ของฉันส่งการตอบสนองที่ไม่ได้ร้องขอไปยังเซิร์ฟเวอร์อื่นได้ (ดูกราฟด้านล่าง) เนื่องจากฉันมี Hit ดังกล่าวน้อยกว่า 0.1% โดยใช้พอร์ตนั้นฉันจึงไม่คิดว่า DNS ของฉันถูกใช้สำหรับการขยายสัญญาณ แต่เป็นเป้าหมาย
การโจมตีทำงานอย่างไร?
ผู้โจมตีตั้งค่าคอมพิวเตอร์ด้วยซอฟต์แวร์ที่ส่งแพ็กเก็ต UDP ไปยังเซิร์ฟเวอร์ DNS แบบสุ่มบางตัวเพื่อขอชื่อโดเมน แพ็คเก็ตดูเป็นปกติยกเว้นข้อเท็จจริงที่ว่าผู้โจมตีใส่ที่อยู่ IP ของคอมพิวเตอร์เครื่องอื่นแทนที่จะเป็นที่อยู่ IP ของเขาเป็นแหล่งที่มา ผลลัพธ์คือ DNS ส่งการตอบกลับไปยังคอมพิวเตอร์ที่ไม่ถูกต้อง :
10.0.0.1 10.0.0.2 10.0.0.3
+------------+ +------------+ +------------+
| | | | | |
| Attacker +-->| Some DNS +-->| Me |
| | | | | |
+------------+ +--+---------+ +------------+
| ^
v |
+---------+--+ This step is not required, it happens if
| | your DNS is setup to accept recursive
| Master DNS | requests (which is not a good idea)
| |
+------------+
10.0.0.4
ในตัวอย่างข้างต้นคำขอของผู้โจมตีควรมี 10.0.0.1 เป็นที่อยู่ต้นทางของ UDP แต่ผู้โจมตีกลับเปลี่ยนที่อยู่ IP ของเขาด้วย 10.0.0.3 ด้วยเหตุนี้เมื่อ DNS ที่ 10.0.0.2 ได้รับแพ็กเก็ต UDP และพร้อมที่จะส่งการตอบกลับระบบจะส่งข้อมูลไปที่ 10.0.0.3
จะมีการใช้ Master DNS ของโดเมนหาก DNS ที่ 10.0.0.2 ไม่ทราบอะไรเกี่ยวกับชื่อโดเมนที่กำลังสอบถาม
หมายเหตุสำคัญ:นี่เป็นความจริงสำหรับบริการ UDP ทั้งหมด DNS น่าจะแย่ที่สุดในแง่ของการขยาย แต่ NTP ก็สามารถกำหนดเป้าหมายได้เช่นกัน
ทำไมไม่ตรวจสอบที่อยู่ต้นทาง
เป็นไปไม่ได้จาก 10.0.0.2 เนื่องจาก UDP ไม่มีการจดจำแหล่งที่มาที่แท้จริงของแพ็กเก็ต
สิ่งที่เป็นไปได้คือให้ ISP ตรวจสอบว่าแพ็กเก็ตทั้งหมดที่ออกจากคอมพิวเตอร์เครื่องใดเครื่องหนึ่งมีที่อยู่ IP ของคอมพิวเตอร์เครื่องดังกล่าว ฉันคิดว่าบางอย่าง แต่ส่วนใหญ่อาจไม่ทำ มีผลกระทบต่อความเร็วเล็กน้อย ... ซึ่งแน่นอนว่าการขยาย DNS คือการหัวเราะเยาะ (การขยาย DNS มีผลต่ออินเทอร์เน็ตที่แย่กว่าการตรวจสอบต้นกำเนิดแพ็คเก็ต UDP เพียงเล็กน้อย)
อีกประการหนึ่งอาจเป็นไปได้ว่าผู้ใช้อาจยังคงสามารถทำได้โดยการเชื่อมต่ออินเทอร์เน็ตในลักษณะที่เลี่ยงผ่านการตรวจสอบของ ISP ฉันไม่รู้ว่าและ / หรือจะเป็นไปได้อย่างไร แต่ฉันก็ไม่แปลกใจเลยที่มันจะทำได้
อันที่จริงปัญหานี้เป็นปัญหามากเนื่องจากต้นกำเนิดของการโจมตีดังกล่าวเป็นเรื่องยากที่จะติดตามและนั่นคือสาเหตุที่ทำให้เกิดขึ้นต่อเนื่อง
ทำไมจึงเป็น DDoS?
แพ็กเก็ตที่จะขอบันทึก DNS ซึ่งเกิดขึ้นที่นี่มีขนาดเล็กมากอาจจะเป็น 300 ไบต์ ดังนั้นผู้โจมตีจะต้องส่งแพ็กเก็ต UDP ขนาดเล็กเพียงชุดเดียว
อย่างไรก็ตามการตอบสนองอาจมีข้อมูลหลายกิโลไบต์ โดยเฉพาะมีโดเมนที่ใช้ในการโจมตีเหล่านี้:
peacecorps.gov
และโดเมนนั้นส่งคืนข้อมูลมากกว่า 3Kb! (กำหนดฟิลด์ 'TXT' จำนวนมากซึ่งใช้ในการโจมตีด้วยการขยายสัญญาณนั้น)นี่คือสาเหตุที่เรียกว่า Amplification Attack
ด้วยเหตุนี้คำขอจากผู้โจมตีจะถูกเปลี่ยนเป็นการตอบสนองที่ใหญ่ขึ้นประมาณ 10 เท่าและคอมพิวเตอร์ที่ถูกโจมตี (10.0.0.3) จะเต็มไปด้วยแพ็กเก็ต UDP ที่ค่อนข้างใหญ่
ฉันจะแสดงรายการผลลัพธ์ในiptables
. ตัวเลขแรกแสดงถึงจำนวน Hit ไปยังคอมพิวเตอร์ DNS ของฉันหลังจากนั้นประมาณ 40 นาที (มากกว่า 10,000 ครั้งต่อนาที ... ):
pkts bytes target prot opt in out source destination
61637 4376227 DROP udp -- eno1 * 0.0.0.0/0 0.0.0.0/0 udp dpt:53 STRING match "|0a7065616365636f72707303676f76|" ALGO name bm TO 65535
โปรดสังเกตด้วยว่าสตริงถูกเปลี่ยนเป็นเลขฐานสิบหกโดยสมบูรณ์อย่างไร
คำขอ HTTP จะไม่แย่ไปกว่านี้หรือ!
HTTP 0.9 / 1.0 / 1.1 / 2 ใช้ TCP ซึ่งเป็นโปรโตคอลสองทางและไม่สามารถสร้างการขยายด้วย TCP ได้ เช่น TCP หยุดพักหากคุณไม่ได้เชื่อมต่อกับการจับมือเต็มรูปแบบก่อน
HTTP / 3 แนะนำโปรโตคอลQUICซึ่งเป็น HTTP ผ่านแพ็กเก็ต UDP จนถึงตอนนี้ฉันยังไม่เคยได้ยินเกี่ยวกับปัญหาหลักเกี่ยวกับ QUIC แต่โปรโตคอลได้เปลี่ยนไปมากในช่วง 6-7 ปีที่ผ่านมาและยังไม่มีการนำไปใช้อย่างกว้างขวาง นี่คือบทความเกี่ยวกับข้อเท็จจริงที่ว่า QUIC ได้สร้างคุณสมบัติไว้เพื่อป้องกันการโจมตีด้วยการขยายสัญญาณดังนั้นจึงมีความหวังว่าจะได้รับการดูแล
บางคนพูดถึงการใช้ HTTP เพื่อค้นหาชื่อโดเมน (DoH - โดเมนผ่าน HTTP) หวังว่าจะไม่ถูกนำไปใช้โดยใช้ QUIC ...
ฉันจะแก้ไขปัญหาได้อย่างไร
การขยายเกิดขึ้นเนื่องจาก DNS ของคุณถูกตั้งค่าให้ยอมรับคำขอของชื่อโดเมนที่คุณไม่ได้ควบคุม (เช่นโดเมนที่คุณไม่ใช่เจ้าของ)
BIND มีตัวเลือกที่อนุญาตให้ทำการขยายซึ่งเรียกว่าการเรียกซ้ำในสำนวน DNS คุณลักษณะนี้ถูกปิดโดยค่าเริ่มต้น แต่คุณอาจเปิดไว้ (โดยไม่ได้ตั้งใจ?)
นี่คือการตั้งค่าที่ไม่ถูกต้อง :
allow-recursion { any; };
สิ่งที่คุณต้องการคือใช้การตั้งค่าที่ถูกต้อง :
trusted-servers { 192.0.2.4; } // list all your trusted servers
allow-recursion { trusted-servers; };
สิ่งนี้จะทำให้เซิร์ฟเวอร์ของคุณปฏิเสธคำขอดังกล่าวทั้งหมดโดยอัตโนมัติ ดังนั้นหากคุณไม่ได้peacecorps.gov
และคุณได้รับคำขอดังกล่าว BIND ก็จะหยุดตรงนั้นและเขียนบันทึกในบันทึก DNS ของคุณเกี่ยวกับคำขอที่ถูกปฏิเสธ
ฉันสามารถบล็อก IP จากคำขอเหล่านั้นได้หรือไม่?
ใช่. ฉันเริ่มต้นด้วยการทำเช่นนั้นเนื่องจากเซิร์ฟเวอร์ของฉันทำงานได้ดีกว่า 100% ในเวลา CPU อย่างไรก็ตามอาจไม่เป็นการฉลาดที่จะทำเช่นนั้น จากภาพด้านบนคุณจะเห็นว่าเซิร์ฟเวอร์ DNS ของคุณอยู่ระหว่างผู้โจมตีและเหยื่อ หากคุณบล็อกที่อยู่ IP ต้นทางไม่ใช่ IP ของผู้โจมตีที่คุณกำลังบล็อกอยู่ แต่เป็นของเหยื่อ ซึ่งหมายความว่าคุณกำลังป้องกันไม่ให้เหยื่อเห็นชื่อโดเมนของคุณและร้องขอที่ถูกต้อง นั่นอาจไม่ใช่สิ่งที่คุณต้องการ!
ในตอนแรกฉันสร้างข้อความบันทึกจากไฟร์วอลล์ของฉัน หากฉันตรวจพบคำขอ 5 รายการขึ้นไปไปยังพอร์ต 53 (UDP) จากที่อยู่ IP เดียวกันในช่วงเวลาสั้น ๆ (5 วินาที) ฉันจะบล็อกที่อยู่ IP fail2ban
ต้องการทำเช่นนั้นผมใช้
ก่อนอื่นฉันมีตัวกรองที่ตรวจพบลิงก์ที่มี UDP และพอร์ต 53 เป็นปลายทาง:
# Filter: /etc/fail2ban/filter.d/named-fast-requests.conf
[Definition]
failregex = \sIN=[a-z0-9]+ .* SRC=<HOST> .* PROTO=UDP .* DPT=53\s
ประการที่สองฉันมีคุกซึ่งให้พารามิเตอร์อื่น ๆ :
# Jail: /etc/fail2ban/jail.d/named-fast-requests.conf
[named-fast-requests]
enabled = true
filter = named-fast-requests
action = named-action[scheme=all,period=year,reason=named fast requests]
logpath = /var/log/iptables/iptables.log
maxretry = 5
findtime = 5
bantime = 1036800
ประเด็นหลักที่นี่คือmaxretry
และfindtime
ตั้งไว้ที่ 5 ครั้งใน 5 วินาทีหรือน้อยกว่า เมื่อเป็นเช่นนั้นฉันจะบล็อกไฟล์<HOST>
.
คุณจะต้องการอัปเดตการกระทำด้วยสิ่งของคุณเอง ฉันใช้iplockเครื่องมือของตัวเองที่นี่ คำสั่งที่ฉันใช้ในการดำเนินการ:
actionban = /usr/sbin/iplock -s named -b <ip>
โดยค่าเริ่มต้น fail2ban จะใช้iptables
โดยตรง ค้นหาการกระทำของพวกเขาเพื่อดูว่าทำอย่างไร
อย่าเป็นแหล่งที่มาของการขยาย
คุณควรบล็อกคำขอที่พอร์ต UDP ต้นทางน้อยกว่า 1024 สิ่งเหล่านี้ไม่ถูกต้อง หากคุณเสนอเซิร์ฟเวอร์พอร์ต 53 จะเป็นพอร์ตปลายทางไม่ใช่ต้นทาง
iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 0:1023 -j DROP
คำเตือน:แทนที่ตำแหน่ง (123) ด้วยตัวเลขที่ถูกต้อง!
กฎนี้บอกว่าสำหรับแพ็กเก็ต UDP ขาเข้าeth0
ที่มีพอร์ตต้นทางระหว่าง 0 ถึง 1023 ให้ทิ้งแพ็กเก็ต ซึ่งจะป้องกันไม่ให้บุคคลอื่นใช้เซิร์ฟเวอร์ DNS ของคุณในการขยายสัญญาณ อย่างไรก็ตามไม่ได้ป้องกันเซิร์ฟเวอร์ของคุณเองจากการขยายสัญญาณจากผู้อื่น โปรดทราบว่าแม้จะมีการallow-recursion
ตั้งค่าที่เหมาะสมคุณจะไม่สามารถป้องกันการโจมตีด้วยการขยายหากผู้โจมตีเลือกชื่อโดเมนของคุณอย่างเหมาะสมสำหรับการโจมตี
หมายเหตุ:หากคุณระบุเนมเซิร์ฟเวอร์อื่นเพื่อแก้ไขชื่อโดเมนบนคอมพิวเตอร์ของคุณคุณอาจต้องการเปิดการเชื่อมต่อเหล่านั้นก่อนที่คุณจะบล็อกทุกอย่างจากพอร์ต 0 ถึง 1023 ซึ่งจะเป็นดังนี้:
iptables -I INPUT 123 -i eth0 -p udp -m udp --sport 53 -s 8.8.8.8 \
-d <your-static-ip> -j ACCEPT
นี่คือข้อมูลที่ส่งคืนจากเนมเซิร์ฟเวอร์ 8.8.8.8 ซึ่งคุณอาจต้องการรับ ไม่น่าจะเป็นไปได้ว่าผู้ให้บริการของคุณหรือเซิร์ฟเวอร์ชื่อทางการอื่น ๆจะเป็นแหล่งที่มาโดยตรงของการโจมตี UDP หากคุณไม่มีที่อยู่ IP แบบคงที่คุณไม่จำเป็นต้องใส่-d
ตัวเลือก
อย่างไรก็ตามมันน่าจะดีกว่ามากที่จะใช้ESTABLISHED
คุณสมบัตินี้ซึ่งตอนนี้พร้อมใช้งานสำหรับข้อความ UDP (ตอนนี้ใช้มาระยะหนึ่งแล้ว แต่ฉันจำช่วงเวลาที่ไม่สามารถใช้ได้ ... ):
iptables -I INPUT 123 -i eth0 -p udp -m state \
--state ESTABLISHED,RELATED -m udp -d <your-static-ip> -j ACCEPT
ซึ่งหมายความว่าคุณจะยอมรับคำตอบจากผู้ให้บริการเนมเซิร์ฟเวอร์ของคุณโดยอัตโนมัติเนื่องจากไฟร์วอลล์จะรู้ว่าคุณส่งคำขอและคุณต้องการยอมรับการตอบกลับ กฎนี้จะต้องปรากฏก่อนDROP
กฎข้างต้น
ส่งคำขอที่ไม่ต้องการก่อน
เห็นได้ชัดว่าการมี BIND ยอมรับคำขอทั้งหมดนั้นpeacecorps.gov
ไม่ใช่สิ่งที่ทุกคนต้องการ คุณสามารถบล็อกสิ่งเหล่านั้นได้โดยตรงในไฟร์วอลล์ของคุณ วิธีนี้ได้ผลเนื่องจากแพ็กเก็ต UDP ไม่ได้เข้ารหัสดังนั้นชื่อโดเมนจึงมองเห็นได้
นี่คือกฎที่สามารถใช้เพื่อบล็อกคำขอชื่อโดเมนเหล่านั้น:
sudo iptables -I INPUT 123 -i eno1 -p udp -m udp --dport 53 \
-m string --hex-string "|0A|peacecorps|03|gov|" --algo bm -j DROP
เห็นได้ชัดว่าหาก DNS ของคุณมีโดเมนหรือโดเมนย่อยรวมถึง "peacecorps.gov" ก็ไม่ควรใช้iptables
กฎนั้น สำหรับพวกเราส่วนใหญ่แม้ว่ามันจะหายาก
--hex-string
ตัวเลือกที่ช่วยให้คุณระบุสตริง วิธีที่กำหนดไว้ในแพ็กเก็ต UDP ใช้รูปแบบของ P-string (ขนาด + ข้อมูล) เนื่องจาก "peacecorps" มีความยาว 10 อักขระเราจึงใส่ 0x0A ไว้ข้างหน้า อีกครั้ง "gov" เป็นตัวอักษรสามตัวดังนั้นเราจึงใช้ 0x03 ถ้าเราจะใช้สตริง "peacecorps.gov" มันจะใช้ไม่ได้เนื่องจากจุดจะไม่ตรงกับ 0x03 ไบต์ ขนาดแรกเป็นทางเลือก (แม้ว่าคุณจะจับคู่สิ่งที่ดูเหมือนกันเช่น "bestpeacecorps")
การมีกฎดังกล่าวจะช่วยประหยัดบริการชื่อโดเมนของคุณจากปริมาณการใช้งานที่ไม่ต้องการโดยสิ้นเชิง
ปรับปรุง:แม้ว่าการโจมตีหยุดประมาณสองสัปดาห์หลังจากที่ผมโพสต์คำถามของฉันที่ "peacecorps.gov" ปัญหายังคงเกิดขึ้นประมาณ 10 ครั้งต่อวัน
ที่มา: https://defragged.org/2020/05/20/tips-and-tricks-blocking-dns-requests-via-iptables/
การดีบัก DNS ของคุณ
ในการดูว่าเซิร์ฟเวอร์ DNS ของคุณได้รับและตอบกลับแบบสอบถามใดคุณสามารถเรียกใช้คำสั่งต่อไปนี้ในคอนโซลของคุณ:
sudo rndc querylog
ตอนนี้ดูบันทึกโดยปกติจะอยู่ที่นี่:
less /var/log/named.log
ดูที่ด้านล่าง (ตีGในless
) และคุณควรจะเริ่มเห็นคำสั่งมาจาก IP ระยะไกล บันทึกรวมถึงชื่อโดเมนที่กำลังตรวจสอบ เป็นประโยชน์อย่างยิ่งโดยเฉพาะอย่างยิ่งหากคุณพลาดการป้อนชื่อโดเมนของคุณเองใน DNS รองหรือระดับตติยภูมิ