WiFi萬能鑰匙蹭網原理詳細剖析
0x00 wifi萬能鑰匙究竟有沒有獲取root之後偷偷上傳密碼?
本次測試版本號為3.2.3,首先透過可疑shell語句定位到疑問的問題程式碼:類名com.snda.wifilocating.f.ba
這段程式碼的作用是在有了root許可權的情況下 將系統的wifi.conf複製出來到應用自己的目錄,並賦予其全域性可讀寫許可權(其實這是個漏洞了...)。
對其做cross-ref查詢引用之後可以發現,該函式主要在兩個地方被直接呼叫。一個是com.snda.wifilocating.e.av:
這是一個api介面,主要功能是用於使用者註冊了之後備份自己的ap密碼,同時在 WpaConfUploadActivity直接呼叫、GetBackupActivity中間接呼叫。第一個Activity在分析的版本中已經被從AndroidManifest中刪除,而第二個Activity則是使用者備份私有wifi時的對應的介面。這證實了備份的時候密碼確實會被上傳,而且從下文來看這個密碼是完全可逆的。
不過在使用過程中,該應用並沒有其他可疑的root行為操作。筆者開啟了SuperSu的root執行監控,短暫的使用過程中也只發現了執行了上述的這一條命令。
0x01 Android系統Wifi連線API概述
Android系統透過WifiManager類來提供對Wifi的掃描、連線介面。應用在請求相應許可權之後可以掃描、連線、斷開無線等。在連線無線功能中,客戶端基本上只要指定SSID,Pre-shared-key(即密碼),就可以用程式碼的方式連線無線。連線一個WPA(2)無線典型程式碼如下,
#!bash
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 wifi萬能鑰匙是怎麼連線上無線的,密碼從哪裡來?
這也是爭議較大的地方,首先該應用肯定是有云端儲存了很多密碼,因為應用會引導使用者備份自己的密碼,但這些密碼有沒有被濫用我們在客戶端就不得而知了。在2月底的這次測試中,筆者先私有備份了自己建立的測試無線(注意不是分享),然後使用另外一個手機安裝該客戶端測試,該客戶端的API請求介面並沒有返回這個測試的無線的密碼。不過這也可能只是個例說明不了什麼,還是建議各位自行測試,但注意測試前清除儲存的無線並給測試無線設定一個弱密碼以免真的洩露了自己的密碼。
無線密碼獲取分析
回到正題,筆者透過代理攔截到了該應用獲取wifi密碼的請求。應用傳送目標的ssid,mac資訊向雲端做查詢,獲取到的密碼到本地之後並不是明文的,而是一個AES加密。首先為了證明其在本地最終還是會以明文出現,先取了個巧,沒有去逆這個演算法(雖然逆下也不會很困難),而是直接hook了系統新增無線的程式碼(回憶上文裡密碼就在NetworkConfiguration.preSharedKey裡)。
部分HOOK程式碼:
#!java
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);
}
}
});
}
這是一個萬能鑰匙上傳wifi ssid以及mac以請求密碼的截圖:
響應截圖:
密碼以AES可逆加密的形式透過pwd這個json key傳遞了回來。
同時,在其嘗試透過這個密碼連線目標無線的時候,本地hook模組也獲取到了真實的明文密碼:
個人備份分析
而個人備份模組,也就是直接會讀取wifi.conf的模組,是透過findprivateap和saveprivateap這兩個json api method進行,具體的http請求邏輯在com.snda.wifilocating.e.av中可以找到,這個類也基本上囊括了所有萬能鑰匙的api請求邏輯。
備份時的請求:把整個wifi.conf全部上傳了上去。
而恢復備份時,只是將密碼從雲端拖了下來。
其他連線方式分析
除此之外,Wifi萬能鑰匙還自帶了2000條的資料庫記錄在ap8.db中,記錄了常見的弱密碼。 例如
這些密碼用在所謂的“深度連線”功能中,其實按程式碼邏輯來看就是一個wifi密碼爆破,每次在字典中嘗試10個密碼。看下logcat就很明顯。
#!bash
I/wpa_supplicant( 884): wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrect
I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=2 duration=20
D/SupplicantStateTracker( 818): Failed to authenticate, disabling network 1
I/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:a0
I/wpa_supplicant( 884): wlan0: CTRL-EVENT-DISCONNECTED bssid=5c:a4:8a:4d:09:a0 reason=23
I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=1 duration=10
I/wpa_supplicant( 884): wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrect
I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=2 duration=20
I/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:aa
D/dalvikvm(13893): GC_CONCURRENT freed 356K, 4% free 18620K/19220K, paused 9ms+2ms, total 29ms
I/wpa_supplicant( 884): wlan0: CTRL-EVENT-DISCONNECTED bssid=5e:aa:aa:aa:aa:aa reason=23
I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=1 duration=10
I/wpa_supplicant( 884): wlan0: WPA: 4-Way Handshake failed - pre-shared key may be incorrect
I/wpa_supplicant( 884): wlan0: CTRL-EVENT-SSID-TEMP-DISABLED id=1 ssid="aaaaaaaaa" auth_failures=2 duration=20
Wifi密碼加解密分析
當然真正去逆向加密程式碼也不是很困難,簡單的搜尋即可得到解密程式碼:(部分直接從反編譯的程式碼中摳出,風格未做修飾)
#!java
public class AESFun {
String a =//略去;
String b = //略去;
String c = //略去;
Cipher cipher;
IvParameterSpec spec;
SecretKeySpec secretKeySpec;
void init() throws NoSuchAlgorithmException, NoSuchPaddingException {
spec = new IvParameterSpec(b.getBytes());
secretKeySpec = new SecretKeySpec(a.getBytes(), "AES");
cipher = Cipher.getInstance("AES/CBC/NoPadding");
}
public final String b(String arg7) throws Exception {
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;
}
將API請求中獲取的16進位制pwd欄位代入解密程式,得到的結果是如下格式:[length][password][timestamp]的格式,如下圖所示,中間就是目標無線明文密碼。
此外介面請求中有一個sign欄位是加簽,事實上是把請求引數合併在一起與預置的key做了個md5,細節就不贅述了。這兩個清楚了之後其實完全可以利用這個介面實現一個自己的Wifi鑰匙了。
0x03 總結
此版本的WiFi萬能鑰匙不會主動把root之後手機儲存的無線密碼發向雲端但在做備份操作(安裝時預設勾選自動備份)時會傳送,當有足夠的使用者使用該應用時,雲端就擁有了一個龐大的WiFi資料庫,查詢WiFi的密碼時,應用會傳送目標的ssid,mac資訊向雲端做查詢,獲取到的密碼到本地之後並不是明文的,而是一個AES加密,本地解密後連線目標WiFi。同時內建了常見的2000條WiFi弱口令,在雲端沒有該WiFi密碼的時候,可以嘗試爆破目標的密碼。
相關文章
- 萬能wifi鑰匙2020-12-24WiFi
- WIFI萬能鑰匙電腦版用不了怎麼辦2019-04-30WiFi
- 如何徹底杜絕家庭路由器的wifi密碼被wifi萬能鑰匙洩露?2020-10-15路由器WiFi密碼
- WiFi萬能鑰匙安全應急響應中心,隨時隨地連上Wifi2018-08-07WiFi
- “萬能鑰匙”漏洞使AI變得邪惡2024-07-02AI
- WiFi萬能鑰匙公司啟動衛星計劃 發射272顆衛星讓全球免費上網2018-11-28WiFi
- 央視曝光WiFi萬能鑰匙竊取使用者隱私 9億使用者隱私如同“裸奔2018-03-30WiFi
- 【汽車科普】數字鑰匙及UWB鑰匙2024-10-18
- 全網最詳細的ReentrantReadWriteLock原始碼剖析(萬字長文)2021-12-07原始碼
- Mofuu:能給Apple Watch充電的鑰匙扣2018-09-07APP
- 為爬蟲獲取登入cookies:使用萬能鑰匙 Selenium 搞定一切登入2018-12-03爬蟲Cookie
- 遊戲體驗設計:給你一把驚喜設計的萬能鑰匙2023-08-14遊戲
- 記憶力訓練:解鎖大腦潛能的鑰匙2024-09-14
- 30美元自制萬能鑰匙,秒開豪車!黑客自曝發家史,稱“技術分享無罪”2020-04-06黑客
- iOS 鑰匙串的基本使用2019-02-18iOS
- 雲盤萬能鑰匙宣佈關閉;MacBook系列再曝質量問題;黑客悄無聲息盜走120萬2020-04-27Mac黑客
- 域滲透的金之鑰匙2020-08-19
- ccf 公共鑰匙盒 java實現2020-11-18Java
- leetcode-841-鑰匙和房間2020-12-09LeetCode
- 鑰匙串密碼忘記了怎麼辦?如何在Mac上重置鑰匙串密碼2020-10-27密碼Mac
- 詳細剖析分散式微服務架構下網路通訊的底層實現原理(圖解)2021-11-08分散式微服務架構圖解
- 13萬字詳細分析JDK中Stream的實現原理2021-10-06JDK
- 獲取所有鑰匙的最短路徑2024-07-22
- 解決資料孤島的鑰匙2022-05-05
- 剖析 | 詳談 SOFABoot 模組化原理2019-02-27boot
- 明日之後傭兵的鑰匙怎麼獲得 明日之後傭兵的鑰匙獲取方法2022-03-20
- git生成ssh金鑰詳細步驟 git如何生成ssh金鑰2022-04-26Git
- 對React、Redux、React-Redux詳細剖析2018-06-25ReactRedux
- Flink 的執行架構詳細剖析2021-11-04架構
- Office2010產品金鑰 萬能office2010金鑰25位2022-02-21
- office2003安裝金鑰 office2003產品金鑰萬能2022-02-24
- 全網最詳細的AbstractQueuedSynchronizer(AQS)原始碼剖析(一)AQS基礎2021-12-11AQS原始碼
- sdf 測試-2-龍脈智慧鑰匙2024-05-23
- LDAP:開啟潘多拉寶盒的鑰匙2023-10-08LDA
- 無鑰匙進入及啟動系統2020-03-25
- 全網最詳細的負載均衡原理圖解2021-01-21負載圖解
- office2003金鑰序列號最新 windows2003產品金鑰萬能2022-01-25Windows
- 萬字長文深度剖析 RocketMQ 設計原理2022-05-13MQ