نلعب بالنار: ندير كودًا تعسفيًا على تطوير iPhone 7

صورة


عشية رأس السنة الجديدة ، سقط مبرمج JC PCIE-7 في أيدينا. في عملية استخدامه تبين أن وظائفه محدودة ، ولكن الشيء القليل الذي تبين أنه كان في قاع مزدوج. داخل هذا المبرمج ، وجدنا لوحة iPhone 7 مع إصدار تصحيح خاص. لمغامرات السنة الجديدة في عالم البحث وتصحيح منتجات "التفاح" - مرحبًا بك في قطة!


من المحتمل أن الباحثين الأمنيين الكسولين فقط لم يشعروا بالإمكانيات التي توفرها checkm8 و checkra1n بناءً عليه (المراجعة الرائعة لـ checkm8 كانت في الآونة الأخيرة على Habré) بأيديهم. بالطبع ، قمنا أيضًا باختبار هواتفنا الذكية وقررنا خلال هذه العملية معرفة ما هو مفيد للباحثين في السوق الصينية من الحرف "الحديدية". ممتع حقيقة: إذا كنت ترغب في اختبار أي جهاز للأمان ، فإن AliExpress لديه بالفعل ألعابه الخاصة لهذا الغرض.


جاءت لعبتنا في ليلة رأس السنة - مبرمج JC PCIE-7 ، والذي يسهل العثور عليه على AliExpress:


صورة


افترضنا أنه بمساعدة هذا المبرمج يمكننا نسخ ذاكرة فلاش iPhone. لكن أثناء التشغيل اكتشف أن مثل هذه الوظيفة في البرنامج ببساطة غير موجودة! نعم ، يمكن للمبرمج قراءة وكتابة التكوين لذاكرة فلاش وإرفاقه بالهاتف ، ولكن قراءة القطع العشوائية غير مدعومة. ثم لاحظنا خطوطًا غير عادية في نافذة وحدة التحكم في برنامج التحكم ، على غرار سجل تمهيد نظام التشغيل:


صورة
إطار لحظة التحميل من فيديو التدريب


أخيرًا ، لفتنا الانتباه إلى وظيفة توصيل المبرمج بالكمبيوتر باستخدام بروتوكول DFU. في هذا الوضع ، تم اكتشاف المبرمج بشكل صحيح في iTunes باعتباره iPhone. قررنا تفكيك الجهاز ومعرفة ما بداخله وكيف يتم محاكاة وضع DFU.


داخل مبرمج ، يتم تثبيت ثلاث لوحات:


  • لوحة التحكم على أساس stm32f103؛
  • مجلس المضاعف مع شريحة NVMe ملحوم وكتلة.
  • وبشكل غير متوقع ، لوحة iPhone 7.

صورة


صورة


اتضح أن المبرمج يقوم بتبديل المضاعف بطريقة يتم فيها تحميل لوحة iPhone أولاً من ذاكرة فلاش ملحوم ، ثم يتم توصيل شريحة NVMe التي تحتاج إلى وميض بها. يتم تنفيذ الإدارة عبر منفذ COM الظاهري ، ويتم في البداية إرسال الأوامر الخاصة بتبديل رقائق NVMe ، ثم تقوم اللوحة بإعادة توجيه وحدة التحكم في تصحيح الأخطاء لـ iPhone ، محاكيةً لكبل DCSD . بعد فحص الأوامر التي تم إرسالها إلى منفذ COM بعناية ، شاهدنا الخطوط:


setenv diags-path /AppleInternal/Diags/bin/diag.img4
diags


بالفعل في هذه المرحلة ، أدركنا أن لوحة iPhone 7 ليست عادية تمامًا (على الأقل يوجد مجلد AppleInternal فيه ). لنرى كيف تتصرف في "بيئة" مألوفة أكثر ، قمنا بإعادة ترتيب اللوحة وشريحة NVMe في هاتف مانح:


صورة


بالإضافة إلى الترس عند التحميل ، في وحدة تصحيح الأخطاء ، رأينا السطر BUILD_STYLE: DEVELOPMENT:


صورة


بعد التنزيل النهائي (باستخدام أوامر العلامات المذكورة أعلاه ) ، حصلنا على شاشة أرجوانية ، وبعد الضغط على مفاتيح الصوت ، تم عرض القائمة التالية على الشاشة:


صورة


أي أن الجهاز الذي جمعناه تبين أنه إصدار خاص من iPhone للاختبار والتطوير! بالمناسبة ، يتم شراء مثل هذه الهواتف من قبل الباحثين وحتى جامعي - هذه هي هدية حقيقية لمجموعتنا الفنية! في مطور iPhone كامل الوظائف ، يتم تثبيت مجموعة iOS خاصة مع وحدة تحكم الجذر ، مما يسهل إلى حد كبير دراسة الهاتف والبحث عن الثغرات الأمنية:


صورة


في حالتنا ، يتم تثبيت الأداة المساعدة التشخيصية فقط على الهاتف ، ويتم التفاعل الرئيسي معها عبر وحدة التحكم في التصحيح:


سجل التمهيد ومساعدة الإخراج
======================================= :: :: iBoot for d10, Copyright 2007-2016, Apple Inc. :: :: Local boot, Board 0x8 (d10ap)/Rev 0xd :: :: BUILD_TAG: iBoot-3406.1.53.1.4 :: :: BUILD_STYLE: DEVELOPMENT :: :: USB_SERIAL_NUMBER: CPID:8010 CPRV:11 CPFM:03 SCEP:01 BDID:08 ECID:000114422885E526 IBFL:3D :: ======================================= Boot Failure Count: 0 Panic Fail Count: 0 Entering recovery mode, starting command prompt ] setenv diags-path /AppleInternal/Diags/bin/diag.img4 ] diags Unable to load image type 64696167 from flashnx_mount:432: reloading after unclean unmount, checkpoint xid 112, superblock xid 11 jumping into image at 0x810000000 pinot_quiesce() mipi_dsim_quiesce() Console router buffer allocated @ 0x87CB84018, size = 262144 bytes WHO_AM_I doesn't match MPU6700's Chip ID! Expected 0x90 got 0x0 Carbon: MPU6900 is found. Carbon: MPU6900 (south) detected Carbon: MPU6900 (south) selected MPU6900 not found. Expected 0x10, found 0x0 Carbon: MPU6900 (north) not detected Phosphorous: BMP284 is found. mcc-supported : 1 Phosphorous: BMP282 is not found on SPI 4. Expected 0x58, found 0x0 time-train: 26719 uS Link 0 speed negotiate to 3 Link 0 width negotiate to 1 APCIE power on completed Device 00:00:0 config space@0x610000000 Vendor:106B Device:1007 Revision:01 ClassCode:060400 Type:01 PriBus:00 SecBus:01 SubBus:01 Capability 0x01 Offset:0x40 Address:0x610000040 Capability 0x05 Offset:0x50 Address:0x610000050 Capability 0x10 Offset:0x70 Address:0x610000070 Extended Capability 0x0001 Ver:0x02 Offset:0x0100 Address:0x610000100 Extended Capability 0x0019 Ver:0x01 Offset:0x0148 Address:0x610000148 Extended Capability 0x001E Ver:0x01 Offset:0x0160 Address:0x610000160 Found device id 0x2002 Device 01:00:0 config space@0x610100000 Vendor:106B Device:2002 Revision:11 ClassCode:018002 Type:00 BAR0 MEM C0000000/00004000 BAR1 IO 00000000/00000004 Capability 0x01 Offset:0x40 Address:0x610100040 Capability 0x05 Offset:0x50 Address:0x610100050 Capability 0x10 Offset:0x70 Address:0x610100070 Extended Capability 0x0001 Ver:0x02 Offset:0x0100 Address:0x610100100 Extended Capability 0x0002 Ver:0x01 Offset:0x0148 Address:0x610100148 Extended Capability 0x0019 Ver:0x01 Offset:0x0168 Address:0x610100168 Extended Capability 0x0018 Ver:0x01 Offset:0x0178 Address:0x610100178 Extended Capability 0x001E Ver:0x01 Offset:0x0180 Address:0x610100180 APCIE Enumerate on completed ICE BB not supported on this platform D10 Diag (factory_d10_pvt) BuildEng build D10Casaval24C302an (24C302an). Revision 6040f18. Built at 2016/08/20 15:57:53 script: device -k ThermalSensor -e sochot 0 on 120 script: device -k ThermalSensor -e sochot 1 on 125 script: cbcolor Setting Screen Color based on iPX Control Bits: script: alias vbat=pmuadc --sel tigris --read vbat script --cont startup.txt script: alias bbon="meta 'baseband --on --load_firmware; baseband --wait_for_ready --ping'" script: alias bbonbypass="meta 'baseband --on --load_firmware; baseband --wait_for_ready --ping --bypass en'" script: alias bboff=baseband --off script: alias getcd=bblib -e BB_GetCD() script: alias erase_rfcal=smokey Tools/RFCalErase --run script: alias erase_efs=smokey Tools/EFSErase --run script: alias erase_pac=smokey Tools/RFPacErase --run script: alias hdq_en=i2c --devwrite 1 0x75 0x1D 1 script: alias hdq_dis=i2c --devwrite 1 0x75 0x1D 0 script: alias bblib="smokeyshell -p -e 'if BBLib_cfg then print [[no init]] else require [[BBLib.14A]];BB_Init() end'" script: alias wcs=smokey --run WCS --clean LogBehavior=ConsoleOnly script: alias bblibcfg=bblib -e printLibCfg() script: alias bbdebug="meta 'base --debug on;ramlog --on 10;consolerouter --add -s *.{warn,error,print},system.debug.debug -d ramlog --quiet;consoleformat --en --sink serial -o ts'" script: alias gpsdebug="meta 'ramlog --on 10;consolerouter --add -s gps.debug.* -d ramlog'" script: alias updateroot="meta 'usbfs --mount;cp -r usbfs:\AppleInternal nandfs:\;usbfs --unmount;smokeyshell -r'" [00011442:2885E526] :-) help DiagShell builtin commands: "time" time <command-line ...> "echo" echo <arguments ...> "waitfor" waitfor <timeout-milliseconds> <string-to-match> "repeat" repeat <time-spec> <command line ...> "alias" alias [<name>[=<command line>]] "unalias" unalias <name> "true" true "false" false "args" args <command line ...> "shopt" shopt EDK Boot Loader commands (help <command> for more info): "accessory" Command to change power settings as well as identifying accessories connected to the unit "aes" Command for AES encryption/decryption "amux" Analog Mux selection command "audio" General command to hande resetting/blanking/scripting of the audio subsystem "audioparam" Audio parameter retrieval/setting utility "audioreg" Manages register operations on audio blocks in the system "barcode" Show S/N and ECID barcode "baseband" Command to control/test baseband functionality "battery" Command to display basic information about the battery "baud" <baud rate> : Set UART Baud rate "bl" BackLight Test "blockdevice" Show information about boot devices. Bare quantities are in bytes. "bluetooth" Command to control/test bluetooth functionality "boardid" Get the board ID "boardrev" Get the board revision "bonfire" Run Bonfire "bootcfg" Get the boot configuration "buckcheck" Buck voltage check "button" Test individual buttons on the unit "buttoncnt" [--dqe] Count button presses on the unit "camisp" camera command that can run in seperat steps. "cat" Print the contents of a file. "cbcolor" iPX Control Bit - Set screen color based on number of passed stations "cbdump" iPX Control Bit - Dump the CB area from the NAND "cberase" iPX Control Bit - Erase a control bit "cbinit" iPX Control Bit - Initialize control bit area "cbread" iPX Control Bit Read "cbreadall" iPX Control Bit - read all "cbwrite" iPX Control Bit Write "charge" Charge controls for system "chipid" Show ChipID "clkmon" [signal/off]; Set Clock Test out pin to specified signal or switch it off "consoleformat" Command to control the formatting of text display on serial output mediums like the console "consolerouter" Main command that deals with all things console in the system "consolesinkctrl" Manage the console sink controls "cp" cp [-r] <source> ... <dest> "debug" Turns on/off global debug levels in the system "device" Interfaces with a devices of the system. "dfufile" Use dfu protocol to transfer file. "directory" DirDev [*match]; directory listing of dirdev. opt match a substring "DisCfg#" Display CFG systemcfg "DisOpts" Display OPTS systemcfg "display" Command to control display "displayid" Get the display ID "displaytext" Display text on the unit's screen "dt" Provide access to the device tree structure "dumpmemmap" Dumps memory map "dwi" backlight test using DWI "event" Signal EFI event groups "filelog" Log formatted console output to a file "getnonce" iPX Control Bit - generate a salt value for control-bit write authentication "getvol" Gets volume information/values from the various audio blocks "gps" Command to test/control GPS functionality "hash" compute Hash "help" [cmd]; Help on cmd or a list of all commands if cmd is ommited "hid" Command for the hid controllers/sensors "i2c" generic read/write to I2C device "key" Read buttons' status from AP side and PMU side "legal" Outputs the copyright for any libraries used by Diags. "loopaudio" Plays/Record full-duplex audio out/in through selected 'playable' and 'recordable' ports on an audio block "lua" lua [options] [script [args]] "mbt" Menu Button Test "memcat" Read memory into file or a file into memory "memory" Memory Utilities [--info] | [--list] | [--leak] | [--dump] <address> <length> "memrw" Read/write/or/and from memory "menu" Navigate menu items in Display "meta" [cmd]; Execute cmd as if it was entered at the shell (useful for scripting) "mipi" Command to interact with mipi "mkdir" mkdir <directory_name> ... "nand" Command to test nand functionality "nandcsid" Read Nand Chip ID and detect ID mismatch "nandppnfwver" Prints the PPN Firmware version for all populated CE's "nandsize" Nand testing "nanduid" Read Unique ID from each Nand die "network" Command to control network interface "nvram" Print or modify NVRAM variables "pattern" [--iqc [#]|--dqe [#]|--fatp [#]|--other [#]|--fill [rgb #] --list will List available displays --pick <name> will Pick Display name [n]:Test LCD display pattern[n] "pcie" qucik pcie test "physaddr" Decodes a physical address into bank/column/row/etc "playaudio" Plays audio out through a selected 'playable' port "pmuadc" PMU ADC Command for Calibration/Reading/Listing Channels "pmubutton" pmu button test "pmuevent" [all|chipid|btn|vbus|chgr|gpio|misc|temp|fault|ouv|clear] "pmugpio" Set a PMU GPIO to a certain state "pmureg" Print the values of all the pmu registers "pmurw" generic read/write to PMU Registers "pmuset" set the buck and ldo voltages value "pmustat" [all|chipid|btn|vbus|chgr|gpio|misc|temp|fault] "pmutemp" PMU TEMP test "processaudio" Post-processes audio data using various audio filters registered in the system "profile" Turns profiling on/off, dumps data, and resets profiling data. "qrbarcode" Command for showing the QRbarcode "quit" Quit EBL "ramlog" Command to manage the ramlog console sink which can be used for logging text to RAM for timing sensitive issues "recordaudio" Records audio in through a selected 'recordable' port "reset" Resets the system "rm" rm [-f] <path> ... "rmdir" rmdir <directory_name> ... "routeaudio" Sets up audio routing. "rtc" Set or get the RTC from PMU "script" [filename]; Execute the commands in the specified file "sensor" General command that interfaces with the various sensors in the system "sensorreg" General command that allows for reading/writing sensor chipset registers "sep" Manipulate the SEP "setvol" Sets volume levels within the various audio blocks "shutdown" Wait until the unit is unplugged then go to standby "signal" Measure Signal Jitter, Period "sleep" Set system to specified sleep state "smash" Memory smasher "smokey" EFI diag scripting sequencer "smokeyshell" EFI diag scripting sequencer debug shell "sn" Read/Write serial number "soc" Command for displaying SoC info "socgpio" Set a GPIO to a certain state "spi" Test Spi buses "spkid" Return 1 bit Speaker ID "stockholm" Command to control/test stockholm functionality "stopaudio" Stop audio out through a selected 'playable/recordable' port "strobe" Command to control the Strobe on the System "syscfg" [init | add | print | list | type | delete] <KEY> <value1> <value2> ...; System Config "sysinfo" Dumps system information "system" Command to display basic information about the unit "tag" Turns tagging of data on/off. "temperature" Control Settings and Dump Readings from various Temperature Sensors in the System "testCDMADDR" CDMA DDR test "testmemory" Run data and address patterns to exercise DRAM subsystem "testmp" boot up second core for simple tests "thermalmonitor" Command to control/test thermal functionality "touch" Command for the Touch subsystem "tristar" TriStar test commands "uartloopback" Perform a loopback test on the specified uart. Note that you will have to put the chip into loopback mode using separate commands. "uartpassthrough" pass through uart traffic from dock uart to select uart "uartrx" Receive and store message from uart <uart #>. It will send the message back to uart <uart #> when a <ExitString> is detected. "uarttx" send message to the selected uart "usbfs" Enables/Disables UsbFS (Filesystem-over-USB) "usbp" Test USB Present "version" Diag Version "wait" [ms]; Wait ms milliseconds "wakeevent" Select wake event for wakeup for PMU STANDBY or Hibernate mode "wakeeventsmanager" Command to control wakeevents in the system "wfi" Enable/Disable the wfi feature "wifi" Command to control/test wifi functionality "writefile" Write text to a file "zerofile" Zero the contents of an existing file 

كما ترون ، وظيفة برنامج تصحيح الأخطاء كبيرة إلى حد ما. الغرض منه هو في المقام الأول لاختبار المعدات - معظم الفرق هي المسؤولة عن اختبار النظم الفرعية المختلفة للجهاز. كانت أكثر الأوامر فائدة بالنسبة لنا هي الدليل و memrw والذاكرة والقط .


من خلال تنفيذ أمر الدليل ، يمكنك التعرف على محتويات نظام الملفات:


 [00011442:2885E526] :-) dir fs0: --------- <DIR> 2016-08-29 07:01 AppleInternal --------- <DIR> 2016-09-22 11:27 System --------- <DIR> 2016-09-22 11:29 private --------- <DIR> 2016-09-22 11:28 usr 

عن طريق تشغيل cat -h ، يمكنك قراءة أي ملف:


ملف قراءة النتيجة
 [00011442:2885E526] :-) cat -h fs0:\AppleInternal\Diags\Logs\Smokey\Shared\ComponentLib\HallSensor\11A\HallSensor.lua 00000000: 2D 2D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D |--==============| 00000010: 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D |================| 00000020: 3D 3D 3D 3D 3D 3D 3D 3D 3D 0A 2D 2D 20 46 69 6C |=========.-- Fil| 00000030: 65 6E 61 6D 65 3A 20 20 48 61 6C 6C 53 65 6E 73 |ename: HallSens| 00000040: 6F 72 2E 6C 75 61 0A 2D 2D 20 44 65 73 63 72 69 |or.lua.-- Descri| 00000050: 70 74 69 6F 6E 3A 20 48 61 6C 6C 53 65 6E 73 6F |ption: HallSenso| 00000060: 72 20 74 65 73 74 20 66 69 6C 65 0A 2D 2D 3D 3D |r test file.--==| 00000070: 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D |================| 00000080: 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D 3D |================| 00000090: 3D 3D 3D 3D 3D 0A 0A 72 65 71 75 69 72 65 20 22 |=====..require "| 000000A0: 43 6F 6D 70 6F 6E 65 6E 74 4C 69 62 2E 43 6F 6D |ComponentLib.Com| 000000B0: 6D 6F 6E 2E 31 31 41 22 0A 0A 6C 6F 63 61 6C 20 |mon.11A"..local | 000000C0: 43 4F 4D 50 4F 4E 45 4E 54 5F 4E 41 4D 45 20 3D |COMPONENT_NAME =| 000000D0: 20 22 48 61 6C 6C 53 65 6E 73 6F 72 22 0A 0A 2D | "HallSensor"..-| 000000E0: 2D 20 48 61 6C 6C 73 65 6E 73 6F 72 20 74 65 73 |- Hallsensor tes| 000000F0: 74 0A 66 75 6E 63 74 69 6F 6E 20 48 61 6C 6C 53 |t.function HallS| 00000100: 65 6E 73 6F 72 54 65 73 74 73 28 29 0A 09 53 51 |ensorTests()..SQ| 00000110: 41 5F 53 68 65 6C 6C 28 22 68 61 6C 6C 73 65 6E |A_Shell("hallsen| 00000120: 73 6F 72 20 2D 2D 6D 65 61 73 20 22 2E 2E 48 41 |sor --meas "..HA| 00000130: 4C 4C 5F 53 45 4E 53 4F 52 5F 4D 45 41 53 2E 2E |LL_SENSOR_MEAS..| 00000140: 22 20 2D 2D 64 65 6C 61 79 20 22 2E 2E 48 41 4C |" --delay "..HAL| 00000150: 4C 5F 53 45 4E 53 4F 52 5F 44 4C 59 29 0A 09 53 |L_SENSOR_DLY)..S| 00000160: 51 41 5F 53 68 65 6C 6C 28 22 68 61 6C 6C 73 65 |QA_Shell("hallse| 00000170: 6E 73 6F 72 20 2D 2D 69 72 71 69 6E 64 65 78 20 |nsor --irqindex | 00000180: 22 2E 2E 48 41 4C 4C 5F 53 45 4E 53 4F 52 5F 49 |"..HALL_SENSOR_I| 00000190: 52 51 5F 49 4E 44 45 58 29 0A 09 53 51 41 5F 53 |RQ_INDEX)..SQA_S| 000001A0: 68 65 6C 6C 28 22 68 61 6C 6C 73 65 6E 73 6F 72 |hell("hallsensor| 000001B0: 20 2D 2D 6F 66 66 20 20 22 29 0A 65 6E 64 0A 0A | --off ").end..| 

عند الجمع بين هذين الأمرين ، نقرأ جميع الملفات من الجهاز (حوالي 150 ميجابايت):


صورة


من بين الملفات كان هناك "بيض عيد الفصح" الذي يوصي بعدم المزاح معه Iphone7 بالنار:


صورة


عن طريق تشغيل أمر الذاكرة - تفريغ ، يمكنك قراءة نطاقات ذاكرة الوصول العشوائي:


 [00011442:2885E526] :-) memory --dump 0x800000000 0x100 0: 30 83 43 5B 39 16 04 49 4D 47 34 30 83 43 40 14 0.C[9..IMG40.C@ 10: 16 04 49 4D 34 50 16 04 64 69 61 67 16 01 31 04 .C@..".X..@.?.. 20: 83 43 40 00 80 22 00 58 01 04 40 F9 3F 00 00 F1 ..T?...@..T... 30: 20 05 00 54 3F 04 00 F1 40 00 00 54 FA 01 00 14 ....B...B...Bt 40: 02 00 80 D2 42 00 00 91 42 08 00 91 42 CC 74 D3 B...BlBBBp. 50: 42 08 04 91 42 AC 6C D3 42 C0 42 91 42 70 00 91 _...!..R....c.. 60: 5F 00 00 B9 21 00 80 52 03 00 80 D2 63 00 00 91 c...ctc..cl 70: 63 08 00 91 63 CC 74 D3 63 08 04 91 63 AC 6C D3 cBcP..a...... 80: 63 C0 42 91 63 50 00 91 61 00 00 B9 03 00 80 D2 c...c...ctc. 90: 63 00 00 91 63 08 00 91 63 CC 74 D3 63 08 04 91 clcBc@..... A0: 63 AC 6C D3 63 C0 42 91 63 40 00 91 7F 00 00 B9 ...RA.......... B0: 81 00 80 52 41 00 00 B9 7F 00 00 B9 00 00 00 14 @.............. C0: 40 03 00 00 00 00 00 00 B0 03 00 00 00 00 00 00 . ...O...?..... D0: 1F 20 03 D5 DF 4F 03 D5 DF 3F 03 D5 1F 87 08 D5 .?.. .;.!.....! E0: 9F 3F 03 D5 20 E2 3B D5 21 00 80 D2 00 00 21 8A .......a...<.@ F0: 20 E2 1B D5 9B F9 FF 10 61 06 00 10 3C 00 40 F9 z...Y.@........ 

أخيرًا ، باستخدام الأمر memrw ، يمكنك الكتابة فوق RAM:


 [00011442:2885E526] :-) memrw 0x800000000 0x12345678abcdef 0x800000000: 0x12345678ABCDEF OK [00011442:2885E526] :-) memory --dump 0x800000000 0x10 0: EF CD AB 78 56 34 12 00 4D 47 34 30 83 43 40 14 ...xV4..MG40.C@ 

على الرغم من أن قراءة الذاكرة تعد بالفعل مقياسًا للوظيفة المفيدة ، فقد قررنا التحقق: هل من الممكن الكتابة فوق مناطق من التعليمات البرمجية القابلة للتنفيذ وتشغيل شيء خاص بنا؟ بعد كل شيء ، iPhone هو تطوير ، وما زالت الوظيفة مخصصة - لن تعمل!


لم يكن من الممكن القيام بذلك بطرق قياسية ، حدث خطأ في سجل التتبع المفصل إلى حد ما:


سجل الاستثناء الذي حدث
 [00011442:2885E526] :-) memrw 0x87BF68AA0 0 panic: unhandled exception: 0 x0: 0x00000000 x1: 0x0000000A x2: 0x00000000 x3: 0x87BF68AA0 x4: 0x00000002 x5: 0x00000003 x6: 0x879D52218 x7: 0x00000003 x8: 0x87BF68E30 x9: 0x87BF6908C x10: 0x00000000 x11: 0x000000E0 x12: 0x000000E0 x13: 0x00000001 x14: 0x00000001 x15: 0x00000000 x16: 0x000000FF x17: 0x00000001 x18: 0x810000308 x19: 0x879D52228 x20: 0x00000008 x21: 0x00000000 x22: 0x87BF68AA0 x23: 0x00000007 x24: 0x00000001 x25: 0x87BF68AA0 x26: 0x00000000 x27: 0x00000002 x28: 0x87CA42332 fp: 0x87FBEFC20 lr: 0x87BF68D3C sp: 0x00000000 PC: 0x87BF68E30 SPSR: 0x80000005 ESR: 0x9600004F FAR: 0x87BF68AA0 EC:0x25 - "Data Abort caused by current EL" ISS:0x4F - "Permission Fault Level 3" Memory Access Fault - write to read-only or unmapped address. FAR contains target address. 0x87BF68AA0: /Users/build/archive/casaval_d10_202/src/shasta/BuildResults/D10diag/release/diag/TestDirectMemoryRW.macho + <0x4AA0> : text section stack buffer at 0x87FBEEED0 printing callstack: 15 frames unrolled. #0 0x87BF68E30 TestDirectMemoryRW.macho @ offset 0x4E30 #1 0x87BF68D38 TestDirectMemoryRW.macho @ offset 0x4D38 #2 0x87BF69620 TestDirectMemoryRW.macho @ offset 0x5620 #3 0x879B2C1D0 DiagShell.macho @ offset 0x41D0 #4 0x879B2C7F0 DiagShell.macho @ offset 0x47F0 #5 0x879B2D11C DiagShell.macho @ offset 0x511C #6 0x87FB75494 DxeMain.macho @ offset 0xD494 #7 0x87CAD8214 DiagBds.macho @ offset 0x4214 #8 0x87CAD8260 DiagBds.macho @ offset 0x4260 #9 0x87CAD82CC DiagBds.macho @ offset 0x42CC #10 0x87FB6C604 DxeMain.macho @ offset 0x4604 #11 0x87FB6C0F0 DxeMain.macho @ offset 0x40F0 #12 0x81034AA04 #13 0x81039C7E4 #14 0x81039C39C Please report panic using panic.apple.com hanging here... 

في هذه الحالة ، يقول سجل التتبع أنه عند التنفيذ في العنوان 0x87BF68E30 ، حدث استثناء في الوحدة النمطية TestDirectMemoryRW.macho بسبب الكتابة إلى عنوان الذاكرة للقراءة فقط . ولكن لا توجد حواجز أمام الباحثين التقنيين عشية رأس السنة الجديدة! لاحظ أحدث مكالمة على المكدس: DxeMain.macho . يسمح لنا وجود اختصار DXE وأوامر EDK Boot Loader الخطية باستنتاج أن الجهاز يعمل بنظام متوافق مع EFI. في الواقع ، يتم فتح diags.img4 صورة النظام بشكل صحيح باستخدام UEFITool :


صورة


أظهر تفكيك وحدات البرنامج أن جميع الوحدات القابلة للتنفيذ تستخدم اصطلاحات استدعاء EFI وهياكل EDK القياسية:


صورة


يتوافق كل أمر طرفي مع وحدة EFI منفصلة ، على سبيل المثال ، يتوافق أمر الذاكرة مع الوحدة النمطية TestUtilities.macho ، والتي يتم تحميلها في RAM عند 0x87BE10000 (يتم تحديدها من سجل التتبع).


دعونا نحاول تعديل رمز البرنامج في هذه الوحدة من أجل تنفيذ التعليمات البرمجية الخاصة بنا.


في العنوان 0x87BE1600D ، يوجد إخراج سلسلة نصية بواسطة أمر memory -info ، نقوم بتعديله:


 [00011442:2885E526] :-) memory --info Total Memory: 0x80000000, free: 0x79B48000, fragmented: 0x10028000, frags: 5, in use: 0x64B8000 [00011442:2885E526] :-) memory --dump 0x87BE1600D 0x30 7BE1600D: 54 6F 74 61 6C 20 4D 65 6D 6F 72 79 3A 20 30 78 Total Memory: 0 7BE1601D: 25 78 2C 20 66 72 65 65 3A 20 30 78 25 6C 78 2C fragmented: 0x 7BE1602D: 20 66 72 61 67 6D 65 6E 74 65 64 3A 20 30 78 25 x, frags: %d, i 

لتعديل مساحة الذاكرة التي نحتاجها ، نحتاج إلى تغيير حقوق الوصول إلى الصفحة على 0x87BE14000 من للقراءة فقط / التنفيذ إلى القراءة / الكتابة / التنفيذ . وفقًا لوثائق AArch64 ، يكون هناك جدول ترجمة خاص مسؤول عن حقوق الوصول. يجب أن يكون الجدول في ذاكرة الوصول العشوائي ويتكون من سجلات من 8 بايتات بالتنسيق التالي:


صورة


تم العثور على جدول ترجمة المستوى الثاني على 0x87FBF4000 ، في نطاق الذاكرة المتاح لإعادة كتابته. في هذا المستوى ، يتوافق كل إدخال مع 32 ميغابايت (0x2000000) من مساحة العنوان ، وبالتالي فإن السجل الذي نحتاجه للنطاق 0x87A000000-0x87BFFFFFF يقع في 0x87FBF4000 + (0x87A000000 / 0x2000000) * 8 = 0x87FBF61E8 :


 [00011442:2885E526] :-) memory --dump 0x87FBF61E8 0x8 7FBF61E8: 03 C0 CE 7F 08 00 00 00 

السجل من نوع الجدول ، أي أنه يشير إلى جدول ترجمة من المستوى الثالث على العنوان 0x87FCEC000 . في هذا الجدول ، يتوافق كل إدخال مع صفحة واحدة تبلغ 16 كيلوبايت (0x4000) من مساحة العنوان وهي من النوع " block" . السجل الذي نحتاجه للصفحة 0x87BE14000 يقع في 0x87FCEC000 + (0x87BE14000 - 0x87A000000) / 0x4000 * 8 = 0x87FCEFC28:


 [00011442:2885E526] :-) memory --dump 0x87FCEFC28 8 7FCEFC28: AB 47 E1 7B 08 00 00 00 .G.{....+..{..` 

نظرًا لأن هذا الإدخال من نوع block ، فإنه يشير إلى صفحة ذاكرة فعلية ويحتوي على سمات الوصول. نحن مهتمون بخصائص الكتلة السفلى ، وهي حقل بتات أذونات الوصول إلى البيانات:


صورة


للسماح بالكتابة إلى الصفحة ، قم بتعيين قيمة هذا الحقل إلى 0:


 [00011442:2885E526] :-) memrw 0x87FCEFC28 --64 0x000000087BE1472B 0x87FCEFC28: 0x87BE1472B OK 

بعد ذلك ، يجب أن يكون لدينا وصول للكتابة في المنطقة المطلوبة. بعد إجراء التغييرات المطلوبة ، نحصل على النتيجة المرجوة:


 [00011442:2885E526] :-) memrw 0x87BE16008 0x6C6548000A535341 0x87BE16008: 0x6C6548000A535341 OK [00011442:2885E526] :-) memrw 0x87BE16010 0x0072626148206F6C 0x87BE16010: 0x72626148206F6C OK [00011442:2885E526] :-) memory --info Hello Habr 

الأخلاقية: باستخدام الطريقة الموضحة ، يمكننا تعديل أي من تطبيقات النظام وتنفيذ تعليمات برمجية عشوائية في بيئة UEFI على تطوير iPhone.


لا يحمل هذا البحث قيمة عملية لإصدارات iPhone الأقدم ، ولكن كان من الممتع فرز شيء غير معروف ونادر ، خاصةً عندما ظهر فجأة كهدية للعام الجديد.


ملاحظة: ولكن لدراسة أحدث إصدارات iPhone والحصول على SecureROM ، قد تكون الطريقة الموضحة مفيدة: تم إصلاح ثغرة checkm8 فيها ، كما أن هناك "مبرمجين" مماثلين على AliExpress يستندون إلى iPhone XR و iPhone 11 معروضين للبيع بالفعل.



راكون سيكيوريتي هو فريق خاص من الخبراء في مركز فولكانو العلمي والتقني في مجال أمن المعلومات العملي ، والتشفير ، والدوائر ، والهندسة العكسية ، وإنشاء برامج منخفضة المستوى.

Source: https://habr.com/ru/post/ar482032/


All Articles