วันอังคารที่ 31 พฤษภาคม พ.ศ. 2554

จุดอ่อนของ DNS Server

จุดอ่อนของ DNS Server

จุดอ่อนของ DNS server


เรามักจะใช้ DNS server กันอย่างไม่รู้คุณค่า บทความนี้จะกล่าวถึงรายละเอียดการโจมตี DNS
server และคุณสามารถทำอะไรเพื่อการรักษาความปลอดภัยที่ดีขึ้น ซึ่งจะตอบคำถามต่อไปนี้คือ

* แคร็กเกอร์(crackers) ใช้ประโยชน์(exploit) จาก DNS เซิร์ฟเวอร์ของคุณได้อย่างไร ?
* คุณสามารถทำให้การรักษาความปลอดภัยของ DNS server แข็งกร่งโดยการกำหนดค่า(configuration)ได้อย่างไร ?
* คุณสามารถทำให้การบุกรุก DNS server ของคุณเป็นฝันร้ายสำหรับผู้ที่บุกรุกได้อย่างไร ?

ซึ่ง อธิบาย ในลักษณะของการโจมตีและการป้องกัน การป้องกันดำเนินการใน DNS server ที่ใช้ BIND เวอร์ชัน 8 แต่แนวความคิดใช้ได้กับ DNS server ทุกชนิด บทความนี้จะเป็นประโยชน์สำหรับผู้ดูแลระบบ

การโจมตี: ผู้ โจมตีหาข้อมูลจาก DNS server ของคุณให้ได้มากที่สุดสมมติว่าโดเมนของเป้าหมายคือ dumb.target.jay เราต้องการรู้ว่า name server ของ dumb.tarbet.jay คืออะไรจึงใช้คำสั่ง nslookup ในยูนิกซ์ ดังต่อไปนี้:

[jay@max jay]$ nslookup
Default Server: ns.my.isp
Address: 10.0.0.1
> set q=ns
> dumb.target.jay
Server: ns.my.isp
Address: 10.0.0.1
Non-authoritative answer:
dumb.target.jay nameserver = dumb.target.jay
dumb.target.jay nameserver = ns2.dumb.target.jay
Authoritative answers can be found from:
dumb.target.jay internet address = 192.168.1.85
>

ต่อ มาเมื่อ รู้ว่าอะไรเป็น name server เพื่อใช้หาข้อมูล จึงถามเซิร์ฟเวอร์นี้ สำหรับรายการของโซน (zone)ใช้คำสั่ง dig เพื่อถามถึง zone transfer:

[jay@max zone]# dig @192.168.1.85 dumb.target.jay axfr
; <<>> DiG 8.2 <<>> @192.168.1.85 dumb.target.jay axfr
; (1 server found)
$ORIGIN dumb.target.jay.
@ 20H IN SOA ns1 hostmaster.dumb.target.jay
(2000111001 ; serial
5H ; refresh
1H ; retry
4d4h ; expire
1D ) ; minimum
1H IN NS dumb.target.jay.
20H IN NS ns.dumb.target.jay.
20H IN NS ns.dumbs.isp.
20H IN A 192.168.1.85
1D IN HINFO "Pentium 133" "Red Hat 6.1"
1D IN MX 10 mail
mail 1D IN A 192.168.1.2
really 1D IN A 192.168.1.20
1D IN TXT "Admin's Trusted Workstation"
1D IN HINFO "Athlon 850" "Red Hat 6.1"
rather 1D IN A 192.168.1.15
1D IN HINFO "Pentium 266" "Mandrake 7.1"
serious 1D IN CNAME extra
extra 1D IN A 192.168.1.80
ns 1D IN A 192.168.1.30
r_g 1D IN A 192.168.1.68
roblimo 1D IN MX 10 r_g
1D IN A 192.168.1.44
tahara 1D IN A 192.168.1.27

ดูจากข้อมูลที่เราได้จากการใช้คำสั่งสองคำ สั่ง จะเห็นว่ามีรายชื่อของเครื่องทั้งหมดที่อยู่ในโซนนี้ นอกจากนี้
ถ้า คุณดูที่ HINFO คุณสามารถรู้ได้ว่าเครื่องเหล่านี้ใช้ลีนุกซ์อะไร ทำให้เรารู้อะไรบ้าง ถ้ามีรายการของ exploit
ที่ใช้ได้กับ Red Hat 6.1 ถ้าสามารถรู้ zone transfer และทำอย่างที่ทำข้างต้นและหา "Red Hat" จะพบ
เครื่อง สองเครื่องที่เสี่ยงต่อการถูกโจมตีซึ่งรวมถึงเครื่อง workstation ของ sysadmin ด้วย จากนี้จึง
มุ่งความสนใจไปที่สองเครื่องนี้ซึ่งมักจะมีความ เชื่อถือกันเองระหว่างสองเครื่องนี้ด้วย เป็นขึ้นตอนแรกสำหรับ
cracker เมื่อต้องการรู้ข้อมูลเกี่ยวกับเน็ตเวิร์คนั้น

กำหนดค่า DNS server อย่างมีความเข้าใจ

DNS ได้รับการออกแบบในตอนที่อินเตอร์เน็ตเป็นสถานที่ที่น่าเชื่อใจกว่านี้มาก ไซต์ใหญ่ ๆ มากมายหลายแห่งยังคงกำหนดค่า DNS server ของพวกเขาให้บอกข้อมูลออกไปจำนวนมากต่อใครก็ตามที่ร้องขอ ข้อมูลในส่วนของ HINFO และ TXT เป็นประโยชน์สำหรับผู้บริหารไซต์นั้นที่จะต้องดูแลเครื่องจำนวนมากในไซต์ แต่เป็นประโยชน์มากกว่าสำหรับ cracker ผู้ซึ่งพยายามหาข้อมูลเกี่ยวกับคอมพิวเตอร์ของบริษัทคุณ

DNS ควรให้ข้อมูลเกี่ยวกับ ip/name mapping เท่านั้น เปรียบเทียบได้กับในบริษัทของคุณที่คุณจะให้ให้แผนกต้อนรับลูกค้าบอกถึงหมาย เลขโทรศัพท์ภายในของบุคคลที่ต้องการเท่านั้น ไม่รวมถึงตำแหน่ง คุณสมบัติและโครงการของบริษัท คุณไม่ทำอย่างนั้นแน่นอนเพราะหมายถึงการเสี่ยงต่อการปล่อยให้ความลับของ บริษัทรั่วใหล และอาจสูญเสียบุคคลากรของบริษัทคุณให้กับบริษัทอื่นคุณสามารถกำหนดค่าของ name server ของคุณได้อย่างง่าย ๆ ให้มันให้ข้อมูลจำเป็นจริง ๆ โดยการแก้ไขไฟล์ /etc/named.conf ไฟล์กำหนดค่าหลักของ BIND

options {
directory "/var/named";
};
zone "dumb.target.jay" {
type master;
file "zone/db.dumb.target.jay";
};
zone "1.168.192.in-addr.arpa" {
type master;
file "zone/db.192.168.1";
};

การ กำหนดค่า นี้แสดงให้เห็นเพียงส่วนของ options ซึ่งแสดงให้เห็น global setting, forward และreverse zone สำหรับโดเมนสมมติ dump.target.jay ตัวอย่างข้างบนได้ละส่วนของ root server และ localhost ไว้เพื่อความกระชับ ตัวอย่างนี้ใช้สำหรับ primary name server มากกว่าที่จะเป็นsecondary name server

ขั้นแรกให้ดูที่ zone transfer, zone transfer ปกติใช้เพื่อให้ secondary name server ได้อัปเดท
ข้อมูลให้เหมือนกับ primary name server เท่านั้น นอกจากนี้แล้วมันใช้เพื่อหาข้อมูลของเป้าหมายเท่านั้น
สมมติว่า secondary name server มี ip address เป็น 192.168.1.30 และ 10.1.1.4 ดังนั้นเครื่องอื่น
ก็ไม่มีความจำเป็นต้องใช้ zone transfer ต่อมาจึงจำกัดมันดังนี้:

options {

directory "/var/named";

allow-transfer { 192.168.1.30; 10.1.1.4; };

};

สมมติว่าเน็ตเวิร์คภายใน ของคุณมีเพียงเครื่องที่มี subnet 192.168.1.x เท่านั้น เครื่องภายนอก subnet นี้
ควรที่จะสอบถาม(query)ได้เฉพาะโซนที่คุณรับผิดชอบอยู่เท่า นั้น สิ่งนี้สำคัญเพราะการโจมตี DNS server
ส่วนใหญ่จำเป็นที่ผู้โจมตี ต้องสามารถสอบถาม server อื่นซึ่งมักจะเป็นโดเมนที่ผู้โจมตีควบคุมอยู่ ถ้าเราไม่
อนุญาตให้ผู้ใช้ภายนอกสามารถสอบถามถึงโดเมนที่ไม่ใช่ของเรา เราจะป้องกันจากการโจมตีได้หลายอย่าง

options {
directory "/var/named";
allow-transfer { 192.168.1.30; 10.1.1.4; };
allow-query { 192.168.1.0/24; };
};
zone "dumb.target.jay" {
type master;
file "zone/db.dumb.target.jay";
allow-query { any; };
};
zone "1.168.192.in-addr.arpa" {
type master;
file "zone/db.192.168.1";
allow-query { any; };
};

ถึงตอนนี้ใคร ๆ ก็สามารถสอบถามถึงโดเมน dumb.target.jay และ reverse ของมัน มีเพียงโฮสต์ภายใน
เน็ตเวิร์คเท่า นั้นที่สามารถสอบถามอย่างอื่นได้ ท้ายสุดให้อนุญาตให้มีการสอบถามแบบเรียกตัวเอง (recursive)
ได้จากโฮสต์ ภายในเท่านั้น โดยต้องทำแต่ละโฮสต์ให้มีเฉพาะไลบรารีสำหรับการ resolve ip/hostname
(resolver library) ซึ่งจะถาม name server สำหรับ name/ip mapping แต่ละโฮสต์จะสอบถาม name
server ถึง ip ของ dumb.tarbet.jay name server จะสอบถาม root server เพื่อให้หาว่าโฮสต์ใดที่
รับผิดชอบโด เมน .jay root server จะตอบ ip มาซึ่งมันจะติดต่อและถาม server ที่รับผิดชอบโดเมน
target.jay ควรมีเพียงโฮสต์ภายในเน็ตเวิร์คของคุณเท่านั้นที่สามารถถาม name server เพื่อให้ทำอย่างนี้
ได้เพราะโฮสต์ภายนอกมี name server ของตัวเองอยู่แล้ว การอนุญาตให้โฮสต์ภายนอกสอบถาม name server
ของคุณให้ ตอบแบบเรียกตัวเองสามารถนำไปสู่การโจมตีแบบ cache poisoning ได้ และโดยทั่วไปสิ่งนี้จะ
ให้ข้อมูลที่มากเกินไปสู่ภายนอกเน็ตเวิร์ค

options {
directory "/var/named";
allow-transfer { 192.168.1.30; 10.1.1.4; };
allow-query { 192.168.1.0/24; };
allow-recursion { 192.168.1.0/24; };
};

เอาละเราได้ทำให้การรักษาความปลอดภัยของ DNS แน่นหนาขึ้นแล้ว แต่ยังมีอะไรเหลืออีกล่ะ บางคนยังสามารถ
สอบถาม HINFO และ TXT records ได้ถึงแม้ว่าจะไม่สามารถทำการสอบถาม zone transfer ดังต่อไปนี้:

[jay@max jay]$ dig @localhost dumb.target.jay hinfo
; <<>> DiG 8.2 <<>> @localhost dumb.target.jay hinfo
; (1 server found)
;; res options: init recurs defnam dnsrch
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0,
ADDITIONAL: 0
;; QUERY SECTION:
;; dumb.target.jay, type = HINFO, class = IN
;; ANSWER SECTION:
dumb.target.jay. 1D IN HINFO "Pentium 166" "Red Hat 6.1"
;; Total query time: 1 msec
;; FROM: max.fictional.attacker to SERVER: localhost 127.0.0.1
;; WHEN: Sun Nov 12 00:17:08 2000
;; MSG SIZE sent: 33 rcvd: 69

คุณมีทางเลือกหนึ่งในสองทางดังต่อไปนี้ คือ:

* เอา record ของ HINFO และ TXT ออกจากไฟล์ที่เกี่ยวกับ zone หรือ
* เซ็ต DNS เป็นแบบ Split Horizon DNS

ทาง เลือก หลังหมายถึงการทำ name server สองชุด ชุดแรกอยู่หลังไฟร์วอล อีกชุดหนึ่งอยู่ข้างนอกโดยใช้ Network Address Translation (NAT) ที่อยู่ภายในเน็ตเวิร์ค ชุดที่อยู่ภายในเน็ตเวิร์คใช้เหมือนกับ ชุดที่อยู่ภายนอกเน็ตเวิร์คแต่ชุดที่อยู่ภายในให้ข้อมูลทุกอย่างรวมทั้ง TXT และ HINFO ในขณะที่ชุดที่อยู่ภายนอกจะให้ข้อมูลที่จำกัดมากโดยจะไม่ให้ข้อมูลแทบ ทุกอย่างที่เกี่ยวกับเครื่องที่อยู่ภายในเน็ตเวิร์ค เนื่องจาก NAT ทำให้ดูเหมือนกับว่าเน็ตเวิร์คภายในมีเพียงเครื่องเดียว

การทำ Split Horizon DNS เป็นงานที่ต้องใช้เวลามาก แต่จะประหยัดเวลาสำหรับการทำโครงการที่
เกี่ยวกับ DNS ที่สำคัญโครงการต่อไป ในตอนนี้ให้ระมัดระวังเกี่ยวกับ record ของ HINFO/TXT ให้มาก
และใช้หลักการให้ข้อมูลสู่ภายนอกให้น้อยที่สุดและให้ข้อมูลสู่ ผู้ใช้ในสิ่งที่เขาต้องการจริง ๆ ไม่ควรตั้งชื่อของ
ผู้ดูแลระบบว่า admin อาจเรียกใหม่ในชื่อ overlord

การ crack name server ของคุณ
เรา ได้แก้ไขช่องโหว่ที่เกี่ยวกับการให้ข้อมูลที่มากเกินไปแล้ว อย่างไรก็ตาม DNS server ที่ใช้ BIND เอง
ยังมีช่องโหว่ทางด้านการรักษาความปลอดภัย อยู่เรื่อย ๆ เช่น BIND เวอร์ชัน 8.2 - 8.22 ที่ยังไม่ได้แก้ไข
ช่องโหว่ มีช่องโหว่ที่สามารถใช้เพื่อให้ได้สิทธิ์ของ root จากเซิร์ฟเวอร์อื่นได้ คุณสามารถอ่านรายละเอียดได้
ที่นี่

script kiddies (ผู้ซึ่งนำสคริปต์ที่ผู้อื่นเขียนขึ้นมาใช้เพื่อการบุกรุกสู่ระบบ) จำนวนมากจะสแกน
โฮสต์ในอินเตอร์เน็ตจำนวนมากเพื่อหา BIND เวอร์ชันที่มีช่องโหว่ ดังต่อไปนี้:

[jay@max bog]$ dig @dumb.target.jay dumb.target.jay
txt chaos version.bind
; <<>> DiG 8.2 <<>> @dumb.target.jay dumb.target.jay
txt chaos version.bind
; (1 server found)
;; res options: init recurs defnam dnsrch
;; got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 1,
AUTHORITY: 0, ADDITIONAL: 0
;; QUERY SECTION:
;; version.bind, type = TXT, class = CHAOS
;; ANSWER SECTION:
VERSION.BIND. 0S CHAOS TXT "8.2.2"
;; Total query time: 1 msec
;; FROM: max.fictional.attacker to
SERVER: dumb.target.jay 192.168.1.85
;; WHEN: Mon Oct 20 18:30:05 2000
;; MSG SIZE sent: 30 rcvd: 63
[jay@max bog]$


จะเห็นได้ว่า BIND บอกเวอร์ชันและมันก็มีช่องโหว่เสียด้วย มันมีผลเสียอย่างร้ายแรงที่ script kiddie จงใจ
สแกนโฮสต์ในอินเตอร์เน็ตเพื่อหา BIND เวอร์ชันที่มีช่องโหว่ พวกเขาอาจดาวน์โหลด perl script ที่ยาวเพียง
สาม บรรทัดเพื่อที่จะสแกนหา name server ที่มีช่องโหว่นี้ พวกเขาสามารถหาเซิร์ฟเวอร์ของเราเจอได้
นอกจากนี้ ถ้า cracker ที่มีความชำนาญกำลังหาข้อมูลเกี่ยวกับคอมพิวเตอร์ของเรา เขาต้องการรู้ว่าเรามี
name server ที่มีช่องโหว่หรือไม่ เขาสามารถหาข้อมูลนั้นโดยไม่ให้ผู้ดูแลระบบรู้ได้ด้วย ปกปิดเวอร์ชันของ BIND ของ cracker และสคริปต์ของพวกเขา:แก้ไขช่องโหว่ รันโดยยูสเซอร์ที่ไม่ใช่ rootโชคดีที่เราสามารถเปลี่ยนข้อความที่มากับ name server ได้โดยเพิ่มเติมลงไปในไฟล์ /etc/named.conf
ในส่วนของ options ดังต่อไปนี้:

options {
directory "/var/named";
allow-transfer { 192.168.1.30; 10.1.1.4; };
allow-query { 192.168.1.0/24; };
version "Go away!";
};

คุณอาจเปลี่ยนเป็นข้อความเป็น "10.0.0" เพื่อให้ดูก้าวร้าวน้อยลง หรือ "4.9.7" เพื่อให้เขาเลิกยุ่งกับเซิร์ฟเวอร์

การ ใช้มาตรการนี้คุณควรแก้ไขช่องโหว่ของ name server ของคุณอย่างสม่ำเสมอ ถึงแม้จะทำเช่นนี้แล้ว
แต่คุณก็อาจมีช่องโหว่อีกคือ DNS server ส่วนมากจะรันโดย root ซึ่งเปิดให้มีการได้สิทธิ์ของ root
จากเซิร์ฟเวอร์ อื่นในระหว่างช่วงเวลาที่มีการค้นพบช่องโหว่และการแก้ไขช่องโหว่ ในระหว่างนี้สิ่งเดียวที่ช่วยได้
คือทำให้การรักษาความปลอดภัยของ name server เข้มแข็งยิ่งขึ้น อับดับแรกที่ต้องทำซึ่งทำได้ง่ายคือให้
BIND รันโดยยูสเซอร์อื่น ถ้าไม่ใช่ root ที่รัน BIND คุณสามารถหาได้โดยพิมพ์ดังต่อไปนี้:

[jay@max jay]$ ps -ef | grep named
named 9179 1 0 12:15 ? 00:00:00 named -u named

คอลัมน์ แรกแสดงชื่อยูสเซอร์ที่รัน BIND เครื่องที่ผมใช้ทดสอบคือ Mandrake 7.1 โปรแกรม named
ของ BIND รันโดยยูสเซอร์ named ถ้าคุณใช้ระบบปฏิบัติการที่แสดงให้เห็นว่า named รันโดย root
ให้หาส คริปต์เริ่มต้น(init script) ที่เริ่มการทำงานของ named แล้วจึงแก้ไขให้ใช้ flag -u และ -g ดังต่อไปนี้:

/usr/sbin/named -u dns_user -g dns_group

คุณจำเป็นต้องสร้างยูสเซอร์ dns_user และกลุ่ม dns_group โดยคุณจะใช้ชื่ออะไรก็ได้ที่ต้องการ
MandrakeSoft ใช้ยูสเซอร์ named และกลุ่ม root ส่วนผมเลือกเอายูสเซอร์ bob และกลุ่ม less
เพื่อไม่ให้ยู สเซอร์อื่นและcracker สงสัย ในกรณีใด ๆ ก็ตามให้ใช้ทั้งสอง flag นอกจากนี้ยูสเซอร์ที่สร้างมานี้
ควรปิดการใช้งานจาก shell เช่น /bin/false และควรมี home directory เป็น /var/named หรืออะไร
ก็ตามที่ เป็นไดเร็กทอรีของ DNS

ขั้นตอนง่าย ๆ เหล่านี้จะป้องกันจากการได้สิทธิ์ของ root จากเซิร์ฟเวอร์อื่น (remote root exploit) ใน
name server ที่ใช้ BIND 8.2 - 8.22 ซึ่งป้องกันได้เพียงไม่ไห้ script kiddie ใช้ shell ได้ และพวกเขา
จำ เป็นต้องพยายามเพิ่มเติมเพื่อให้ได้สิทธิ์ของ root วิธีนี้สามารถหยุดการโจมตีจาก script kiddie เท่านั้น
ถ้าป้องกันจากการ โจมตีขั้นสูงแล้วต้องใช้อีกวิธีหนึ่ง

เทคนิคขั้นสูง: chroot the server

เราสามารถตีวงเซิร์ฟเวอร์ให้รันอยู่ในสภาวะ chroot ได้ซึ่งจะจำกัดให้เซิร์ฟเวอร์สามารถเข้าถึงได้เพียง
ส่วนย่อยของ filesystem เท่านั้น มักจะเป็น /home/dns หรือ /chroot/dns โมดูล DNS.pm ของ
Bastille Linux สามารถ chroot DNS server จากระบบของ Red Hat 6.0-6.2 ซึ่งรายละเอียดอยู่ใน
เว็ปไซต์ของผู้เขียน http://www.bastille-linux.org/jay มีรายละเอียดเกี่ยวกับ chroot ที่นั่นด้วย



Web HACKING

ไม่มีความคิดเห็น:

แสดงความคิดเห็น