

GitHub - bazad/xpc-string-leak: CVE-2018-4248: Out-of-bounds read in libxpc duri...
source link: https://github.com/bazad/xpc-string-leak
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

README.md
xpc-string-leak
xpc-string-leak is a proof-of-concept exploit for an out-of-bounds memory read in libxpc. This
exploit uses the vulnerability to read out-of-bounds heap memory from diagnosticd, an unsandboxed
root process with the task_for_pid-allow
entitlement.
The vulnerability: CVE-2018-4248
On macOS 10.13.5 and iOS 11.4, the function _xpc_string_deserialize
does not verify that the
deserialized string is of the proper length before creating an XPC string object with
_xpc_string_create
. This can lead to a heartbleed-style out-of-bounds heap read if the XPC string
is then serialized into another XPC message.
Here is the implementation of _xpc_string_deserialize
, decompiled using IDA:
OS_xpc_string *__fastcall _xpc_string_deserialize(OS_xpc_serializer *xserializer) { OS_xpc_string *xstring; // rbx@1 char *string; // rax@4 char *contents; // [rsp+8h] [rbp-18h]@1 size_t size; // [rsp+10h] [rbp-10h]@1 MAPDST xstring = 0LL; contents = 0LL; size = 0LL; if ( _xpc_string_get_wire_value(xserializer, (const char **)&contents, &size) ) { if ( contents[size - 1] || (string = _xpc_try_strdup(contents)) == 0LL ) { xstring = 0LL; } else { xstring = _xpc_string_create(string, size - 1); LOBYTE(xstring->flags) |= 1u; } } return xstring; }
_xpc_string_deserialize
first calls _xpc_string_get_wire_value
to retrieve a pointer to the
string data as well as the serialized size of the string, as reported by the string header.
_xpc_string_deserialize
then checks that the string has a null terminator at the end of its
reported size, but crucially does not check that there is no null terminator earlier in the data.
Finally, it creates a copy of the string on the heap and creates the OS_xpc_string
object using
_xpc_string_create
.
Here is the decompiled code for _xpc_string_create
:
OS_xpc_string *__fastcall _xpc_string_create(const char *string, size_t length) { OS_xpc_string *xstring; // rax@1 xstring = (OS_xpc_string *)_xpc_base_create(&OBJC_CLASS___OS_xpc_string, 16LL); if ( (((_DWORD)length + 4) & 0xFFFFFFFC) + 4 < length ) _xpc_api_misuse("Unreasonably large string"); xstring->wire_length = ((length + 4) & 0xFFFFFFFC) + 4; xstring->string = string; xstring->length = length; return xstring; }
_xpc_string_create
trusts the value of length supplied by _xpc_string_deserialize
and sets the
appropriate fields in the OS_xpc_string
object. At this point, the deserialized string may have a
length
field that is larger than the allocated string data.
Exploitation
Theoretically, this could be used to trigger memory corruption in services that get the length of
the string using xpc_string_get_length
, but this pattern seems to be uncommon. A less powerful
but more practical exploit strategy is to get the string to be re-serialized and sent back to us,
giving us a heartbleed-style window into the victim process's memory.
This is the implementation of _xpc_string_serialize
:
void __fastcall _xpc_string_serialize(OS_xpc_string *string, OS_xpc_serializer *serializer) { int type; // [rsp+8h] [rbp-18h]@1 int size; // [rsp+Ch] [rbp-14h]@1 type = *((_DWORD *)&OBJC_CLASS___OS_xpc_string + 10); _xpc_serializer_append(serializer, &type, 4uLL, 1, 0, 0); size = LODWORD(string->length) + 1; _xpc_serializer_append(serializer, &size, 4uLL, 1, 0, 0); _xpc_serializer_append(serializer, string->string, string->length + 1, 1, 0, 0); }
The OS_xpc_string
's length
parameter is trusted during serialization, meaning that many bytes
are read from the heap into the serialized message. If the deserialized string was shorter than its
reported length, the message will be filled with out-of-bounds heap data.
We're still limited to exploiting XPC services that reflect some part of the XPC message back to
the client, but this is much more common. For example, on macOS and iOS, diagnosticd is a promising
candidate that also happens to be unsandboxed, root, and has task_for_pid
privileges. Diagnosticd
is responsible for processing diagnostic messages (for example, messages generated by os_log
) and
streaming them to clients interested in receiving these messages. By registering to receive our own
diagnostic stream and then sending a diagnostic message with a shorter than expected string, we can
obtain a snapshot of some of the data in diagnosticd's heap, which can aid in getting code
execution in the process.
Usage
To build, run make
. See the top of the Makefile for various build options.
Run the exploit by specifying the size of the leak on the command line:
$ ./xpc-string-leak 0x40
0x2000000000000000 0xe00007ff39bf0992
0x00007fff56858570 0x00007fff7ed23d0e
0x0000000000000000 0x0000000000000000
0x00007fff7ed52be2 0x00007fff7ed29ed6
The leak size must be a multiple of 8 and at least 16.
License
The xpc-string-leak code is released into the public domain. As a courtesy I ask that if you reference or use any of this code you attribute it to me.
Timeline
I discovered this bug early in 2018 (January or February), but forgot to investigate it until May. I reported the issue to Apple on May 9, and it was assigned CVE-2018-4248 and patched in iOS 11.4.1 and macOS 10.13.6 on July 9.
Brandon Azad
Recommend
-
38
Impact CVSS v3.0 Severity and Metrics: Base Score:
-
36
Bounds.js Asynchronous boundary detection. 1KB, no dependencies. Demo . Why Whether you're lazy-loading images, implementing i...
-
27
Year in review: smart analytics makes leaps and bounds 2019-12-19adminGoogleCloud
-
10
The following discussion occured on the FPChat Slack (invite link) . It was pasted into a gist by Emily Pillmore . However, th...
-
15
Posted on July 13, 2020 by Troels Henriksen Futhark is supposed to be a safe programming language. This implies that risky operations, such as a[i] which indexes an array at some arbitrary index, should b...
-
6
References[1] Bargmann, V., D. Montgomery andJ. von Neumann: Solution of linear systems of high order. Report prepared under contract NORD 9596 with the Bureau of Ordnance, Navy Department, Institute for Advanced Study, 1946....
-
12
Member m-ou-se commented
-
5
Copy link Contributor FabianWolff com...
-
8
New issue Allow ~const bounds on trait assoc functions #88418
-
11
Facebook fined $18.6M over string of 2018 breaches of EU's GDPRNatasha LomasWed, March 16, 2022, 1:20 AM·8 min readFacebook's parent company, Meta, has been fined €17 millio...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK