Exploits & Vulnerabilities
Analyzing The ForcedEntry Zero-Click iPhone Exploit Used By Pegasus
Citizen Lab has released a report on a new iPhone threat dubbed ForcedEntry. This zero-click exploit seems to be able to circumvent Apple's BlastDoor security, and allow attackers access to a device without user interaction.
Citizen Lab has released a report detailing sophisticated iPhone exploits being used against nine Bahraini activists. The activists were reportedly hacked with the NSO Group’s Pegasus spyware using two zero-click iMessage exploits: Kismet, which was identified in 2020; and ForcedEntry, a new vulnerability that was identified in 2021. Zero-click attacks are labelled as sophisticated threats because unlike typical malware, they do not require user interaction to infect a device. The latter zero-click spyware is particularly notable because it can bypass security protections such as BlastDoor, which was designed by Apple to protect users against zero-click intrusions such as these.
According to Citizen Lab’s report, Kismet was used from July to September 2020 and was launched against devices running at least iOS 13.5.1 and 13.7. It was likely not effective against the iOS 14 update in September. Then, in February 2021, the NSO Group started deploying the zero-click exploit that managed to circumvent BlastDoor, which Citizen Lab calls ForcedEntry. Amnesty Tech, a global collective of digital rights advocates and security researchers, also observed zero-click iMessage exploit activity during this period and referred to it as Megalodon.
Diving into ForcedEntry
According to the report from Citizen Lab, when the ForcedEntry exploit was launched against the victim’s device, the device logs showed two types of crashes. The first crash apparently happened when invoking ImageIO’s functionality for rendering Adobe Photoshop PSD data.
Our analysis focuses on the second crash, which is detailed in Figure 1. This crash happened when invoking CoreGraphics’ functionality for decoding JBIG2-encoded data in a PDF file. This analysis is solely based on samples from Citizen Lab; no new samples were obtained.
From this crash log, we can deduce three interesting points: First, the zero-click attack is dependent on iMessage attachment parsing. Next, the slide of dyld_shared_cache is 0, which means all the system modules are loaded into a fixed address. Lastly, the crash point 0x181d6e228 is not the first place of vulnerability exploitation. We discuss the details of these conclusions in the following sections.
Root cause of CVE-2021-30860
The vulnerability is inside the function JBIG2Stream::readTextRegionSeg of CoreGraphics.framework The crash point 0x181d6e228 (as seen in box 3 in the preceding figure) is at line 161 of the function JBIG2Stream::readTextRegionSeg of the following screenshot:
First, it calculates the numSyms according to the JBIG2SymbolDict segment:
The type of numSyms is unsigned int, and the return type of function seg->getSize() is also unsigned int. Therefore, numSyms could be smaller than the size of one JBIG2Segment due to integer overflow. One example is numSyms=1=(0x80000000+0x80000001) < 0x80000000.
Then, it allocates the heap buffer syms, with the size numSyms * 8 :
Finally, it fills the syms with the value from bitmap:
The loop times are dependent on the JBIG2Segment size, which could be larger than the buffer syms size. This leads to the out-of-bounds write access for the heap buffer syms.
Looking at Apple’s fix
Apple patched the function in iOS 14.8:
We can see that Apple adds two new boundary checks (the red box in Figure 3), to avoid overflowing the syms buffer.
On the Pegasus spyware exploitation
Disabling ASLR
The dyld_shared_cache of version iOS 14.6 (18F72) was loaded into IDA Pro for static analysis, after which a surprising result emerged. We were able to go to the addresses on the call stack directly without rebasing the segment.
As deduced from the screenshot in Figure 1 (see box 2), the slide of dyld_shared_cache is 0. However, in common crash scenarios, these addresses should be in slide.
If the screenshot of the original crash log has not been modified, then the conclusion is worrying. It should be noted that Pegasus already disabled Address Space Layout Randomization (ASLR) before its exploitation.
Bypassing PAC
By inspecting the address 0x181d6e20c from Frame 1 of the call stack trace, we can see that register x0, the return value of function JBIG2Stream::findSegment, is a subclass of JBIG2Segment:
There are four kinds of subclasses that override the getType() virtual function, but the following code shows that they just return one of the enumerate values:
For example, JBIG2SymbolDict::getType just returns jbig2SegSymbolDict=1:
Therefore, the frame 1 should have called the virtual function seg->getType(). But in actuality, it was already subverted to the current function itself (frame 0).
This shows that the virtual functions table of the object JBIG2Segment had already been replaced, and the pointer authentication code (PAC) security feature was bypassed. This is significant because the PAC security mechanism was developed to help prevent zero-click hacking. This also shows that the crash point is not the first place of the vulnerability exploitation.
Conclusion and recommendations
From the view of attack technologies used, we can see that Pegasus is quite an advanced threat for iOS users. However, it seems that these attacks are being launched on very specific targets, rather than common users.
The information from the recent Pegasus attack is from the forensic analysis of Citizen Lab and Amnesty Tech, and we have not found Pegasus attack samples that are at large yet. We are actively searching and monitoring for these threats and will continue to share more details as our investigation continues.
Essentially, this attack is a very common file format parsing vulnerability. We previously discovered CVE-2020-9883, a vulnerability similar to ForcedEntry, which could be exploited to do the same as what Pegasus has done here. ForcedEntry’s key point is the exploit technology as it is still unknown how it is able to bypass the PAC and disable ASLR.
In the meantime, we strongly recommend updating your device to iOS 14.8. As stated previously, common iOS users are not the target for attacks using this spyware. However, there are simple security steps that users can take. For example, concerned users can block iMessages from unknown senders, while a more drastic step would be to disable the iMessage function completely in the device’s Preferences.