写个破解WIFI程序,以防不时之需(简易版,未成功)
【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权)
https://www.cnblogs.com/cnb-yuchen/p/18032045
出自【进步*于辰的博客】
此方法本人尝试未成功,既然未成功,为何我还要发布出来?
两个原因:
- 让我对wlan的连接有了初步的了解。
- 让我掌握了2个类:
java.lang.Process
、java.lang.Runtime
。为此,我补充了两篇API解析博文,大家有兴趣可以看看。
完整代码
public class NetworkCrack1 { // wlan配置文件操作(生成、导出...)路径 private static final String WLAN_FILE_DIR_PATH = "C:\\Users\\于辰\\Downloads\\新建文件夹\\"; /** * 注: * 1、以下netsh wlan系列命令通过 Runtime.exec() 系列方法执行,即在 cmd 执行,故依赖于工作目录,在此项目中即上面的 WLAN_FILE_DIR_PATH。 * 在下述的编码中,会写死。故在如下的命令中,不需要考虑。目录; * 2、之所以如下命令采用“替换合成”,而不是“拼接合成”,是因为:这些命令的格式都是固定的,后续拼接容易错误或遗漏, * 而替换容易、保险 */ // 列出所有可用wlan private static final String CMD_SHOWWLAN = "netsh wlan show networks mode=bssid"; // 添加wlan配置文件 private static final String CMD_ADDWLAN = "netsh wlan add profile filename=WLAN-ssid_name.xml"; // 连接wlan,ssid_name是wlan的名称 private static final String CMD_CONNWLAN = "netsh wlan connect name=ssid_name"; // 此命令用于确认是否已连上wlan,即是否可上网。因此是间接测试,而不是直接测试。 private static final String CMD_PING = "ping www.baidu.com"; /** * wlan配置文件模板 * 注:此项目生成wlan配置文件的方法就是将需要的信息替换到模板的相应位置,仅此而已,而不是通过调用第三方包 */ private static String XML_FORMAT = "<?xml version=\"1.0\"?>" + "<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">" + "<name>WIFI_NAME</name>" + "<SSIDConfig>" + "<SSID>" + "<name>WIFI_NAME</name>" + "</SSID>" + "<nonBroadcast>true</nonBroadcast>" + "</SSIDConfig>" + "<connectionType>ESS</connectionType>" + "<connectionMode>manual</connectionMode>" + "<MSM>" + "<security>" + "<authEncryption>" + "<authentication>WPA2PSK</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>"; public static void main(String[] args) throws Exception { // 打印出当前可用的所有wlan的ssid_name和信号强度 Map<String, String> networksMap = showNetworks(); for (Map.Entry<String,String> e: networksMap.entrySet()) { System.out.println(e); } Scanner sc = new Scanner(System.in); System.out.print("请输入计划破解的wlan编号:(从1开始)"); int index = sc.nextInt(); // 获取ssid_name String ssidName = null; Iterator<String> it = networksMap.keySet().iterator(); while (it.hasNext() && index-- > 0) { ssidName = it.next(); } // 获取随机密码 String password = RandCodeGenerator.incrGeneSixBitsCode(); // 尝试连接 if (!connect(ssidName, password)) { return; } // 测试网络 if (testNetwork()) { System.out.println("*连接成功,ssid_name" + ssidName + "\t密码:" + password); } else { System.out.println("*连接失败,ssid_name" + ssidName + "\t密码:" + password); } } /** * 尝试对指定wifi设定一个密码,然后连接,连接成功返回true */ private static boolean connect(String ssidName, String password) throws Exception { boolean flag = false; if (!generateXml(ssidName, password)) { System.out.println("配置文件生成失败,ssid_name:" + ssidName + "\t密码:" + password); return false; } if (!addXml(ssidName)) { System.out.println("配置文件加载失败,ssid_name:" + ssidName + "\t密码:" + password); return false; } execute2(CMD_CONNWLAN + ssidName);// 连接wlan Thread.sleep(8000);// 配置文件添加成功,执行连接命令后,若密码正确,大概需要8s才能连接成功 return flag; } /** * 最后,ping 一个地址,测试是否真的连上网络了 */ private static boolean testNetwork() throws Exception { boolean flag = false; String result = execute2(CMD_PING); if (result.indexOf("Ping 请求找不到主机 www.baidu.com。请检查该名称,然后重试。") != -1) { flag = false; } return flag; } /** * 加载wlan配置文件 * * @param ssidName wlan名称 */ private static boolean addXml(String ssidName) throws Exception { boolean flag = false; String cmdResult = execute2(CMD_ADDWLAN.replace("ssid_name", ssidName)); if (cmdResult.indexOf("已将配置文件") != -1) { flag = true; } return flag; } /** * 生成wlan配置文件 * * @param ssidName wlan名称 */ private static boolean generateXml(String ssidName, String password) throws Exception { boolean flag = false; PrintWriter out = null; try { out = new PrintWriter(WLAN_FILE_DIR_PATH + "\\WLAN-" + ssidName + ".xml"); String xmlContent = XML_FORMAT.replaceAll("WIFI_NAME", ssidName).replaceAll("PASSWORD", password); out.println(xmlContent); out.flush(); flag = true; } catch (FileNotFoundException e) { e.printStackTrace(); } finally { closeIO(null, out); } return flag; } /** * 获取所有可用的wlan名称,key是wifi名称,value是信号强度 */ private static Map<String, String> showNetworks() throws Exception { Map<String, String> cmdMap = new HashMap<>(); boolean putFlag = false;// 用于判断 put() 时机 List<String> networksList = execute1(CMD_SHOWWLAN); String key = "", value = ""; for (int i = 0; i < networksList.size(); i++) { String str = networksList.get(i); if (str.startsWith("SSID")) { key = str.substring(9); } else if (str.endsWith("%")) { if (str.indexOf(100) != 01) { cmdMap.put(key, "100%"); putFlag = false; continue; } value = str.substring(str.length() - 3); putFlag = true; } if (putFlag) { cmdMap.put(key, value); putFlag = false; } } return cmdMap; } /** * 在指定目录(固定)下执行指定命令 command,返回命令相应的内容 * 注:为查看当前所有可用wlan,因为将命令相应信息以 List<String> 格式返回,便于获取所需信息。 * 而其他命令返回 String 即可满足需求。 */ private static List<String> execute1(String command) throws Exception { List<String> cmdList = new ArrayList<>(); BufferedReader in = null; try { Process process = Runtime.getRuntime().exec(command); in = new BufferedReader(new InputStreamReader(process.getInputStream(), "gbk")); String lineStr; while ((lineStr = in.readLine()) != null) { cmdList.add(lineStr); } } catch (IOException e) { e.printStackTrace(); } finally { closeIO(in, null); } return cmdList; } /** * 在指定目录(固定)下执行指定命令 command,返回命令相应的内容 */ private static String execute2(String command) throws Exception { StringBuffer cmdResult = new StringBuffer(); InputStreamReader in = null; try { Process process = Runtime.getRuntime().exec(command, null, new File(WLAN_FILE_DIR_PATH)); in = new InputStreamReader(process.getInputStream(), "gbk"); int len; char[] tempCArr = new char[1024]; while ((len = in.read(tempCArr)) != -1) { cmdResult.append(new String(tempCArr, 0, len)); } } catch (IOException e) { e.printStackTrace(); } finally { closeIO(in, null); } return cmdResult.toString(); } /** * 关闭IO管道,此项目需要高频次创建IO管道,因此必须确保每次使用后都关闭(finally),否则可能导致栈溢出。 */ private static void closeIO(Reader in, Writer out) throws Exception { if(in != null) in.close(); if(out != null) out.close(); } }
我画了张图,方便大家理解。
这里呢,我也只能提供这一点辅助了,具体的大家看代码。
放心,是完整代码,大家copy后,如果报错,相应方法的代码可以在这篇博文中找到,如果找不到,自行开发一下,简单实现就行。
改进方案
将上述代码中的generateXml()
,修改成:
private static boolean generateXml(String ssidName, String password) throws Exception { boolean flag = false; FileOperator.writeFile1(WLAN_FILE_DIR_PATH + "WLAN-simon.xml", WLAN_FILE_DIR_PATH + "\\WLAN-" + ssidName + ".xml"); flag = true; return flag; }
代码中的writeFile1()
的源码,我就不附加了,大家自行开发,其功能是通过IO流,实现文件复制。
为什么改进此方法?
从上述的完整代码,大家可以看出,生成wlan配置文件的方法其实就是用String
存储一个xml配置文件的模板。在生成时,用wlan名称和密码替换到相应位置,形成一个新的xml配置文件内容,然后使用IO流输出文件,从而生成一个新的wlan配置文件。
这个思路非常简单,而并通过调用第三方包实现。
但这个方法有个弊端,由于xml文件不是纯文本文件,有自己的格式,上述方法仅能生成xml文件的内容,使用IO流输出的xml文件是有问题的。打开文件,从表面上看没有问题,但后面添加配置文件时就会提示“文件损坏”,从而无法添加成功。
因此,改进的方法是通过IO流,复制wlan配置文件来生成新的wlan配置文件。
当然了,如此改进从表面上看,功能也是不完整的,因为没有替换wlan名称和密码。
不成功原因
为什么我没有继续开发了?
下图是一个wlan配置文件。
图中红框部分我找了一些资料,都没弄明白是做什么的。
我做了一个测试,先将一个成功连接的wlan配置文件删除(删除后连接自动断开),然后打开这个wlan的配置文件(删除前先导出了一份),仅修改这个hex
,然后,添加配置文件 → 连接wlan,结果无法连接成功。
可见,这个hex
至关重要,我猜测应该是wlan-id
之类的参数。至少目前,我不知道如何生成。
这个关键的hex
无法生成,整个流程就无法完成,后续的功能自然没必要继续开发了。
注:还有其他几个命令(如:删除、导出wlan配置文件),本文中就不列举了,大家有需要还需自行查找。
最后
本文为技术性文章,旨在阐述WIFI的连接过程,让大家对其有一个初步的了解,并不倡导大家实测,仅是抛砖引玉。
本文完结。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南