Abstract: In previous work we presented preliminary results obtained by reviewing the source code of Qlink.it web application. In this article, after summarizing previous findings, results of the source code review of Qlink.it Android application will be described. This analysis focused on the implementation of cryptographic functionalities. The aim of this publication is also to invite other researchers to analyze the application in order to determine if Qlink.it could be considered secure.
Keywords: Information security, application security, source code review, cryptography, random number generation.
Resumen: En un trabajo previo presentamos los resultados preliminares obtenidos al revisar el código fuente de la aplicación web de Qlink.it. En este artículo, después de resumir los hallazgos anteriores, se describirán los resultados de la revisión del código fuente de la aplicación Android de Qlink.it. Este análisis se centró en la implementación de funcionalidades criptográficas. El objetivo de esta publicación es invitar a otros investigadores a analizar la aplicación para determinar si Qlink.it podría considerarse seguro.
Palabras clave: Seguridad informática, seguridad de aplicaciones, revisión de código fuente, criptografía, generación de números aleatorios.
Other potential problems in Qlink.it
Otros Problemas Potenciales en Qlink.it
Received: 20 February 2018
Accepted: 30 July 2018
In previous work  we presented the preliminary results obtained by reviewing the source code of the Qlink.it web application. These results will be summarized below. In this article, the source code review findings of potential security problems in the Qlink.it Android application will be described. This source code is also published on the project repository on github.com , and the application can be installed on Android devices from Google Play .
This analysis also focused on the implementation of cryptographic functionalities. We’ll describe implemented mechanisms that discard key material significantly reducing the security against brute-force attacks, code that reuses the same key and initialization vector applying AES 256 in CBC mode, and insecure ways of seeding secure random generators. At least one problem that could compromise the secrecy of the encrypted message will be described. This problem could be exploited if the qlink was generated in versions of the Android operating system prior to 4.2 and under certain very specific circumstances of message length and timing conditions.
As mentioned in , given the news [4,5] about the availability of the Qlink.it source code , and considering, that among GICSI objectives, the group studies techniques and mechanisms for the revision of source code, focusing on aspects related to information security in general and to cryptography in particular [7,8]; and, that the DGT has the responsibility, among others, to periodically evaluate alternatives for the secure communication of the Institution's personnel; a first general review of the source code of the Qlink.it web application  was carried out jointly.
Our findings on the web application were published in our previous article. Here we describe the results obtained after the review of the source code of the Android application. By the time the first part of the analysis was completed (May 2017), the preliminary results of the review would indicate the existence of potential security problems, for which reason it was decided to consult Qlink.it developers sharing these results.
Although it was a review that did not cover the entire system, and it was not finished, permission was requested to publish, in the form of an article, with the intention of inviting other reviewers to study the application, who could confirm or reject these potential risks, and determine if the system could be considered safe.
A limited summary without all the details of the first results was also published on a website dedicated to information security, Segu-Info .
These functions, based on the Mersenne Twister generator, are not suitable for generating random numbers for cryptographic operations, warning also explicitly noted in PHP official documentation .
For example, the following code snippet shows how the seed used to generate the first part of a qlink could be obtained:
It was shown that generating a new qlink and using its first ten characters to obtain the seed, it is possible to estimate of when the previous qlink was created. The script included in our previous work used the module or package pyphp_rand  as used in the example code of Algorithm 1.
Suppose x as the Unix epoch timestamp from the moment the previous qlink was generated, in seconds; and xm to the parameter that was sent to the server at that moment, in milliseconds, so for the purposes of this approximate estimate, 1000x <xm <1000x + 999. Also assume t equal to the Unix epoch timestamp of the moment when we generate the new qlink, in seconds. Finally consider u as the amount in microseconds used in PHP, which would be generated such that 0 < u < 99999.
Therefore, the seed for the qlink that we are generating, s, would correspond to xm + t + u. Then, s = xm + t + u , s = 1000x + y + t + z, with 0 < y < 999 and 0 < z < 99999. Then, x = (s - y - t - z) / 1000. This being an approximation, the term y / 1000 could by eliminated, and z / 1000 is replaced by a delta d, with 0 < d < 99, then x = [(s - t) / 1000 - 99, (s - t) / 1000]. So the approximation result corresponds to a range of 99 seconds.
Also based on previous examples, it is possible to obtain the tracking code, or “DN number” from the first ten characters of the variable part of a qlink. The proof of concept script included in our previous article could be used against any qlink.
The “DN number” is generated by a function very similar to the one used to generate the first ten characters code of a qlink, laying the difference in the set of possible characters for the mapping of random numbers. In this case, the result corresponds to ten digits. Also, the same timestamp is used for the generation of the first part of a qlink. The function is invoked after just over about 50 lines of code of the generation of the first part of the qlink.
Therefore, another script of our previous article brute-force the time elapsed between the invocation of these two functions and then check the existence of the tracking code in a limited space, with the intention of reducing the amount of tests to be performed.
Regarding issues related to the code executed in the browser, specifically in relation to the generation of random numbers, we have demonstrated potential problems with the use of a library based on the function that browsers provide, implementing the Xorshift128 + generator.
In this case, our test script was an adaptation of another available in , which works directly with outputs of the Math.Random() function, using the Z3 tool, “a high-performance theorem prover being developed at Microsoft Research” , for the symbolic resolution of the system of equations given the known partial information. The test example was adapted for resolution with values truncated by CryptoJS.lib.WordArray.random(). The way to generate the salt and the initialization vector in qlink was taken as an example to estimate or guess the following possible values of the generator. While the example does represent a risk, it should be considered that the same function is used to generate key material.
From a SecureRandom instance seeded with timestamps and results of previous invocations, the source code snippet in Algorithm 3 shows the generation of the string that then would be encoded in base 64, truncated and used as input for generating the AES key, using SecretKeyFactory. getInstance("PBKDF2WithHmacSHA1"), requesting 256 bits of key material, and specifying only 100 iterations.
Considering that truncation con leave only 16 base 64 encoded characters, the password consist of 12 characters in the range [0-9a-zA-Y] (the Z is not included in the set because of an error in the nextInt() parameter). This leaves 61 possible characters, so if an attacker would try to brute-force this password, he will need to make, on average, 6112/2 ≈ 270 tries.
It is well known that for symmetric block ciphers operating in Cipher Block Chaining (CBC) mode, the key and the initialization vector should not be used more than once.
The Qlink.it Android application allows to attach multiple files to a message, unlike the web application, here the same key and IV are used for the message and all the attached files.
The following source code snippet in Algorithm 4 shows that the contents of the fpassword variable, used also for encrypting the message, would be used for the attached file. This code, as the one from Algorithm 3, are taken from the src/com/qlink/ar/ QlinkActivity.java Qlink.it source file.
According to the cryptography entry on Android 4.2 security notes , the default implementation of SecureRandom was modified. Also from an official Google source , it was publicly known that there was a problem with using SecureRandom() in the way Qlink.it uses it. Starting with Android 4.2, the default provider is OpenSSL and a developer can no longer override SecureRandom’s internal state, but the old implementation allowed overriding the internally generated key for each instance. Developers which attempted to explicitly seed the random number generator, as done in the Qlink.it application, would find that their seed replaces, not supplements, the existing seed. Using the same seed, prior to Android 4.2, invocations of nextInt() would always return the same number.
Other problems beside [23,24], the way Qlink.it generates the password may be insecure in these devices because it consist in repeatedly seeding the generator with timestamps (with milliseconds precision) and previous results. Estimating a timestamp range, first user interaction could be brute-forced. For example, in Algorithm 5:
The password variable is “updated” in every user interaction with the application, and exactly the same code is executed in afterTextChanged(). The variable is initialized with an empty string, so the first interaction seeds the generator with the timestamp only. The JSON encoded message that’s sent to the server includes a timestamp also with millisecond precision (as seen in Algorithm 1), giving a maximum limit to a potential attacker. Although in our experiments we have tested only very short messages, it was possible to find keys estimating time between interactions and processing time.
Assuming the user would launch the app, tap on the message area (1), type two characters (2x3), and use the button (1) that generates the qlink (1); our debugging showed that a total of 9 invocations of the password update would be executed. However, for example, in most cases the first two of the three invocations per character are executed two milliseconds apart.
This observation among others of the behavior of the application and estimations of fixed processing times were considered to write a simple program just for demonstration purposes (since larger messages and broader timing limits would imply incrementing exponentially the brute-force difficulty), that knowing the last timestamp, tries to decipher a two character (“no”) message making 10 x (1 x 3 x 130)#characters x 10 x 10 ≈ 29,96 + 8,60(#characters) tries. A positive result example run of the far from optimized Java program, that on an Intel(R) Core(TM) i-7 notebook would take approximately five hours (two and a half in average), is shown in the following Algorithm 6.
We have shown that the manipulation of parameters is possible, random number generation is not implemented in a secure manner, timestamps are used as seeds and key material can be truncated to an extent that may permit brute-force attacks. Other potential problems remains to be probed, for example, if the date and time could be estimated in the way described in , to possibly generate the same qlink repeatedly.
Although most of the problems described may not be exploitable or impose a serious security risk, it is clear that the implementation is not following security best practices nor secure programming techniques from, for example, OWASP . Till other reviewers or the developers confirm or reject the potential risks described, sending sensitive information via Qlink.it may not be recommended.
Cómo citar: A. Castro Lechtaler, M. Cipriano, E. García, P.
Lázaro, J. Liporace, E. Malvacio and A. Maiorano. “Other potential problems in Qlink.it”, Journal of Computer Science & Technology, vol. 18, no. 2, pp.
We would like to thank Qlink.it developers for their quick response to our queries and their permission for the publication of our preliminary results.
We are grateful to the CACIC2017 anonymous reviewers for their constructive input on our first article .
Cristian Borghello is also thanked for his help in the initial summary publication on Segu-Info .