1 poin oleh GN⁺ 2025-05-25 | 2 komentar | Bagikan ke WhatsApp
  • tachy0n adalah exploit eskalasi hak akses kernel yang berjalan di iOS 13.0–13.5; pada 23 Mei 2020, exploit ini disertakan sebagai 0day dalam unc0ver v5.0.0 dan saat itu menargetkan langsung iOS terbaru
  • Intinya adalah kondisi race Lightspeed pada lio_listio, yang memungkinkan objek kalloc.16 dibebaskan dua kali sehingga dua objek berbeda dapat menunjuk ke memori yang sama
  • Bug dari keluarga yang sama sebelumnya juga dipakai dalam jailbreak/untether Spice untuk iOS 11, tetapi lingkungan sandbox aplikasi dan racoon memiliki batasan yang sangat berbeda dalam hal hak akses, sandbox, dan teknik spray
  • Exploit untuk unc0ver secara berulang mengamankan overlap OSData, lalu menggunakan IOBufferMemoryDescriptor dan IOAcceleratorFamily2 untuk menyusun fake task dan fake mach port
  • Sejak iOS 14, Apple beralih ke pendekatan yang memblokir strategi exploit itu sendiri melalui pemisahan allocator, sequestering, PAC, dan hardening per objek; pengetahuan publik tentang exploit kernel iOS kini jauh tertinggal dibanding era iOS 13

Mengapa publikasi tachy0n tidak biasa

  • tachy0n adalah exploit lama yang memengaruhi iOS 13.0 hingga 13.5, dan dipublikasikan pada 23 Mei 2020 dengan disertakan dalam unc0ver v5.0.0
  • Menurut standar saat itu, ini adalah eskalasi hak akses lokal kernel (kernel LPE) yang biasa, tetapi jarang terjadi karena dipublikasikan sebagai 0day jailbreak yang memengaruhi versi iOS terbaru
  • Apple merilis patch khusus untuk bug tersebut sekitar satu minggu setelah exploit dipublikasikan
  • Bug ini adalah 0day di iOS 13.5, tetapi sebelumnya sudah pernah dimanfaatkan dalam bentuk 1day
  • Pwn20wnd mencari 0day yang dapat dijangkau dari sandbox aplikasi, dan titik awalnya adalah pengujian regresi terhadap 1day yang sudah dikenal
    • SockPuppet di iOS 12 dipatch pada iOS 12.3, tetapi muncul kembali di iOS 12.4
    • Kasus ini memperlihatkan tidak adanya pengujian regresi Apple untuk jenis bug tersebut, dan Pwn20wnd mengimplementasikan beberapa pengujian regresi 1day yang dikenal lalu mendapatkan hit

Lightspeed: kondisi race lio_listio

  • Bug inti tachy0n adalah bug Lightspeed dari Synacktiv, dan terkait dengan kemungkinan CVE-2020-9859 serta CVE-2018-4344
  • Kerentanan ini berada pada syscall lio_listio, yang menjalankan I/O file secara asinkron atau batch
  • Kernel mengalokasikan struktur aio_lio_context untuk melacak pekerjaan I/O yang diajukan
    • Struktur ini memiliki field io_waiter, io_issued, dan io_completed
  • Pekerjaan sebenarnya dijalankan di thread terpisah, dan ketika semua I/O selesai, do_aio_completion membebaskan konteks tersebut
  • Jika tidak ada pekerjaan yang dijadwalkan, thread saat ini dari lio_listio harus membebaskan konteks tersebut
  • Masalahnya, pemeriksaan ini memiliki kondisi race
    • Pekerjaan bisa saja sudah diajukan ke thread lain, tetapi selesai dan konteksnya sudah dibebaskan sebelum waktu pemeriksaan
    • Pada saat itu, lio_listio kembali memeriksa lio_context yang sudah menjadi dangling pointer

Alur dari double free menuju exploit

  • Urutan yang diperlukan untuk exploit adalah sebagai berikut
    • lio_listio mengalokasikan lio_context
    • Pekerjaan selesai dan do_aio_completion membebaskan lio_context
    • Memori yang sudah dibebaskan dialokasikan ulang sebagai objek yang dikendalikan penyerang dan dibuat seolah-olah lio_context->io_issued == 0
    • lio_listio melihatnya dan kembali membebaskan objek penyerang tersebut
    • Memori yang sama dialokasikan ulang sebagai objek lain, sehingga dua alokasi berbeda menunjuk ke memori yang sama
  • Pada perangkat 64-bit, lio_context masuk ke zone terkecil, yaitu kalloc.16
  • Sebelum iOS 14, allocation site yang sama dibagi berdasarkan ukuran, terlepas dari jenis objek
    • Objek C++, array pointer, dan buffer data yang disediakan pengguna dapat saling menggunakan ulang memori dalam bucket berukuran sama
  • Double free ini berperilaku berbeda dari double free umum yang mudah berujung pada kondisi fatal jika tidak ada realokasi perantara
    • lio_context->io_issued tidak bernilai 0 saat masih dialokasikan
    • Setelah dibebaskan, allocator menimpa 8 byte pertama dengan nilai canary dan freelist pointer atau nilai XOR alamat objek
    • Karena itu, free kedua hanya terjadi jika ada realokasi di antaranya dan byte ke-4 sampai ke-7 bernilai 0
  • Exploit nyata dapat mencoba ulang race ini berkali-kali, dan di praktiknya jarang ada objek sistem lain yang secara kebetulan membuat byte yang diperlukan menjadi 0 hingga memicu double free

Pemanfaatan sebelumnya di Spice

  • Bug yang sama digunakan juga dalam jailbreak/untether Spice yang menargetkan iOS 11.x
  • Spice dikerjakan oleh tim Jake Blair bersama Sparkey dan littlelailo, dan versi terbaru saat itu adalah iOS 13.x
  • Tujuannya adalah membuat mach port forgery baik di lingkungan aplikasi maupun lingkungan racoon
    • Pada exploit kernel sebelum iOS 14, jika nilai yang disediakan pengguna dapat ditafsirkan sebagai pointer mach port, tahap berikutnya menjadi jauh lebih mudah
  • Alur dasar untuk membuat mach port forgery dengan Lightspeed adalah sebagai berikut
    • Memicu free pertama pada lio_context
    • Melakukan spray mach message yang memiliki OOL mach ports descriptor berukuran 1 atau 2
    • Membiarkan entry pertama sebagai MACH_PORT_NULL agar masuk ke kalloc.16 dan tampak seperti io_issued bernilai 0
    • Dengan free kedua, membebaskan array OOL mach ports
    • Melakukan spray data terkendali ke kalloc.16 untuk mengganti array mach ports dengan fake pointer

Perbedaan batasan sandbox aplikasi dan racoon

  • Pada A7–A9(X), tidak ada PAN, sehingga alamat userland dapat didereferensi seperti pointer kernel hanya dengan mmap dan mlock
  • A10 dan A11 juga hendak didukung, tetapi di sandbox aplikasi, dukungan itu tidak selesai karena tidak ditemukan kebocoran alamat kernel yang sesuai dan target untuk menempatkan data kendali
  • 1day yang hendak dimanfaatkan mencakup kebocoran informasi kernel stack dari Ian Beer serta escape sandbox backboardd
    • Rencananya adalah membocorkan pointer shared memory atau menempatkan data di segmen __DATA kernel
    • Karena target yang sesuai tidak ditemukan, dukungan A10/A11 melalui jalur aplikasi tidak terwujud
  • Jalur racoon memiliki kondisi berbeda
    • Berjalan sebagai root, tetapi memiliki sandbox yang lebih ketat daripada aplikasi biasa
    • Tidak memiliki akses IOSurface, sehingga tidak bisa memakai spray OSUnserializeXML umum melalui IOSurface::setValue
    • Sebagai gantinya, pemanggilan OSUnserializeXML di dalam RootDomainUserClient::secureSleepSystemOptions dapat digunakan untuk melakukan spray sebagian objek dalam bentuk leak
  • racoon memiliki profil sandbox yang mengizinkan semua pembacaan dan penulisan sysctl, serta memiliki hak root
    • Jika kernel slide diketahui, sysctl global di __DATA kernel dapat digunakan seperti penyimpanan data pada alamat yang diketahui
    • Di Spice, yang dipilih adalah vm.swapfileprefix
  • Untuk memperoleh kernel slide, digunakan CVE-2018-4413 dari panicall
    • Kebocoran informasi sysctl_procargsx dapat membocorkan hampir satu halaman memori kernel yang belum diinisialisasi dari kernel_map
    • Dengan ini, pointer kode kernel dan heap dapat diperoleh, sehingga A7–A11 dapat ditangani
    • Di sandbox aplikasi, sysctl_procargsx diblokir sehingga metode yang sama tidak mungkin dilakukan

Struktur exploit tachy0n untuk unc0ver

  • Target unc0ver adalah A8–A13, sehingga A10+ tidak bisa diabaikan atau bergantung pada dereferensi userland
  • Exploit ini dirancang dalam struktur dua lapis dengan mempertimbangkan tahap memory corruption yang bisa gagal
    • Lapisan bawah menjalankan thread freerer yang memanggil lio_listio dan thread racer yang melakukan unserialize OSData melalui IOSurface
    • Nilai defaultnya adalah 4 freerer dan 16 racer, dan dapat disesuaikan
  • Data yang di-unserialize melalui IOSurface adalah OSDictionary dengan beberapa entry OSData
    • Posisi yang sesuai dengan io_issued harus bernilai 0
    • Magic value seperti 0x41414141, 0x69696969, serta nilai key k digunakan untuk mendeteksi overlap
  • Setelah race, semua nilai OSData diperiksa
    • Objek yang magic value-nya berubah dianggap telah diambil oleh objek sistem lain dan ditandai sebagai target cleanup nanti
    • Jika key dan nilai k di dalam buffer berbeda, itu dinilai sebagai overlap ketika objek OSData lain menunjuk ke backing buffer yang sama
  • Fungsi maybe_reyoink dan overlap dalam kode menyusun informasi overlap tersebut dan meneruskannya ke lapisan atas
  • Lapisan atas menggunakan objek OSData yang overlap untuk menyusun fake mach port
    • Membebaskan satu OSData
    • Melakukan spray mach message dengan OOL port descriptor
    • Membebaskan OSData lainnya
    • Mengalokasikan ulang sebagai OSData baru yang berisi pointer fake task port

Menempatkan data terkendali pada alamat kernel yang diketahui

  • Exploit dapat membocorkan raw kernel pointer dari mach port dengan membaca isi yang telah dialokasikan ulang sebagai array OOL ports descriptor melalui OSData
  • Pada tahap berikutnya, ini digunakan untuk membocorkan alamat task port dan service port IOSurfaceRoot, tetapi masalah utamanya adalah memperoleh alamat kernel dari buffer yang dapat dikendalikan secara stabil
  • Kandidat yang ditemukan di source XNU adalah IOMemoryDescriptor
    • Field _ranges adalah array IOVirtualRange, dan satu IOVirtualRange tepat masuk ke kalloc.16
    • Namun, IOMemoryDescriptor biasa menggunakan _singleRange alih-alih heap allocation jika rangenya hanya satu
  • IOBufferMemoryDescriptor menjadi pengecualian karena memanggil IONew(IOAddressRange, 1) untuk satu range sehingga melakukan heap allocation
  • Tempat yang praktis untuk mengalokasikannya secara arbitrer dan memetakannya ke ruang alamat pengguna adalah antarmuka AGX dari IOAcceleratorFamily2
    • Jika userclient type 0 dibuka dari IOGraphicsAccelerator2, akan diperoleh IOAccelContext2
    • Tiga memory descriptor dapat di-map melalui ::clientMemoryForType()
    • Type 0 berukuran 0x8000 byte sehingga digunakan untuk mengidentifikasi victim descriptor
  • Exploit menggunakan loop berikut
    • Membuka IOAccelContext2 dan memperoleh dua OSData yang overlap
    • Membebaskan salah satu OSData
    • Menghubungkan IOAccelSharedUserClient2 yang sudah dibuka sebelumnya dengan IOConnectAddClient()
    • Membaca OSData yang tersisa untuk memastikan 8 byte pertama adalah kernel pointer yang page-aligned dan 8 byte berikutnya adalah 0x8000
    • Jika kondisi tidak cocok, menutup IOAccelContext2 dan mengulang

Pageable memory, fake port, zone_require

  • Setelah memory descriptor di-map ke process dan alamat kernelnya diketahui, masih ada masalah bahwa memori dibuat sebagai kIOMemoryPageable
  • Karena fake mach port dan objek fake task dapat diakses saat preemption dimatikan, page tersebut perlu di-fault-in di sisi kernel
  • Ini ditangani dengan memanggil dua kali external method 2 IOAccelContext2::submit_data_buffers, yang secara tidak langsung memanggil IOAccelContext2::processSidebandBuffer
    • Membaca struktur pada offset 0x10 byte dari awal shared memory
    • Struktur pertama memiliki tok == 0x100 dan dibuat menutupi seluruh page agar proses berlanjut hingga page kedua
    • Page kedua kemudian dapat digunakan untuk meletakkan data fake object
  • Tahap berikutnya berlanjut ke penyusunan fake task, fake port, switcheroo OOL descriptor, dan primitive pembacaan arbitrer
  • Bypass zone_require juga diperlukan
    • Saat itu, zone_require mengizinkan page di luar zone_map dan menafsirkan 0x20 byte pertama page seperti metadata
    • Dengan memasukkan zone index yang benar, ini dapat digunakan seperti tiket lolos untuk zone yang diinginkan
    • Karena itu diperlukan dua page: satu page untuk task dan satu page untuk mach port
  • Exploit ini sekarang dipublikasikan di GitHub

Analisis dan patch setelah publikasi

  • Publikasi exploit 0day lengkap untuk versi terbaru yang masih ditandatangani menarik perhatian scene jailbreak iOS
  • Brandon Azad, yang saat itu bekerja di Project Zero, mengidentifikasi kerentanannya dalam waktu kurang dari 4 jam setelah exploit dipublikasikan dan memberi tahu Apple
  • Enam hari setelah exploit dipublikasikan, Synacktiv melalui artikel baru membahas kemungkinan bahwa fix asli di iOS 12 membuat memory leak, dan upaya memperbaiki memory leak itu justru menghidupkan kembali bug semula
  • Sembilan hari setelah exploit dipublikasikan, Apple merilis patch
  • Setelah itu, pengujian regresi untuk bug tersebut ditambahkan ke XNU
  • Lima puluh empat hari setelah publikasi, versi reverse-engineered bernama “tardy0n” disertakan dalam jailbreak Odyssey, dengan target yang juga iOS 13.0–13.5

Lingkungan exploit yang berubah sejak iOS 14

  • iOS 14 menunjukkan perubahan strategi keamanan kernel Apple
  • Sebelum iOS 14, apa pun primitive awalnya—heap overflow, over-release objek C++, type confusion, dan sebagainya—target berikutnya umumnya adalah mach port
  • Salah satu perubahan terbesar di iOS 14 adalah allocator kalloc dan zalloc
    • Zone map dibagi menjadi beberapa rentang “kheap”
    • Data yang dikendalikan pengguna dan objek kernel dipisahkan agar masuk ke heap berbeda
    • Sequestering diterapkan pada objek kernel, sehingga page virtual address yang dialokasikan pada zone tertentu tidak digunakan ulang oleh zone lain sampai reboot
    • Physical memory dapat dibebaskan, tetapi rentang virtual memory tidak digunakan ulang untuk objek lain, sehingga type confusion pada objek kernel secara praktis terblokir
  • Guard page, posisi awal zone allocation yang berubah tiap boot, serta penyempurnaan berikutnya membuat keandalan serangan cross-zone jauh lebih rendah
  • Apple bergeser dari sekadar memblokir bug individual menjadi memblokir strategi exploit
    • Jika exploit memakai struct kmsg sebagai target corruption, struktur tersebut ditandatangani
    • Jika pipe buffer dipakai sebagai antarmuka baca/tulis kernel yang stabil, pointer terkait menjadi target penerapan PAC
    • Jika muncul teknik yang memakai objek tidak terkait sebagai victim, tipe objek tersebut di-hardening
  • Akibatnya, dalam pengembangan exploit, exploit strategy menjadi lebih bernilai daripada 0day memory corruption awal

Terputusnya pengetahuan publik

  • Sebelum iOS 14, pengetahuan riset keamanan iOS yang publik dinilai hampir setara dengan pengetahuan privat
  • Setelah iOS 14, kecuali beberapa pengecualian, berbagi informasi pada dasarnya terhenti
  • Bahkan ketika iOS 19 beta tinggal beberapa minggu lagi, dirangkum bahwa tidak ada exploit kernel publik untuk iOS 18 atau iOS 17
  • Catatan keamanan Apple sesekali memuat kerentanan yang dieksploitasi di dunia nyata, tetapi informasi publik tidak mampu mengikuti riset privat
  • Fakta bahwa baru 5 tahun berlalu sejak tachy0n dipublikasikan menunjukkan betapa cepatnya bidang exploit kernel iOS berubah

2 komentar

 
ndrgrd 2025-05-26

Perangkat keras Apple memang hebat, tetapi perangkat lunaknya penuh dengan niat untuk mengekang pengguna.
Bahkan jika Anda hanya ingin menjalankan aplikasi yang Anda buat dan build sendiri di perangkat milik Anda, tetap perlu berlangganan seharga $100.

Kalau Anda adalah pengembang yang memakai aplikasi open source skala kecil hingga menengah dan membangunnya sendiri untuk dipakai,
daripada harus melakukan sideload dengan memanfaatkan celah di perangkat Apple sampai perlu jailbreak, lebih mudah pakai Android saja.

 
GN⁺ 2025-05-25
Komentar Hacker News
  • Yang mengesankan adalah cara mengalahkan perusahaan bernilai 1 triliun dolar ternyata lewat pekerjaan sederhana dan membosankan yang menjadi kelemahan khusus Apple, yaitu regression testing
    SockPuppet, salah satu kerentanan besar yang dipakai untuk jailbreak di iOS 12, ditemukan dan dilaporkan ke Apple oleh Ned Williamson dari Project Zero, dipatch di iOS 12.3, lalu kemudian dipublikasikan di bug tracker Project Zero
    Namun di iOS 12.4 kerentanan itu muncul lagi seolah-olah belum pernah dipatch, mungkin karena Apple melakukan fork XNU ke branch terpisah untuk versi tersebut dan gagal menerapkan patch-nya
    Ini adalah sinyal kuat bahwa tidak ada regression test untuk kerentanan semacam ini, dan hanya dengan mengotomatiskan beberapa 1-day yang sudah dikenal, Pwn bisa langsung mengenai sasaran
    Saya penasaran ada berapa pihak yang menjalankan CI farm untuk terus menguji kerentanan lama pada versi baru proyek seperti Linux, FreeBSD, OpenWRT, dan OpenSSH

    • Regression testing adalah prosedur QA standar untuk memastikan bug yang sudah diperbaiki tidak muncul lagi
      Saat kuliah 20 tahun lalu, saya menjadi relawan QA di Mozilla, dan saat itu ada kumpulan regression test yang terus bertambah, terutama untuk bug rendering/layout dan JavaScript engine
      Karena kami membuat test case minimal untuk reproduksi dan verifikasi perbaikan, test itu juga mudah dimasukkan ke build pipeline
      Bug memang tidak bisa dihindari, tetapi bug yang sudah diperbaiki dengan waktu dan uang lalu hidup kembali adalah skenario terburuk
      Organisasi yang peduli pada kualitas jelas berinvestasi pada regression testing, tetapi banyak organisasi tidak menghargai QA dan entah tidak melakukannya sama sekali atau menyerahkannya ke outsourcing termurah
      Benar-benar aneh bahwa Apple tidak memiliki regression test untuk jailbreak, kategori bug yang secara historis paling menarik perhatian
      Mozilla sekarang mungkin bisa dikritik dari banyak sisi, tetapi bahkan pada awal 2000-an mereka menjalankan QA dan CI/CD yang cukup solid dengan alat seperti Tinderbox dan Bugzilla
      Ketika DevOps menjadi tren dan memopulerkan cara kerja seperti ini, saya sempat mengira semua orang sudah melakukannya, tetapi ternyata itu salah paham saya
    • Jika “proyek” di sini juga mencakup badan intelijen, aman untuk berasumsi bahwa setidaknya badan intelijen G10, Rusia, Tiongkok, Korea Utara, dan banyak grup swasta melakukan pekerjaan semacam ini
    • Masalah mendasarnya tampaknya adalah banyak organisasi mengisolasi pekerjaan keamanan ke alur terpisah dan klasifikasi bug terpisah
      Ini seperti situasi ala Hukum Conway yang tercipta dari pemisahan keamanan dan pengembangan fitur
      Meskipun ada prosedur build/release dan kumpulan regression test yang matang, karena struktur organisasi internal, besar kemungkinan isu keamanan semacam ini tidak masuk ke dalamnya
    • Saya tidak ingat namanya, tetapi pernah melihat proyek FOSS yang memiliki direktori test case untuk setiap issue
      Jumlahnya mudah saja ribuan, dan mungkin itu SQLite
      Ini pendekatan yang layak ditiru
      Jika perbaikan tidak di-backport, kemungkinan besar test-nya juga tidak akan di-backport
  • Saat melihat istilah seperti kheap separation, mitigasi task port, SSV, dan SPTM, rasanya seperti sedang lancar berbicara dengan teman dalam bahasa asing lalu tiba-tiba beralih ke penjelasan bedah otak atau fisika nuklir, dan pemahaman saya jatuh dari tebing
    Rasanya mirip ketika saya pernah mencoba menerjemahkan percakapan tentang renovasi tungku peleburan
    Sayang jailbreak sekarang tidak seramai dulu
    Hampir tidak ada hal praktis yang saya lakukan dengan iPad yang di-jailbreak, tetapi itu menyenangkan, dan kalau sekarang saya ingin memasang aplikasi tethering, UTM, serta solusi JIT
    SideStore juga terlihat menjanjikan, tetapi akun saya dulu sempat menjadi akun Apple Developer berbayar, sehingga masih ada 10 app ID yang tidak kedaluwarsa, dan karena itu saya tidak bisa memasang aplikasi seperti UTM kecuali membuat akun baru atau membayar lagi

    • Dulu saya memakai iPhone 4 yang sudah di-jailbreak, dan itu praktis satu-satunya cara agar iPhone bisa saya jadikan perangkat utama
      Setelah kehilangan itu, saya kembali ke Android, dan pada saat itu Android sudah cukup mengejar dari sisi fitur bawaan
  • Saya dengar Apple sekarang membayar 1 juta dolar untuk jailbreak, dan itu kemungkinan adalah batas bawah harga pasar bebas

  • Kalau ini benar, berarti Apple memakai strategi yang luar biasa
    Dengan menutup semua jalan untuk mendapatkan root di perangkat, Apple bisa mempatch kerentanan yang ditemukan gratis oleh developer jailbreak

    • Namun tidak sepenuhnya begitu
      Menurut tulisan itu, komunitas privat masih memiliki exploit dan Apple mempatch exploit tersebut
      Hanya komunitas publik atau developer ini yang tampaknya, entah karena alasan apa, tidak lagi seperti itu
  • Kalimat favorit saya dari seluruh tulisan adalah: “Saya juga ingin berterima kasih kepada seseorang yang meng-unpatch bug itu di iOS 13.0. Itu juga tindakan yang sangat keren.”

  • Katanya “saya tidak bisa membayangkan kita akan berada di mana 5 tahun lagi”, tetapi saya bisa membayangkannya
    iMessage masih memungkinkan pengambilalihan perangkat, akun, dan data

  • Tidak disebutkan dalam tulisan apakah ini tethered atau untethered

    • tachy0n adalah eskalasi hak lokal (LPE), jadi klasifikasi itu tidak terlalu cocok
      Setahu saya, unc0ver, jailbreak yang menyertakan ini dalam distribusinya, mungkin termasuk “semi-untethered”