- 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
0x84000000và yêu cầu đọc USB0xA1: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,__textcủa Mach-O và chạy payload viết bằng Rust, nhưng khi chuỗi tĩnh bị đặt trong__constthì 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 4 và iPhone 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 Exploitscủ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ìnhRestore iPhone
- Khi khởi động bình thường, nó boot
- 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ớ
0x0nơ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ại0x84000000về host
- MMU của A4 ánh xạ phần đầu SRAM vào
- 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
- Payload sao chép dữ liệu mong muốn vào
- 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
- Payload sao chép giá trị con trỏ lệnh (instruction pointer) và con trỏ stack (stack pointer) vào
- Script tự động sau khi chạy exploit sẽ dump vài word đầu tiên tại
0x84000000và 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
- Con trỏ lệnh nằm gầ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-iostừ đầu năm 2020, nhưng có thể chuyển sang toolchain cũ còn hỗ trợ bằngrustup - 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
__texttrong 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,__textra 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ư
starthoặ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ó
_mainhoặcstart - 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
- Binary đó không dùng dyld nên không có
- 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__constkhô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ác chuỗi tĩnh đã biên dịch được đặt trong
- Cách giải quyết là đưa dữ liệu tĩnh vào trong
__TEXT,__textvà 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
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
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
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
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
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 đã đọ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