Skip to content
KitploitKITPLOIT
ToolsBlog
Log in
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2019-11932 — Technical write-up and exploit code for CVE-2019-11932, a double-free vulnerability in WhatsApp for Android that leads to remote code execution via a crafted GIF file. | Kitploit
Tools/GitHubGitHub/infiniteloopers/cve-2019-11932
Android SecurityVulnerability AnalysisExploitationMobile SecurityLearning & EducationBinary Exploitation
GitHubinfiniteloopers/cve-2019-11932

CVE-2019-11932

Technical write-up and exploit code for CVE-2019-11932, a double-free vulnerability in WhatsApp for Android that leads to remote code execution via a crafted GIF file.

View Repository
4296 years agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

CVE-2019-11932

How a double-free bug in WhatsApp turns to RCE

I’m going to share about a double-free vulnerability that I discovered in WhatsApp for Android, and how I turned it into an RCE. I informed this to Facebook. Facebook acknowledged and patched it officially in WhatsApp version 2.19.244. Facebook helped to reserve CVE-2019-11932 for this issue.

WhatsApp users, please do update to latest WhatsApp version (2.19.244 or above) to stay safe from this bug.

The steps are as below:

0:16 Attacker sends GIF file to user via any channels

One of them could be as Document via WhatsApp (i.e. pressing the Paper Clip button and choose Document to send the corrupted GIF) If the attacker is in the contact list of the user (i.e. a friend), the corrupted GIF is downloaded automatically without any user interaction.

0:24 User wants to send a media file to any of his/her WhatsApp friend. So the user presses on the Paper clip button and opens the WhatsApp Gallery to choose a media file to send to his friend.

Take note that the user does not have to send anything because just opening the WhatsApp Gallery will trigger the bug. No additional touch after pressing WhatsApp Gallery is necessary.

0:30 Since WhatsApp shows previews of every media (including the GIF file received), it will trigger the double-free bug and our RCE exploit.

Double-free vulnerability in DDGifSlurp in decoding.c in libpl_droidsonroids_gif

When a WhatsApp user opens Gallery view in WhatsApp to send a media file, WhatsApp parses it with a native library called libpl_droidsonroids_gif.so to generate the preview of the GIF file. libpl_droidsonroids_gif.so is an open-source library with source codes available at https://github.com/koral–/android-gif-drawable/tree/dev/android-gif-drawable/src/main/c.

A GIF file contains multiple encoded frames. To store the decoded frames, a buffer with name rasterBits is used. If all frames have the same size, rasterBits is re-used to store the decoded frames without re-allocation. However, rasterBits would be re-allocated if one of three conditions below is met:

width * height > originalWidth * originalHeight

width - originalWidth > 0

height - originalHeight > 0

Re-allocation is a combination of free and malloc. If the size of the re-allocation is 0, it is simply a free. Let say we have a GIF file that contains 3 frames that have sizes of 100, 0 and 0.

After the first re-allocation, we have info->rasterBits buffer of size 100.

In the second re-allocation of 0, info->rasterBits buffer is freed.

In the third re-allocation of 0, info->rasterBits is freed again.

This results in a double-free vulnerability. The triggering location can be found in decoding.c:

int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth; int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight; const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height; if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) { void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, <<-- double-free here sizeof(GifPixelType)); if (tmpRasterBits == NULL) { gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM; break; } info->rasterBits = tmpRasterBits; info->rasterSize = newRasterSize; }

How a double-free bug in WhatsApp turns to RCE 14 minute read ON THIS PAGE DEMO DOUBLE-FREE VULNERABILITY IN DDGIFSLURP IN DECODING.C IN LIBPL_DROIDSONROIDS_GIF CONTROLLING PC REGISTER DEAL WITH ASLR AND W^X PUTTING EVERYTHING TOGETHER AFFECTED VERSIONS ATTACK VECTORS In this blog post, I’m going to share about a double-free vulnerability that I discovered in WhatsApp for Android, and how I turned it into an RCE. I informed this to Facebook. Facebook acknowledged and patched it officially in WhatsApp version 2.19.244. Facebook helped to reserve CVE-2019-11932 for this issue.

WhatsApp users, please do update to latest WhatsApp version (2.19.244 or above) to stay safe from this bug.

Demo https://drive.google.com/file/d/1T-v5XG8yQuiPojeMpOAG6UGr2TYpocIj/view

Google Drive link to download if the above link is not accessible https://drive.google.com/open?id=1X9nBlf5oj5ef2UoYGOfusjxAiow8nKEK

The steps are as below:

0:16 Attacker sends GIF file to user via any channels One of them could be as Document via WhatsApp (i.e. pressing the Paper Clip button and choose Document to send the corrupted GIF) If the attacker is in the contact list of the user (i.e. a friend), the corrupted GIF is downloaded automatically without any user interaction. 0:24 User wants to send a media file to any of his/her WhatsApp friend. So the user presses on the Paper clip button and opens the WhatsApp Gallery to choose a media file to send to his friend. Take note that the user does not have to send anything because just opening the WhatsApp Gallery will trigger the bug. No additional touch after pressing WhatsApp Gallery is necessary. 0:30 Since WhatsApp shows previews of every media (including the GIF file received), it will trigger the double-free bug and our RCE exploit. Double-free vulnerability in DDGifSlurp in decoding.c in libpl_droidsonroids_gif When a WhatsApp user opens Gallery view in WhatsApp to send a media file, WhatsApp parses it with a native library called libpl_droidsonroids_gif.so to generate the preview of the GIF file. libpl_droidsonroids_gif.so is an open-source library with source codes available at https://github.com/koral–/android-gif-drawable/tree/dev/android-gif-drawable/src/main/c.

A GIF file contains multiple encoded frames. To store the decoded frames, a buffer with name rasterBits is used. If all frames have the same size, rasterBits is re-used to store the decoded frames without re-allocation. However, rasterBits would be re-allocated if one of three conditions below is met:

width * height > originalWidth * originalHeight width - originalWidth > 0 height - originalHeight > 0 Re-allocation is a combination of free and malloc. If the size of the re-allocation is 0, it is simply a free. Let say we have a GIF file that contains 3 frames that have sizes of 100, 0 and 0.

After the first re-allocation, we have info->rasterBits buffer of size 100. In the second re-allocation of 0, info->rasterBits buffer is freed. In the third re-allocation of 0, info->rasterBits is freed again. This results in a double-free vulnerability. The triggering location can be found in decoding.c:

int_fast32_t widthOverflow = gifFilePtr->Image.Width - info->originalWidth; int_fast32_t heightOverflow = gifFilePtr->Image.Height - info->originalHeight; const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height; if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) { void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, <<-- double-free here sizeof(GifPixelType)); if (tmpRasterBits == NULL) { gifFilePtr->Error = D_GIF_ERR_NOT_ENOUGH_MEM; break; } info->rasterBits = tmpRasterBits; info->rasterSize = newRasterSize; }

In Android, a double-free of a memory with size N leads to two subsequent memory-allocation of size N returning the same address.

(lldb) expr int $foo = (int) malloc(112) (lldb) p/x $foo (int) $14 = 0xd379b250

(lldb) p (int)free($foo) (int) $15 = 0

(lldb) p (int)free($foo) (int) $16 = 0

(lldb) p/x (int)malloc(12) (int) $17 = 0xd200c350

(lldb) p/x (int)malloc(96) (int) $18 = 0xe272afc0

(lldb) p/x (int)malloc(180) (int) $19 = 0xd37c30c0

(lldb) p/x (int)malloc(112) (int) $20 = 0xd379b250

(lldb) p/x (int)malloc(112) (int) $21 = 0xd379b250

Download Tool