Detailed analysis of the principle of WiFi universal key network
0x00 does the wifi universal key obtain the root user's password and then upload it secretly?
In this test, the version is 3.2.3. First, the problematic code is located through the suspicious shell statement: Class Name com. snda. wifilocating. f. ba
The function of this Code is to set the system's wifi with the root permission. the conf file is copied to the app's own directory, and the global read/write permission is granted to it (in fact, this is a vulnerability ...).
After performing cross-ref lookup and referencing, we can find that this function is called directly in two places. One is com. snda. wifilocating. e. av:
This is an api interface. It is used to back up your ap password after you register it. It is also called directly in WpaConfUploadActivity and indirectly in GetBackupActivity. The first Activity has been deleted from AndroidManifest in the analyzed version, and the second Activity is the interface corresponding to the user's backup of private wifi. This confirms that the password will be uploaded during the backup, and the password is completely reversible from the following.
However, this application does not perform any other suspicious root action during use. I opened the SuperSu root to execute monitoring. during a short period of use, I only found that the above command was executed.
0x01 overview of Wifi connection APIs in Android
The Android system uses the WifiManager class to provide interfaces for scanning and connecting to Wifi. The application can scan, connect, and disconnect wireless devices after requesting permissions. In the wireless connection function, the client can connect to the wireless connection in code mode by specifying the SSID and Pre-shared-key (that is, the password. A typical code for connecting to a WPA (2) wireless connection is as follows,
wifiConfiguration.SSID = "\"" + networkSSID + "\"";wifiConfiguration.preSharedKey = "\"" + networkPass + "\"";wifiConfiguration.hiddenSSID = true;wifiConfiguration.status = WifiConfiguration.Status.ENABLED;wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA); int res = wifiManager.addNetwork(wifiConfiguration);Log.d(TAG, "### add Network returned " + res);
0x02 How does the wifi universal key connect to the wireless network? Where does the password come from?
This is also highly controversial. First, the application must have a lot of passwords stored on the cloud, because the application will guide users to back up their own passwords, but we don't know whether these passwords have been abused on the client. In this test at the end of February, the author first privately backed up the wireless test set up by myself (note not to share it), and then installed the client on another mobile phone for testing, the client's API request interface does not return the wireless password for this test. However, this may not be an example. We recommend that you test it by yourself. However, note that you need to clear the saved wireless device before the test and set a weak password for the test wireless device to avoid leaking your password.
Wireless password acquisition and analysis
Back to the question, I intercepted the application's request for a wi-fi password through a proxy. The application sends the target ssid and mac information to the cloud for query. The obtained password is not plaintext, but an AES encryption. First, in order to prove that it will eventually appear in plain text locally, it takes a coincidence that there is no de-inverse algorithm (although it is not difficult ), instead, it directly hooks the code for adding a wireless device to the system (recall that the above password is in NetworkConfiguration. preSharedKey ).
Part of the HOOK code:
Class wifimgr = XposedHelpers.findClass( "android.net.wifi.WifiManager", lpparam.classLoader); XposedBridge.hookAllMethods(wifimgr, "addNetwork", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { WifiConfiguration configuration = (WifiConfiguration) param.args[0]; if(configuration.preSharedKey != null) { Log.e("FUCKFUCK", "psk: "+configuration.preSharedKey); } } }); XposedBridge.hookAllMethods(wifimgr, "updateNetwork", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { WifiConfiguration configuration = (WifiConfiguration) param.args[0]; if(configuration.preSharedKey != null) { Log.e("FUCKFUCK", "psk: "+configuration.preSharedKey); } } }); }
This is the 10 thousand key to upload the wifi ssid and mac to request the password:
Response:
The password is passed back through the json key pwd in the form of AES reversible encryption.
At the same time, when it tries to connect to the target wireless using this password, the local hook module also obtains the real plaintext password:
Personal backup Analysis
The personal backup module directly reads wifi. the conf module is implemented through the findprivateap and saveprivateap json api methods. The specific http request logic is in the com. snda. wifilocating. e. this class also covers the api request logic of all the omnipotent keys.
Backup request: All wifi. conf files are uploaded.
When the backup is restored, the password is dragged down from the cloud.
Other Connection Methods
In addition, the Wifi universal key also comes with 2000 database records in ap8.db, which records common weak passwords. For example
These passwords are used in the so-called "deep connection" function. In fact, according to the Code logic, a Wi-Fi password is cracked and 10 passwords are tried in the dictionary each time. Check logcat.
I/wpa_supplicant( 884): wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrectI/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=2 duration=20D/SupplicantStateTracker( 818): Failed to authenticate, disabling network 1I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-REENABLED id=1 ssid="aaaaaaaaa"I/wpa_supplicant( 884): wlan0: Trying to associate with 5c:a4:8a:4d:09:a0 (SSID='aaaaaaaaa' freq=2412 MHz)I/wpa_supplicant( 884): wlan0: Associated with 5c:a4:8a:4d:09:a0I/wpa_supplicant( 884): wlan0: CTRL-EVENT-DISCONNECTED bssid=5c:a4:8a:4d:09:a0 reason=23I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=1 duration=10I/wpa_supplicant( 884): wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrectI/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=2 duration=20I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-REENABLED id=1 ssid="aaaaaaaaa"I/wpa_supplicant( 884): wlan0: Trying to associate with 5e:aa:aa:aa:aa:aa (SSID='aaaaaaaaa' freq=2462 MHz)I/wpa_supplicant( 884): wlan0: Associated with 5e:aa:aa:aa:aa:aaD/dalvikvm(13893): GC_CONCURRENT freed 356K, 4% free 18620K/19220K, paused 9ms+2ms, total 29msI/wpa_supplicant( 884): wlan0: CTRL-EVENT-DISCONNECTED bssid=5e:aa:aa:aa:aa:aa reason=23I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=1 duration=10I/wpa_supplicant( 884): wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrectI/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=2 duration=20
Analysis of Wifi password encryption and decryption
Of course, it is not very difficult to actually reverse encrypt the code. The decryption code can be obtained after a simple search: (part of the code is extracted directly from the decompiled code, and the style is not modified)
Public class AESFun {String a = // omitted; String B = // omitted; String c = // omitted; Cipher cipher; IvParameterSpec spec; SecretKeySpec secretKeySpec; void init () throws NoSuchAlgorithmException, NoSuchPaddingException {spec = new IvParameterSpec (B. getBytes (); secretKeySpec = new SecretKeySpec (. getBytes (), "AES"); cipher = Cipher. getInstance ("AES/CBC/NoPadding");} public final String B (String arg7) throws E Xception {byte [] array_b1; byte [] array_ B = null; int I = 2; String string = null; {try {this. cipher. init (2, secretKeySpec, spec); Cipher cipher = this. cipher; if (arg7! = Null & arg7.length ()> = I) {int i1 = arg7.length ()/2; array_ B = new byte [i1]; int i2; for (i2 = 0; i2 <i1; ++ i2) {String string1 = arg7.substring (i2 * 2, i2 * 2 + 2); array_ B [i2] = (byte) Integer. parseInt (string1, 0x10);} array_b1 = cipher. doFinal (array_ B);} catch (Exception exception) {StringBuilder stringBuilder = new StringBuilder ("[decrypt]"); string = exception. getMessage (); StringBuilder stringBuilder1 = stringBuilder. append (string); string = stringBuilder1.toString (); exception. printStackTrace (); throw new Exception (string);} string = new String (array_b1);} return string ;}
Enter the hexadecimal pwd field obtained in the API request into the decryption program. The result is in the following format: [length] [password] [timestamp], as shown in, the target wireless plaintext password is in the middle.
In addition, a sign field in the interface request is a signature. In fact, the request parameter is merged with the preset key for md5, and the details are not described in detail. After the two are clear, you can use this interface to implement your own Wifi key.
0x03 Summary
The WiFi universal key will send the wireless password stored on the mobile phone after the root user to the cloud. When enough users use this application, the cloud will have a huge WiFi database, when querying a wi-fi password, the app sends the target ssid and mac information to the cloud for query. The obtained password is not in plaintext, but is encrypted by AES, connect to the target WiFi after local decryption. At the same time, a common weak Wi-Fi password of 2000 is built in. If you do not have the Wi-Fi password on the cloud, you can try to crack the target password.