A Deep Dive Into an NSO Zero-Click iMessage Exploit

A deep dive into an NSO zero-click iMessage manipulate Remote Code Implementation

No, We wish to thank Citizen Lab for sharing a sample of the FORCED ENTRY make use of with us, and Apple’s Protection Engineering as well as Architecture (SEAR) group for collaborating with us on the technological analysis. The content opinions mirrored below are solely Project No’s and do not always show those of the companies we teamed up with throughout this research study.

Previously this year, Citizen Lab managed to record an NSO iMessage-based zero-click exploit being used to target a Saudi activist. In this two-part article series, we will explain for the very first time just how an in-the-wild zero-click iMessage makes use of jobs.

Based upon our research and also findings, we assess this to be among one of the most technically sophisticated exploits we have actually ever before seen, additionally showing that the capacities NSO supplies rival those previously believed to come to just a handful of country states.

The vulnerability discussed in this post was fixed on September 13, 2021, in iPhone 14.8 as CVE-2021-30860.


NSO Team is just one of the highest-profile companies of “access-as-a-service”, marketing packaged hacking options which make it possible for nation-state actors without a home-grown offensive cyber capacity to “pay-to-play”, significantly broadening the variety of nations with such cyber capabilities.

For many years, groups like Citizen Laboratory and also Amnesty International has actually been tracking using NSO’s mobile spyware bundle “Pegasus”. Despite NSO’s claims that they” [evaluate] the possibility for negative human rights impacts arising from the abuse of NSO products” Pegasus has actually been linked to the hacking of the New York Times journalist Ben Hubbard by the Saudi regime, hacking of civil rights defenders in Morocco as well as Bahrain, the targeting of Amnesty International staff as well as lots of other instances.

Last month the USA added NSO to the “Entity List”, severely restricting the capacity of US companies to do company with NSO and mentioning in a press release that” [NSO’s devices] made it possible for foreign federal governments to perform global suppression, which is the method of authoritarian federal governments targeting objectors, journalists and also protestors outside of their sovereign boundaries to silence dissent.”

Resident Laboratory was able to recuperate these Pegasus makes use of from an iPhone and consequently, this evaluation covers NSO’s capabilities against iPhone. We are aware that NSO markets similar zero-click capacities which target Android gadgets; Project Zero does not have samples of these exploits however if you do, please connect.

From One to Zero

In previous situations such as the Million Dollar Dissident from 2016, targets were sent links in SMS messages:

Screenshots of Phishing SMSs reported to Resident Laboratory in 2016 resource: https://citizenlab.ca/2016/08/million-dollar-dissident-iphone-zero-day-nso-group-uae/

The target was only hacked when they clicked the link, a technique known as a one-click exploit. Recently, nonetheless, it has actually been recorded that NSO is using their customer’s zero-click exploitation modern technology, where even extremely technically smart targets who might not click a phishing link are entirely not aware they are being targeted. In the zero-click situation, no individual interaction is called for. Meaning, the enemy does not require to send out phishing messages; the manipulate just functions quietly in the background. Short of not utilizing a tool, there is no other way to stop exploitation by a zero-click manipulation; it’s a tool against which there is no protection.

One weird trick

The preliminary entrance factor for Pegasus on iPhone is iMessage. This implies that a target can be targeted simply utilizing their contact number or AppleID username.

iMessage has native assistance for GIF images, the typically tiny as well as low-quality computer-animated images popular in meme society. You can send out as well as obtain GIFs in iMessage talks and also they appear in the conversation home window. Apple wanted to make those GIFs loophole endlessly as opposed to just play once, so extremely early on in the iMessage parsing and also processing pipe (after a message has been received however well prior to the message is shown), iMessage calls the following technique in the IMTranscoderAgent process (outside the “BlastDoor” sandbox), passing any photo data obtained with the extension.gif:

[IMGIFUtils copyGifFromPath: to destination path: mistake]

Considering the selector name, the intent right here was probably to simply duplicate the GIF file before editing and enhancing the loop matter area, however, the semiotics of this approach are various. Under the hood, it makes use of the CoreGraphics APIs to render the source image to new GIF documents at the destination path. As well as even if the source filename has to finish in.gif, that does not imply it’s really a GIF document.

The ImageIO collection, as outlined in a previous Project Zero blog post, is utilized to presume the right layout of the source file as well as parse it, totally ignoring the data extension. Utilizing this “phony gif” technique, over 20 image codecs are all of a sudden part of the iMessage zero-click strike surface, consisting of some really obscure as well as complex formats, from another location revealing most likely hundreds of hundreds of lines of code.

Note: Apple educate us that they have restricted the readily available ImageIO styles obtainable from IMTranscoderAgent beginning in iOS 14.8.1 (26 October 2021), and also entirely removed the GIF code course from IMTranscoderAgent beginning in iPhone 15.0 (20 September 2021), with GIF deciphering happening completely within BlastDoor.

A PDF in your GIF

NSO uses the “fake gif” trick to target a vulnerability in the CoreGraphics PDF parser.

PDF was a preferred target for exploitation around a decade earlier, because of its universality and also complexity. And also, the availability of javascript inside PDFs made the development of dependable exploits much simpler. The CoreGraphics PDF parser doesn’t appear to translate javascript, but NSO managed to find something equally effective inside the CoreGraphics PDF parser…

Extreme compression

In the late 1990s, transmission capacity and storage space were a lot more limited than they are now. It remained in that setting that the JBIG2 conventional emerged. JBIG2 is a domain-specific image codec developed to compress images where pixels can only be black or white.

It was established to attain incredibly high compression ratios for scans of message records as well as was implemented and made use of in premium workplace scanner/printer devices like the XEROX WorkCenter gadget shown below. If you used the check to pdf performance of a device similar to this a decade ago, your PDF likely had a JBIG2 stream in it.

A Xerox WorkCentre 7500 series multifunction printer, which made use of JBIG2 for its scan-to-pdf performance resource: https://www.office.xerox.com/en-us/multifunction-printers/workcentre-7545-7556/specifications

The PDF documents produced by those scanners were exceptionally small, perhaps just a couple of kilobytes. There are two novel techniques that JBIG2 uses to accomplish these severe compression proportions which pertain to this exploit:

Technique 1: Segmentation and also Substitution

Successfully every text record, particularly those written in languages with little alphabets like English or German, includes numerous repeated letters (additionally referred to as glyphs) on each web page. JBIG2 tries to segment each page right into glyphs then utilizes simple pattern matching to pair up glyphs that look the same:

Straightforward pattern matching can locate all the forms which look similar on a page, in this situation all the ‘e’s.

JBIG2 does not actually recognize anything concerning glyphs and it isn’t doing optical character recognition (optical character recognition.) A JBIG encoder is just looking for linked regions of pixels as well as organizing similar-looking regions together. The compression formula is to merely replace all sufficiently-similar-looking areas with a duplicate of just one of them:

Changing all incidents of comparable glyphs with a copy of simply one frequently yields a document that is still quite understandable and enables really high compression proportions.

In this situation, the outcome is completely legible however the amount of information to be kept is substantially decreased. Rather than requiring to keep all the initial pixel details for the entire web page you only need a pressed version of the “recommendation glyph” for each character and the family member works with of all the locations where copies should be made. The decompression algorithm after that treats the result web page as a canvas and also “draws” the precise very same glyph in all the stored places.

There’s a significant issue with such a system: it’s far also easy for a poor encoder to accidentally switch comparable looking characters, and this can happen with interesting repercussions. D. Kriesel’s blog site has some encouraging instances where PDFs of scanned billings have different numbers or PDFs of checked construction illustrations wind up with incorrect dimensions. These aren’t the problems we’re checking out, but they are one considerable reason why JBIG2 is not a common compression style any longer.

Method 2: Refinement coding.

As discussed over, the substitution-based compression result is lossy. After a round of compression as well as decompression the provided output does not look specifically like the input. However, JBIG2 additionally supports lossless compression as well as an intermediate “much less lossy” compression setting.

It does this by likewise storing (as well as compressing) the difference between the replaced glyph as well as each original glyph. Right here’s an instance showing a difference mask between a substituted character left-wing as well as the original lossless character in the middle:

Utilizing the XOR driver on bitmaps to compute a distinction image.

In this simple instance, the encoder can save the difference mask shown on the right, then throughout decompression, the difference mask can be XORed with the substituted personality to recoup the specific pixels comprising the original personality. There are even more methods beyond the range of this blog post to more compress that difference mask utilizing the intermediate kinds of the replaced character as a “context” for the compression.

Rather than totally inscribing the whole distinction in one go, it can be performed in actions, with each iteration using a logical driver (among as well as, OR, XOR or XNOR) to set, clear, or flip little bits. Each succeeding improvement action brings the rendered output closer to the original as well as this allows a level of control over the “lossiness” of the compression. The application of these improvement coding steps is extremely adaptable and they are likewise able to “review” values already existing on the outcome canvas.

A JBIG2 stream

The majority of the CoreGraphics PDF decoder appears to be Apple-exclusive code, however, the JBIG2 application is from Xpdf, the resource code for which is freely offered.

The JBIG2 layout is a series of sections, which can be considered a collection of attracting commands which are executed sequentially in a single pass. The CoreGraphics JBIG2 parser supports 19 different section types that include operations like specifying a new page, decoding a Huffman table, or providing a bitmap to provide coordinates on the page.

Sections are represented by the course JBIG2Segment and its subdivisions JBIG2Bitmap as well as JBIG2SymbolDict.

A JBIG2Bitmap stands for a rectangle-shaped array of pixels. Its data area points to a backing buffer consisting of the providing canvas.

A JBIG2SymbolDict teams JBIG2Bitmaps with each other. The destination page is stood for as JBIG2Bitmap, as are private glyphs.

JBIG2Segments can be described by a section number as well as the GList vector kind shops pointers to all the JBIG2Segments. To search for a section by section number the GList is scanned sequentially.

The Vulnerability

The vulnerability is a traditional integer overflow when collecting referenced segments:

Guint numSyms; // (1)

  numSyms = 0;

  for (i = 0; i < nRefSegs; ++i) {

    if ((seg = findSegment(refSegs[i]))) {

      if (seg->getType() == jbig2SegSymbolDict) {

        numSyms += ((JBIG2SymbolDict *)seg)->getSize();  // (2)

      } else if (seg->getType() == jbig2SegCodeTable) {



    } else {

      error(errSyntaxError, getPos(),

            “Invalid segment reference in JBIG2 text region”);

      delete codeTables;




  // get the symbol bitmaps

  syms = (JBIG2Bitmap **)gmallocn(numSyms, sizeof(JBIG2Bitmap *)); // (3)

  kk = 0;

  for (i = 0; i < nRefSegs; ++i) {

    if ((seg = findSegment(refSegs[i]))) {

      if (seg->getType() == jbig2SegSymbolDict) {

        symbolDict = (JBIG2SymbolDict *)seg;

        for (k = 0; k < symbolDict->getSize(); ++k) {

          syms[kk++] = symbolDict->getBitmap(k); // (4)





numSyms is a 32-bit integer stated at (1 ). By supplying thoroughly crafted recommendation sections it’s feasible for the repeated enhancement at (2) to create numSyms to overflow to a regulated, small worth.

That smaller-sized value is used for the load allocation dimension at (3) indicating syms indicate a small barrier.

Inside the inner-most loop at (4) JBIG2Bitmap guideline worths are written into the undersized syms buffer.

Without an additional trick, this loophole would certainly edit 32GB of data into the small syms buffer, definitely causing an accident. To prevent that accident the stack is groomed such that the first couple of writes off of completion of the syms buffer corrupt the GList support buffer. This GList stores all well-known sections and also is utilized by the findSegments routine to map from the segment numbers come on refSegs to JBIG2Segment reminders. The overflow causes the JBIG2Segment guidelines in the GList to be overwritten with JBIG2Bitmap reminders at (4 ).

Conveniently given that JBIG2Bitmap acquires from JBIG2Segment the seg- > getType() online phone call be successful also on gadgets where Pointer Verification is made it possible for (which is made use of to carry out a weak kind examine online calls) yet the returned type will now not be equal to jbig2SegSymbolDict, therefore, creating more composes at (4) to not be gotten to and also bounding the level of the memory corruption.

A streamlined view of the memory design when the lot overflow takes place shows the undersized buffer listed below the GList support barrier as well as the JBIG2Bitmap.

Boundless unbounding

Directly after the damaged segments GList, the enemy grooms the JBIG2Bitmap things which represents the current page (the place where present drawing commands provide).

JBIG2Bitmaps are basic wrappers around a backing buffer, keeping the buffer’s width and also height (in little bits) in addition to a line value that specifies the number of bytes are stored for each line.

The memory design of the JBIG2Bitmap object reveals the segnum, w, as well as line fields that are damaged throughout the overflow.

By meticulously structuring refSegs they can quit the overflow after writing precisely 3 more JBIG2Bitmap pointers after completion of the sectors GList barrier. This overwrites the vtable tip and the very first four areas of the JBIG2Bitmap standing for the existing page. As a result of the nature of the iPhone address space layout, these guidelines are very likely to be in the 2nd 4GB of digital memory, with addresses in between 0x100000000 and 0x1ffffffff. Considering that all iOS equipment is little-endian (meaning that the w and line fields are likely to be overwritten with 0x1– the most-significant fifty percent of a JBIG2Bitmap reminder) and the segNum and h areas are most likely to be overwritten with the least-significant half of such a guideline, a rather arbitrary worth depending upon heap format and ASLR someplace in between 0x100000 and 0xffffffff.

This provides the current location web page JBIG2Bitmap an unknown, but huge, worth for h. Since that h value is used for bounds examining and also is supposed to reflect the allocated size of the web page backing buffer, this has the impact of “unbounding” the attracting canvas. This means that succeeding JBIG2 section commands can read as well as write memory outside of the initial bounds of the web page backing buffer.

The stack bridegroom also places the present web page’s support barrier simply listed below the small syms barrier, such that when the web page JBIG2Bitmap is unbounded, it’s able to check out and compose its very own areas:


The memory design shows how the unbounded bitmap backing barrier has the ability to reference the JBIG2Bitmap object and change areas in it as it is located after the support buffer in memory.

By providing 4-byte bitmaps at the correct canvas coordinates they can contact all the areas of the page JBIG2Bitmap and also by very carefully choosing brand-new values for w, h and line, they can contact arbitrary offsets from the page support barrier.

Now it would certainly likewise be possible to contact approximate outright memory addresses if you recognized their offsets from the page support barrier. But exactly how to calculate those offsets? Thus far, this manipulate has proceeded in a way extremely comparable to a “canonical” scripting language manipulate which in Javascript could end up with an unbounded ArrayBuffer object with accessibility to memory. However, in those situations, the enemy has the capacity to run arbitrary Javascript which can undoubtedly be utilized to calculate offsets and perform arbitrary calculations. How do you do that in a single-pass image parser?

My other compression layout is Turing-complete!

As stated earlier, the sequence of actions that implement JBIG2 improvement is extremely adaptable. Improvement steps can reference both the result bitmap and any kind of previously created segments, along with providing output to either the present page or a segment. By carefully crafting the context-dependent part of the improvement decompression, it’s feasible to craft a series of segments where just the refinement mix drivers have any kind of result.

In practice this indicates it is possible to apply the AND, OR, XOR as well as XNOR sensible operators between memory areas at approximate offsets from the present web page’s JBIG2Bitmap support buffer. And because that has been unbounded … it’s possible to do those sensible operations on memory at arbitrary out-of-bounds offsets:

Also Read:- Beware! Public Phone Chargers New Hacking Hubs Around Delhi-NCR

The memory design shows how logical drivers can be applied out-of-bounds.

It’s when you take this to its most severe form that things begin to get actually fascinating. What if instead of operating on glyph-sized sub-rectangles you instead operated on solitary bits?

You can currently give as input a sequence of JBIG2 sector commands which apply a series of rational bit operations to apply to the page. As well as since the page buffer has been unbounded those little bit procedures can operate approximate memory.

With a bit of back-of-the-envelope jotting, you can persuade yourself that with just the available and also, OR, XOR as well as XNOR logical drivers you can as a matter of fact compute any determinable feature – the simplest proof being that you can produce a logical NOT operator by XORing with 1 and afterward placing an AND gateway before that to create a NAND gateway:

An as well as gateway linked to one input of an XOR entrance. The other XOR gate input is linked to the continuous worth 1 producing a NAND.

A NAND gateway is an instance of a global logic entrance; one from which all various other entrances can be built and also where a circuit can be developed to compute any determinable feature.

Practical circuits

JBIG2 doesn’t have scripting abilities, but when combined with a susceptibility, it does have the capability to emulate circuits of approximate reasoning gateways operating on approximate memory. So why not simply utilize that to build your very own computer architecture and also manuscript that !? That’s specifically what this makes use of does. Utilizing over 70,000 segment commands specifying sensible bit procedures, they specify a small computer architecture with functions such as registers and a full 64-bit adder and also comparator which they utilize to search memory and also execute arithmetic operations. It’s not as quick as Javascript, yet it’s basically computationally equivalent.

The bootstrapping procedures for the sandbox getaway manipulate are contacted operate on this logic circuit and the entire thing runs in this strange, emulated atmosphere developed out of a single decompression go through a JBIG2 stream. It’s rather unbelievable, and at the same time, pretty terrifying.

In a future message (presently being finished), we’ll take a look at specifically just how they get away with the IMTranscoderAgent sandbox. Ryan at 9:00 AM.

About Author

Leave a Reply

Your email address will not be published. Required fields are marked *

Open chat
Can we help you?