SSD Advisory – iOS powerd Uninitialized Mach Message Reply to Sandbox Escape and Privilege Escalation

(This advisory follows up on a vulnerability provided in Hack2Win Extreme competition, that won the iOS Privilege Escalation category in our offensive security event in 2018 in Hong Kong – come join us at TyphoonCon – June 2019 in Seoul for more offensive security lectures and training)
Vulnerabilities Summary
The following advisory describes security bugs discovered in iOS’s powerd, which leads to arbitrary address read with unlimited amount of memory and an arbitrary address deallocation with arbitrary size, which can lead to Sandbox Escape and Privilege Escalation.
Vendor Response
“Power Management
Available for: iPhone 5s and later, iPad Air and later, and iPod touch 6th generation
Impact: A malicious application may be able to execute arbitrary code with system privileges
Description: Multiple input validation issues existed in MIG generated code. These issues were addressed with improved validation.
CVE-2019-8549: Mohamed Ghannam (@_simo36) of SSD Secure Disclosure (”
An independent Security Researcher, Mohamed Ghannam, has reported this vulnerability to SSD Secure Disclosure program.
Affected systems
iOS versions before 12.2.
Vulnerability Details
The powerd has its own MIG implementation, it’s based on _SC_CFMachPortCreateWithPort which is nothing more than a wrapper of CFMachPortCreateWithPort, it hosts a MIG callback called mig_server_callback(). This Callback is the main MIG resource handler which acts like mach_msg_server() in user-space or ipc_kmsg_server() in XNU kernel.
When powerd receives a Mach message, it allocates a reply message buffer via CFAllocatorAllocate with the default allocator and then later the reply message got partially initialized in pm_mig_demux().

We can notice that pm_mig_demux() doesn’t well initialize the reply buffer and only considers the message reply as Simple Mach Message and not a Complex Mach Message .
Unlike the MIG kernel, the MIG semantics in user-space (at least for powerd) is a bit different, the MIG routine takes the ownership of all passed objects (Mach ports, OOL memories and OOL ports), in case of failure, the MIG routine deallocates the appropriate object and returns KERN_SUCCESS (except for some few MIG routines which break this rule) which makes the MIG handler thinks that the routine returned successfully and took the ownership of all passed arguments. This is very important to understand because the bugs hugely rely on this logic.
Another important thing to mention, is that powerd uses retval parameters to store the real return value, this is kind of informing the client whether the Mach message request succeed or failed.

_io_pm_connection_copy_status() is a simple function which does nothing but returns KERN_SUCCESS, by looking to the MIG generated code, we can see that it has to reply with a complex message :

From the described above, we are obviously in front of an uninitialized OOL descriptor with full control of the address and size data members.
With some basic knowledge on how Mach IPC works, it’s possible to turn this into arbitrary code execution.
it’s worth noting that this bug does not cause any crash or a undefined behavior (unless the attacker filled memory with meaningful data), and will always returns success to the sender as we’ve seen earlier.
By controlling the uninitialized memory via spraying the heap, we could successfully fake the address and size members of mach_msg_ool_descriptor_t, thus we could reliably read an arbitrary memory address of powerd with unlimited amount of content.

Here we came across a problem, we cannot control an important member of mach_msg_ool_descriptor_t which is the .deallocate flag, if it is set to TRUE, the sender will directly deallocate the memory, otherwise, it won’t.
Unfortunately, _io_pm_connection_copy_status() sets .deallocate = FALSE, so we cannot make anything more than just reading powerd’s memory content.
We can make this bug more impcatful by finding a vulnerable function with .deallocate flag set to TRUE
After inspecting few MIG methods, we came across this MIG call:

If we can make sendData to be NULL, the method will jump into exit block and returns KERN_SUCCESS without initializing array_data and array_dataLen.
gHIDEventHistory is a global variable and we don’t have a direct control over it, after looking for a way of controlling it, it is safe to say that there is no direct way to make it invalid.
How can we make gHIDEventHistory invalid?
After inspecting powerd’s behavior, we came across this fact: if we will start a fresh powerd service process, gHIDEventHistory will still contain NULL and only after some time and via a MIG routine it will become a valid CFArray.
We came into this conclusion:
If we can force powerd to restart we can have gHIDEventHistory set to NULL which is sufficient to make sendData to NULL and trigger the bug shown above. In order to do this , we need another memory corruption to just make powerd crashe and Launchd has nothing to do but spawn a fresh powerd instance.
Here is a trivial bug NULL pointer dereference:

We can control details_ptr. If we will pass a malformed serialized data into IOCFUnserialize(), it will return NULL, and CFRelease() is called later within details_ptr without checking its value.
By testing out the primitive described above and combining the bugs together, we can turn this bug into Use-After-Deallocate. As an example, we can deallocate the CoreFoundation Library and reading its content with unlimited size:

And by deallocating such mandatory library, we would expect a random crash as follows:

Approach for exploitation
Once we have the two reliable primitives, we are in front of multiple ways to reach controlling the flow of the execution, in the exploit, we tried to do the following:
We have powersource objects which has a description CF object, this object can be updated by the attacker as he wishes if the current working powersource object has been created by himself.
We will send a very large CF Object with lots of CFData objects with some tagged values, and since we have a reliable primitive to read unlimited amount of memory from powerd, we can locate these objects and get the offset of one of the CFData objects. Later with the deallocation primitive, we will deallocate the located CFData object in page-aligned manner, and re-fill it with user controlled memory.
By sending multiple Mach OOL messages with .copy = MACH_PHYSICAL_COPY, otherwise, we can’t refill memory as we would like, since powerd MIG routines deallocate OOL descriptor in the end of each function, we can successfully control the ISA pointer of the CFData, and by releasing the target powersource->description, we get a PC control with X0 pointing to our controlled payload. And the exploitation becomes straightforward.
Source Code
You can find the full source code of the exploit here:
iOS powerd Uninitialized Mach Message Reply to Sandbox Escape and Privilege Escalation
The exploit that will be provided here, steals powerd’s task port using ROP/JOP chains as follow:


SSD Advisory – Firefox JavaScript Type Confusion RCE

Vulnerabilities Summary
A vulnerability in register allocation in JavaScript can lead to type confusion, allowing for an arbitrary read and write, which leads to remote code execution inside the sandboxed content process when triggered.
Vendor Response
The reported security vulnerability was fixed in Firefox 62.0.3 and Firefox ESR 60.2.2.
Independent security researchers, Niklas Baumstark, Samuel Groß and Bruno Keith, had reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program.

SSD Advisory – Firefox Information Leak

Vulnerabilities Summary
A vulnerability where the JavaScript JIT compiler inlines Array.prototype.push with multiple arguments that results in the stack pointer being off by 8 bytes after a bailout. This leaks a memory address to the calling function which can be used as part of an exploit inside the sandboxed content process.
Vendor Response
The security vulnerability was fixed in Firefox 62.0.3 and Firefox ESR 60.2.2
Independent security researchers, Bruno Keith and Niklas Baumstark, have reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program.

Hack2Win eXtreme Warm Up

Hack2Win eXtreme

In our upcoming Hack2Win eXtreme event in Hong Kong we will be asking contest participants to come and try their skills breaking into devices and software, showing their abilities in finding vulnerabilities in iOS and Android, as well as in Chrome and Firefox.
In preparation for the event, we are launching a “warm up” event where the target is different from the above devices and software. The event will be open to anyone who wants to participate, and will be open until the 19th of September (inclusive).
The target for this Hack2Win eXtreme warm-up will be Adobe Reader on Android, and the goal is to get it to run arbitrary code when a PDF file is opened.
An award prize of 30,000$ USD will be given to any person (up to 5 winners) that is able to provide a PDF file which is opened from either the local storage (on the Android device) or accessed through a URL being typed into a browser (Chrome, Firefox, etc), where that the PDF is able to:

  • Get code execution, which is able to do either:
    • Write an arbitrary file to the data folder of the Adobe Reader
    • Run /bin/bash – which should be visible when you run ‘ps’ on the Android OS

In addition, the vulnerability should be in Adobe Reader and not in some external application that can be launched from within Adobe Reader; it should not require any interaction beyond opening the file (e.g. clicking on popups or a confirmation dialog after the PDF is opened will not be considered a code execution vulnerability).
How to submit?
The submission process will be the same as any other vulnerability that being submitted to us, please refer to Submission Process page for more details.
Contest Deadline
Once we have reached the deadline (19th of September) or receive 5 valid submissions, we will no longer accept additional submissions. We will announce this on this blog page as well as on our @SecuriTeam_SSD twitter account.
The Hack2Win eXtreme is open for registration to anyone who is 18 years of age or older at the time of submission – excluding anyone working for Adobe. Also excluded are Beyond Security employees and any of its affiliates.
Winner Selection
The first 5 (five) submissions received will be selected, according to the email timestamp. Only complete and working submissions will be considered. If a submission does not work you will be asked to provide a working version – the submission date will be the date the working version was sent to Beyond Security.
Vulnerabilities and exploit techniques revealed by contest winners will be disclosed to Adobe and the exploits and whitepapers will be the property of Beyond Security. The original finder of the vulnerability will receive credit (or remain anonymous if he/she wishes to remain anonymous) for the vulnerabilities, the whitepaper and the disclosure.

SSD Advisory – Hack2Win – Cisco RV132W Multiple Vulnerabilities

Vulnerabilities Summary
The following advisory describes two (2) vulnerabilities found in Cisco RV132W Wireless N VPN version
The Cisco RV132W Wireless-N ADSL2+ VPN Router is “easy to use, set up, and deploy. This flexible router offers great performance and is suited for small or home offices (SOHO) and smaller deployments.”
The vulnerabilities found are:

  • Information Disclosure That Leads to Password Disclosure
  • Unauthenticated WAN Remote Code Execution

A security researcher from, NSHC, has reported this vulnerability to Beyond Security’s SecuriTeam Secure Disclosure program
Vendor response
Cisco were informed of the vulnerabilities and released patches to address them:
CVE: CVE-2018-0125 / CVE-2018-0127