Monday, October 28, 2019

KTRW: The journey to build a debuggable iPhone

Posted by Brandon Azad, Project Zero

In my role here at Project Zero, I do not use some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tooling used by some external iOS security researchers, in particular development-fused iPhones with hardware debugging capabilities like JTAG enabled. I believe that access to such devices puts those who can obtain cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m at a significant advantage over researchers who can not or do not wish to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. Thus, early this year I decided I would try to find a way to build such a capability using regular iPhones you can buy at an Apple store. I identified iBoot and KTRR as primary areas for research, and spent several months looking for vulnerabilities.

On June 16th, I discovered that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 A11 SoC used in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone 8 and iPhone X has cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CoreSight External Debug registers enabled. Combined with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 capabilities I reversed from a proprietary debugging register called DBGWRAP, this is sufficient to debug cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CPU at any time during its operation, including during execution of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset vector after a core sleeps and before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU and KTRR have been re-enabled. By single-stepping execution of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset vector and modifying register state at key points, it is possible to skip MMU KTRR lockdown and remap protected kernel memory as writable. I used this capability to build a hardware-level single-step kernel debugger for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone X called KTRW that can be used with LLDB and IDA Pro and works with an off-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-shelf Lightning cable.

This research was conducted before @axi0mX released cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 checkm8 iOS SecureROM exploit and is independent of it.

The bootstrapping problem

Doing security research on iPhones is hard, and in my opinion, much harder than it needs to be. Apple has done an impressive job locking down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir devices, and while such security improvements are certainly welcome, it does mean that security researchers have to invest a lot of time and effort to create a viable research platform.

The need to maintain a research platform can create perverse incentives for well-intentioned security researchers. One common outcome is that researchers will hoard vulnerabilities, only reporting some while keeping cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest for bootstrapping. This is of course less than ideal, since some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se vulnerabilities could simultaneously be used as 0-days to attack users.

Alternatively, many security researchers are able to acquire development-fused iPhones with hardware debugging features (SWD, JTAG) enabled, allowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to debug cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main Application Processor (AP) and some peripherals like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Always On Processor (AOP) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Secure Enclave Processor (SEP). By halting execution in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bootloader, it is possible to patch cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel to disable security features before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel has even had a chance to run. This makes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se devices extremely useful for security research.

More recently, virtualization solutions have gained prominence in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iOS security research community. In principle, virtualization offers a way to conduct security testing on iOS without being subject to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware restrictions that prevent kernel modification. The caveat is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se products are often accessed over cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 web, which would mean that any experiments conducted on a virtualized device could in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory be visible to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 company providing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 service.

None of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se options sit well with me. I do not withhold security bugs, I do not use development-fused devices, and I do not feel it is appropriate for me to run sensitive experiments that could disclose potential iOS security vulnerabilities on third party servers. This puts me at a disadvantage relative to adversaries developing and deploying 0-day capabilities who may be using any or all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se strategies.

Thus, back in March, I decided it would be worthwhile to investigate whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r it was possible to create my own homebrewed development iPhone using only certified Apple parts.

KTRR and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r hardware mitigations

At cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 heart of what makes conducting security research on iOS difficult is a hardware mitigation called KTRR, which likely stands for Kernel Text Readonly Region. Siguza (@s1guza) has an excellent article on KTRR which I highly recommend reading.

Since Apple does not publish details about cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir hardware mitigations, it is hard to know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exact boundary of each mitigation. In this post I will try to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 terminology suggested in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public XNU sources, even though this differs from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 terms used in some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r articles.

In effect, KTRR is a stronger form of W^X protection, enforced over all memory accesses from EL1 and implemented in both cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory management unit (MMU) and in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory controller. (Apple's memory controller appears to be referred to as AMCC in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sources.) The MMUs and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC can each be programmed with a physical address range, respectively referred to as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR region and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC KTRR region. Each MMU ensures that writes to physical addresses within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR region and EL1 instruction fetches from addresses outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 region will generate a synchronous exception. Likewise, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC ensures that writes issued to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory controller for physical addresses inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC KTRR region will be discarded. In this way, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel locks down its executable code (and read-only data) so that it cannot be modified and new executable code cannot be injected.

In order to lock down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU, Apple has defined three new system registers: KTRR_LOWER_EL1, KTRR_UPPER_EL1, and KTRR_LOCK_EL1. KTRR_LOWER_EL1 and KTRR_UPPER_EL1 define cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 lower and upper bounds of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR region. KTRR_LOCK_EL1 is a lockdown register: once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value 1 has been written to it, all three registers are locked down and can no longer be modified (although cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y still lose cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir values on core reset, that is, after a core wakes from sleep).

Once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU has been enabled, it enforces that all memory writes to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR region and all instruction fetches at EL1 from outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 region will generate a synchronous exception. This means that regardless of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 permission bits specified in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 page tables, and regardless of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 configuration of any ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r system registers (including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 APRR registers), it is impossible to have memory that is both writable and executable, and it is impossible to change which memory is executable.

However, implementing KTRR in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU alone is not enough to ensure kernel code integrity. For example, DMA attacks and ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r attacks from peripherals would reach cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory controller without first passing through an MMU on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application processor. Thus, Apple had to bring KTRR to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC as well, with its own readonly region and lockdown registers accessible via memory-mapped I/O (MMIO).


This is a diagram showing the inteactions between memory, AMCC KTRR and the MMU KTRR regions. On an A11 device, the MMU KTRR region protects all kernel const data except __LAST.__pinst, for example __PRELINK_TEXT, __DATA_CONST, and __TEXT_EXEC are protected. Any writes to the MMU KTRR region and any instruction fetches from outside the MMU KTRR region fault. The AMCC KTRR region is the same as the MMU KTRR region, plus it includes __LAST.__pinst. Any writes to the AMCC KTRR region are discarded at the memory controller. The page tables live in __DATA_CONST, where they are protected by both KTRR regions. Privileged instructions like MSR TTBR1_EL1 reside in __LAST.__pinst and are only protected by the AMCC KTRR region.


This combination of implementing KTRR in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC makes it extremely effective. The MMU and AMCC KTRR regions protect all critical kernel resources, including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 page table root and page tables describing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 readonly region itself. Instructions which might be used to break KTRR have been moved to a special page, __LAST.__pinst, which is outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR range (making it non-executable) but inside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC KTRR range (making it non-writable). In particular, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are no executable copies of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 instruction MSR TTBR1_EL1, X0, which sets a new page table root for address translations for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's half of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address space, or of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 instruction MSR SCTLR_EL1, X0, which could be used to turn off cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU. (This last part is only true on A10 and A11; Apple added a new hardware mitigation on A12 that brings SCTLR_EL1 back into executable memory.)

In order to bypass KTRR and load new executable code, one would need to find a way to prevent cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR lockdown from occurring. However, this attack surface is incredibly slim: after a core wakes from sleep, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system will begin by executing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset vector, LowResetVectorBase, which programs and locks down cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR registers within cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first 100 instructions.

The goals for a research iPhone

So, now that we know what we're up against, what exactly are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 features I think would be most useful in a homebrewed research iPhone?

  1. The most important feature, but also cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardest to achieve, is that it should be possible to patch KTRR-protected kernel memory, and in particular to patch __TEXT_EXEC, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 segment that contains cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's executable code. If this were possible, it would cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n become easy to disable ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r mitigations (like codesigning) that make userspace security research difficult.
  2. It should be possible to perform single-step iOS kernel debugging. This would aid in runtime analysis of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel and make it easier to demonstrate incorrect behavior in a PoC for a vulnerability.
  3. It should not be tied to a specific version of iOS: that is, it should be possible to debug new kernel versions as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y come out, eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r by updating cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device normally or by chainloading an updated kernel.
  4. It should be usable with existing debugging tools. In particular, I wanted to be able to perform kernel debugging on a live, production-fused iPhone using LLDB and IDA Pro.
  5. It should be relatively easy to port to newer versions of iOS.

In fact, this research concept is nothing new. Goal 1 was partially demonstrated back in iOS 10.1.1, and goals 2 and 4 were demonstrated in iOS 11.1.2.

iOS 10.1.1: The Yalu KTRR bypass

Luca Todesco (@qwertyoruiopz) demonstrated a KTRR bypass for iOS 10.1.1 that remapped cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's __DATA_CONST segment, normally protected by KTRR, as writable. His technique relied on two components: one to gain code execution after reset and anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r to remap KTRR-protected memory.

First, Luca used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that writable data was being used in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset path (LowResetVectorBase, in osfmk/arm64/start.s) to gain code execution after every reset. This in and of itself was not a KTRR bypass, since KTRR had already been initialized and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU turned on at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 point at which he gained code execution. But it was useful for persisting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 true bypass so that it would be applied every time a core reset.

Second, an off-by-one error in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR lockdown code in LowResetVectorBase resulted in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 __LAST.__pinst page accidentally being included in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU KTRR region, meaning that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 instruction MSR TTBR1_EL1, X0 was left executable even after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU was turned on. To take advantage of this, Luca used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first capability to execute a ROP payload after each reset. This ROP payload would bypass KTRR by using that executable MSR instruction to set TTBR1_EL1 to a new page table base that remapped __DATA_CONST to new, writable physical pages.

The reason __TEXT_EXEC was left readonly is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bypass ran after KTRR was already initialized on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU: even though cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 page tables could be changed, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU still prevented any physical pages except cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 original ones protected by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRR AMCC region from being executed. Thus, it remained impossible to patch cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel's executable code.

iOS 11.1.2: Build your own iOS kernel debugger

The ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r precedent for this work came with iOS 11.1.2, when Ian Beer (@i41nbeer) released async_wake_ios_with_kdp, a single-step kernel debugger that worked with LLDB. You should absolutely read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 slides from his MOSEC 2018 talk "Build your own iOS kernel debugger", which explain in great detail how he accomplished this. I also recommend looking through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 source code, which is very well commented.

If you look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARMv8 Architecture Reference Manual (all quotes are from version E.a, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latest at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time of writing), Chapter D2 describes an interesting feature called "Aarch64 Self-hosted Debug":


Self-hosted debug supports debugging through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 generation and handling of debug exceptions, that are taken using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exception model described in Chapter D1 The AArch64 System Level Programmers' Model.
[...]
Within this chapter, debugger means that part of an operating system, or higher level of system software, that handles debug exceptions and programs cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Debug System registers.


Essentially, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 architecture allows an operating system to program special debug registers in order to act as a debugger, catching exceptions that occur when certain debug-related events are encountered. According to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 manual, relevant exception types include:

  1. Breakpoint instruction exceptions: Generated when a BRK instruction is executed.
  2. Breakpoint exceptions: Generated when a hardware breakpoint is hit.
  3. Watchpoint exceptions: Generated when a hardware watchpoint is hit.
  4. Software step exceptions: Generated after a software single-step operation completes.

If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug registers are configured properly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se events will be delivered as synchronous exceptions to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exception vector specified in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 register VBAR_EL1.

Under what circumstances will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se debug exceptions actually be generated and delivered?


The PE can only generate a particular debug exception when both:


  1. Debug exceptions are enabled from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current Exception level and Security state.

    See Enabling debug exceptions from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current Exception level on page D2-2405. Breakpoint Instruction exceptions are always enabled from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current Exception level and Security state.


  1. A debugger has enabled that particular debug exception.

    All of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug exceptions except for Breakpoint Instruction exceptions have an enable control contained in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MDSCR_EL1. See The debug exception enable controls on page D2-2402.


Reading through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 mentioned sections, we find that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following registers are relevant for enabling self-hosted debug:

  1. PSTATE: Process State. This is not a real register, but a collection of important processor state information. The relevant flags for debugging are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exception mask bits:
    1. D: Debug exception mask. When set, debug exceptions are suppressed. This field resets to 1 when an exception is taken.
    2. A , I, F: Asynchronous exception mask bits. These bits mask SError, IRQ, and FIQ interrupts, respectively.
  2. MDSCR_EL1: Monitor Debug System Control Register. This register holds cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 main debug configuration options.
    1. MDE: Monitor Debug Enable. Controls whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r breakpoint and watchpoint exceptions are enabled.
    2. KDE: Kernel Debug Enable. Enables cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel running at EL1 to catch its own debug exceptions.
  3. DBGBCR_EL1: Debug Breakpoint Control Register n, n = 0 - 15. These 16 registers control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 behavior of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware breakpoints.
  4. DBGBVR_EL1: Debug Breakpoint Value Register n, n = 0 - 15. These registers contain information to match cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual address at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding breakpoint should trigger.
  5. DBGWCR_EL1: Debug Watchpoint Control Register n, n = 0 - 15. These registers control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 behavior of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware watchpoints.
  6. DBGWVR_EL1: Debug Watchpoint Value Register n, n = 0 - 15. These registers contain information to match cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 virtual address at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding watchpoint should trigger.


Basically, Ian's debugger worked by finding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 appropriate system calls, Mach traps, and gadget sequences to set cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se registers to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 necessary values, thus enabling hardware breakpoints and allowing EL1 (kernel mode) to generate debug exceptions.

The final piece is catching those debug exceptions. Being able to trigger a kernel breakpoint exception is not of much use if we cannot somehow catch that exception, dump registers and memory, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n resume normal execution.

What Ian found is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exception handling function sleh_synchronous() (in osfmk/arm64/sleh.c) actually enters a deliberate infinite loop when it catches a breakpoint exception from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel:


void
sleh_synchronous(arm_context_t *context, uint32_t esr, vm_offset_t far)
{
    esr_exception_class_t   class = ESR_EC(esr);
    arm_saved_state_t       *state = &context->ss;
...
    switch (class) {
...
    case ESR_EC_BKPT_REG_MATCH_EL1:
        if (FSC_DEBUG_FAULT == ISS_SSDE_FSC(esr)) {
            kprintf("Hardware Breakpoint Debug exception from kernel.  Hanging here (by design).\n");
            for (;;);

            __unreachable_ok_push
            DebuggerCall(EXC_BREAKPOINT, &context->ss);
            break;
            __unreachable_ok_pop
        }
        panic("Unsupported Class %u event code. state=%p class=%u esr=%u far=%p",
              class, state, class, esr, (void *)far);
        assert(0); /* Unreachable */
        break;
...
    }
...
}


At cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 point at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 thread that generated cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 breakpoint exception enters that infinite loop, its register state at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exception will have been spilled to memory, making it possible to inspect and modify cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 register values. And finally, Ian was able to restart execution of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugged thread by waiting for it to be preempted while spinning in that loop and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n modifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 spilled state so that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 thread resumes execution at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 desired location.

Ian's async_wake kernel debugger was able to achieve two of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 goals mentioned above: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugger supported single-stepping and it worked with LLDB. This was certainly enough to make a useful research platform. However, Apple mitigated cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gadgets Ian used, meaning that I couldn't use his technique on more recent iOS versions. Ideally I wanted something that met all five goals: kernel patching, single-step debugging, support for any iOS version, compatibility with LLDB, and easy maintenance across iOS versions. For that, I turned to iBoot.

Researching iBoot

My initial goal was to find a vulnerability in iBoot that would allow me to boot a patched kernelcache. iBoot is Apple's second-stage bootloader on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone: it runs after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SecureROM and is responsible for loading cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernelcache, verifying its signature, and jumping to it. With code execution in iBoot, it is possible to boot a kernelcache that is patched to disable KTRR and enable debugging features.

There are two reasons why iBoot was a particularly attractive research target.

First, an iBoot bug easily checks cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 updateability box. With an iBoot bug, you could cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365oretically boot any kernelcache you want, allowing you to "upgrade" or "downgrade" cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iOS version arbitrarily. Even after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bug is fixed, iPhones with a vulnerable iBoot version should still be able to boot cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latest version of iOS with a patched kernel.

Second, an iBoot bug could make it possible to load a patched kernelcache even when no kernel vulnerabilities are known. Currently, in order to develop an iOS kernel research platform, you need to already have a kernel vulnerability. Unless you withhold bugs, this makes it difficult to analyze cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latest kernel version in which all known vulnerabilities have been fixed. However, if iBoot is your entry point, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n you do not need any kernel vulnerabilities to conduct research.

Ultimately, I did not end up finding any vulnerabilities in iBoot. That said, I believe such bugs exist, and it could be an interesting area for future research.

All paths lead to debug registers

Eventually, a number of things drew me away from iBoot and back to KTRR, and in particular to revisit cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 concept of debug registers:

  1. I had read somewhere (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exact source is lost to history) that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug registers Ian used in his iOS 11.1.2 kernel debugger (DBGBCR_EL1, etc.) were also accessible via a memory-mapped interface. If true, this would mean that using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se registers for single-step kernel debugging would probably be possible even after Apple mitigated cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 specific gadgets he used to initialize cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.
  2. Looking through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARMv8 Architecture Reference Manual's table of contents, I noticed that self-hosted debug (Chapter D2) is just one place where debugging is mentioned. In fact cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a whole section (Part H, Chapters H1 - H9) that is devoted to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r debugging interface called External Debug.
  3. In LowResetVectorBase, XNU's reset vector, this is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 very first instruction:

    // Unlock cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core for debugging
    msr             OSLAR_EL1, xzr
  4. At MOSEC 2019, Zhenyu Ning and Fengwei Zhang presented an interesting attack on Android platforms called Nailgun. The Nailgun attack abuses debug registers enabled on certain Android devices to break privilege barriers, for example by extracting fingerprint images stored in TrustZone protected memory.

Thus, debug registers were really on my mind when I finally decided to pay attention to what an odd panic message I had occasionally encountered in my experiments was telling me.

If you have ever played around on an iPhone and managed to get a core stuck in an infinite loop with interrupts disabled, you may have received a panic message that goes something like this:


"panicString" : "Attempting to forcibly halt cpu 1\ncpu 1 failed to halt with error -5: halt not supported for this configuration\nDebugger synchronization timed out; waited 10000000 nanoseconds\npanic(cpu 0 caller 0xfffffff00b5c96bc): \"WDT timeout: CPU 1 failed to respond\"@\/BuildRoot\/...


This message says that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 application processor's watchdog timer (WDT) timed out while waiting on CPU (core) 1. This happens when a core fails to check in with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AppleARMWatchDogTimer kext for several seconds.

But what caught my attention was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 panic string: "Attempting to forcibly halt cpu 1". Forcibly halting a CPU while it is running really sounds like some sort of CPU control register might be involved. And with an error string to grep for, I had a starting place.

Searching for this string in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 XNU sources, I found that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function DebuggerXCallEnter() (file osfmk/arm/model_dep.c) contained cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following interesting snippet:


for (cpu=0; cpu <= max_cpu; cpu++) {
...
    if (proceed_on_sync_failure) {
        paniclog_append_noflush("Attempting to forcibly halt cpu %d\n", cpu);
        dbgwrap_status_t halt_status = ml_dbgwrap_halt_cpu(cpu, 0);
        if (halt_status < 0)
            paniclog_append_noflush("cpu %d failed to halt with error %d: %s\n", cpu, halt_status, ml_dbgwrap_strerror(halt_status));
...
    }
...
}


A comment above DebuggerXCallEnter() states that this function is responsible for interrupting ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cores on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AP "so this core can run in a single-threaded context". This is what we are seeing in this for loop: cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function ml_dbgwrap_halt_cpu() seems to be cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 one that actually does cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 work to halt a specific core. And looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file osfmk/kern/debug.c, we can see that DebuggerXCallEnter() is indeed being called as part of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 panic path.

So, how does ml_dbgwrap_halt_cpu() actually halt a running CPU core? The implementation is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file osfmk/arm64/dbgwrap.c, which is just filled with interesting information.

Here is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implementation of ml_dbgwrap_halt_cpu():


dbgwrap_status_t
ml_dbgwrap_halt_cpu(int cpu_index, uint64_t timeout_ns)
{
    cpu_data_t *cdp = cpu_datap(cpu_index);
    if ((cdp == NULL) || (cdp->coresight_base[CORESIGHT_UTT] == 0))
        return DBGWRAP_ERR_UNSUPPORTED;
...
    volatile dbgwrap_reg_t *dbgWrapReg = (volatile dbgwrap_reg_t *)
            (cdp->coresight_base[CORESIGHT_UTT] + DBGWRAP_REG_OFFSET);

    if (ml_dbgwrap_cpu_is_halted(cpu_index))
        return DBGWRAP_WARN_ALREADY_HALTED;

    /* Clear all ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r writable bits besides dbgHalt; none of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365
     * power-down or reset bits must be set. */
    *dbgWrapReg = DBGWRAP_DBGHALT;
...
    else
        return DBGWRAP_SUCCESS;
}


This tells us a lot of tantalizing information! The cpu_datap() function retrieves a pointer to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 current core's cpu_data struct, so whatever cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 coresight_base array is, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is one for each AP core. Then, we see an assignment of some value derived from that array to a volatile variable called dbgWrapReg; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 name and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fact that it is declared volatile strongly suggest that dbgWrapReg is a pointer to some sort of MMIO, and reading and writing it will directly read and write a core-specific register. And cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 comment below suggests that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DBGWRAP register contains bits involved in halting, powering down, and resetting cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core.

But cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 real gem is a bit furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r down. Keep scrolling past ml_dbgwrap_halt_cpu() and you will find a fascinating function called ml_dbgwrap_halt_cpu_with_state():


dbgwrap_status_t
ml_dbgwrap_halt_cpu_with_state(int cpu_index, uint64_t timeout_ns,
        dbgwrap_thread_state_t *state)
{
    cpu_data_t *cdp = cpu_datap(cpu_index);
    if ((cdp == NULL) || (cdp->coresight_base[CORESIGHT_ED] == 0))
        return DBGWRAP_ERR_UNSUPPORTED;

    /* Ensure memory-mapped coresight registers can be written */
    *((volatile uint32_t *)(cdp->coresight_base[CORESIGHT_ED]
                + ARM_DEBUG_OFFSET_DBGLAR)) = ARM_DBG_LOCK_ACCESS_KEY;

    dbgwrap_status_t status = ml_dbgwrap_halt_cpu(cpu_index, timeout_ns);

    /* A core that is not fully powered (e.g. idling in wfi) can still be
     * halted; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 dbgwrap register and certain coresight registers such
     * EDPRSR are in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 always-on domain. However, EDSCR/EDITR are not in
     * cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 always-on domain and will generate a parity abort on read.
     * EDPRSR can be safely read in all cases, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 OS lock defaults to
     * being set but we clear it first thing, so use that to detect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365
     * offline state. */
    if (*((volatile uint32_t *)(cdp->coresight_base[CORESIGHT_ED]
                    + EDPRSR_REG_OFFSET)) & EDPRSR_OSLK) {
        bzero(state, sizeof(*state));
        return DBGWRAP_WARN_CPU_OFFLINE;
    }

    uint32_t instr;

    for (unsigned int i = 0;
            i < (sizeof(state->x) / sizeof(state->x[0])); ++i) {
        instr = (0xD51U << 20) | (2 << 19) | (3 << 16)
            | (4 << 8) | i; // msr DBGDTR0, x
        ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
        state->x[i] = ml_dbgwrap_read_dtr(cdp, timeout_ns, &status);
    }

    instr = (0xD51U << 20) | (2 << 19) | (3 << 16)
        | (4 << 8) | 29; // msr DBGDTR0, fp
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    state->fp = ml_dbgwrap_read_dtr(cdp, timeout_ns, &status);

    instr = (0xD51U << 20) | (2 << 19) | (3 << 16)
        | (4 << 8) | 30; // msr DBGDTR0, lr
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    state->lr = ml_dbgwrap_read_dtr(cdp, timeout_ns, &status);

    /* Stack pointer (x31) can't be used as a register operand for msr;
     * register 31 is treated as xzr racá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than sp when used as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365
     * transfer operand cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re.  Instead, load sp into a GPR we've already
     * saved off and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n store that register in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DTR.  I've chosen x18
     * as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 temporary GPR since it's reserved by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 arm64 ABI and unused
     * by xnu, so overwriting it poses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 least risk of causing trouble
     * for external debuggers. */

    instr = (0x91U << 24) | (31 << 5) | 18; // mov x18, sp
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    instr = (0xD51U << 20) | (2 << 19) | (3 << 16)
        | (4 << 8) | 18; // msr DBGDTR0, x18
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    state->sp = ml_dbgwrap_read_dtr(cdp, timeout_ns, &status);

    /* reading PC (e.g. through adr) is undefined in debug state.  Instead
     * use DLR_EL0, which contains PC at time of entry into debug state.*/

    instr = (0xD53U << 20) | (1 << 19) | (3 << 16) | (4 << 12)
        | (5 << 8) | (1 << 5) | 18; // mrs    x18, DLR_EL0
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    instr = (0xD51U << 20) | (2 << 19) | (3 << 16)
        | (4 << 8) | 18; // msr DBGDTR0, x18
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    state->pc = ml_dbgwrap_read_dtr(cdp, timeout_ns, &status);

    /* reading CPSR is undefined in debug state.  Instead use DSPSR_EL0,
     * which contains CPSR at time of entry into debug state.*/
    instr = (0xD53U << 20) | (1 << 19) | (3 << 16) | (4 << 12)
        | (5 << 8) | 18; // mrs    x18, DSPSR_EL0
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    instr = (0xD51U << 20) | (2 << 19) | (3 << 16)
        | (4 << 8) | 18; // msr DBGDTR0, x18
    ml_dbgwrap_stuff_instr(cdp, instr, timeout_ns, &status);
    state->cpsr = (uint32_t)ml_dbgwrap_read_dtr(cdp, timeout_ns, &status);

    return status;
}


What ml_dbgwrap_halt_cpu_with_state() appears to do is halt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 specified CPU core and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n retrieve its register state. That in and of itself is not remarkable. What is remarkable is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 way it does this.

In order to retrieve cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 values of registers on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 halted CPU core, this function actually forces cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 halted CPU to execute instructions that write cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 general-purpose register values to a special debug register called DBGDTR0. And cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se instructions are generated programmatically on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 fly, not preexisting instructions protected by KTRR.

What this means is that, at least in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ory, it might be possible to make a CPU core execute a KTRR-sensitive instruction like MSR TTBR1_EL1, X0 even if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are no copies of that instruction in KTRR-protected memory.

Digging deeper

My next step was to figure out what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se debug registers were, and if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were actually enabled.

A bit of research revealed that some of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registers mentioned in dbgwrap.c were related to an ARMv8 feature called External Debug and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug architecture into which it is embedded called CoreSight. Let's start with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 latter.




CoreSight is an on-chip infrastructure to support debugging via an external interface like JTAG or SWD. The CoreSight architecture is much too complex to explain here (and I barely understand it myself), so I refer interested readers to a few of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 resources I found helpful: an Arm webpage containing CoreSight documentation (including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CoreSight Architecture Specification), a blog post series on CoreSight debugging, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CoreSight SoC-400 Technical Reference Manual.

The external debug interface is much simpler to describe, and is documented in Part H of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARMv8 Architecture Reference Manual. Just like self-hosted debug provides debug exceptions which cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core to execute debugger code in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 exception vector, external debug provides debug events which cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core to enter debug state.

These are a few of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug events mentioned in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 manual:

  1. Exception catch debug event: An external debugger can program a core to generate an exception catch debug event every time cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core enters a particular exception level.
  2. Reset catch debug event: This event can be generated every time cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core resets and is about to execute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset vector.
  3. Breakpoint debug event: This event can be generated when a core hits a hardware breakpoint.
  4. Watchpoint debug event: This event can be generated when a core hits a hardware watchpoint.
  5. Halting step debug event: This event can be generated after a core completes executing an instruction as part of a single-step operation.

Once a debug event occurs, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core will halt and enter debug state, from where it can be manipulated by an external debugger. From cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 manual:


In external debug, debug events allow an external debugger to halt cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PE. The PE cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n enters Debug state. When cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PE is in Debug state:


  • It stops executing instructions from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 location indicated by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 program counter, and is instead controlled through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 external debug interface.
  • The Instruction Transfer Register, ITR, passes instructions to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PE to execute in Debug state.
  • The Debug Communications Channel, DCC, passes data between cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PE and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugger.

The PE cannot service any interrupts in Debug state.


The Instruction Transfer Register (ITR) and Debug Communications Channel (DCC) are respectively responsible for making cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 halted core execute instructions and transferring data from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 halted core to ml_dbgwrap_halt_cpu_with_state(). In order to read a register from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 halted core, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function ml_dbgwrap_stuff_instr() uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory-mapped ITR to supply cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 halted core with an instruction that moves cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 desired register value into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system register DBGDTR_EL0. From cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of DBGDTR_EL0 is read by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function ml_dbgwrap_read_dtr() using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory-mapped DCC registers DBGDTRRX_EL0 and DBGDTRTX_EL0.

Finding cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registers

The XNU code seems to suggest that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 external debug registers exist, but how do we find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m?

Tracing through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 XNU source, we find cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 function configure_coresight_registers() in osfmk/arm64/cpu.c:


static void
configure_coresight_registers(cpu_data_t *cdp)
{
...
    /*
     * ARMv8 coresight registers are optional. If cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree did not
     * provide cpu_regmap_paddr, assume that coresight registers are not
     * supported.
     */
    if (cdp->cpu_regmap_paddr) {
        for (i = 0; i < CORESIGHT_REGIONS; ++i) {
            /* Skip CTI; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se registers are debug-only (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are
             * not present on production hardware), and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is
             * at least one known Cyclone errata involving CTI
             * (rdar://12802966).  We have no known clients that
             * need cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel to unlock CTI, so it is safer
             * to avoid doing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 access.
             */
            if (i == CORESIGHT_CTI)
                continue;
            /* Skip debug-only registers on production chips */
            if (((i == CORESIGHT_ED) || (i == CORESIGHT_UTT))
                    && !coresight_debug_enabled)
                continue;

            if (!cdp->coresight_base[i]) {
                addr = cdp->cpu_regmap_paddr + CORESIGHT_OFFSET(i);
                cdp->coresight_base[i] = (vm_offset_t)
                        ml_io_map(addr, CORESIGHT_SIZE);
...
            }
...
        }
    }
}


This suggests that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CoreSight registers (external debug, cross-trigger interconnect (CTI), and something called UTT) are mapped at offsets from a fixed base address supplied in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iOS device tree.

The device tree is passed to XNU by iBoot and specifies parameters of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system's hardware, including cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical addresses of any special hardware registers used to interact with devices. In this case, by comparing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of cpu_regmap_paddr read at runtime, I learned that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base address of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CoreSight registers for CPU core n can be found in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree property cpus/cpu/reg-private. On my iPhone 8, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se addresses are 0x20810000 for core n.

Thus, assuming cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are enabled, all one would need to do in order to access cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 external debug registers is map physical address 0x20810000 (or whatever cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reg-private address is in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree) and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n read and write to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offsets (available in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 manual) corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registers.

Testing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug registers

So, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 registers used by ml_dbgwrap_halt_cpu_with_state() are documented in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARMv8 manual, and we know cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 base address at which cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are mapped, but that does not necessarily mean that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se features are implemented and accessible on production hardware. In order to find out, I needed to test whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication signals were on and whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug registers actually worked.

According to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 manual, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re should be an implementation-defined aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication interface for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 external debug features. When cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication signals are off, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 corresponding debug features are disabled; when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 signals are on, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug features are available.

To check which debug aucá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ntication signals are enabled, I read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 value of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 external debug register DBGAUTHSTATUS_EL1 at offset 0xfb8. The architecture provides four signals: SNID (Secure Non-Invasive Debug), SID (Secure Invasive Debug), NSNID (Non-Secure Non-Invasive Debug), and NSID (Non-Secure Invasive Debug). The debugging features we need to bypass KTRR rely on NSNID and NSID being enabled. Surprisingly, reading cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DBGAUTHSTATUS_EL1 register via MMIO produced 0xf, suggesting that both signals were in fact enabled.

So cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next step was to test whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r ml_dbgwrap_halt_cpu_with_state() could actually halt a core and execute instructions on it to read that core's register state. After modifying voucher_swap to map cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 CoreSight registers manually and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n call ml_dbgwrap_halt_cpu_with_state(), I saw cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 following output:


This screenshot shows an experiment trying to access the debug registers in Xcode. After mapping and initializing the debug registers, the function ml_dbgwrap_halt_cpu_with_state() was invoked on an iPhone 8 and the output copied to userspace and printed. The values in the registers look valid and correspond to a CPU executing at EL1 with the MMU off.


In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 output window, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 register values read by ml_dbgwrap_halt_cpu_with_state() look valid. Thus, it is entirely possible to execute dynamically-generated instructions on a halted CPU core on production A11 iPhones!

But what is even more remarkable from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above screenshot is that it appears that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core was halted while it was executing code from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset vector with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU off! The value of CPSR shows that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core is executing in kernel mode with interrupts disabled, and yet cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PC value 0x8042e4120 is not a normal kernel address. In fact, it is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 physical address corresponding to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unslid kernel virtual address 0xfffffff0070e4120, which is near cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 end of LowResetVectorBase (specifically, at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 instruction that loads cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 address of const_boot_args into X20 before verifying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset handler).

The reason this is remarkable is that it opens up anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r possible technique to bypass KTRR: given that we can halt a core and execute instructions on it before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU has been turned on, is it perhaps possible to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se debug registers to modify execution of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset vector itself to prevent KTRR from ever being enabled on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU?

More debugging features needed

Actually, even though we have proved that it is possible to execute instructions on a debugged core while cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU is off, this alone is not necessarily enough to bypass KTRR. For example, even though we can use DBGWRAP to halt a core, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ARMv8 external debug interface contains no mechanism to get a core out of debug state and resume normal execution (which is called restarting). Thus, I needed to find some ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r feature that would make cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se debugging registers useful.

The first thing I looked at was finding a useful instruction to execute on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugged core. Even though cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core will execute instructions written to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ITR, not all instructions are available in debug state. The ARMv8 manual specifies a list of instructions that are available, most of which are related to moving values between registers, accessing system registers, and loading and storing from memory. But even fewer are actually available on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 A11: for some reason, load and store instructions fail to execute in debug state.

Even so, most instructions that read and write system registers (MSR and MRS instructions) do work in debug state. Thus, anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r idea I investigated was whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re exists a system register shared between cores such that writing to it would change global state in some way that facilitates a KTRR bypass. However, without better knowledge of Apple's proprietary system registers, I was unable to find anything that worked.

Finally, I decided to turn back to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DBGWRAP register mentioned in dbgwrap.c. The comment in ml_dbgwrap_halt_cpu() suggests that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 register contains many different bits to control cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 behavior of a core, and yet only 2 bits (DBGHALT to halt a core and DBGACK to check if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core is halted) are defined in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 file. Thus, I suspected that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re might be ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r bits of interest and performed experiments to figure out what cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y might be.

As it turns out, DBGWRAP actually contains at least 3 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r, undocumented bits, all of which are extremely useful. Setting bit 29 will cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core to enter debug state cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 next time it resets and is about to execute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 reset vector. Setting bit 30 will cause cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core to restart, exiting debug state and resuming normal execution. And setting bit 26 seems to prevent cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core from resetting so long as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 phone is plugged in and active (i.e. not sleeping).

With that, we now have everything necessary to bypass KTRR.

Bypassing KTRR

This is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method I chose to disable KTRR on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU (repeated for each core):

  1. Using DBGWRAP, configure cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core to enter debug state next time it resets.
  2. Wait for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core to halt. Once it has halted, it is about to execute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first instruction of LowResetVectorBase. The KTRR registers will not yet be initialized.
  3. Using cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 external debug registers and DBGWRAP, repeatedly single-step execution of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core. On each step, read cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PC value on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugged core to determine cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 instruction about to be executed.
  4. Once cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core is about to execute cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRR initialization instructions, use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 external debug registers to overwrite values in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugged core's general purpose registers such that it skips KTRR initialization.
  5. Use DBGWRAP to restart cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 core, exiting out of debug state. KTRR will be disabled on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 MMU, meaning that it is now possible to execute memory outside cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRR readonly region.

With that, it is possible to set TTBR1_EL1 to a custom page table base and remap cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel onto fresh, writable physical pages outside of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 AMCC KTRR range.

KTRW

In order to make this functionality useful, I packaged cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRR bypass in an iOS kext loader and kernel debugger named KTRW. KTRW makes it possible to compile a C program into a Mach-O file and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n dynamically load and link cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 binary against cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 running kernel. The iOS kernel debugger implements a GDB stub accessible over USB.

Of course, KTRW (and in particular cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 GDB stub kext) is significantly more complicated than just cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRR bypass itself, and I encountered numerous interesting challenges that needed to be overcome (including writing a USB stack from scratch for undocumented hardware). However, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 KTRW source code should be reasonably well commented, so I refer interested readers cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re.

This particular KTRR bypass only works on A11 devices; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugging registers do not appear accessible on A12 devices, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y appear only partially functional on A9 (0x202010000) and A10 (0x202210000, which differs from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device tree). It is difficult to know for sure whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debugging registers are truly unusable on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r devices without greater insight into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hardware; cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y might work perfectly under some slight variation of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 setup I'm using or if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are first configured using some proprietary mechanism.

You can find KTRW on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Project Zero GitHub.

Is this a security vulnerability?

While this was reported to Apple as Project Zero issue 1900, neicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r Project Zero nor Apple considers cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 existence of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se debug registers a security vulnerability.

The reason is that in order to use cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se registers to bypass KTRR, one would already need to have a kernel arbitrary read/write capability, at which point cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device should be considered fully compromised anyway. Once an attacker has kernel read/write, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y have access to any data used by any app on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 system.

For evidence that kernel read/write is all an attacker needs in practice, I highly recommend reading Ian's phenomenal technical analysis of five in-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-wild iOS exploit chains, including his analysis of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant itself. He found that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attackers only used cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel read/write capability to launch cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant binary; after cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 implant has launched, it gets access to all cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data it exfiltrates using normal userspace APIs.

On research phones and SecureROM exploits

Apple announced at BlackHat 2019 that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are considering providing "research-fused" devices to security researchers. I genuinely hope that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y deliver on that promise soon (without requiring NDAs or ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r restrictions placed on security researchers like myself), as I personally believe that would be a tremendous step forward for open security research.

The presence of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 debug registers allow one to bypass KTRR and debug cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 kernel even in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 absence of a SecureROM vulnerability. In practice, however, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 publication of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 SecureROM exploit solves most of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 goals I listed for a research iPhone, and provides cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 added benefit of not needing a kernel vulnerability to do so. I expect future A11 research platforms to be based around that capability.

Conclusion

One of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 things I hoped to convey in this post is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 path to discovering this KTRR bypass was surprisingly straightforward. Considering Ian's prior work looking at self-hosted debug, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 extensive ARM documentation on external debug, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 public research on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Nailgun attack on Android, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 XNU sources practically spelling out how to execute dynamically generated instructions, I’m confident that I'm not cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first one to discover this issue.

My general fear is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 secrecy surrounding knowledge and techniques in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iOS security research community is allowing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 privately held state-of-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-art of security research to diverge from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 publicly shared state-of-cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365-art. If this happens, it puts defenders at a systemic disadvantage.

I suspect that KTRR bypasses (and this bypass in particular) are one example of this divergence. Having spoken with several members of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iOS research community, I believe knowledge of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se debug registers was widespread in certain circles. For example, Xerub (@xerub) presented a slide at MOSEC 2018 that hinted at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 surprising capabilities offered by debugging features. And Siguza hinted at a KTRR bypass in his blog post on APRR.

Furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rmore, I suspect that ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r KTRR bypass techniques have been privately discovered. This technique is not cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 only way to bypass KTRR, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are almost certainly techniques that still work on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 A12. And yet, researchers rarely if ever publicly admit that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se capabilities. All of which makes me wonder: what ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r techniques and capabilities are known only in private circles?

In making KTRW public, I want to facilitate security researchers like myself interested in understanding how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 iPhone works and improving its security, and hopefully narrow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 gap between publicly shared and privately held capabilities in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process. Those who acquire development-fused devices have access to troves of information that ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r researchers (who choose not to use such devices) do not have. Adversaries looking to harm iPhone users already have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se capabilities. Hopefully, with more eyes on iOS internals, we can continue to improve its security in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 long run.

No comments:

Post a Comment