1 điểm bởi GN⁺ 2023-10-03 | 1 bình luận | Chia sẻ qua WhatsApp
  • gala là một dự án tự triển khai trực tiếp bản jailbreak iOS 4 cho iPhone 4, và phần 1 tập trung vào quá trình giành được thực thi mã ban đầu bằng cách khai thác lỗ hổng SecureROM trên thiết bị cũ
  • Quá trình khởi động iOS tiếp diễn theo một chuỗi tin cậy trong đó SecureROM xác minh LLB hoặc iBSS, rồi mỗi giai đoạn tiếp theo lại xác minh giai đoạn kế tiếp; SecureROM không thể bị thay thế bằng bản cập nhật sau khi thiết bị đã xuất xưởng
  • limera1n nhắm vào SecureROM của SoC A4 bằng cách tấn công thiết bị đang chờ nhận iBSS trong chế độ DFU, và vụ sập được phát hiện qua fuzzing thông điệp điều khiển USB dường như dẫn tới tràn heap và thực thi shellcode
  • Tham khảo SecureROM dumper của pod2g, bài viết tái hiện luồng sử dụng vùng giao tiếp 0x84000000 và yêu cầu đọc USB 0xA1:2 để đưa bản dump SecureROM cùng các giá trị debug về máy chủ
  • Một pipeline đã được dựng để trích shellcode từ __TEXT,__text của Mach-O và chạy payload viết bằng Rust, nhưng khi chuỗi tĩnh bị đặt trong __const thì cần dùng địa chỉ hóa tương đối theo con trỏ lệnh và bố trí bằng assembly

Điểm khởi đầu của dự án jailbreak iPhone 4

  • gala là một dự án xây dựng jailbreak iOS 4 cho iPhone 4, và tài liệu này tương ứng với phần 1 của nó, “Gaining Entry”
  • Kinh nghiệm phát triển tweak iOS trước đây đã dẫn tới việc phân phối qua Cydia, thay đổi tính năng của SpringBoard, sử dụng trực tiếp runtime Objective-C, và reverse engineering các binary mã nguồn đóng
  • Mục tiêu của việc tự viết jailbreak là để hiểu cách quy trình jailbreak thực sự hoạt động
  • Công việc này phụ thuộc rất nhiều vào kiến thức mà p0sixninja và axi0mX đã chia sẻ dưới dạng mã nguồn mở

Chọn iPhone đời cũ và lỗ hổng Boot ROM

  • Bước đầu tiên là mua iPhone 4iPhone 3GS trên eBay
  • Do Xcode mới không cho phép nhắm mục tiêu các phiên bản iOS cũ, con đường build và cài ứng dụng theo kiểu thập niên 2010 nhanh chóng bị chặn
    • Tác giả cũng từng cân nhắc cài Mac OS X và Xcode cũ trong máy ảo nhưng đã dừng lại
    • Cũng không rõ Apple còn ký các binary nhắm tới iOS đời cũ hay không
  • Giải pháp thay thế là nhắm trực tiếp vào lỗ hổng Boot ROM
    • Có thể thử chỉ với mã tương tác với thiết bị qua USB từ máy host, không cần toolchain cũ hay máy ảo
    • Trong mục Vulnerabilities and Exploits của iPhone Wiki, tác giả đã xem mã khai thác limera1n

SecureROM và chuỗi tin cậy khi khởi động iOS

  • Theo thuật ngữ của Apple, SecureROM là giai đoạn đầu tiên của quy trình khởi động iOS và là thành phần khởi chạy bước boot tiếp theo
  • SecureROM có thể nạp hai thành phần
    • Khi khởi động bình thường, nó boot Low Level Bootloader, tức LLB, từ phân vùng đĩa trên NOR
    • Khi kết nối với máy tính qua USB ở chế độ DFU, nó có thể nhận bootloader iBoot Single Stage, tức iBSS, trong quá trình Restore iPhone
  • SecureROM xác minh rằng LLB hoặc iBSS là image đáng tin cậy có chữ ký của Apple
  • Sau đó, LLB và iBSS cũng xác minh giai đoạn tiếp theo mà chúng nạp, tạo thành chuỗi tin cậy
  • Vì SecureROM là giai đoạn đầu tiên nên nó không bị giai đoạn trước xác minh, và được khắc trong bộ nhớ chỉ đọc ngay từ khi sản xuất
    • Các giai đoạn khác có thể được thay thế bằng bản cập nhật iOS
    • Lỗ hổng trong một phiên bản SecureROM cụ thể sẽ tồn tại vĩnh viễn trên các thiết bị được sản xuất với phiên bản đó

Giành thực thi mã trên thiết bị DFU bằng limera1n

  • limera1n là một khai thác SecureROM do geohot công bố năm 2010 và được đóng gói thành công cụ jailbreak cùng tên
  • Có thể dùng limera1n khi thiết bị ở chế độ DFU đang chờ nhận iBSS từ máy host qua USB
  • Vì SecureROM trong SoC A4 có lỗ hổng, iPhone 4 trở thành mục tiêu phù hợp
  • Cơ chế hoạt động chính xác của limera1n vẫn chưa được công khai đầy đủ
    • geohot từng nói rằng chính anh cũng không biết vì sao nó hoạt động
    • p0sixninja đã đưa ra giả thuyết
    • Vụ sập được tìm thấy qua fuzzing thông điệp điều khiển USB, và có vẻ là một race condition dẫn tới tràn heap, từ đó cho phép chèn và thực thi shellcode

Đọc bộ nhớ từ thiết bị ở chế độ DFU

  • SecureROM dumper của pod2g là một hiện thực tham chiếu cho thấy cách triển khai limera1n, ví dụ payload, và cơ chế đọc bộ nhớ qua USB
  • SecureROM dumper sao chép vùng nhớ 0x0 nơi SecureROM được ánh xạ vào vùng nhận USB, rồi máy host đọc dữ liệu bằng thông điệp điều khiển USB
  • Luồng hoạt động được hiểu như sau
    • MMU của A4 ánh xạ phần đầu SRAM vào 0x84000000
    • Máy host có thể gửi image iBSS theo từng mảnh bằng gói điều khiển USB với request type 0x21, request ID 1
    • Dữ liệu này được chép vào SRAM bắt đầu từ 0x84000000, và SecureROM duy trì một bộ đếm nội bộ để theo dõi vị trí sao chép của gói tiếp theo
    • Thiết bị cũng phản hồi gói điều khiển với request type 0xA1, request ID 2, và gửi nội dung bộ nhớ tại 0x84000000 về host
  • Chức năng đọc này đặc biệt hữu ích khi đã có thể thực thi mã trên thiết bị
    • Payload sao chép dữ liệu mong muốn vào 0x84000000
    • Máy host có thể lấy dữ liệu đó bằng yêu cầu đọc A1:2
  • Slide trong bài trình bày Hack In the Box Malaysia năm 2013 của p0sixninja nói rằng SecureROM dumper của pod2g dựa trên SHAtter, nhưng tiện ích thực tế lại dùng hiện thực limera1n
  • Tác giả đã dump SecureROM thành công bằng hiện thực limera1n của riêng mình

Debug payload bằng 0x84000000

  • Sau khi giành được thực thi mã, cần xác định shellcode đang chạy ở đâu, stack nằm ở đâu, và shellcode ghi đè vùng nhớ nào
  • Luồng đọc của SecureROM dumper được tái sử dụng làm đầu ra debug
    • Payload sao chép giá trị con trỏ lệnh (instruction pointer) và con trỏ stack (stack pointer) vào 0x84000000
    • Mã phía host đọc lại các giá trị này theo cùng cách
    • Theo cách này, dump bộ nhớ đóng vai trò như một print() đơn giản
  • Script tự động sau khi chạy exploit sẽ dump vài word đầu tiên tại 0x84000000 và hiển thị chúng trong cửa sổ đầu ra
  • Các giá trị xác nhận được cho thấy vị trí thực thi shellcode và vị trí stack
    • Con trỏ lệnh nằm gần 0x8402b048
    • Con trỏ stack là 0x8403bfa0
    • Con trỏ stack nằm trong vùng stack thông thường do SecureROM thiết lập, còn con trỏ lệnh nằm trong vùng image đã nhận

Payload Rust và trích shellcode từ Mach-O

  • Thay vì viết payload hoàn toàn bằng assembly, tác giả dựng một hệ thống build để biên dịch payload Rust rồi chuyển nó thành shellcode
  • Rust đã ngừng hỗ trợ mục tiêu armv7-apple-ios từ đầu năm 2020, nhưng có thể chuyển sang toolchain cũ còn hỗ trợ bằng rustup
  • Khi biên dịch bằng ngôn ngữ bậc cao, binary tạo ra không chỉ chứa mã máy thô mà còn có metadata, thông tin cấu hình không gian địa chỉ ảo, bảng ký hiệu và thông tin linker
  • Với exploit, chỉ cần các byte được nạp vào bộ nhớ và nhảy tới, nên không cần toàn bộ Mach-O mà chỉ cần section __text trong segment __TEXT
  • strongarm là thư viện phân tích Mach-O, được dùng trong hệ thống build để parse Mach-O và trích section __TEXT,__text ra file
  • Các byte trong file đã trích trở thành shellcode mà limera1n sẽ chạy trên thiết bị

Linker và vấn đề dữ liệu tĩnh

  • Binary thông thường dùng hạ tầng của hệ điều hành và quy ước symbol điểm vào như start hoặc _main, nhưng kiểu shellcode này không cần các symbol đó
  • Theo mặc định, linker sẽ báo lỗi nếu không có _main hoặc start
  • Tác giả đã có thể tạo file Mach-O không dùng dyld bằng cách kết hợp các tùy chọn -U _main, -U start, -static
  • Ban đầu strongarm ném ra ngoại lệ vì không xử lý được binary không có lệnh nạp LC_DYLD_INFO
    • Binary đó không dùng dyld nên không có LC_DYLD_INFO
    • Tác giả đã thêm bản vá vào strongarm để xử lý trường hợp này
  • Khi thêm chuỗi tĩnh vào mã Rust, payload bị hỏng
    • Các chuỗi tĩnh đã biên dịch được đặt trong __const
    • Quá trình trích shellcode chỉ giữ lại __TEXT,__text, nên dữ liệu __const không được nạp vào bộ nhớ
    • Kết quả là mã cố đọc chuỗi từ một địa chỉ không được ánh xạ và bị crash
  • Cách giải quyết là đưa dữ liệu tĩnh vào trong __TEXT,__text và dùng địa chỉ hóa tương đối theo con trỏ lệnh để không phải giả định một địa chỉ nạp cố định
  • Cách làm hiện tại là định nghĩa chuỗi trong assembly rồi truyền địa chỉ của nó vào điểm vào payload Rust

Pipeline thực thi hoàn chỉnh ở phần 1

  • Pipeline cuối cùng hoạt động theo trình tự sau
    • Chỉnh sửa payload Rust
    • Nhấn nút để biên dịch payload
    • Trích shellcode từ binary
    • Runner thực thi payload bằng limera1n trên iPhone ở chế độ DFU đã kết nối
    • Runner tự động đọc dữ liệu từ 0x84000000, vùng được dùng làm không gian giao tiếp, và hiển thị dưới dạng hexdump
  • Tại thời điểm này, đã có thể thực thi mã tùy ý trên thiết bị
  • Về mặt lý thuyết, thực thi mã tùy ý cho phép làm được rất nhiều việc, nhưng để khiến thiết bị thực sự làm điều gì đó thú vị lại là một bước riêng khác
  • Bước tiếp theo là Phần 2: Bỏ qua Bootchain

1 bình luận

 
GN⁺ 2023-10-03
Các ý kiến trên Hacker News
  • Sau nhiều năm chỉ đọc thầm, cuối cùng tôi đã tạo tài khoản Hacker News chỉ để để lại lời này. Cảm ơn vì đã hệ thống hóa một việc từng là chiếc hộp đen bí ẩn đối với rất nhiều người trong suốt thời gian dài
    Tôi vẫn nhớ rõ cảm giác cực kỳ hồi hộp khi jailbreak chiếc iPod 4G chạy iOS 4, nhìn các dòng thông báo terminal chạy liên tục. Sau đó, vào giờ ăn trưa ở trường, tôi còn làm giúp thiết bị của bạn bè, vừa làm vừa lo lỡ tay làm hỏng điện thoại và biến nó thành một cục gạch trị giá hàng trăm đô la
    Nhìn lại sau nhiều năm, chính “phép màu” xuyên qua bức tường của Apple để chạy mã của người dùng đã khiến tôi say mê lập trình, và tôi vô cùng biết ơn tất cả những người liên quan

    • Khi làm trong ngành công nghệ, có nhiều ngày dù đặt mục tiêu nhưng lại chán nản vì những việc mình không hiểu hoặc không làm được. Dù vậy, thỉnh thoảng đọc những bài như thế này lại khiến tôi muốn không từ bỏ mã nguồn mở hay cộng đồng công nghệ nói chung
    • Tôi thích iPhone, nhưng vẫn nhớ thời từng cài CyanogenMod lên nhiều thiết bị Android. Cảm giác thật sự rất tuyệt
    • Tôi cũng có trải nghiệm tương tự. Cuối cùng tôi bắt đầu tự làm tweak jailbreak, và đó là cơ duyên đưa tôi nghiêm túc bước vào lập trình
  • Thật sự cảm ơn vì bài viết. Để giải thích những khái niệm phức tạp như thế này một cách dễ hiểu cần phải có hiểu biết rất sâu. Khi đọc, tôi nhớ lại những kỷ niệm đẹp về những đêm thức khuya hack các dự án jailbreak

  • Tôi đã đọc rất thích từ đầu đến cuối. Đặc biệt là vì bản thân tôi vẫn còn kém về reverse engineering mã native
    Cách này có vẻ là jailbreak tethered, vì nó tận dụng cơ chế khôi phục hệ thống để phá chuỗi tin cậy và boot một iOS đã được chỉnh sửa. Vậy tôi tò mò jailbreak untethered hoạt động như thế nào. Có đúng là nó không đụng tới chuỗi secure boot, để nguyên như vậy, rồi exploit một tiến trình có đặc quyền hoặc không có đặc quyền trong hệ thống đang chạy, sau đó leo thang đặc quyền riêng không? Tôi cũng tò mò persistence được đảm bảo ra sao, và làm thế nào để patch kiểm tra chữ ký của kernel mà không động đến kiểm tra chữ ký của bootloader và chính kernel

    • Thường thì người ta cấu hình để trong hoặc ngay sau quá trình boot, kernel sẽ bị exploit lại từ userland. Một vài kỹ thuật tôi nhớ gồm thêm launch daemon mới, ký app bằng chứng chỉ nhà phát triển, đặt binary lợi dụng hành vi đặc biệt của dynamic linker để vượt qua kiểm tra chữ ký, v.v.
  • Bài viết thật sự xuất sắc. Rất vui khi thấy bạn vẫn còn hoạt động trong cộng đồng

  • Cảm ơn vì đã tạo ra cái này. Tôi có một chiếc iPhone 4s chứa rất nhiều bức ảnh đặc biệt, nhưng chẳng may quên PIN nên đã phải để đó chờ suốt mấy năm
    Nếu không vì ảnh thì tôi đã reset rồi; tôi tự hỏi liệu có thể dùng cách này để đặt lại PIN và chép ảnh ra không

    • Có lẽ khó đấy. Theo [0], mật mã được dùng để bảo vệ khóa mã hóa hệ thống tệp, nên nếu không có mật mã thì không thể giải mã tệp. Tôi không biết ảnh có được lưu dưới dạng mã hóa hay không, nhưng có lẽ nên giả định là có
      Sửa: Có thể tôi sai. [0] cũng nói rằng trong một thời gian chỉ kho lưu trữ Mail được mã hóa, và mặc định đã thay đổi từ iOS 7. Vì vậy nếu iPhone đang chạy iOS <= 6, có lẽ có thể dùng phương pháp này để truy cập thiết bị và sao chép ảnh. Công cụ ở [1] có thể hữu ích
      [1] https://code.google.com/archive/p/iphone-dataprotection/
      [0] https://darthnull.org/ios-encryption/
  • Bài viết thật sự rất hay. Tuy nhiên, cảnh giao diện iOS cũ phô bày trọn vẹn thời hoàng kim của thiết kế skeuomorphic khiến tôi thấy khó chịu. Nó làm tôi lại nhận ra mình ghét John Ive đến mức nào

    • Ý bạn là thời mà nút bấm trông giống như nút có thể bấm được ấy à? Khác với bây giờ, khi thiết kế phẳng quá tệ đến mức cuối cùng phải thêm tính năng trợ năng để đi đường vòng qua các khiếm khuyết
      Có lẽ Jony đáng ra nên tiếp tục thiết kế mấy phần kê cổ tay bằng nhôm sắc như dao cạo, thay vì phụ trách phần mềm
    • Tôi nghĩ iPhone đạt đỉnh ở iPhone 4 và iOS 4. Sau đó vẫn có những cải tiến dần dần, nhưng đó là lần cuối tôi cảm thấy một chiếc iPhone mới thực sự là một nâng cấp lớn. Nếu bỏ qua antennagate, thiết kế phần cứng và phần mềm khi đó đơn giản là ăn khớp với nhau
  • Tôi đã đọc vài phần đầu rất thích thú. Theo dõi từ góc nhìn như thế này thật hay. Tôi cũng đọc rất nhiều mã nguồn để tìm hiểu người khác triển khai những thứ như exploit ra sao, nên thật vui khi biết cũng có người khác làm như vậy

  • Tôi vẫn chưa đọc, nhưng rất mong chờ. Những tweak được liệt kê ở phần đầu tôi đều đã dùng, và tôi muốn nói lời cảm ơn vì đã tạo ra chúng. Jailbreak iOS thời kỳ đầu thật sự rất thú vị

  • Rất hay. Tôi đã định chạy thử, nhưng tiếc là thiết bị cũ của tôi ngay từ đầu đã không boot được
    Hồi đó tôi cũng làm tweak, và jailbreak từng có cảm giác như ma thuật hắc ám. Đọc xong bài này rồi mà ở một mức độ nào đó tôi vẫn còn cảm thấy như vậy

  • Thật sự cảm ơn vì đã hệ thống hóa những điều này. Tôi rất quan tâm đến việc học các nội dung như vậy. Đặc biệt là muốn học cách “giải phóng” các camera an ninh Wi-Fi giá rẻ như dafang-hacks bằng firmware tùy chỉnh của mình, hoặc cách tạo exploit mới để root máy tính bảng Kindle Fire
    Nhưng các bài viết đi sâu vào quá trình đó lại khó tìm đến mức đáng ngạc nhiên