เจาะชื่อจริงของผู้ใช้ macOS จากเบราว์เซอร์ด้วยการเดาชื่อผ่าน mDNS
(fingerprint.com)- ชื่อโฮสต์ภายในเครื่องเริ่มต้นของ macOS อาจมีชื่อผู้ใช้อยู่ ทำให้เว็บไซต์สามารถค่อย ๆ แคบวงรายชื่อที่เป็นไปได้ผ่าน ความต่างของเวลาการ resolve ชื่อ mDNS ได้โดยไม่ต้องขอสิทธิ์
- ผู้โจมตีสามารถนำชื่อยอดนิยม 50 ชื่อตามประเทศและเพศมาผสมกับตัวเลือกชื่ออุปกรณ์ และจากการทดลองพบว่าสามารถเดาชื่อผู้ใช้ macOS ได้ถูกต้องเฉลี่ย 65% ของกรณี
- JavaScript ในเบราว์เซอร์ไม่สามารถเปิด arbitrary UDP socket ได้ แต่สามารถเปรียบเทียบ ความหน่วงของการตอบสนอง ของที่อยู่
.localได้ผ่านคำขอfetch,iframe,Image,WebRTC - ข้อมูลอย่างเขตเวลา ภาษา ตำแหน่งจาก IP,
navigator.languageของ Safari, ความละเอียดหน้าจอ และscreen.isExtendedถูกใช้เพื่อลดจำนวนตัวเลือกของ locale และรุ่นอุปกรณ์ - แม้การใช้งานจริงจะต่ำและสังเกตได้ง่ายในแท็บ Network ของเครื่องมือนักพัฒนา แต่เทคนิคการสำรวจ mDNS แบบเดียวกันนี้ยังอาจใช้ตรวจหาเครื่องพิมพ์ สมาร์ตทีวี สมาร์ตสปีกเกอร์ และอุปกรณ์ IoT ได้ด้วย
โครงสร้างที่ทำให้ชื่อรั่วจาก local hostname ของ macOS
- ชื่อจริงของผู้ใช้ macOS สามารถถูกคาดเดาได้จากในเบราว์เซอร์โดยไม่ต้องขอสิทธิ์ และหัวใจสำคัญคือโปรโตคอล mDNS กับรูปแบบ local hostname เริ่มต้น
- เพียงใช้รายชื่อชื่อยอดนิยม 50 ชื่อตามเพศของประเทศหนึ่ง ก็สามารถตรวจจับชื่อผู้ใช้ macOS ได้ถูกต้องเฉลี่ย 65% ของกรณี
- Fingerprint ไม่ได้นำเทคนิคนี้ไปใช้ในผลิตภัณฑ์ และไม่ได้ให้บริการติดตามข้ามเว็บไซต์
- จุดประสงค์ของการเปิดเผยครั้งนี้คือช่วยให้ผู้พัฒนาเบราว์เซอร์แก้เทคนิคประเภทนี้ได้เร็วขึ้น
วิธีการทำงานของ mDNS และ Apple Bonjour
- multicast DNS เป็นโปรโตคอลสำหรับลงทะเบียน ค้นหา และกระจายชื่ออุปกรณ์บนเครือข่ายภายใน
- อุปกรณ์อย่างเครื่องพิมพ์จะส่งแพ็กเก็ตลงทะเบียนแบบ UDP ไปยัง IP ภายในที่สงวนไว้
224.0.0.251และอาจมี hostname อย่างHP_LaserJet_Printer.local - โดเมนระดับบนสุด
.localบ่งชี้ว่า hostname นั้นต้องถูก resolve ผ่าน mDNS - เราเตอร์จะกระจายแพ็กเก็ตเหล่านี้ไปยังอุปกรณ์อื่นบนเครือข่ายภายในโดยอัตโนมัติ เพื่อให้อุปกรณ์เหล่านั้นแคช hostname ได้
- อุปกรณ์จะส่งแพ็กเก็ต query ไปยัง IP ที่สงวนไว้เดียวกันเพื่อค้นหาอุปกรณ์ชื่อเฉพาะที่อาจมีอยู่บนเครือข่าย
- ตัวอย่าง hostname มีดังนี้
johns-mac-mini.localdavid-ZenBook-UX431DA-UM431DA.localjames-iphone.localcanon-mf644c.localbedroom-appletv.localdlinkrouter.local
- บนอุปกรณ์ Apple มีการใช้ mDNS อย่างแพร่หลายในฐานะส่วนหนึ่งของ Apple Bonjour
- local hostname เริ่มต้นอาจเผยชื่อผู้ใช้ได้ และบน macOS สามารถดูหรือเปลี่ยน local hostname ได้ที่ System Settings > Sharing
วิธีอ้อมเพื่อตรวจสอบ mDNS hostname จากในเบราว์เซอร์
- mDNS ทำงานบนแพ็กเก็ต UDP จึงไม่สามารถเรียกใช้โดยตรงผ่าน arbitrary UDP socket ในสภาพแวดล้อม JavaScript ของเบราว์เซอร์ได้
- แต่สามารถทำ timing attack ได้ โดยอาศัยคุณสมบัติที่เบราว์เซอร์พยายาม resolve hostname ใน URL
- การพิสูจน์แนวคิดใช้วิธีส่งคำขอ
fetchแบบ GET ปกติไปยังdevice-1.localที่มีอยู่จริง และdevice-2.localที่ไม่มีอยู่ - หากที่อยู่ถูก resolve ได้ เบราว์เซอร์จะส่งแพ็กเก็ต TCP ไปยังพอร์ต 80 ซึ่งโดยทั่วไปมีแนวโน้มว่าจะปิดอยู่
- ในระดับเครือข่ายจะเกิดข้อผิดพลาดต่างกัน
device-1.localที่มีอยู่จริง:ERR_CONNECTION_REFUSEDdevice-2.localที่ไม่มีอยู่จริง:ERR_NAME_NOT_RESOLVED
- ใน JavaScript ข้อผิดพลาดทั้งสองแบบจะถูกแมปเป็น
Failed to fetchเหมือนกัน จึงไม่สามารถพึ่งชนิดของข้อผิดพลาดเองได้ - เนื่องจากเครือข่ายภายในทำงานเร็ว hostname mDNS ที่ถูกต้องจึงถูก resolve ได้เร็วกว่าค่า timeout เริ่มต้นของการเชื่อมต่อมาก
- ในตัวอย่าง ที่อยู่ที่ถูกต้องใช้เวลา 4ms ส่วนที่อยู่ไม่ถูกต้องใช้เวลา 5 วินาที
- วิธีนี้ให้ผลสม่ำเสมอเพียงพอสำหรับการพิสูจน์แนวคิด และทำงานคล้ายกันในเบราว์เซอร์หลัก
- ในทางปฏิบัติ นอกจาก
fetchแล้ว ยังสามารถทำ timing attack กับการ resolve DNS ผ่าน API เครือข่าย JavaScript เช่นiframe,Image,WebRTCได้ด้วย
วิธีเดาชื่อผู้ใช้ macOS แบบ brute force
- local hostname เริ่มต้นของ macOS มีทั้งชื่อผู้ใช้และชื่ออุปกรณ์อยู่ด้วย และรูปแบบจะแตกต่างกันตาม locale ภาษาของระบบ
- English:
<name>s-macbook-pro.local - French:
macbook-air-de-<name>.local - Russian:
mac-mini-<name>.local
- English:
- หากใช้วิธีตรงไปตรงมาโดยผสมชื่อยอดนิยม 1,000 ชื่อ, 10 locale ยอดนิยม และชื่ออุปกรณ์ macOS ทั่วไป 5 แบบ จะต้องตรวจสอบ hostname ทั้งหมด 50,000 รายการ
- ในกรณีนี้ การตรวจสอบทั้งหมดอาจใช้เวลามากกว่า 1 ชั่วโมง
- กลยุทธ์ที่มีประสิทธิภาพกว่าคือจำกัดขอบเขตการค้นหาให้เหลือ locale เดียว อุปกรณ์เดียว และชื่อที่พบบ่อย 50 ชื่อของ locale นั้น
- เมื่อจำกัดขอบเขตลง ความแม่นยำจะลดลง แต่เวลาโจมตีจะสั้นลงจนใกล้เคียงสถานการณ์จริงมากขึ้น
- การเลือก locale อาจอาศัยเขตเวลา ภาษา และตำแหน่งจาก IP ของเบราว์เซอร์
- Safari เผย locale ของระบบผ่านพร็อพเพอร์ตี
navigator.languageและค่านี้มักตรงกับ locale ของ hostname เป้าหมาย - วิธีอ้อมอีกแบบในการหาประเทศต้นทางของผู้ใช้คือวิธี Apple ID region detection ที่เคยกล่าวถึงก่อนหน้านี้
- ตัวเลือกอุปกรณ์สามารถคัดให้แคบลงได้จากความละเอียดหน้าจอ
- ตัวอย่างเช่น ความละเอียด
1728x1117มีโอกาสสูงว่าเป็น MacBook Pro 16 นิ้ว - จอต่อขยายสามารถตรวจจับได้ผ่านพร็อพเพอร์ตี
screen.isExtended - หากตรวจพบจอต่อขยาย ก็สามารถย้อนกลับไปใช้รายชื่ออุปกรณ์ Apple macOS ที่พบบ่อยที่สุด 3–5 รุ่นเป็นตัวเลือกได้
- ตัวอย่างเช่น ความละเอียด
ข้อจำกัดและความเป็นไปได้ในการประยุกต์ใช้อื่น
- การโจมตีนี้ ไม่ค่อยใช้งานได้จริง เนื่องจากมีทั้งจุดอ่อนโดยธรรมชาติและข้อจำกัดหลายอย่าง
- เว้นแต่ว่าเจ้าของเว็บไซต์ตั้งใจจะเปิดเผยตัวตนของผู้เยี่ยมชมโดยเจตนา วิธีนี้มักถูกตรวจพบได้ง่ายในแท็บ Network ของเครื่องมือนักพัฒนาเบราว์เซอร์
- หากนำวิธีนี้ไปรวมกับ installed applications detection ก็อาจสร้างเว็บไซต์ที่เป็นอันตรายซึ่งแสดงทั้งชื่อจริงของผู้ใช้และตำแหน่งงานโดยอาศัยรายชื่อแอปเฉพาะทางที่ติดตั้งอยู่ได้โดยไม่ต้องขอสิทธิ์
- แม้อุปกรณ์ Apple ที่รัน macOS จะเป็นตัวอย่างหลัก แต่เทคนิคการสำรวจ mDNS สามารถขยายไปใช้ได้อีกหลายแบบ
- ยังสามารถใช้ตรวจหาเครื่องพิมพ์ สมาร์ตทีวี สมาร์ตสปีกเกอร์ และอุปกรณ์ IoT ภายในบ้านอื่น ๆ ผ่านการสแกนเครือข่ายภายในได้ด้วย
- ใช้กับ iPhone และ iPad ได้เช่นกัน โดยมีเงื่อนไขว่าต้องเปิด Wi-Fi syncing หรือฟีเจอร์ Safari remote debug อยู่
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
บน macOS ฉันใช้ Little Snitch อยู่ ซึ่งมี UI ที่ดีพอสมควรและสามารถตั้งให้ถามผู้ใช้ในเครื่องอย่างชัดเจนก่อนอนุญาตคำขอเครือข่ายได้
https://www.obdev.at/products/littlesnitch/index.html
บางครั้งมันจะติดขัดตอนล็อกอินจากระยะไกล โดยปกติคือเวลาเซสชัน SSH พยายามดาวน์โหลดอะไรใหม่ๆ เช่น NPM ไปดึงองค์ประกอบของ NodeJS มาใช้ ดาวน์โหลดผ่าน SSH ในเทอร์มินัลแบบข้อความก็จะค้าง แล้วพอรู้ว่าต้นเหตุคือ Little Snitch ก็ต้องเดินลงไปที่โต๊ะข้างล่าง ขยับเมาส์ปลุกจอ ปลด screensaver แล้วกด “Allow” ในกล่องโต้ตอบของ Little Snitch
ก็ถือว่ามันทำงานตามที่ตั้งใจไว้ เพียงแต่เครื่องมือแบบนี้มักตั้งค่าให้อนุญาตคำขอในเครือข่ายภายในแบบเงียบๆ เป็นค่าเริ่มต้น เลยไม่แน่ใจว่ากลเม็ดในโพสต์ต้นฉบับจะใช้ได้กับสภาพแวดล้อมของฉันไหม
พอเห็นว่าแอปต่างๆ แอบเปิดการเชื่อมต่อ socket อะไรบ้างก็น่าตกใจ รวมถึงแอปธนาคารด้วย
https://havoc.app/package/netfence
https://news.ycombinator.com/item?id=35363343
Confirmถ้าเพิ่ม Pi-hole เข้าไปในเครือข่าย คุณจะไม่เสียใจทั้งเวลา เงิน หรือการลงทุนที่ลงไป
มีวิธีป้องกันไม่ให้เว็บไซต์บนอินเทอร์เน็ตวงกว้างส่งคำขอเครือข่ายเข้ามายังเครือข่ายภายในของฉันไหม? นึกไม่ออกเลยว่าทำไมสิ่งนี้ถึงควรถูกอนุญาตโดยปริยาย
ไม่ได้หมายความว่าอยากชุบชีวิตสิทธิ์แบบ Local Intranet Zone ของ IE กลับมานะ
แต่ถึงคุณจะรันอะไรบางอย่างอยู่ที่ https://192.168.2.1 เว็บแอปที่รันจาก https://my-own-domain.com ก็จะเข้าถึงไม่ได้ เว้นแต่บริการบน 192.168.2.1 จะอนุญาต my-own-domain.com เป็น
Originhttps://brave.com/privacy-updates/27-localhost-permission/
โพสต์ HN: https://news.ycombinator.com/item?id=36574775
เมื่อเบราว์เซอร์ไปยังหน้าคำเชิญเข้าร่วมช่องของ Discord มันจะส่งคำขอผ่านพอร์ตนี้ไปยัง localhost และส่งต่อ channel ID ให้ไคลเอนต์ จากนั้นแอปก็จะแสดงประสบการณ์แบบเนทีฟ “Join Channel” ได้
ฉันรู้เรื่องนี้เพราะเห็นว่ามันยังทำงานต่อแม้อยู่ในโหมดไม่ระบุตัวตน และเบราว์เซอร์ก็ล็อกเอาต์จาก Discord ไปแล้วด้วย ไม่ดีเลย โลกเดสก์ท็อปจำเป็นต้องยกระดับ sandboxing ของทุกแอปพลิเคชันอย่างมาก
||local^$allแบบนี้จะบล็อกทุกคำขอที่ไปยัง .local รวมถึงคำขอที่มาจาก .local เองด้วย ถ้าคุณต้องการให้ foo.local คุยกับตัวเองได้ เช่น เพื่อรันเว็บเซิร์ฟเวอร์ ก็ต้องเพิ่มข้อยกเว้นแยกตามโดเมน:
@@||foo.local^$domain=foo.local,allหรือถ้าคุณเชื่อถือ .local ทั้งหมดและอยากอนุญาตให้ foo.local ใดๆ คุยกับ bar.local ใดๆ ได้ ก็เพิ่มข้อยกเว้นครอบทั้ง .local ได้หนึ่งรายการ:
@@||local^$domain=local,allยิ่งเวลาผ่านไป ฉันยิ่งรู้สึกสบายใจกว่าถ้าใช้อินเทอร์เน็ตผ่าน Qubes box เป็นหลัก โดยใช้ Whonix/Tor VM แบบใช้แล้วทิ้ง และปิด JavaScript ไว้
นี่มันน่าขยะแขยงจริงๆ ไม่ได้แปลกใจ แต่แค่ความจริงที่ว่ามันเป็นไปได้ก็น่ากลัวในหลายแง่มุมแล้ว
ถ้าไม่รู้จัก fingerprint.com บริษัทนี้ทำ “การทำโปรไฟล์ผู้ใช้เชิงลึก” ประมาณว่ารักษา user ID เดิมไว้ได้ต่อเนื่องแม้จะเปลี่ยนคอมพิวเตอร์ เบราว์เซอร์ หรือระบบปฏิบัติการก็ตาม มีเดโมอยู่บนหน้าแรก แล้วมันเดาได้แม่นขนาดไหนก็ค่อนข้างชวนขนลุก
ฟิลเตอร์ uBlock Origin ที่ทำให้เดโมพัง:
||fpjscdn.netด้วยการโจมตีแบบอาศัยจังหวะเวลาลักษณะคล้ายกัน ก็สามารถสแกนพอร์ตของเครื่อง local และอุปกรณ์อื่นในเครือข่าย local จากในเบราว์เซอร์ได้
https://github.com/Flu1dTeam/PortScanner
เมื่อก่อน eBay ก็เคยทำแบบนี้แล้วโดนจับได้
https://blog.nem.ec/2020/05/24/ebay-port-scanning/
โชคดีที่ฉันเปลี่ยนชื่ออุปกรณ์ไว้ตลอด
การตั้งชื่อเริ่มต้นของ Apple ถือเป็นความพลาดด้านความเป็นส่วนตัว. ครั้งหนึ่งฉันเคยไปเดตครั้งแรกกับคนที่ทำงานในหน่วยงานบังคับใช้กฎหมาย เธอมาคนเดียว และเป็นผู้หญิงที่ชัดเจนว่าใส่ใจการปกป้องตัวเองมาก เธอบอกว่าตรวจสอบประวัติฉันแล้ว และบอกตำแหน่งของพวกเราให้คนในชุมชนรอบตัวเธอสองสามคนรู้ไว้ด้วย
แต่ฝั่งฉันกลับไม่รู้แม้แต่นามสกุลของเธอ และยังเอาเรื่องนั้นมาล้อเล่นอีก หลังมื้อเย็นพอเราขึ้นรถ หน้าจอบนแดชบอร์ดก็ขึ้นว่า iPhone ถูกจับคู่อัตโนมัติแล้ว และชื่อ iPhone เครื่องนั้นตั้งเป็นชื่อกับนามสกุลของเธอ ฉันเลยรู้สึกสนใจขึ้นมา ฉันไม่ได้ชี้เรื่องนั้นตรง ๆ แต่ปล่อยให้เธอลองเดาว่าฉันรู้ชื่อเธอได้ยังไงจนกระทั่งจบการขับรถ
ปัญหาคือสิ่งที่ยากที่สุดคือการเตือนตัวเองให้ลบโปรไฟล์ของตัวเองก่อนคืนรถ
ในตัวอย่างข้างบน ที่อยู่ที่ใช้ได้ใช้เวลา4 มิลลิวินาที ส่วนที่อยู่ที่ใช้ไม่ได้ใช้เวลา 5 วินาที
อันนี้น่าแปลกใจ ฉันคาดว่าการค้นหา DNS ที่ล้มเหลวน่าจะเร็วกว่า timeout การเชื่อมต่อปกติที่เกิดหลังการค้นหา DNS สำเร็จเสียอีก
ถึงอย่างนั้น ฉันก็ยังคิดว่า s-mac-xxxx เป็นตัวเลือกที่แปลกอยู่เสมอ โดยเฉพาะเมื่อคิดว่านี่คือบริษัทที่ขายจุดเด่นเรื่องความเป็นส่วนตัวอย่างหนัก น่าจะคาดหวังได้ว่าจะไม่ใช้ชื่อจริง หรือไม่ก็กรณีนี้ให้ “ความเป็นมิตรต่อผู้ใช้” มาก่อน ในมุมความเป็นส่วนตัว ชื่อโฮสต์แบบสุ่มที่ Windows สร้างให้นั้นดีกว่า
† ถ้าจะพูดให้เป๊ะก็ไม่ถูกทั้งหมด ถ้ามีอุปกรณ์ที่รู้ว่าชื่อนั้นเป็นของตัวเอง มันก็สามารถตอบว่าไม่ใช่ได้
บทความเขียนดีและน่าสนใจ โดยเฉพาะน้ำเสียงที่ไม่โอ้อวดเกินจริงอย่างประโยคว่า “เมื่อพิจารณาจากจุดอ่อนโดยเนื้อแท้และข้อจำกัดมากมาย การโจมตีนี้จึงไม่ใช่สิ่งที่ใช้งานได้จริง” ซึ่งฉันชอบมาก
วิธีนี้ทำให้เราทดสอบได้ว่ามีชื่อโฮสต์บางชื่ออยู่ในเครือข่ายหรือไม่
ถ้าเป็นชื่อโฮสต์ที่ไม่ซ้ำเพียงชื่อเดียวอาจไม่ใช่ปัญหาใหญ่ แต่ถ้าเป็นชื่อคงที่หรือชื่อเริ่มต้นที่พบได้บ่อยในโลก IoT ล่ะ
เว็บไซต์จะสามารถเดาแบบลับ ๆ ได้ว่าผู้ใช้เป็นเจ้าของอุปกรณ์บางชนิดหรือไม่ ถ้านำไปใช้กับการโจมตีแบบเจาะจงเป้าหมายก็ยิ่งแย่กว่าเดิม ถ้ารู้อุปกรณ์บางส่วนในเครือข่ายอยู่แล้ว ก็อาจเดาได้ว่าผู้ใช้ที่เชื่อมต่ออยู่ในเครือข่ายเป้าหมายนั้นหรือไม่
ถ้าการปิด JavaScript ไม่ได้ปิดประสบการณ์ของผู้ใช้ปลายทางไปด้วยก็คงดี
แต่ดูเหมือนจากนี้ไปฉันคงต้องปิดไว้เป็นค่าเริ่มต้นเพราะกังวลเรื่องความเป็นส่วนตัว
โชคดีที่ชื่ออุปกรณ์ของฉันมักจะเป็นประมาณ “xxxs's MacBook Pro (34)” อยู่แล้ว. ไม่ใช่บั๊ก แต่เป็นฟีเจอร์
userและตั้งชื่อโฮสต์เป็นhostnameกันเถอะ ยิ่งมีคนทำแบบนี้มากเท่าไรก็ยิ่งดีน่าสนใจ เขียนก็ดี และยังมีproof of conceptที่ใช้ได้ด้วย ทำออกมาได้ดี
มาตรการตอบโต้ที่น่าสนุกอย่างหนึ่งคือเปลี่ยนชื่อโฮสต์ของอุปกรณ์เป็นอะไรแบบ atemptingurl.local เพื่อหลอกให้ผู้โจมตีอยากเข้าไปดูเว็บไซต์นั้น แล้วทำหน้าเว็บนั้นให้ประณีตพอที่จะใช้เทคนิคเดียวกันเล่นงานผู้โจมตีคืน พร้อมแสดงข้อความประมาณนี้:
“สวัสดี [ชื่ออุปกรณ์ของแฮ็กเกอร์]! ข้อมูลเครื่องของคุณ, IP address, ตำแหน่งทางภูมิศาสตร์ และข้อมูล fingerprint อื่น ๆ ได้ถูกรวบรวมและรายงานไปยัง [ใส่ชื่อหน่วยงานไซเบอร์สุดน่ากลัว] แล้ว” อย่างน้อยต่อให้เป็นตัวเก๋าที่ชำนาญไม่ใช่ script kiddie ก็น่าจะเรียกเสียงหัวเราะได้บ้าง
ผู้คนควรมีเหตุผลให้หัวเราะมากกว่านี้ :-)