Lucene search

K
myhack58佚名MYHACK58:62201784623
HistoryMar 25, 2017 - 12:00 a.m.

Firefox an integer overflow leading to the mmap region is out of bounds write use-vulnerability warning-the black bar safety net

2017-03-2500:00:00
佚名
www.myhack58.com
37

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

0.01 Low

EPSS

Percentile

82.0%

This article will explore a very interesting Vulnerabilityβ€”CVE-2016-9066, a very simple but very interesting could lead to code execution Firefox vulnerability.
The code in the presence of an integer overflow vulnerability, leading to loading of mmap area bounds. There is an advantage of this method is that the JavaScript stack in the buffer back, and then overflow to its meta-data to create a false idle unit. Then the ArrayBuffer created instance is placed in another ArrayBuffer inline data. Then can arbitrarily modify the internal ArrayBuffer, generating arbitrary read and write. And can easily achieve code execution. The complete vulnerability report can be found here, this is for MacOS 10.11.6 on Firefox 48.0.1 were tested. Bugzilla bug report can be found here.
The Vulnerability
The following code is used to load the script tag of the data:
the result
nsScriptLoadHandler::TryDecodeRawData(const uint8_t* aData,
a uint32_t that aDataLength,
bool aEndOfStream)
{
int32_t srcLen = aDataLength;
const char* src = reinterpret_cast(aData);
int32_t dstLen;
nsresult rv =
mDecoder->a getmaxlength(src, srcLen, &dstLen);
NS_ENSURE_SUCCESS(rv, rv);
a uint32_t that haveRead = mBuffer. length();
a uint32_t that capacity = haveRead + dstLen;
if (! mBuffer. reserve(capacity)) {
return NS_ERROR_OUT_OF_MEMORY;
}
rv = mDecoder->Convert(src,
&srcLen,
mBuffer. begin() + haveRead,
&dstLen);
NS_ENSURE_SUCCESS(rv, rv);
haveRead += dstLen;
MOZ_ASSERT(haveRead
MOZ_ALWAYS_TRUE(mBuffer. resizeUninitialized(haveRead));
return NS_OK;
}
When new data from the server arrives, the code will be OnIncrementalData call. Here the bug is a simple integer overflow occurs when the server sends more than 4GB of data. In this case, the capacity will wrap around, and call mBuffer. reserve, but will not in any way modify the buffer. mDecode->Convert and then in the buffer at the end to write more than 8GB of data, the data in the browser is stored as a char16_t, which will consist of a mmap block is a common, very large mmap block support under the complete.
The patch is also very simple:
a uint32_t that haveRead = mBuffer. length();
- a uint32_t that capacity = haveRead + dstLen;
- if (! mBuffer. reserve(capacity)) {
+
+ CheckedInt capacity = haveRead;
+ capacity += dstLen;
+
+ if (! capacity. isValid() || ! mBuffer. reserve(capacity. value())) {
return NS_ERROR_OUT_OF_MEMORY;
}
First, look not so reliable. For example, it needs to send and to allocate multiple gigabytes of memory. However, we will see that the bug may in fact be very reliable use, and in my 2015 version of the MacBook Pro open on the page after about one minute to complete the vulnerability trigger. We will now first discuss how to use this bug in macOS on the pop-up a calculator, and then improve the exploit’s reliability, and use less bandwidth, we will use HTTP compression.
Exploit
#include
#include
const size_t MAP_SIZE = 0x100000; // 1 MB
int main()
{
char* chunk1 = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
char* chunk2 = mmap(NULL, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
printf(β€œchunk1: %p - %p\n”, chunk1, chunk1 + MAP_SIZE);
printf(β€œchunk2: %p - %p\n”, chunk2, chunk2 + MAP_SIZE);
return 0;
}
The above program prints a result, can tell us through a simple mmap, the mapping memory until there is space to be filled, and then through the mmap allocates a block of memory to allocate overflow buffer behind the things. To verify this, we will perform the following operations:
Load script(εŒ…ε« payload.js will cause overflow of the code) and some asynchronous execution of JavaScript code(code.js to perform the following step 3 and step 5)
When the browser requests the payload. js, let the server reply Content-Length for 0x100000001, but only the transmission data of the first 0xffffffff bytes
Then, let the JavaScript code to assign a plurality of large enough(1GBοΌ‰ArrayBuffers memory will not necessarily be used until it is actually written to the buffer
Let the webserver send the payload. js the remaining two bytes
Check each of the ArrayBuffer of the first few bytes, there is a should be included by the webserver to send the data
In order to achieve this, we will need to run in the browser the JavaScript code and theweb serverbetween some kind of synchronization primitive. For this reason, I’m on python’s asyncio library, the above has written a smallweb server

[1] [2] [3] [4] next

7.5 High

CVSS3

Attack Vector

NETWORK

Attack Complexity

LOW

Privileges Required

NONE

User Interaction

NONE

Scope

UNCHANGED

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

HIGH

CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

5 Medium

CVSS2

Access Vector

NETWORK

Access Complexity

LOW

Authentication

NONE

Confidentiality Impact

NONE

Integrity Impact

NONE

Availability Impact

PARTIAL

AV:N/AC:L/Au:N/C:N/I:N/A:P

0.01 Low

EPSS

Percentile

82.0%