I have long been fond of information security, but one thing is an understanding of the surface logic of software operation, and a completely different thing is an understanding of the logic of its internal implementation. Outwardly, any program can look great and harmonious, creating the illusion of complete security and security, but it’s worth going deeper, digging deeper, and on the surface are unpleasant facts that can lead to system hacking and, ultimately, to leakage or data loss, as well as temporary and financial losses. The reason for the presence of vulnerabilities in the application can be as a banal inattention, a catastrophic lack of time, algorithmic or architectural complexity, ignorance of the features of the work or the implementation of third-party API, and self-serving intent. It is often difficult to judge exactly what could have caused this or that vulnerability, but the more important point is the speed of the developers' reaction to its elimination.
Today we will talk about the vulnerability that I discovered in the process of familiarizing myself with the software package for MAC-cameras MACROSCOP from the resident of the Skolkovo technopark of the company Satellite LLC (Perm). MACROSCOP is a software package, as the solution includes a number of applications: the server and all-in-one parts for Microsoft Windows operating systems (the developers have recently abandoned the development of Linux solutions), the client part for Windows, Android, iOS and Windows Phone, configurator, Web camera connection program, native format file player, local archive viewer and backup program, system state monitoring program, various intelligent modules, as well as integration applications with some third-party systems and wide possibilities for integration with any software through the SDK. There are many advantages in MACROSCOP and, nevertheless, it is not without flaws, a separate article can be devoted to this: after all, developers do not always advertise the negative aspects of their product.
The discovered vulnerability is in the use of a weak username and password for an undocumented superuser account, as well as the ability to make some requests to the server using this record. When testing MACROSCOP, it became necessary to check how securely the accounts for the cameras and the program itself are stored, and my attention eventually attracted the configuration file “Current.CmnConf”. As it turned out, the passwords to the cameras are stored in clear text, and the passwords for program accounts are in the form of md5 hash, and also, most likely, in a reversibly encrypted form. When studying the configuration file, I came across the lines SuperUser and SuperPass, as well as two consecutive lines, remotely resembling a hash. Attempting to use this pair for authorization using the client application and the configurator did not bring the proper result, but the thought did not leave me that it needed something and should work somewhere. The user documentation did not contain a word about this account, so I decided to study the documentation on using the MACROSCOP SDK for developing external modules, where I also did not find any information, but I was interested in the description of using the HTTP interface to receive data streams from the program. What was my surprise when I tried to check the use of this pair for the query of the form:
')
server:8080/video?channel=""&login=superuser&password=superpass
Checking this request met my expectations: the browser offered to save the data on the specified link, and this is nothing more than a video stream in real time from the channel under the name "Street". Next in order, I had a question about how to get the names of all the channels of the video system. This question is answered by the developers themselves in their SDK, where in order to get the names of channels, their identifiers and settings in MACROSCOP, you need to run the following query:
server:8080/configex?login=superuser&password=superpass
The answer to the request comes in xml-format. Based on this response, you can form a request for receiving video in real time from any channel. At first glance, it seemed to me that there is nothing special in the fact that developers use an undocumented account for the internal purposes of the program, but I was tormented by vague doubts, and I decided not to stop there.
I decided to figure out how this account is formed. Since the MACROSCOP programs and libraries are mostly written under the .NET software platform, I had to use the .NET Reflector program to research them. A keyword search did not take long to wait, and the code of interest was found in the Common.dll library in the implementation of the CommonConfig class:
Random random = new Random(); byte[] buffer = new byte[21]; byte[] buffer2 = new byte[21]; random.NextBytes(buffer); random.NextBytes(buffer2); this.SuperUser = SDKCommon.MD5Hash(Encoding.UTF8.GetString(buffer)); this.SuperPass = SDKCommon.MD5Hash(Encoding.UTF8.GetString(buffer2));
In MACROSCOP, this code is used when applying the first configuration, then the superuser account is created, which is inaccessible from the program settings, has certain privileges and always remains the same. From the code you can see that the instance of the Random class is being initialized, then getting two arrays of arbitrary data of a certain length, then getting the strings from them and eventually md5 hash. It seems to be no dirty trick: the use of an arbitrary sequence of data and irreversible transformations, but there would be no vulnerability in this article, if it were not for the use of the Random class, in essence, the whole problem lies.
The root cause of the vulnerability in MACROSCOP lies precisely in the use of the standard Random class of the .NET environment, which leads to the generation of an account that can be picked up in a reasonable time. The fact is that this class for initializing an array of pseudo-random numbers uses a 32-time value obtained by calling the system function GetTickCount: the number of milliseconds that have elapsed since the computer was turned on. Thus, based on this number, a pair of username and password is formed. This pair can be detected by enumerating all possible values ​​of the time elapsed from the moment the computer was turned on until the first configuration was applied. The problem is also aggravated by the fact that from the moment the computer is turned on until the first configuration is applied, in most cases very little time may pass. For example, if the first configuration was applied an hour after the computer was turned on, then only 3.6 million combinations would need to be checked (1 h * 60 min * 60 s * 1000 ms). Even if the computer was turned on for a very long time, then this will not make the brute force attack much more difficult, because The class Random uses the value of a 32-bit signed number for initialization, then the number of input values ​​is ultimately limited to a 31-bit number. Thus, the maximum number of combinations for enumeration is 2 ^ 31 (2147483648) values, which is about 25 days from the moment the computer is turned on until the first configuration is applied, after which the time begins from the beginning. The search is carried out using the previously specified request for receiving channel names, their identifiers and settings. Under ideal conditions (outgoing server channel speed of at least 50 Mbit / s, multi-core processor, low processor load), the search speed can reach about 5000 accounts per second. So, if the first configuration was applied an hour after the computer was turned on, then the account search time would be no more than 12 minutes. It is also possible to reduce the search time, taking into account the expected time of turning on the computer during working hours, for example, if the computer could be turned on during workdays and hours, then the search time can be reduced by 3.7 times.
Selected account can be used in the future for certain purposes. From what I found, this, as previously noted, is the ability to view video on all channels in real time, as well as the ability to apply any configuration to the server. The latter possibility represents the greatest threat, since full control of the server can be obtained. In a simple view, a configuration change attack is implemented as follows: an attacker can prepare a configuration change request, in which, for example, a script will be executed for one of the cameras to provide remote access to the server. This request will use the previously received account, as well as take into account such moments as the revision number, identifier and date of the configuration change. After an intruder penetrates the server, a backdoor can be installed, the log files are changed, and the old configuration is restored from the backup.
According to preliminary verification, the superuser account cannot be used, for example, to access the archive of channel records and the current configuration (although I may be mistaken), but with a high degree of probability it can be used for other purposes, which developers should be better known.
The developers were notified about the vulnerability in MACROSCOP, and after 2 weeks (March 12, 2014) they closed it with the release of version 1.9.72 of the program. Now the code for generating the built-in account is as follows:
byte[] data = new byte[21]; byte[] buffer2 = new byte[21]; try { RNGCryptoServiceProvider provider = new RNGCryptoServiceProvider(); provider.GetBytes(data); provider.GetBytes(buffer2); } catch (Exception exception) { b1x.a(exception, "dsfimdfsmsdfdkfskfds"); Random random = new Random(Guid.NewGuid().GetHashCode()); random.NextBytes(data); random.NextBytes(buffer2); } Buffer.BlockCopy(Guid.NewGuid().ToByteArray(), 0, data, 0, 8); Buffer.BlockCopy(Guid.NewGuid().ToByteArray(), 0, buffer2, 0, 8); this.SuperUser = SDKCommon.MD5Hash(Encoding.UTF8.GetString(data)); this.SuperPass = SDKCommon.MD5Hash(Encoding.UTF8.GetString(buffer2));
The new version of the code uses a crypto-resistant class of random data generation mixed with Guid, which guarantees the practical impossibility of selecting an account, besides the developers have closed the possibility of using this account in the two previously mentioned requests to the server. Nevertheless, this account is still used when applying the configuration, but the search speed in this case is much lower: the minimum request to the server is about 10 Kb, which is 10 times more traffic than the previously possible method, and only the risk of updating old users. The fact is that for the existing configuration, the pair of hashes is not modified when installing a new version of the program, so this procedure remains to be done only independently. Most importantly, if a multi-server configuration is used, then a couple of hashes and, accordingly, the configuration itself must be the same on all servers. Otherwise there will be a conflict when applying the new configuration. Thus, for new users of MACROSCOP, who are just beginning to use the program, from version 1.9.72 the vulnerability is not terrible, but for old users there is a small risk that can be eliminated as follows:
- stop the MacroscopServer service or shut down the standalone version on the computer;
- open the “Current.CmnConf” configuration file located in the program folder in the hex editor, (first make a backup copy of the file);
- we find in the file the string “Alarus.Config.SystemEditions”, namely the second result of the entry;
- Immediately just below the search result there will be two lines 32 characters long - this is the data of the built-in account;
- we change the contents of strings to arbitrary values, taking into account the valid characters from the set “0123456789ABCDEF”, without changing the length of the strings;
- save the configuration;
- run the service or standalone version of the program;
- in the case of using a multi-server configuration, we perform the same actions, only as strings we use previously edited values ​​or simply replace the configuration with the corrected one.
Summing up, I can’t help all developers not to repeat mistakes using the standard Random class, but to use crypto-resistant implementations of the random data generation algorithm, and also to respond promptly to potential threats in applications.