Research by Dikla Barda & Gal Elbaz
As of 2021, WhatsApp is the most popular global mobile messenger app worldwide with approximately two billion monthly active users. It allows users to send text and voice messages, make voice and video calls, and share images, documents, user locations, and other content.
Check Point Research (CPR) recently revealed a new Out-Of-Bounds read-write vulnerability in the popular messaging application. The issue, which has been patched and remains theoretical, would have required complex steps and extensive user interaction in order to exploit, and could have allowed an attacker to read sensitive information from WhatsApp memory. WhatsApp confirmed that they saw no evidence of abuse related to this vulnerability.
The vulnerability related to the WhatsApp image filter functionality and was triggered when a user opened an attachment that contained a maliciously crafted image file, then tried to apply a filter, and then sent the image with the filter applied back to the attacker.
Following the process of coordinated disclosure, Check Point Research disclosed the findings to the WhatsApp team on November 10, 2020.
WhatsApp verified and acknowledged the security issue and developed a fix.
The fix is available since version 184.108.40.206. and has two new checks on the source image and filter image
Approximately 55 billion messages are sent daily over WhatsApp, with 4.5 billion photos and 1 billion videos shared per day.
We focused our research on the way WhatsApp processes and sends images.
We started with a few image types such as bmp, ico, gif, jpeg, and png, and used our AFL fuzzing lab at Check Point to generate malformed files.
The AFL fuzzer takes a set of input files and applies various modifications to them in a process called mutation. This generates a large set of modified files, which are then used as input in a target program. When the tested program crashes or hangs due to these crafted files, this might suggest the discovery of a new bug, possibly a security vulnerability.
Now that we had a set of inputs for our fuzzing target (“corpus”), we started to fuzz the interesting WhatsApp libraries.
During the process, we noticed that some of the images couldn’t be sent. We looked for other ways of using those images, and one of the operations we thought of was image filters.
An image filter is a process through which pixels of the original image are modified to achieve some visual effects (e.g. blur, sharpen, etc.). This makes filters a very promising candidate to cause a crash, as a lot of computations occur on the image file during the filter application, which involves reading the image contents, manipulating the pixel values, and writing data to a new destination image.
We found that switching between various filters on crafted GIF files indeed caused WhatsApp to crash.
Figure 1 :WhatsApp crash screenshot.
We connected the phone to our lab and captured the crash location using adb logcat:
11-08 13:45:00.382 5278 5278 F DEBUG : pid: 5099, tid: 5171, name: WhatsApp Worker >>> com.whatsapp <<<
11-08 13:45:00.382 5278 5278 F DEBUG : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x718e400000
11-08 13:45:00.382 5278 5278 F DEBUG : x0 0000000000000320 x1 0000000000000000 x2 000000718e3ff8c0 x3 00000071a11b47c0
11-08 13:45:00.382 5278 5278 F DEBUG : x4 000000718e3ff8c0 x5 0000000000000000 x6 0000000000000005 x7 0000000000000007
11-08 13:45:00.382 5278 5278 F DEBUG : x8 00000000000000e2 x9 0000000000000320 x10 0000000000000258 x11 0000000000000c80
11-08 13:45:00.382 5278 5278 F DEBUG : x12 000000000000001f x13 0000000000000150 x14 000000718e400000 x15 000000718e400000
11-08 13:45:00.382 5278 5278 F DEBUG : x16 00000000ff000000 x17 0000000000000000 x18 0000000000000003 x19 0000000000000005
11-08 13:45:00.382 5278 5278 F DEBUG : x20 0000000000000001 x21 00000071c3f77abc x22 0000000000000000 x23 00000071c3f78588
11-08 13:45:00.382 5278 5278 F DEBUG : x24 0000000012ce9e90 x25 0000000012d40828 x26 0000000013583220 x27 0000000012d46778
11-08 13:45:00.382 5278 5278 F DEBUG : x28 0000000012d46998 x29 00000071c3f77a90 x30 00000071c6dca1c8
11-08 13:45:00.382 5278 5278 F DEBUG : sp 00000071c3f77a00 pc 00000071c6dca258 pstate 0000000020000000
11-08 13:45:00.383 5278 5278 F DEBUG :
11-08 13:45:00.383 5278 5278 F DEBUG : backtrace:
11-08 13:45:00.383 5278 5278 F DEBUG : #00 pc 0000000000042258 /data/data/com.whatsapp/files/decompressed/libs.spk.zst/libwhatsapp.so
11-08 13:45:00.383 5278 5278 F DEBUG : #01 pc 00000000000421c4 /data/data/com.whatsapp/files/decompressed/libs.spk.zst/
11-08 13:45:00.383 5278 5278 F DEBUG : #02 pc 00000000005e4bf8 /data/app/com.whatsapp-LFoGvXqXx1IH1wEGoNLxrg==/oat/arm64/base.odex (offset 0x4e7000)
11-08 13:48:00.459 5290 5328 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x71b5200000 in tid 5328 (WhatsApp Worker)
11-08 13:48:01.073 5290 5328 F libc : crash_dump helper failed to exec
11-08 13:48:09.339 6005 6108 F libc : Fatal signal 11 (SIGSEGV), code 1, fault addr 0x71b5a00000 in tid 6108 (WhatsApp Worker)
11-08 13:48:09.402 6139 6139 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
After some reverse engineering to review the crashes we got from the fuzzer, we found an interesting crash that we identified as a memory corruption.
Before we continued our investigation we reported the issue to WhatsApp, which gave us a name for this vulnerability: CVE-2020-1910 Heap-Based out-of-bounds read and write.
What’s important about this issue is that given a very unique and complicated set of circumstances, it could have potentially led to the exposure of sensitive information from the WhatsApp application.
Now that we know we have Heap Based out of bounds read and write according to WhatsApp, we started to dig deeper.
We reverse-engineered the libwhatsapp.so library and used a debugger to analyze the root cause of the crash. We found that the vulnerability resides in a native function applyFilterIntoBuffer() in libwhatsapp.so library.
Figure 2: applyFilterIntoBuffer function.
The vulnerable function takes as input 3 AndroidBitmap objects:
- “src_jbitmap” – Represents the input image.
- “flt_jbitmap” – Represents the filter to apply.
- “dst_jbitmap” – Holds the result of the new image.
The vulnerable function first calls to “AndroidBitmap_getInfo” on the source and filter images to get the struct “AndroidBitmapInfo”.
The structure holds the following members: “width”, “height”, “stride” (number of bytes per row), “format” and “flags”.
The function iterates over the source image pixels, calculates new pixel values by applying the filter, and copies them into the destination buffer.
The iteration is performed in a way that causes the source and destination buffers to advance each time by “height” * 4, which represents the column size in bytes (line 55).
Figure 3: applyFilterIntoBuffer.
The problem is that both destination and source images are assumed to have the same dimensions and also the same format RGBA (meaning each pixel is stored as 4 bytes, hence the multiplication by 4).
However, there are no checks performed on the format of the source and destination images.
Therefore, when a maliciously crafted source image has only 1 byte per pixel, the function tries to read and copy 4 times the amount of the allocated source image buffer, which leads to an out-of-bounds memory access.
This is the crash we got in IDA, caused by the program trying to read from an unmapped memory region.
Figure 4: Crash screenshot from IDA.
WhatsApp introduced the fix in version 220.127.116.11 and disclosed it in their February Security Advisory update.
The fixed function has two new checks on the source image and filter image:
- Validates that the image format equals 1 (ANDROID_BITMAP_FORMAT_RGBA_8888). This means that both source and filter images must be in RGBA format.
- Validates image size by checking that the (stride*height)/4 equals width*height.
Because “stride” equals the number of bytes per pixel multiplied by width, the second check actually ensures that the image indeed has 4 bytes per pixel.
WhatsApp previously disclosed this bug within its February 2021 Security Advisory Report. WhatsApp has shared the following statement for us to include in this report:
“We regularly work with security researchers to improve the numerous ways WhatsApp protects people’s messages, and we appreciate the work that Check Point does to investigate every corner of our app. People should have no doubt that end-to-end encryption continues to work as intended and people’s messages remain safe and secure.
This report involves multiple steps a user would have needed to take and we have no reason to believe users would have been impacted by this bug. That said, even the most complex scenarios researchers identify can help increase security for users. As with any tech product, we recommend that users keep their apps and operating systems up to date, to download updates whenever they’re available, to report suspicious messages, and to reach out to us if they experience issues using WhatsApp.” – WhatsApp
Figure 5: WhatsApp Fix.