In this article, we will be detailing an issue we discovered affecting a number of low-cost devices. It allowed for adversaries to remotely execute commands on the devices as a privileged user if they were in a position to conduct a Man-in-the-Middle attack. The binary responsible appears to be an insecure implementation of an OTA (Over-the-air) mechanism for device updates associated to the software company, Ragentek Group, in China. All transactions from the binary to the third-party endpoint occur over an unencrypted channel, which not only exposes user-specific information during these communications, but would allow an adversary to issue commands supported by the protocol. One of these commands allows for the execution of system commands. This issue affected devices out of the box.
On Tuesday, November 15th, the New York Times reported on an issue affecting a similar set of device manufacturers that caused the devices to report sensitive material, such as text messages and the user’s previous physical locations, back to the Chinese software company Shanghai ADUPS Technology Co., Ltd. This was an issue discovered and announced by Kryptowire, and covered in more detail in a posted article on their website. The issue described in this article is unrelated to the one discovered by Kryptowire.
ANALYSIS
We acquired one of the affected devices, a BLU Studio G, from Best Buy. After building a passive network traffic capturing system, an unencrypted transaction to the Ragentek head-end (oyag[.]lhzbdvm[.]com) was observed not long after proceeding through the Android first-use setup process on the device:

The device then attempted to contact two other pre-configured domains, which were previously unregistered until AnubisNetworks acquired them. This gave us immediate visibility into the larger population of affected devices, which are detailed later in this article. We were able to associate the network transactions back to specific binaries on the device, and were the ones investigated as part of this analysis:

The fact that the device reached out to defined head-ends immediately after initialization implies that the devices are affected by this issue out of the box, and were not subsequently compromised through other means, such as through a subsequent update.
Endpoints and Hosts
This binary has been observed to cycle through three specific hosts:

Only one HTTP Path has been seen in use when communicating with these hosts:
![]()
Submissions have been only been observed as a HTTP POST with the data blob passed as a parameter named ‘data’ in the URL, e.g.:

The set of HTTP headers from the client are consistent between the head-ends, with the exception of the Host header, which does not use the actual DNS host but uses the IP address of the host. An example is below:

The name of the command from the client is contained in the ‘name’ key of the pseudo-json blob that is sent as described above. The known key types and their expected responses are listed below for each command.
Client Solicitations
This command appears to be purposed for checking itself into the designated head-ends. Based from the response from the head-end, the device could enter either one of three states:
- Sleep for 6 months until the process restarts, or more likely until the device is rebooted.
- Enter a period of checking in via the “c_get_msg” command at an interval of every 10 minutes.
- If the “c_regist” request remains unanswered, as is the case for the majority of devices at the moment, it will try again in 10 minutes.
It’s worth noting that any response could be issued to the device in response to “c_regist” or “c_get_msg”. Through traffic analysis and simulated clients, any submission to the Ragentek head-end thus far using the c_regist command results in an immediate TCP RST response.
The payloads typically seen for this command contain mixed-use datatypes in the key values, but the key is always the same. Below is a sample of the values observed from the test device:
As shown above, this payload contains information such as the device model and version, the user’s phone number, their IMEI, among other identifiers, and is transmitted unencrypted.
Server Commands
The server is able to respond to requests from the client, but since the actual Ragentek head-end did not issue any commands in the course of this analysis, this had to be discovered by further investigation of the binary. By determining that it utilized Rui Maciel’s JSON library, it was straightforward to reverse the expected data structure of the server response. As shown below:

The values for “code” are strings, and are either:

The value of the “name” field was the desired command that server wished to issue. The protocol supports six defined command types:
- push_commands
- push_apk
- push_link
- push_text
- push_client
- push_config
The “details” JSON key value varies by command, but is also always a JSON object.
The most notable of the aforementioned commands is “push_commands”. The push_commands function allows the head-end to execute an arbitrary command of its choice on the device. In the communication structure, it requires a “details” JSON object of the following schema:

Before the command is executed, the values of “title” and “comments” are written into the local sqlite database. Whether it was successful, for example due to database error, the value of “commands” is executed via a system call. Despite the name of the key, it is a string, and not a list of commands. The client will subsequently send a “c_update_commands” message to the head-end, with a status value of “61”. If the client received a valid-form JSON back from the server, it will access the local database to likely log the response from the server.
Using the described information above, an example response from the server could thus be:








