19.11.2016 Views

Technical Analysis of the Pegasus Exploits on iOS

eNQc3Ry

eNQc3Ry

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

eing called again, but <str<strong>on</strong>g>the</str<strong>on</strong>g> sec<strong>on</strong>d call will be given <str<strong>on</strong>g>the</str<strong>on</strong>g> vtable specified at <str<strong>on</strong>g>of</str<strong>on</strong>g>fset 0x08. This call<br />

kicks <str<strong>on</strong>g>of</str<strong>on</strong>g>f a series <str<strong>on</strong>g>of</str<strong>on</strong>g> subsequent calls that ultimately leads to a call to _copyin that replaces <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

getattr handlers for <str<strong>on</strong>g>the</str<strong>on</strong>g> real-time and battery clocks, as described in Establishing<br />

Read/Write/Execute Primitives <strong>on</strong> Previously Rooted Devices.<br />

Following <str<strong>on</strong>g>the</str<strong>on</strong>g> executi<strong>on</strong> <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> exploit, and if <str<strong>on</strong>g>the</str<strong>on</strong>g> victim’s ph<strong>on</strong>e is an “iPh<strong>on</strong>e4,1” model, <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

global variable c<strong>on</strong>trolling <str<strong>on</strong>g>the</str<strong>on</strong>g> 1000 threads generated previously is set to -1 in order to<br />

terminate <str<strong>on</strong>g>the</str<strong>on</strong>g> threads.<br />

To verify that <str<strong>on</strong>g>the</str<strong>on</strong>g> battery clock’s getattr handler is working as a kernel memory address<br />

reader, clock_get_attributes is called with <str<strong>on</strong>g>the</str<strong>on</strong>g> read locati<strong>on</strong> specified as <str<strong>on</strong>g>the</str<strong>on</strong>g> base<br />

address for <str<strong>on</strong>g>the</str<strong>on</strong>g> kernel. If <str<strong>on</strong>g>the</str<strong>on</strong>g> result from clock_get_attributes is not <str<strong>on</strong>g>the</str<strong>on</strong>g> magic value <str<strong>on</strong>g>of</str<strong>on</strong>g><br />

0xFEEDFACE, <str<strong>on</strong>g>the</str<strong>on</strong>g> attempt is made <strong>on</strong>ce more. A sec<strong>on</strong>d failure results in <str<strong>on</strong>g>the</str<strong>on</strong>g> assert callback<br />

being called and 32Stage2 terminating.<br />

Establishing Kernel Read/Write Primitives (64-Bit)<br />

The same underlying vulnerability is exploited in <str<strong>on</strong>g>the</str<strong>on</strong>g> 64-bit versi<strong>on</strong> <str<strong>on</strong>g>of</str<strong>on</strong>g> Stage 2. In principle, <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

exploit is structured in a very similar way. The primary difference is that <str<strong>on</strong>g>the</str<strong>on</strong>g> ultimate execute<br />

primitive is established by writing to <str<strong>on</strong>g>the</str<strong>on</strong>g> net.inet.ip.dummynet.extract_heap sysctl<br />

handler. The OSSerializer::serialize is used in a similar way as within 32Stage2.<br />

Arbitrary code executi<strong>on</strong> (through <str<strong>on</strong>g>the</str<strong>on</strong>g> executi<strong>on</strong> <str<strong>on</strong>g>of</str<strong>on</strong>g> arbitrary ROP chains) is <str<strong>on</strong>g>the</str<strong>on</strong>g>n achieved using<br />

<str<strong>on</strong>g>the</str<strong>on</strong>g> same mechanism described in Establishing Kernel Execute Primitive (32-Bit).<br />

Establishing a Kernel Execute Primitive (32-Bit)<br />

As explained previously in Installing Kernel Access Handlers <strong>on</strong> Rooted Devices, <str<strong>on</strong>g>the</str<strong>on</strong>g> real-time<br />

clock’s getattr handler points to OSSerializer::serialize, which allows <str<strong>on</strong>g>the</str<strong>on</strong>g> caller <str<strong>on</strong>g>of</str<strong>on</strong>g><br />

clock_get_attributes to pass a specially crafted structure to<br />

OSSerializer::serialize in order to execute instructi<strong>on</strong>s within kernel space. By virtue <str<strong>on</strong>g>of</str<strong>on</strong>g><br />

executing within kernel space, <str<strong>on</strong>g>the</str<strong>on</strong>g> userland 32Stage2 process must have a way <str<strong>on</strong>g>of</str<strong>on</strong>g> transferring<br />

data to <str<strong>on</strong>g>the</str<strong>on</strong>g> kernel address space in a reliable manner. 32Stage2 uses a clever quirk <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g><br />

pipe-created pipe set to accomplish this task.<br />

After establishing <str<strong>on</strong>g>the</str<strong>on</strong>g> battery clock’s new getattr handler as _bufattr_cpx, 32Stage2 has<br />

a reliable method for reading DWORDs from <str<strong>on</strong>g>the</str<strong>on</strong>g> kernel address space into userland. 32Stage2<br />

uses this functi<strong>on</strong>ality to find <str<strong>on</strong>g>the</str<strong>on</strong>g> addrperm value stored within <str<strong>on</strong>g>the</str<strong>on</strong>g> kernel. addrperm defines<br />

<str<strong>on</strong>g>the</str<strong>on</strong>g> <str<strong>on</strong>g>of</str<strong>on</strong>g>fset applied to <str<strong>on</strong>g>the</str<strong>on</strong>g> address from <str<strong>on</strong>g>the</str<strong>on</strong>g> kernel when passed to userland in order to obfuscate<br />

<str<strong>on</strong>g>the</str<strong>on</strong>g> true locati<strong>on</strong> <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> data in <str<strong>on</strong>g>the</str<strong>on</strong>g> kernel. By obtaining this value, it is possible to deobfuscate<br />

kernel addresses back to <str<strong>on</strong>g>the</str<strong>on</strong>g>ir real address values. 32Stage2 calls fstat <strong>on</strong> <str<strong>on</strong>g>the</str<strong>on</strong>g> read pipe<br />

from <str<strong>on</strong>g>the</str<strong>on</strong>g> generated pipe set and <str<strong>on</strong>g>the</str<strong>on</strong>g>n calculates <str<strong>on</strong>g>the</str<strong>on</strong>g> difference between <str<strong>on</strong>g>the</str<strong>on</strong>g> locati<strong>on</strong> <str<strong>on</strong>g>of</str<strong>on</strong>g> <str<strong>on</strong>g>the</str<strong>on</strong>g> stat<br />

Page 30

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!