การเจลเบรก 0day ครั้งสุดท้าย: Tachy0n
(blog.siguza.net)- tachy0n เป็น exploit ยกระดับสิทธิ์เคอร์เนลที่ทำงานบน iOS 13.0~13.5 และถูกใส่เป็น 0day ใน unc0ver v5.0.0 เมื่อวันที่ 23 พฤษภาคม 2020 โดยมุ่งเป้าไปที่ iOS เวอร์ชันล่าสุดในเวลานั้นโดยตรง
- หัวใจสำคัญคือ race condition Lightspeed ใน
lio_listioซึ่งทำให้สามารถ free อ็อบเจ็กต์kalloc.16ซ้ำสองครั้ง จนทำให้อ็อบเจ็กต์ต่างชนิดกันชี้ไปยังหน่วยความจำตำแหน่งเดียวกันได้ - บั๊กตระกูลเดียวกันเคยถูกใช้ใน jailbreak/untether Spice สำหรับ iOS 11 มาก่อน แต่สภาพแวดล้อมของ app sandbox และ
racoonมีข้อจำกัดด้านสิทธิ์, sandbox และเทคนิคการ spray แตกต่างกันมาก - exploit สำหรับ unc0ver จะพยายามทำให้เกิดการ overlap ของ
OSDataซ้ำ ๆ และใช้IOBufferMemoryDescriptorกับIOAcceleratorFamily2เพื่อสร้าง fake task และ fake mach port - หลัง iOS 14 เป็นต้นมา Apple เปลี่ยนไปสู่แนวทางการ ปิดกั้นตัวกลยุทธ์ exploit เอง ด้วยการแยก allocator, sequestering, PAC และ hardening รายอ็อบเจ็กต์ ทำให้องค์ความรู้ exploit เคอร์เนล iOS ที่เปิดเผยต่อสาธารณะล้าหลังกว่ายุค iOS 13 ไปมาก
เหตุผลที่การเผยแพร่ tachy0n ถือว่าผิดปกติ
- tachy0n เป็น exploit เก่าที่ส่งผลตั้งแต่ iOS 13.0 ถึง 13.5 และถูกเผยแพร่เมื่อวันที่ 23 พฤษภาคม 2020 โดยรวมอยู่ใน unc0ver v5.0.0
- หากมองตามมาตรฐานเวลานั้น มันเป็นการยกระดับสิทธิ์ภายในเครื่องของเคอร์เนล (kernel LPE) ทั่วไป แต่ที่พบได้ยากคือมันถูกเผยแพร่ในฐานะ 0day jailbreak ที่กระทบ iOS เวอร์ชันล่าสุด
- Apple ออก แพตช์ สำหรับบั๊กนี้โดยเฉพาะราว 1 สัปดาห์หลังการเผยแพร่ exploit
- บั๊กนี้เป็น 0day บน iOS 13.5 แต่ก่อนหน้านั้นเคยถูกนำไปใช้ในรูปแบบ 1day แล้ว
- Pwn20wnd มองหา 0day ที่เข้าถึงได้จาก app sandbox และจุดเริ่มต้นคือ การทดสอบ regression กับ 1day ที่รู้จักอยู่แล้ว
- SockPuppet ของ iOS 12 ถูกแพตช์ใน iOS 12.3 แต่กลับมาอีกครั้งใน iOS 12.4
- กรณีนี้เผยให้เห็นว่า Apple ไม่มี regression test สำหรับบั๊กประเภทดังกล่าว และ Pwn20wnd ได้สร้าง regression test สำหรับ 1day ที่รู้จักบางรายการจนได้ hit
Lightspeed: race condition ใน lio_listio
- บั๊กหลักของ tachy0n คือบั๊ก Lightspeed ของ Synacktiv และเกี่ยวข้องกับความเป็นไปได้ของ CVE-2020-9859 และ CVE-2018-4344
- ช่องโหว่อยู่ใน syscall
lio_listioซึ่งใช้ทำ I/O ของไฟล์แบบ asynchronous หรือแบบ batch - เคอร์เนลจะ allocate โครงสร้าง
aio_lio_contextเพื่อติดตามงาน I/O ที่ส่งเข้ามา- ในโครงสร้างมีฟิลด์
io_waiter,io_issued,io_completed
- ในโครงสร้างมีฟิลด์
- งานจริงจะถูกทำในอีกเธรดหนึ่ง และเมื่อ I/O ทั้งหมดเสร็จสิ้น
do_aio_completionจะ free context นั้น - หากไม่มีงานใดถูก schedule เธรดปัจจุบันของ
lio_listioต้องเป็นฝ่าย free context - ปัญหาคือการตรวจสอบนี้มี race condition
- งานอาจถูกส่งไปยังอีกเธรดหนึ่งแล้ว แต่เสร็จสิ้นและ context ถูก free ไปก่อนจังหวะที่ตรวจสอบ
- ในจังหวะนั้น
lio_listioจะตรวจสอบlio_contextอีกครั้ง ทั้งที่กลายเป็น dangling pointer แล้ว
ลำดับจาก double free ไปสู่ exploit
- ลำดับที่ exploit ต้องการมีดังนี้
lio_listioallocatelio_context- งานเสร็จสิ้นและ
do_aio_completionfreelio_context - หน่วยความจำที่ถูก free ถูก reallocate เป็นอ็อบเจ็กต์ที่ผู้โจมตีควบคุม และทำให้ดูเหมือน
lio_context->io_issued == 0 lio_listioเห็นเช่นนั้นแล้ว free อ็อบเจ็กต์ของผู้โจมตีอีกครั้ง- reallocate หน่วยความจำเดิมเป็นอ็อบเจ็กต์อีกตัวหนึ่ง ทำให้ allocation สองรายการต่างชี้ไปยังหน่วยความจำเดียวกัน
- บนอุปกรณ์ 64 บิต
lio_contextจะอยู่ใน zone ที่เล็กที่สุดคือkalloc.16 - ก่อน iOS 14 allocation site เดียวกันถูกแชร์ตามขนาด โดยไม่ขึ้นกับชนิดของอ็อบเจ็กต์
- อ็อบเจ็กต์ C++, อาร์เรย์ pointer และบัฟเฟอร์ข้อมูลที่ผู้ใช้ให้มา สามารถนำหน่วยความจำของกันและกันกลับมาใช้ใน bucket ขนาดเดียวกันได้
- double free นี้ทำงานต่างจาก double free ทั่วไปที่หากไม่มีการ reallocate คั่นกลางมักนำไปสู่สภาวะร้ายแรงได้ง่าย
lio_context->io_issuedจะไม่เป็น 0 ระหว่างที่ถูก allocate อยู่- หลัง free แล้ว allocator จะเขียนทับ 8 ไบต์แรกด้วยค่า canary และ freelist pointer หรือค่า XOR ของที่อยู่อ็อบเจ็กต์
- ดังนั้น free ครั้งที่สองจะเกิดขึ้นก็ต่อเมื่อมีการ reallocate คั่นกลาง และไบต์ที่ 4~7 เป็น 0
- exploit จริงสามารถลองแข่งซ้ำได้หลายครั้ง และในภาคสนามแทบไม่เกิดกรณีที่อ็อบเจ็กต์อื่นของระบบบังเอิญทำให้ไบต์ที่ต้องการเป็น 0 จนก่อ double free
การใช้งานก่อนหน้านี้ใน Spice
- บั๊กเดียวกันนี้ถูกใช้ใน Spice jailbreak/untether ที่มุ่งเป้า iOS 11.x ด้วย
- Spice ถูกพัฒนาในทีม Jake Blair ร่วมกับ Sparkey และ littlelailo โดยตอนนั้นเวอร์ชันล่าสุดคือ iOS 13.x
- เป้าหมายคือการสร้าง mach port forgery ทั้งในสภาพแวดล้อมแอปและสภาพแวดล้อม
racoon- ใน exploit เคอร์เนลก่อน iOS 14 หากทำให้ค่าที่ผู้ใช้ให้มาถูกตีความเป็น pointer ของ mach port ได้ ขั้นตอนถัดไปจะง่ายขึ้นอย่างมาก
- โฟลว์พื้นฐานในการสร้าง mach port forgery ด้วย Lightspeed มีดังนี้
- ทำให้เกิด free ครั้งแรกของ
lio_context - spray mach message ที่มี OOL mach ports descriptor ขนาด 1 หรือ 2
- ตั้ง entry แรกเป็น
MACH_PORT_NULLเพื่อให้อยู่ในkalloc.16และดูเหมือนio_issuedเป็น 0 - free ครั้งที่สองเพื่อ free อาร์เรย์ OOL mach ports
- spray ข้อมูลที่ควบคุมได้ใน
kalloc.16เพื่อแทนที่อาร์เรย์ mach ports ด้วย fake pointer
- ทำให้เกิด free ครั้งแรกของ
ความต่างของข้อจำกัดระหว่าง app sandbox กับ racoon
- บน A7~A9(X) ไม่มี PAN จึงสามารถ dereference ที่อยู่ userland เหมือนเป็น kernel pointer ได้ด้วย
mmapและmlockเท่านั้น - มีความพยายามรองรับ A10 และ A11 ด้วย แต่ใน app sandbox ไม่สามารถหาการรั่วไหลของ kernel address และเป้าหมายสำหรับวางข้อมูลควบคุมที่เหมาะสมได้ จึงไม่เสร็จสมบูรณ์
- 1day ที่ตั้งใจจะใช้มี kernel stack information leak ของ Ian Beer และการ escape sandbox ของ backboardd
- แผนคือ leak pointer ของ shared memory หรือวางข้อมูลไว้ในเซกเมนต์
__DATAของเคอร์เนล - เพราะไม่พบ target ที่เหมาะสม จึงไม่มีการรองรับ A10/A11 ผ่านเส้นทางแอป
- แผนคือ leak pointer ของ shared memory หรือวางข้อมูลไว้ในเซกเมนต์
- เส้นทาง
racoonมีเงื่อนไขต่างออกไป- รันเป็น root แต่มี sandbox ที่เข้มงวดกว่าแอปทั่วไป
- ไม่มีการเข้าถึง IOSurface จึงใช้การ spray
OSUnserializeXMLผ่านIOSurface::setValueแบบปกติไม่ได้ - แทนที่จะใช้วิธีนั้น สามารถอาศัยการเรียก
OSUnserializeXMLภายในRootDomainUserClient::secureSleepSystemOptionsเพื่อ spray อ็อบเจ็กต์บางส่วนในรูปแบบ leak ได้
racoonมี sandbox profile ที่อนุญาตให้อ่านและเขียน sysctl ทั้งหมด และยังมีสิทธิ์ root ด้วย- หากรู้ kernel slide ก็สามารถใช้ sysctl global ใน
__DATAของเคอร์เนลเป็นเหมือนแหล่งเก็บข้อมูลที่มี address รู้ล่วงหน้าได้ - ใน Spice เลือกใช้
vm.swapfileprefix
- หากรู้ kernel slide ก็สามารถใช้ sysctl global ใน
- การหา kernel slide ใช้ CVE-2018-4413 ของ panicall
- จาก information leak ใน
sysctl_procargsxสามารถ leak หน่วยความจำเคอร์เนลที่ยังไม่ initialized ของkernel_mapได้เกือบหนึ่งหน้า - ทำให้ได้ kernel code และ heap pointer และจัดการ A7~A11 ได้
- ใน app sandbox
sysctl_procargsxถูกบล็อก จึงใช้วิธีเดียวกันไม่ได้
- จาก information leak ใน
โครงสร้าง exploit tachy0n สำหรับ unc0ver
- เป้าหมายของ unc0ver คือ A8~A13 จึงไม่สามารถละเลย A10+ หรือพึ่งพา userland dereference ได้
- exploit ถูกออกแบบเป็น โครงสร้างสองชั้น โดยคำนึงถึงขั้นตอน memory corruption ที่อาจล้มเหลว
- ชั้นล่างรันเธรด freerer ที่เรียก
lio_listioและเธรด racer ที่ unserializeOSDataผ่าน IOSurface - ค่าเริ่มต้นคือ freerer 4 ตัวและ racer 16 ตัว โดยปรับได้
- ชั้นล่างรันเธรด freerer ที่เรียก
- ข้อมูลที่ถูก unserialize ผ่าน IOSurface คือ
OSDictionaryที่มี entryOSDataหลายรายการ- ตำแหน่งที่ตรงกับ
io_issuedต้องเป็น 0 - magic value อย่าง
0x41414141,0x69696969และค่า keykถูกใช้ตรวจจับ overlap
- ตำแหน่งที่ตรงกับ
- หลังการแข่ง จะตรวจสอบค่า
OSDataทั้งหมด- อ็อบเจ็กต์ที่ magic value เปลี่ยนไป จะถือว่าถูกอ็อบเจ็กต์อื่นของระบบยึดไป และทำเครื่องหมายไว้สำหรับ cleanup ภายหลัง
- หาก key กับค่า
kภายใน buffer ไม่ตรงกัน จะตัดสินว่าเกิด overlap ที่อ็อบเจ็กต์OSDataอื่นชี้ไปยัง backing buffer เดียวกัน
- ฟังก์ชัน
maybe_reyoinkและoverlapในโค้ดจะจัดโครงสร้างข้อมูล overlap เหล่านี้แล้วส่งให้ชั้นบน - ชั้นบนใช้อ็อบเจ็กต์
OSDataที่ overlap กันเพื่อสร้าง fake mach port- free
OSDataตัวหนึ่ง - spray mach message ที่มี OOL port descriptor
- free
OSDataอีกตัวหนึ่ง - reallocate เป็น
OSDataใหม่ที่มี pointer ของ fake task port
- free
การวางข้อมูลควบคุมไว้ใน kernel address ที่รู้
- exploit สามารถอ่านเนื้อหาที่ถูก reallocate เป็นอาร์เรย์ OOL ports descriptor ผ่าน
OSDataเพื่อ leak raw kernel pointer ของ mach port ได้ - ในขั้นตอนต่อมาใช้สิ่งนี้เพื่อ leak address ของ task port และ service port
IOSurfaceRootแต่ปัญหาหลักคือการหา kernel address ของ buffer ที่ควบคุมได้อย่างเสถียร - ผู้สมัครที่พบในซอร์ส XNU คือ
IOMemoryDescriptor- ฟิลด์
_rangesเป็นอาร์เรย์IOVirtualRangeและIOVirtualRangeหนึ่งรายการพอดีกับkalloc.16 - อย่างไรก็ตาม
IOMemoryDescriptorทั่วไปหากมี range เดียว จะใช้_singleRangeแทน heap allocation
- ฟิลด์
IOBufferMemoryDescriptorเป็นข้อยกเว้น โดยเรียกIONew(IOAddressRange, 1)สำหรับ range หนึ่งรายการ ทำให้เกิด heap allocation- จุดที่สะดวกสำหรับ allocate สิ่งนี้ตามใจและ map เข้าพื้นที่ address ของผู้ใช้คืออินเทอร์เฟซ AGX ของ
IOAcceleratorFamily2- เมื่อเปิด type 0 userclient จาก
IOGraphicsAccelerator2จะได้IOAccelContext2 - สามารถ map memory descriptor ได้สามรายการด้วย
::clientMemoryForType() - type 0 มีขนาด 0x8000 bytes จึงใช้ระบุ victim descriptor
- เมื่อเปิด type 0 userclient จาก
- exploit ใช้ลูปต่อไปนี้
- เปิด
IOAccelContext2และหาOSDataสองตัวที่ overlap กัน - free
OSDataตัวหนึ่ง - เชื่อม
IOAccelSharedUserClient2ที่เปิดไว้ล่วงหน้าด้วยIOConnectAddClient() - อ่าน
OSDataที่เหลือ เพื่อตรวจว่า 8 ไบต์แรกเป็น page-aligned kernel pointer และ 8 ไบต์ถัดไปเป็น0x8000หรือไม่ - หากเงื่อนไขไม่ตรง ให้ปิด
IOAccelContext2แล้ววนซ้ำ
- เปิด
pageable memory, fake port, zone_require
- แม้จะ map memory descriptor เข้ากับ process และรู้ kernel address แล้ว ก็ยังมีปัญหาว่าหน่วยความจำถูกสร้างเป็น
kIOMemoryPageable - fake mach port และ fake task object อาจถูกเข้าถึงในขณะที่ preemption ถูกปิดอยู่ ดังนั้นฝั่งเคอร์เนลต้อง fault-in page นั้นก่อน
- จัดการเรื่องนี้ด้วยการเรียก external method 2 คือ
IOAccelContext2::submit_data_buffersซึ่งเรียกอ้อมไปยังIOAccelContext2::processSidebandBufferสองครั้ง- อ่านโครงสร้างที่อยู่ถัดจากจุดเริ่มต้นของ shared memory ไป 0x10 ไบต์
- โครงสร้างแรกมี
tok == 0x100และถูกทำให้ครอบคลุมทั้ง page เพื่อให้ดำเนินต่อไปถึง page ที่สอง - page ที่สองสามารถวางข้อมูล fake object ต่อจากนั้นได้
- ขั้นตอนถัดไปนำไปสู่การสร้าง fake task, fake port, OOL descriptor switcheroo และ arbitrary read primitive
- ยังต้อง bypass
zone_requireด้วย- ในเวลานั้น
zone_requireอนุญาต page นอกzone_mapและตีความ0x20ไบต์แรกของ page เป็นเหมือน metadata - หากใส่ zone index ที่ถูกต้อง ก็ใช้เหมือนบัตรผ่านสำหรับ zone ที่ต้องการได้
- ด้วยเหตุนี้จึงต้องใช้สอง page คือ page สำหรับ task และ page สำหรับ mach port
- ในเวลานั้น
- exploit นี้เผยแพร่อยู่บน GitHub แล้ว
การวิเคราะห์และแพตช์หลังการเผยแพร่
- การเผยแพร่ exploit 0day ที่สมบูรณ์สำหรับเวอร์ชันล่าสุดที่ยังเซ็นอยู่ ดึงดูดความสนใจของวงการ iOS jailbreak
- Brandon Azad ซึ่งตอนนั้นทำงานที่ Project Zero ระบุช่องโหว่ได้ภายใน 4 ชั่วโมงหลัง exploit ถูกเผยแพร่ และแจ้ง Apple
- การวิเคราะห์ดังกล่าวถูกรวบรวมไว้ใน How to unc0ver a 0-day in 4 hours or less
- 6 วันหลังการเผยแพร่ exploit Synacktiv ออก บทความใหม่ ว่าการ fix เดิมใน iOS 12 ทำให้เกิด memory leak และความพยายามแก้ memory leak นั้นอาจทำให้บั๊กเดิมกลับมา
- 9 วันหลังการเผยแพร่ exploit Apple ออกแพตช์
- ต่อมา XNU เพิ่ม regression test สำหรับบั๊กนี้
- 54 วันหลังการเผยแพร่ เวอร์ชันที่ reverse-engineered ชื่อ “tardy0n” ถูกใส่ใน Odyssey jailbreak โดยยังมุ่งเป้า iOS 13.0~13.5 เช่นกัน
สภาพแวดล้อม exploit ที่เปลี่ยนไปหลัง iOS 14
- iOS 14 แสดงให้เห็นการเปลี่ยนยุทธศาสตร์ความปลอดภัยเคอร์เนลของ Apple
- ก่อน iOS 14 ไม่ว่า primitive เริ่มต้นจะเป็น heap overflow, C++ object over-release, type confusion หรืออะไรก็ตาม target ถัดไปมักเป็น mach port
- หนึ่งในความเปลี่ยนแปลงใหญ่ที่สุดใน iOS 14 คือ allocator อย่าง
kallocและzalloc- แบ่ง zone map ออกเป็นช่วง “kheap” หลายช่วง
- แยกข้อมูลที่ผู้ใช้ควบคุมได้กับอ็อบเจ็กต์เคอร์เนลให้อยู่คนละ heap
- ใช้ sequestering กับอ็อบเจ็กต์เคอร์เนล ทำให้ page ของ virtual address ที่เคย allocate ให้ zone หนึ่งไม่ถูกนำไปใช้ซ้ำกับ zone อื่นจนกว่าจะ reboot
- physical memory อาจถูก free ได้ แต่ virtual memory range จะไม่ถูกนำไปใช้ซ้ำกับอ็อบเจ็กต์อื่น จึงแทบปิดกั้น type confusion ของอ็อบเจ็กต์เคอร์เนล
- guard page, ตำแหน่งเริ่มต้นของ zone allocation ที่เปลี่ยนทุกครั้งที่บูต และการปรับปรุงเชิงละเอียดในภายหลัง ทำให้ความน่าเชื่อถือของการโจมตี cross-zone ลดลงมาก
- Apple เปลี่ยนจากการป้องกันบั๊กรายตัว ไปเป็น การป้องกันกลยุทธ์ exploit
- หาก exploit ใช้ kmsg struct เป็น corruption target โครงสร้างนั้นจะถูกเซ็น
- หากใช้ pipe buffer เป็นอินเทอร์เฟซอ่าน/เขียนเคอร์เนลที่เสถียร pointer ที่เกี่ยวข้องจะถูกนำไปใช้ PAC
- หากมีวิธีใช้อ็อบเจ็กต์ที่ไม่เกี่ยวข้องเป็น victim อ็อบเจ็กต์ชนิดนั้นจะถูก hardening
- ผลลัพธ์คือในงานพัฒนา exploit กลยุทธ์ exploit มีคุณค่ามากกว่า memory corruption 0day เริ่มต้นเสียอีก
การขาดช่วงของความรู้สาธารณะ
- ก่อน iOS 14 มีการประเมินกันว่าความรู้ด้านวิจัยความปลอดภัย iOS ที่เปิดเผยต่อสาธารณะอยู่ในระดับใกล้เคียงกับความรู้ที่ไม่เปิดเผย
- หลัง iOS 14 หากไม่นับข้อยกเว้นบางกรณี การแบ่งปันข้อมูลแทบหยุดลง
- แม้เหลือเวลาอีกไม่กี่สัปดาห์ก่อน iOS 19 beta ก็สรุปได้ว่ายังไม่มี exploit เคอร์เนลสาธารณะสำหรับ iOS 18 หรือ iOS 17
- บันทึกความปลอดภัยของ Apple มีการระบุช่องโหว่ที่ถูกนำไปใช้จริงในธรรมชาติเป็นครั้งคราว แต่ข้อมูลสาธารณะยังตามงานวิจัยที่ไม่เปิดเผยไม่ทัน
- ข้อเท็จจริงที่ว่า tachy0n เพิ่งถูกเผยแพร่เมื่อ 5 ปีก่อน แสดงให้เห็นว่าวงการ exploit เคอร์เนล iOS เปลี่ยนแปลงรวดเร็วเพียงใด
2 ความคิดเห็น
ฮาร์ดแวร์ของ Apple นั้นยอดเยี่ยมก็จริง แต่ซอฟต์แวร์กลับเต็มไปด้วยเจตนาที่จะล่ามผู้ใช้ไว้
ต่อให้แค่อยากให้แอปที่ตัวเองสร้างและบิลด์ขึ้นมาทำงานได้เฉพาะบนอุปกรณ์ของตัวเอง ก็ยังต้องมีค่าสมาชิกราคา 100 ดอลลาร์
ถ้าคุณเป็นนักพัฒนาที่ใช้แอปโอเพนซอร์สขนาดเล็กถึงกลางและบิลด์ใช้เอง
บนอุปกรณ์ของ Apple แค่จะ sideload ก็ต้องเจลเบรกด้วยการอาศัยช่องโหว่ แบบนั้นใช้ Android ไปเลยยังสะดวกกว่า
ความคิดเห็นจาก Hacker News
น่าประทับใจที่วิธีซึ่งเอาชนะบริษัทมูลค่า 1 ล้านล้านดอลลาร์ได้ คือเรื่องงานง่าย ๆ น่าเบื่อที่ Apple ดูจะอ่อนแอเป็นพิเศษ นั่นคือ การทดสอบถดถอย
SockPuppet ซึ่งเป็นหนึ่งในช่องโหว่ใหญ่ที่ถูกใช้กับการ jailbreak บน iOS 12 ถูกค้นพบโดย Ned Williamson จาก Project Zero และรายงานให้ Apple จากนั้นถูกแพตช์ใน iOS 12.3 และเปิดเผยภายหลังใน bug tracker ของ Project Zero
แต่ใน iOS 12.4 มันกลับโผล่มาอีกครั้งราวกับไม่เคยถูกแพตช์มาก่อน น่าจะเป็นเพราะ Apple แยก fork ของ XNU สำหรับเวอร์ชันนั้นเป็นอีก branch แล้วไม่ได้ใส่แพตช์เข้าไป
นี่เป็นสัญญาณชัดเจนมากว่าไม่มีการทำ regression test สำหรับช่องโหว่ประเภทนี้ และแค่เอา known 1-day ไม่กี่ตัวมาทำอัตโนมัติ Pwn ก็ยิงเข้าเป้าได้ทันที
เลยสงสัยว่ามีสักกี่ที่ที่รัน CI farm เพื่อทดสอบช่องโหว่เก่า ๆ ซ้ำกับเวอร์ชันใหม่ของโปรเจกต์อย่าง Linux, FreeBSD, OpenWRT, OpenSSH
เมื่อ 20 ปีก่อนสมัยเรียนมหาวิทยาลัย ฉันเคยเป็นอาสาสมัคร QA ให้ Mozilla ซึ่งมีชุด regression test ที่ใหญ่ขึ้นเรื่อย ๆ โดยเน้นบั๊กด้าน rendering/layout และ JavaScript engine
เพราะต้องทำ test case แบบเล็กที่สุดเพื่อใช้ทั้งในการ reproduce และยืนยันการแก้ไข จึงเอาใส่ build pipeline ได้ง่ายด้วย
บั๊กเป็นสิ่งเลี่ยงไม่ได้ แต่การที่บั๊กที่ทุ่มทั้งเวลาและเงินไปแก้กลับฟื้นขึ้นมาใหม่ คือสถานการณ์ที่แย่ที่สุด
องค์กรที่ให้ความสำคัญกับคุณภาพย่อมลงทุนกับ regression test อย่างแน่นอน แต่หลายองค์กรไม่ให้คุณค่ากับ QA เลย ไม่ทำเองหรือโยนให้ outsourcing ราคาถูกที่สุด
ที่แปลกมากคือ Apple กลับไม่มี regression test สำหรับ jailbreak ซึ่งเป็นกลุ่มบั๊กที่ถูกจับตามองมากที่สุดกลุ่มหนึ่งมาโดยตลอด
ทุกวันนี้ Mozilla อาจถูกวิจารณ์ได้หลายเรื่อง แต่ตั้งแต่ต้นยุค 2000 ก็มี QA และ CI/CD ที่ค่อนข้างแข็งแรงอยู่แล้วด้วยเครื่องมืออย่าง Tinderbox และ Bugzilla
ตอนที่ DevOps กลายเป็นกระแสและทำให้แนวทางแบบนี้แพร่หลาย ฉันเคยนึกว่าทุกคนทำกันอยู่แล้ว แต่กลายเป็นว่าฉันเข้าใจผิด
เป็นสถานการณ์คล้ายกฎของ Conway ที่เกิดจากการแยกระหว่าง security กับการพัฒนาฟีเจอร์
ต่อให้มีขั้นตอน build/release และชุด regression test ที่โตเต็มที่แล้ว แต่ด้วยโครงสร้างองค์กรภายใน ก็มีโอกาสสูงที่ประเด็นความปลอดภัยแบบนี้จะไม่ถูกดึงเข้าไปอยู่ในนั้น
มีเป็นพัน ๆ อันได้สบาย ๆ และน่าจะเป็น SQLite
เป็นแนวทางที่น่าเอาอย่าง
ถ้าไม่ได้ backport ตัวแก้ไข ก็ดูมีแนวโน้มสูงว่าจะไม่ได้ backport ตัวทดสอบด้วย
พอเห็นคำอย่าง kheap separation, task port mitigation, SSV, SPTM ก็ให้ความรู้สึกเหมือนกำลังคุยกับเพื่อนเป็นภาษาต่างประเทศได้ลื่น ๆ แล้วจู่ ๆ อีกฝ่ายก็เปลี่ยนไปอธิบายการผ่าตัดสมองหรือฟิสิกส์นิวเคลียร์ จนความเข้าใจตกหน้าผาทันที
ตอนที่เคยพยายามล่ามบทสนทนาเรื่องการปรับปรุงเตาหลอมก็คล้ายกัน
น่าเสียดายที่ทุกวันนี้วงการ jailbreak ไม่คึกคักเหมือนเมื่อก่อนแล้ว
ฉันแทบไม่เคยใช้ iPad ที่ jailbreak ไปทำอะไรที่เป็นประโยชน์จริงจัง แต่ก็สนุกดี และถ้าเป็นตอนนี้ก็อยากลงแอป tethering, UTM และวิธีแก้เรื่อง JIT
SideStore ก็ดูมีอนาคต แต่บัญชีของฉันเคยเป็นบัญชี Apple Developer แบบเสียเงินมาก่อน เลยยังมี app ID แบบไม่หมดอายุเหลืออยู่ 10 ตัว ทำให้ติดตั้งแอปอย่าง UTM ไม่ได้ เว้นแต่จะสร้างบัญชีใหม่หรือกลับไปจ่ายเงินอีกครั้ง
พอเสียสิ่งนั้นไป ฉันก็กลับไป Android และตอนนั้น Android ก็ไล่ตามฟีเจอร์พื้นฐานมาทันมากแล้ว
ได้ยินมาว่าตอนนี้ Apple จ่าย 1 ล้านดอลลาร์สำหรับ jailbreak และนั่นน่าจะเป็นราคา floor ของตลาดเสรี
ไม่รู้ว่าต้องผ่านนายหน้าหรือเปล่า หรือมีอีเมลสาธารณะที่ไม่ใช่โยนเข้าไปในด่าน customer support ชั้นแรกแล้วหายเงียบไหม
ถ้าเรื่องนี้จริง เท่ากับว่า Apple ใช้กลยุทธ์ที่น่าทึ่งมาก
แค่ปิดทุกทางที่จะได้ root บนอุปกรณ์ ก็ทำให้ Apple แพตช์ช่องโหว่ที่นักพัฒนา jailbreakหาเจอให้ฟรีได้
ตามบทความบอกว่าชุมชนแบบปิดยังคงมี exploit อยู่ และ Apple ก็แพตช์สิ่งเหล่านั้น
ดูเหมือนว่าจะเป็นเฉพาะฝั่งชุมชนสาธารณะหรือฝั่งนักพัฒนากลุ่มนี้เท่านั้นที่ไม่เป็นแบบนั้นอีกต่อไปด้วยเหตุผลบางอย่าง
ประโยคที่ชอบที่สุดทั้งบทความคือ “ผม/ฉันอยากขอบคุณใครก็ตามที่ unpatch บั๊กนั้นใน iOS 13.0 ด้วย มันเป็นการกระทำที่เท่มากจริง ๆ”
เขาบอกว่า “ฉันนึกภาพไม่ออกเลยว่าอีก 5 ปีเราจะอยู่ตรงไหน” แต่ฉันนึกออก
iMessage จะยังคงเปิดทางให้ยึดอุปกรณ์ บัญชี และข้อมูลได้อยู่ดี
ในบทความไม่ได้บอกว่าเป็น tethered หรือ untethered
ส่วน unc0ver ซึ่งเป็น jailbreak ที่รวมตัวนี้ไปแจกด้วย เท่าที่จำได้ น่าจะเป็นแบบ “semi-untethered”