3 điểm bởi GN⁺ 2023-07-14 | 1 bình luận | Chia sẻ qua WhatsApp
  • Tên máy cục bộ mặc định của macOS có thể chứa tên người dùng, nên website có thể thu hẹp các ứng viên tên mà không cần quyền, thông qua chênh lệch thời gian phân giải tên mDNS
  • Kẻ tấn công kết hợp 50 tên phổ biến theo quốc gia và giới tính với các ứng viên tên thiết bị; trong thử nghiệm, đoán đúng tên người dùng macOS trong trung bình 65% trường hợp
  • JavaScript trên trình duyệt không thể mở socket UDP tùy ý, nhưng có thể so sánh độ trễ phản hồi của địa chỉ .local bằng các yêu cầu fetch, iframe, Image, WebRTC
  • Các thông tin như múi giờ, ngôn ngữ, vị trí IP, navigator.language của Safari, độ phân giải màn hình, screen.isExtended được dùng để thu hẹp ứng viên locale và mẫu thiết bị
  • Tính thực dụng thấp và dễ lộ trong tab mạng của công cụ dành cho nhà phát triển, nhưng cùng kỹ thuật dò mDNS này cũng có thể được dùng để phát hiện máy in, TV thông minh, loa thông minh và thiết bị IoT

Cách tên bị rò rỉ từ tên máy cục bộ trên macOS

  • Tên thật của người dùng macOS có thể bị suy đoán từ trình duyệt mà không cần xin quyền; cốt lõi nằm ở giao thức mDNS và định dạng tên máy cục bộ mặc định
  • Chỉ cần dùng danh sách 50 tên phổ biến theo giới tính của một quốc gia cụ thể cũng phát hiện đúng tên người dùng macOS trong trung bình 65% trường hợp
  • Fingerprint không dùng kỹ thuật này trong sản phẩm của mình và cũng không cung cấp dịch vụ theo dõi chéo trang
  • Mục đích của việc công khai thảo luận là giúp các nhà cung cấp trình duyệt sửa nhanh kỹ thuật kiểu này

Cách mDNS và Apple Bonjour hoạt động

  • multicast DNS là giao thức để đăng ký, khám phá và phát quảng bá tên thiết bị trong mạng cục bộ
  • Các thiết bị như máy in gửi gói đăng ký UDP tới IP nội bộ được dành riêng 224.0.0.251, có thể chứa tên máy như HP_LaserJet_Printer.local
  • Miền cấp cao nhất .local cho biết tên máy đó phải được phân giải bằng mDNS
  • Router tự động phát quảng bá các gói như vậy tới các thiết bị khác trong mạng cục bộ để chúng có thể lưu tên máy vào bộ nhớ đệm
  • Thiết bị gửi gói truy vấn tới cùng IP dành riêng đó để tìm thiết bị có tên cụ thể có thể đang tồn tại trên mạng
  • Ví dụ tên máy:
    • johns-mac-mini.local
    • david-ZenBook-UX431DA-UM431DA.local
    • james-iphone.local
    • canon-mf644c.local
    • bedroom-appletv.local
    • dlinkrouter.local
  • Trên thiết bị Apple, mDNS được dùng rộng rãi như một phần của tính năng Apple Bonjour
  • Tên người dùng có thể lộ ra trong tên máy cục bộ mặc định; trên macOS, có thể xem hoặc đổi tên máy cục bộ tại System Settings > Sharing

Cách vòng qua để kiểm tra tên máy mDNS từ trình duyệt

  • mDNS dựa trên gói UDP nên trong môi trường JavaScript của trình duyệt không thể dùng trực tiếp qua socket UDP tùy ý
  • Thay vào đó, kỹ thuật này tận dụng đặc tính trình duyệt cố phân giải tên máy trong URL để thực hiện tấn công thời gian
  • Bản chứng minh khái niệm gửi yêu cầu GET fetch thông thường tới device-1.local có tồn tại và device-2.local không tồn tại
  • Nếu địa chỉ được phân giải, trình duyệt sẽ gửi gói TCP tới cổng 80; cổng này thường có khả năng đang đóng
  • Ở cấp mạng, các lỗi khác nhau sẽ xuất hiện
    • device-1.local tồn tại: ERR_CONNECTION_REFUSED
    • device-2.local không tồn tại: ERR_NAME_NOT_RESOLVED
  • Trong JavaScript, cả hai lỗi đều được ánh xạ thành cùng một lỗi Failed to fetch, nên không thể dựa vào chính loại lỗi
  • Vì mạng cục bộ nhanh, tên máy mDNS hợp lệ sẽ được phân giải nhanh hơn nhiều so với thời gian chờ kết nối mặc định
  • Trong ví dụ, địa chỉ hợp lệ mất 4ms, còn địa chỉ không hợp lệ mất 5 giây
  • Cách tiếp cận này đủ nhất quán cho bản chứng minh khái niệm và hoạt động tương tự trên các trình duyệt chính
  • Trên thực tế, ngoài fetch còn có thể thực hiện tấn công thời gian phân giải DNS bằng các API mạng JavaScript như iframe, Image, WebRTC

Cách brute-force tên người dùng macOS

  • Tên máy cục bộ mặc định của macOS chứa tên người dùng và tên thiết bị, và định dạng thay đổi theo locale ngôn ngữ hệ thống
    • English: <name>s-macbook-pro.local
    • French: macbook-air-de-<name>.local
    • Russian: mac-mini-<name>.local
  • Với cách tiếp cận đơn giản, nếu kết hợp 1.000 tên phổ biến nhất, 10 locale phổ biến nhất và 5 tên thiết bị macOS thông dụng, cần kiểm tra 50.000 tên máy
  • Trong trường hợp này, toàn bộ quá trình kiểm tra có thể mất hơn 1 giờ
  • Chiến lược hiệu quả hơn là giới hạn phạm vi tìm kiếm vào một locale, một thiết bị và 50 tên phổ biến của locale đó
  • Việc thu hẹp phạm vi làm giảm độ chính xác nhưng rút ngắn thời gian tấn công, tạo ra kịch bản thực tế hơn
  • Có thể chọn locale bằng múi giờ, ngôn ngữ và vị trí theo địa chỉ IP của trình duyệt
  • Safari lộ locale hệ thống qua thuộc tính navigator.language, và giá trị này thường trùng với locale của tên máy mục tiêu
  • Một cách vòng khác để tìm quốc gia xuất thân của người dùng là phương pháp phát hiện vùng Apple ID từng được đề cập trước đó
  • Có thể thu hẹp ứng viên thiết bị bằng độ phân giải màn hình
    • Ví dụ, độ phân giải 1728x1117 có khả năng cao là MacBook Pro 16 inch
    • Màn hình mở rộng có thể được phát hiện bằng thuộc tính screen.isExtended
    • Nếu phát hiện màn hình mở rộng, có thể đưa danh sách ứng viên thiết bị về 3–5 thiết bị Apple macOS phổ biến nhất

Giới hạn và các khả năng áp dụng khác

  • Cuộc tấn công này không thực tế vì có điểm yếu nội tại và nhiều giới hạn
  • Trừ khi nhà vận hành website cố ý giải ẩn danh người truy cập, nó rất dễ bị phát hiện trong tab mạng của công cụ dành cho nhà phát triển trình duyệt
  • Nếu kết hợp phương pháp này với phát hiện ứng dụng đã cài đặt, có thể tạo ra website độc hại hiển thị tên thật của người dùng và chức danh công việc suy ra từ danh sách ứng dụng chuyên môn đang dùng mà không cần quyền
  • Thiết bị Apple chạy macOS là ví dụ chính, nhưng kỹ thuật dò mDNS có thể được mở rộng theo nhiều cách
  • Nó cũng có thể được dùng để phát hiện máy in, TV thông minh, loa thông minh và các thiết bị IoT gia dụng khác thông qua quét mạng cục bộ
  • Cũng có thể áp dụng cho iPhone và iPad, với điều kiện đồng bộ hóa Wi‑Fi hoặc tính năng gỡ lỗi từ xa của Safari đang được bật

1 bình luận

 
GN⁺ 2023-07-14
Ý kiến trên Hacker News
  • Tôi đang dùng Little Snitch trên macOS, và đây là một UI khá ổn vì có thể cấu hình để hỏi rõ ràng người dùng cục bộ trước khi cho phép yêu cầu mạng
    https://www.obdev.at/products/littlesnitch/index.html
    Thỉnh thoảng nó gây vướng khi tôi đăng nhập từ xa, thường là lúc phiên SSH đang cố tải thứ gì đó mới, kiểu như NPM lấy các thành phần NodeJS. Tải xuống qua SSH trong terminal dạng văn bản sẽ bị treo, và khi nhận ra thủ phạm là Little Snitch, tôi phải đi xuống tận bàn làm việc ở tầng dưới, lắc chuột để bật màn hình, mở khóa màn hình chờ, rồi bấm “Allow” trong hộp thoại của Little Snitch
    Xem như nó hoạt động đúng như thiết kế. Dù vậy, các công cụ kiểu này thường được cấu hình mặc định để âm thầm cho phép các yêu cầu trong mạng cục bộ, nên tôi không chắc trò đùa trong bài gốc có hiệu quả trong môi trường của tôi hay không

    • Với tôi thì rất khó hình dung việc cấu hình LittleSnitch để chỉ cho phép một số hostname nhất định từ trình duyệt. Tôi có một quy tắc kiểu “cho phép mọi lưu lượng tới 53/80/443”, nếu không thì hầu hết website sẽ làm LittleSnitch hiện ra hàng trăm popup
    • Tôi dùng NetFence trên iPhone đã jailbreak
      Nhìn các ứng dụng âm thầm mở những kết nối socket nào thật sự rất đáng ngạc nhiên, kể cả ứng dụng ngân hàng
      https://havoc.app/package/netfence
    • Tuy nhiên, Little Snitch vẫn làm rò rỉ IP ngay cả khi chặn :(
      https://news.ycombinator.com/item?id=35363343
    • Tôi đã thử OpenSnitch, phần mềm tương tự trên Linux. Nó không phát hiện được gì đáng ngờ, nhưng lại gây phiền khá nhiều trong hầu hết các tác vụ cơ bản
    • Nhân tiện, phân giải DNS xảy ra trước popup cho phép/từ chối kết nối. Ví dụ, www.example.com có thể được phân giải thành 1.1.1.1, nhưng kết nối thực sự tới 1.1.1.1 sẽ không được tạo cho tới khi bạn bấm Confirm
      Nếu thêm Pi-hole vào mạng của mình, bạn sẽ không hối tiếc về thời gian/tiền bạc/công sức đã bỏ ra
  • Có cách nào ngăn website trên Internet rộng lớn gửi yêu cầu mạng tới mạng cục bộ của tôi không? Tôi rất khó hiểu vì sao điều này lại nên được cho phép mặc định
    Ý tôi không phải là muốn hồi sinh lại quyền của Local Intranet Zone trong IE

    • Thông thường thì CORS sẽ ngăn điều đó. Lý do duy nhất “mánh” này hoạt động là vì thời gian từ chối khác nhau giữa yêu cầu tới miền không phân giải được và yêu cầu đã phân giải nhưng bị từ chối
      Nhưng ngay cả khi bạn đang chạy thứ gì đó ở https://192.168.2.1, ứng dụng web chạy từ https://my-own-domain.com vẫn không thể truy cập nó trừ khi dịch vụ ở 192.168.2.1 cho phép my-own-domain.com trong Origin
    • Brave gần đây đã thêm tính năng yêu cầu quyền để truy cập mạng cục bộ
      https://brave.com/privacy-updates/27-localhost-permission/
      Bài HN: https://news.ycombinator.com/item?id=36574775
    • Một ứng dụng thường lạm dụng cách này là ứng dụng desktop Discord, vì nó mở một cổng cục bộ và lắng nghe ở đó
      Khi trình duyệt điều hướng tới trang mời vào kênh Discord, nó sẽ gửi yêu cầu tới localhost qua cổng này và chuyển channel ID cho client. Sau đó ứng dụng có thể hiện trải nghiệm gốc “Join Channel”
      Tôi phát hiện ra điều này khi thấy nó vẫn hoạt động ở chế độ ẩn danh và cả khi trình duyệt đã đăng xuất khỏi Discord. Không ổn chút nào. Thế giới desktop cần cải thiện mạnh việc sandbox cho mọi ứng dụng
    • Có thể chặn bằng bộ lọc tĩnh của uBlock Origin:
      ||local^$all
      Cách này sẽ chặn mọi yêu cầu đi tới .local, kể cả các yêu cầu xuất phát từ chính .local. Nếu bạn muốn cho phép foo.local giao tiếp với chính nó, ví dụ để chạy webserver, thì cần thêm ngoại lệ cho từng domain:
      @@||foo.local^$domain=foo.local,all
      Hoặc nếu bạn tin tưởng toàn bộ .local và muốn cho phép bất kỳ foo.local nào cũng có thể giao tiếp với bất kỳ bar.local nào, bạn có thể thêm một ngoại lệ chung cho toàn bộ .local:
      @@||local^$domain=local,all
    • Để tránh nhầm lẫn, vấn đề ở đây không phải là máy chủ trên Internet gửi yêu cầu vào mạng cục bộ, mà là trình duyệt web cục bộ gửi các yêu cầu đó. Tất nhiên, JavaScript chạy trong trình duyệt có thể được tải từ máy chủ trên Internet
  • Càng về sau tôi càng thấy yên tâm hơn khi dùng Internet chủ yếu trong một box Qubes, với VM Whonix/Tor dùng một lần, và tắt JavaScript
    Chuyện này thật sự kinh tởm. Không bất ngờ, nhưng việc nó có thể xảy ra tự thân đã quá khủng khiếp ở nhiều khía cạnh
    Nếu bạn chưa biết fingerprint.com, họ làm kiểu “lập hồ sơ người dùng chuyên sâu”. Cứ hiểu là họ có thể giữ nguyên cùng một ID người dùng ngay cả khi máy tính, trình duyệt và hệ điều hành thay đổi. Trang chủ có demo, hơi rợn người khi thấy nó đoán trúng tốt đến mức nào

    • Nó vẫn nhận diện chính xác là cùng một thiết bị ngay cả khi dùng các IP VPN khác nhau. Thật sự rợn người
    • Thật kinh tởm. Khá ấn tượng khi nó làm được điều đó trong chế độ ẩn danh mặc định của iPhone dù đã đổi hai địa chỉ IP, trong khi rõ ràng nó phải trông giống hệt những chiếc iPhone khác
      Bộ lọc uBlock Origin để phá demo:
      ||fpjscdn.net
  • Có thể dùng một kiểu tấn công timing tương tự để quét cổng của máy cục bộ và các thiết bị khác trong mạng nội bộ từ trình duyệt
    https://github.com/Flu1dTeam/PortScanner
    Trước đây eBay từng bị phát hiện làm việc này
    https://blog.nem.ec/2020/05/24/ebay-port-scanning/

    • Gì vậy, rùng mình thật, sao đến giờ tôi vẫn chưa từng nghe về chuyện này nhỉ?
  • May là tôi luôn đổi tên thiết bị
    Cách đặt tên mặc định của Apple là một lỗi riêng tư. Trước đây tôi từng có buổi hẹn đầu với một người làm trong cơ quan thực thi pháp luật; cô ấy đi một mình và rõ ràng rất cẩn trọng trong việc tự bảo vệ bản thân, nói rằng đã tìm hiểu lý lịch tôi và cũng báo vị trí của chúng tôi cho vài người trong cộng đồng xung quanh
    Trong khi đó tôi còn chẳng biết họ của cô ấy, và còn đem chuyện đó ra đùa. Sau bữa tối, khi lên xe, màn hình táp-lô hiện thông báo iPhone đã tự động ghép nối, và tôi thấy tên chiếc iPhone đó được đặt theo tên và họ của cô ấy nên thấy khá thú vị. Tôi không chỉ ra điều đó, mà bảo cô ấy thử đoán xem bằng cách nào tôi biết được tên mình cho đến tận lúc kết thúc chuyến đi

    • Xe thuê cực kỳ hay còn lưu lại cả chục hồ sơ điện thoại đã ghép nối từ trước, kèm theo danh bạ, địa điểm bản đồ đã lưu, thậm chí cả lịch sử. Tất nhiên mấy thứ đó không hữu ích lắm, nhưng thông tin cứ thế bị rò rỉ một cách vô thức
      Vấn đề là thứ khó nhất lại là tự nhắc mình xóa hồ sơ của chính mình trước khi trả xe
  • Trong ví dụ trên, địa chỉ hợp lệ mất 4 mili giây, còn địa chỉ không hợp lệ mất 5 giây
    Điều này khá bất ngờ. Tôi đã nghĩ việc tra cứu DNS thất bại sẽ nhanh hơn rất nhiều so với timeout kết nối mặc định sau một lần tra cứu DNS thành công
    Dù vậy, tôi vẫn thấy s-mac-xxxx luôn là một lựa chọn hơi kỳ. Nhất là khi nghĩ đến việc đây là công ty lấy quyền riêng tư làm điểm bán hàng lớn. Có lẽ họ cho rằng sẽ không dùng tên thật, hoặc trong trường hợp này “tính thân thiện với người dùng” được ưu tiên hơn. Xét về riêng tư, hostname được tạo ngẫu nhiên của Windows tốt hơn

    • DNS thông thường hỏi một máy chủ duy nhất tại một IP duy nhất để nhận câu trả lời có/không, nhưng mDNS là multicast, nên không có máy chủ nào có thẩm quyền để nói “không”†. Chỉ khi không có máy chủ nào phản hồi và truy vấn bị timeout thì mới biết là không có bản ghi
      † Nói chính xác thì không hoàn toàn đúng. Nếu có thiết bị nào biết rằng tên đó thuộc về nó, nó có thể trả lời là không
    • Lý do tên thật của người dùng xuất hiện trong hostname có lẽ là vì AirDrop. Có vẻ hệ thống dùng hostname cho các tính năng như Personal Hotspot hay AirDrop, và các kiểu tên khác có thể gây nhầm lẫn trên diện rộng khi chia sẻ tệp
    • Ngoài chuyện timeout kết nối mặc định, ở đây còn có điểm là đây là connection refused, tức nhận RST, chứ không phải timeout kết nối
  • Bài viết được viết tốt và rất thú vị. Tôi đặc biệt thích giọng điệu không cường điệu kiểu như “xét đến các điểm yếu cố hữu và nhiều hạn chế, cuộc tấn công này không thực tế”

    • Ở một vũ trụ khác thì thứ này đã thành “FINGERBleed”, kèm một website hoành tráng và cả logo nữa
    • Tôi không chắc lắm
      Cách này cho phép kiểm tra xem một hostname cụ thể có tồn tại trong mạng hay không
      Nếu chỉ là một hostname duy nhất thì có thể không thành vấn đề, nhưng còn những hostname cố định hoặc hostname mặc định vốn rất phổ biến trong thế giới IoT thì sao
      Website có thể âm thầm đoán xem người dùng có sở hữu một thiết bị cụ thể hay không. Nếu dùng cho tấn công có chủ đích thì còn tệ hơn. Nếu biết trước một vài thiết bị trong mạng, có thể đoán xem người đang truy cập có đang ở trong mạng mục tiêu hay không
  • Giá mà việc tắt JavaScript không đồng nghĩa với việc tắt luôn cả trải nghiệm người dùng cuối

    • Đây là lý do duy nhất khiến tôi không thể vô hiệu hóa JavaScript toàn cục
      Dù vậy, có vẻ từ giờ tôi sẽ buộc phải để mặc định là tắt vì lo ngại về quyền riêng tư
    • Không có cách nào để giới hạn mạnh những gì JavaScript engine có thể làm à?
  • May mắn là tên thiết bị của tôi thường kiểu như “MacBook Pro của xxx (34)”. Không phải bug mà là tính năng

    • Hãy đặt username của laptop là user, hostname là hostname. Càng nhiều người làm vậy càng tốt
  • Thú vị, viết hay, lại còn có cả proof of concept tử tế. Làm rất tốt
    Một biện pháp đối phó vui vui là đổi hostname thiết bị thành kiểu atemptingurl.local, để kẻ tấn công muốn thử truy cập website đó. Trang đó có thể được dựng khéo léo để chạy chính kỹ thuật tương tự ngược lại với kẻ tấn công, rồi hiện ra thông điệp như sau:
    “Xin chào [tên thiết bị của hacker]! Thông tin máy của bạn, địa chỉ IP, vị trí địa lý và các dữ liệu fingerprint khác đã được thu thập và báo cáo tới [chèn tên một cơ quan an ninh mạng đáng sợ].” Dù họ là tay lão luyện chứ không phải script kiddie, ít nhất cũng có thể khiến họ bật cười
    Mọi người cần thêm lý do để cười :-)

    • Muốn làm vậy thì phải chạy một HTTP server bật cho phép toàn bộ CORS. Như thế cũng đồng nghĩa tự mở mình ra trước mọi lỗ hổng của HTTP server đó, nên an ninh của bản thân cũng giảm đi