Wednesday, December 12, 2018

Adventures in Video Conferencing Part 4: What Didn't Work Out with WhatsApp

Posted by Natalie Silvanovich, Project Zero

Not every attempt to find bugs is successful. When looking at WhatsApp, we spent a lot of time reviewing call signalling hoping to find a remote, interaction-less vulnerability. No such bugs were found. We are sharing our work with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 hopes of saving ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r researchers cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 time it took to go down this very long road. Or maybe it will give ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365rs ideas for vulnerabilities we didn’t find.

As discussed in Part 1, signalling is cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process through which video conferencing peers initiate a call. Usually, at least part of signalling occurs before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving peer answers cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call. This means that if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a vulnerability in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code that processes incoming signals before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call is answered, it does not require any user interaction.

WhatsApp implements signalling using a series of WhatsApp messages. Opening libwhatsapp.so in IDA, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are several native calls that handle incoming signalling messages.

Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOffer
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOfferAck
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallGroupInfo
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallRekeyRequest
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallFlowControl
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOfferReceipt
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallAcceptReceipt
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOfferAccept
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOfferPreAccept
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallVideoChanged
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallVideoChangedAck
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOfferReject
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallTerminate
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallTransport
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallRelayLatency
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallRelayElection
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallInterrupted
Java_com_whatsapp_voipcalling_Voip_nativeHandleCallMuted
Java_com_whatsapp_voipcalling_Voip_nativeHandleWebClientMessage

Using apktool to extract cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 WhatsApp APK, it appears cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se natives are called from a loop in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 com.whatsapp.voipcalling.Voip class. Looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 smali, it looks like signalling messages are sent as WhatsApp messages via cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 WhatsApp server, and this loop handles cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 incoming messages.

Immediately, I noticed that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re was a peer-to-peer encrypted portion of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message (cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 rest of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message is only encrypted peer-to-server). I thought this had cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 highest potential of reaching bugs, as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server would not be able to sanitize cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data. In order to be able to read and alter encrypted packets, I set up a remote server with a python script that opens a socket. Whenever this socket receives data, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 data is displayed on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 screen, and I have cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 option of eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r sending cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 unaltered packet or altering cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 packet before it is sent. I cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n looked for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 point in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 WhatsApp smali where messages are peer-to-peer encrypted.

Since WhatsApp uses libsignal for peer-to-peer encryption, I was able to find where messages are encrypted by matching log entries. I cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n added smali code that sends a packet with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bytes of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server I set up, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n replaces it with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 bytes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server returns (changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 size of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 byte array if necessary). This allowed me to view and alter cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peer-to-peer encrypted message. Making a call using this modified APK, I discovered that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peer-to-peer message was always exactly 24 bytes long, and appeared to be random. I suspected that this was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 encryption key used by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call, and confirmed this by looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 smali.

A single encryption key doesn’t have a lot of potential for malformed data to lead to bugs (I tried lengcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ning and shortening it to be safe, but got nothing but unexploitable null pointer issues), so I moved on to looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peer-to-server encrypted messages. Looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Voip loop in smali, it looked like cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 general flow is that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device receives an incoming message, it is deserialized and if it is of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 right type, it is forwarded to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messaging loop. Then certain properties are read from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message, and it is forwarded to a processing function based on its type. Then cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processing function reads even more properties, and calls one of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above native methods with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 properties as its parameters. Most of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se functions have more than 20 parameters.

Many of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se functions perform logging when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are called, so by making a test call, I could figure out which functions get called before a call is picked up. It turns out that during a normal incoming call, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device only receives an offer and calls Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOffer, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n spawns cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 incoming call screen in WhatsApp. All cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r signal types are not used until cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call is picked up.

An immediate question I had was whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r signal types are processed if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are received before a call is picked up. Just because cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 initiating device never sends cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se signal types before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call is picked up doesn’t mean cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving device wouldn’t process cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m if it received cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m.

Looking through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 APK smali, I found cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class com.whatsapp.voipcalling.VoiceService$DefaultSignalingCallback that has several methods like sendOffer and sendAccept that appeared to send cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages that are processed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se native calls. I changed sendOffer to call ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r send methods, like sendAccept instead of its normal messaging functionality. Trying this, I discovered that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Voip loop will process any signal type regardless of whecá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call has been answered. The native methods will cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n parse cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parameters, process cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m and put cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 results in a buffer, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n call a single method to process cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 buffer. It is only at that point processing will stop if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message is of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 wrong type.
I cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n reviewed all of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 above methods in IDA. The code was very conservatively written, and most needed checks were performed. However, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re were a few areas that potentially had bugs that I wanted to investigate more. I decided that changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parameters to calls in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 com.whatsapp.voipcalling.VoiceService$DefaultSignalingCallback was too slow to test cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 number of cases I wanted to test, and went looking for anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r way to alter cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages.

Ideally, I wanted a way to pass peer-to-server encrypted messages to my server before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were sent, so I could view and alter cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. I went through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 WhatsApp APK smali looking for a point after serialization but before encryption where I could add my smali function that sends and alters cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 packets. This was fairly difficult and time consuming, and I eventually put my smali in every method that wrote to a non-file ByteArrayOutputStream in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 com.whatsapp.protocol and com.whatsapp.messaging packages (about 10 total) and looked for where it got called. I figured out where it got called, and fixed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 class so that anywhere a byte array was written out from a stream, it got sent to my server, and removed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r calls. (If you’re following along at home, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 smali file I changed included cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 string “Double byte dictionary token out of range”, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 two methods I changed contained calls to toByteArray, and ended with invoking a protocol interface.) Looking at what got sent to my server, it seemed like a reasonably comprehensive collection of WhatsApp messages, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 signalling messages contained what I thought cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y would.

WhatsApp messages are in a compressed XMPP format. A lot of parsers have been written for reverse engineering this protocol, but I found cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 whatsapp-reveng parser worked cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 best. I did have to replace cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tokens in whatsapp_defines.py with a list extracted from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 APK for it to work correctly though. This made it easier to figure out what was in each packet sent to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server.

Playing with this a bit, I discovered that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are three types of checks in WhatsApp signalling messages. First, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server validates and modifies incoming signalling messages. Secondly, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 messages are deserialized, and this can cause errors if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 format is incorrect, and generally limits cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 contents of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 Java message object that is passed on. Finally, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 native methods perform checks on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir parameters.

These additional checks prevented several of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 areas I thought were problems from actually being problems. For example, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re is a function called by Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOffer that takes in an array of byte arrays, an array of integers and an array of booleans. It uses cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se values to construct candidates for cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call. It checks that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 array of byte arrays and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 array of integers are of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same length before it loops through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, using values from each, but it does not perform cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 same check on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 boolean array. I thought that this could go out of bounds, but it turns out that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 integer and booleans are serialized as a vector of pairs, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 arrays are cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n copied from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 vector, so it is not actually possible to send arrays with different lengths.

One area of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 signalling messages that looked especially concerning was cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 voip_options field of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message. This field is never sent from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 sending device, but is added to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server before it is forwarded to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving device. It is a buffer in JSON format that is processed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving device and contains dozens of configuration parameters.

{"aec":{"offset":"0","mode":"2","echo_detector_mode":"4","echo_detector_impl":"2","ec_threshold":"50","ec_off_threshold":"40","disable_agc":"1","algorithm":{"use_audio_packet_rate":"1","delay_based_bwe_trendline_filter_enabled":"1","delay_based_bwe_bitrate_estimator_enabled":"1","bwe_impl":"5"},"aecm_adapt_step_size":"2"},"agc":{"mode":"0","limiterenable":"1","compressiongain":"9","targetlevel":"1"},"bwe":{"use_audio_packet_rate":"1","delay_based_bwe_trendline_filter_enabled":"1","delay_based_bwe_bitrate_estimator_enabled":"1","bwe_impl":"5"},"encode":{"complexity":"5","cbr":"0"},"init_bwe":{"use_local_probing_rx_bitrate":"1","test_flags":"982188032","max_tx_rott_based_bitrate":"128000","max_bytes":"8000","max_bitrate":"350000"},"ns":{"mode":"1"},"options":{"connecting_tone_desc": "test","video_codec_priority":"2","transport_stats_p2p_threshold":"0.5","spam_call_threshold_seconds":"55","mtu_size":"1200","media_pipeline_setup_wait_threshold_in_msec":"1500","low_battery_notify_threshold":"5","ip_config":"1","enc_fps_over_capture_fps_threshold":"1","enable_ssrc_demux":"1","enable_preaccept_received_update":"1","enable_periodical_aud_rr_processing":"1","enable_new_transport_stats":"1","enable_group_call":"1","enable_camera_abtest_texture_preview":"1","enable_audio_video_switch":"1","caller_end_call_threshold":"1500","call_start_delay":"1200","audio_encode_offload":"1","android_call_connected_toast":"1"}
Sample voip_options (truncated)

If a peer could send a voip_options parameter to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r peer, it would open up a lot of attack surface, including a JSON parser and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 processing of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se parameters. Since this parameter almost always appears in an offer, I tried modifying an offer to contain one, but cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 offer was rejected by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 WhatsApp server with error 403. Looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 binary, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re were three ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r signal types in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 incoming call flow that could accept a voip_options parameter. Java_com_whatsapp_voipcalling_Voip_nativeHandleCallOfferAccept and Java_com_whatsapp_voipcalling_Voip_nativeHandleCallVideoChanged were accepted by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server if a voip_options parameter was included, but it was stripped before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 message was sent to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peer. However, if a voip_options parameter was attached to a Java_com_whatsapp_voipcalling_Voip_nativeHandleCallGroupInfo message, it would be forwarded to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 peer device. I confirmed this by sending malformed JSON looking at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 log of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving device for an error.

The voip_options parameter is processed by WhatsApp in three stages. First, cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON is parsed into a tree. Then cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 tree is transformed to a map, so JSON object properties can be looked up efficiently even though cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365re are dozens of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m. Finally, WhatsApp goes through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 map, looking for specific parameters and processes cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m, usually copying cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365m to an area in memory where cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y will set a value relevant to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call being made.

Starting off with cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON parser, it was clearly cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 PJSIP JSON parser. I compiled cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 code and fuzzed it, and only found one minor out-of-bounds read issue.

I cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365n looked at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conversion of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON tree output from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 parser into cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 map. The map is a very efficient structure. It is a hash map that uses FarmHash as its hashing algorithm, and it is designed so that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 entire map is stored in a single slab of memory, even if cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON objects are deeply nested. I looked at many open source projects that contained similar structures, but could not find one that looked similar. I looked through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 creation of this structure in great detail, looking especially for type confusion bugs as well as errors when cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 memory slab is expanded, but did not find any issues.

I also looked at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 functions that go through cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 map and handle specific parameters. These functions are extremely long, and I suspect cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are generated using a code generation tool such as bison. They mostly copy parameters into static areas of memory, at which point cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y become difficult to trace. I did not find any bugs in this area eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r. Ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r than going through parameter names and looking for value that seemed likely to cause problems, I did not do any analysis of how cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 values fetched from JSON are actually used. One parameter that seemed especially promising was an A/B test parameter called setup_video_stream_before_accept. I hoped that setting this would allow cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device to accept RTP before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call is answered, which would make RTP bugs interaction-less, but I was unable to get this to work.

In cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process of looking at this code, it became difficult to verify its functionality without cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 ability to debug it. Since WhatsApp ships an x86 library for Android, I wondered if it would be possible to run cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON parser on Linux.

Tavis Ormandy created a tool that can load cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 libwhatsapp.so library on Linux and run native functions, so long as cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y do not have a dependency on cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JVM. It works by patching cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 .dynamic ELF section to remove unnecessary dependencies by replacing DT_NEEDED tags with DT_DEBUG tags. We also needed to remove constructors and deconstructors by changing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 DT_FINI_ARRAYSZ and DT_INIT_ARRAYSZ to zero. With cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se changs in place, we could load cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 library using dlopen() and use dlsym() and dlclose() as normal.

Using this tool, I was able to look at cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON parsing in more detail. I also set up distributed fuzzing of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 JSON binary. Unfortunately, it did not uncover any bugs eicá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r.

Overall, WhatsApp signalling seemed like a promising attack surface, but we did not find any vulnerabilities in it. There were two areas where we were able to extend cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack surface beyond what is used in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 basic call flow. First, it was possible to send signalling messages that should only be sent after a call is answered before cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 call is answered, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were processed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 receiving device. Second, it was possible for a peer to send voip_options JSON to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r device. WhatsApp could reduce cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 attack surface of signalling by removing cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se capabilities.

I made cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365se suggestions to WhatsApp, and cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y responded that cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were already aware of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 first issue as well as variants of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 second issue. They said cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y were in cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 process of limiting what signalling messages can be processed by cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 device before a call is answered. They had already fixed ocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r issues where a peer can send voip_options JSON to anocá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r peer, and fixed cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 method I reported as well. They said cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365y are also considering adding cryptographic signing to cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 voip_options parameter so a device can verify it came from cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 server to furcá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365r avoid issues like this. We appreciate cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365ir quick resolution of cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 voip_options issue and strong interest in implementing defense-in-depth measures.

In Part 5, we will discuss cá cược thể thao bet365_cách nạp tiền vào bet365_ đăng ký bet365 conclusions of our research and make recommendations for better securing video conferencing.

No comments:

Post a Comment